0

I need to create a plot using matplotlib.pyplotthat shows distance between Earth and Mars over time. In addition to that some months e.g. March to August should be shown in a different color than the other months. Data is provided from an array containing the date, distance and also a flag indicating whether the date is in the March to August-span or not.

The array containing the whole data is called master_array. First column containing the date, second the distance; seventh the s/w-flag. ('s' for summer, 'w' for winter).

I tried to make use of the fact that pyplot.plot switches color for every single .plot command in a way that I first plot the winter months and in a second plot the summer months.

import numpy as np
from matplotlib import pyplot as plt

def md_plot2(dt64=np.array, md=np.array):
    """Erzeugt Plot der Marsdistanz (y-Achse) zur Zeit (x-Achse)."""
    plt.style.use('seaborn-whitegrid')

    y, m, d = dt64.astype(int) // np.c_[[10000, 100, 1]] % np.c_[[10000, 100, 100]]
    dt64 = y.astype('U4').astype('M8') + (m-1).astype('m8[M]') + (d-1).astype('m8[D]')

    wFilter = np.argwhere(master_array[:,6] == 0)
    sFilter = np.argwhere(master_array[:,6] == 1)

    plt.plot(dt64[wFilter], md[wFilter], label='Halbjahr der fallenden \nTemperaturen')
    plt.plot(dt64[sFilter], md[sFilter], label='Halbjahr der steigenden \nTemperaturen')

    plt.xlabel("Zeit in Jahren\n")
    plt.xticks(rotation = 45)
    plt.ylabel("Marsdistanz in AE\n(1 AE = 149.597.870,7 km)")
    plt.legend(loc='upper right', frameon=True)

plt.figure('global betrachtet...') # diesen Block ggf. auskommentieren
#plt.style.use('seaborn-whitegrid')
md_plot2(master_array[:,0], master_array[:,1]) # Graph

plt.show()
#plt.close()

Problem now is that between the last point of a summer period and first point of the following summer period the plot for summers shows a line where the other plot (for winters) shows the correct data of the winter period that lays between those two summers. The data is containing many data points what will lead to many segments of those two colors. How can I stop the plot to draw a line, when the next data point is more that one day in the future? Is there maybe another method of pyplot for this task?

As I wrote a lot of code in the script where this belongs without using pandas I would be very happy to find a solution to this problem not using pandas as I try to avoid it because I don't want to bloat my script when there is a way to get the task done by using the modules I am already using. I also read it would decrease the speed here.

12
  • 2
    Kudos for your philosophy on not using Pandas when you don't need it – after all, it probably wouldn't even help in this case! Commented Apr 1, 2019 at 10:22
  • You need to 'cut' your data into parts, e.g. plot each summer separately with the same colour and then plot each winter separately as well. This way you will skip the connecting lines. Another solution would be to set all winter values to np.nan, then draw the summer line for all summers, then do the reverse for the winters. Commented Apr 1, 2019 at 10:27
  • 1
    @AKX Thanks! I'm adding this disclaimer now, because everyone during this project suggested to use pandas and now this is the last problem (hopefully) to solve and it works completly without any line of pandas ¯\_(ツ)_/¯ Commented Apr 1, 2019 at 10:28
  • It looks like this question would be what you're after. Of course it does use pandas, because that makes it a bit simpler. I do not entirely understand your custom datetime format used here, so if you need further help, maybe you want to explain what the input dt64 is, and how that relates to dates. Commented Apr 1, 2019 at 12:56
  • 1
    I updated the original question's answer with a new piece of code that does not use pandas. Commented Apr 2, 2019 at 11:19

2 Answers 2

1

The multicolored_line example looks like what you're going for.

Also see this article for more information about the colormap system in Matplotlib.

Sign up to request clarification or add additional context in comments.

4 Comments

This looks more like a comment to me than an actual answer. Maybe this turns out to be a duplicate in the end?
I know it's a link-only-ish answer, but I didn't feel it would be worth the while to copy in the examples and diagrams from the linked articles.
@AKX could you explain the following section of multicolored_line for my case? points = np.array([x, y]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) I don't know how to customize these section for my code.
more specified: I don't know how to customize the line segments = np.concatenate([points[:-1], points[1:]], axis=1) in my case...
0

Here is a simple one, just "overwrite" part where you want another color:

import matplotlib.pyplot as plt
%matplotlib inline
x = list(range(10))
y = [ 2*i for i in x]
x_1 = x[4:7]
y_1 = y[4:7]
plt.plot(x,y)
plt.plot(x_1,y_1)
plt.show()

1 Comment

Nice idea but not handy if you have many segments. Moreover it won't cover the unwanted lines from the code in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.