ailsa_naismith
ailsa_naismith

Reputation: 343

Vertical lines do not appear in matplotlib plot

I have a code which allows me to plot two timeseries of data. I also have a number of events which I plot as a series of vertical lines within the timeseries. I have this timeseries for three years: 2015, 2016, and 2017. My code works well for 2015 and 2016, and I produce a graph like so (this is for 2016):Timeseries data (red and blue) and event data (dotted vertical lines) plotted.

However, when I plot my data for 2017, I cannot reproduce the vertical lines for event data, as shown below (it's hard to see, but in this graph there are no vertical dashed lines as there were in first one):

Timeseries data (red and blue) but no event data plotted.

Any ideas as to why my code does not work for 2017? The data are stored in .csv files, and event data is plotted from a column of data in the .csv file that I have converted into a series of datetime objects. I have checked, and the formats for the 2015, 2016 and 2017 .csv files remain the same.

FYI, here is the code that I have used to plot:

#Change format of "dates" column from string to datetime object    
FMT = '%d/%m/%Y'
dtlist = []
for i in range(0, len(dates)):
    dtlist.append(datetime.datetime.strptime(dates[i], FMT))  


##EVENT:
#Remove all values where there is no event
df2 = df_17[pd.notnull(df_17['event'])]

#Convert event values to datetime objects
df2['event'] = pd.to_datetime(df2['event'], format="%d/%m/%Y")
event_list = df2['event'].tolist()

#Plot timeseries on graph
fig, ax1 = plt.subplots(figsize=(18, 6))
plt.plot(dtlist, series_1, color='b', label='Series 1')
ymin, ymax = ax1.get_ylim()
for value in event_list:
    plt.axvline(x=value, ymin=ymin, ymax=ymax-1, color='k', linewidth=1.0, linestyle='--')    
ax1.set_xlabel('Time')
ax1.set_ylabel('Series 1')

ax2=ax1.twinx()
ax2.plot(dtlist, series_2, color='r', label='Series_2')
ax2.set_ylabel('Series 2')

plt.legend
plt.show()

Any help much appreciated!

Upvotes: 4

Views: 8567

Answers (2)

ailsa_naismith
ailsa_naismith

Reputation: 343

Many thanks to all who contributed. Warren Weckesser gave the correct solution: using axvline understands that ymin and ymax are determined in fractions between 0 and 1 of the y-axis. Removing them, and using this line instead:

plt.axvline(x=value, color='k', linewidth=1.0, linestyle='--') 

solved the issue. My output graph:2017 Events plotted.

Cheers!

Upvotes: 0

Warren Weckesser
Warren Weckesser

Reputation: 114956

In a comment, you say you got the idea for your values for ymin and ymax from Pandas graphing a timeseries, with vertical lines at selected dates, but the example there uses vlines, not axvline. vlines uses the data scale. axvline expects values between 0 and 1 for ymin and ymax. That is, the y values are specified in fractions (between 0 and 1) of the y-axis. If you specify, say, ymin=0 and ymax=0.5, you will get a vertical line that goes from the bottom of the axis to the middle of the axis, regardless of the current data scale of the plot. If you zoom in or out, or pan up or down, the half-height vertical line remains.

The default values for ymin and ymax are 0 and 1, respectively, so to get a line that goes from the bottom to the top, you could simply leave out the arguments.

Try this:

    plt.axvline(x=value, color='k', linewidth=1.0, linestyle='--') 

Upvotes: 8

Related Questions