Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plot two pandas time series on same plot with legends and secondary y-axis?

I want to plot two time series on the same plot with same x-axis and secondary y-axis. I have somehow achieved this, but two legends are overlapping and is unable to give label to x-axis and secondary y-axis.I tried putting two legend at upper-left and upper-right, but it is still not working.

Code:

plt.figure(figsize=(12,5))

# Number of request every 10 minutes
log_10minutely_count_Series = log_df['IP'].resample('10min').count()
log_10minutely_count_Series.name="Count"
log_10minutely_count_Series.plot(color='blue', grid=True)
plt.legend(loc='upper left')
plt.xlabel('Number of request ever 10 minute')

# Sum of response size over each 10 minute
log_10minutely_sum_Series = log_df['Bytes'].resample('10min').sum()
log_10minutely_sum_Series.name = 'Sum'
log_10minutely_sum_Series.plot(color='red',grid=True, secondary_y=True)
plt.legend(loc='upper right')
plt.show()

enter image description here

Thanks in advance

like image 261
Om Prakash Avatar asked Sep 02 '17 08:09

Om Prakash


People also ask

How do you plot two time series together?

First, we create a data vector that has data for all the time series that have to be drawn. Then we plot the time series using the first dataset and plot() function. Then add other time series using line() function to the existing plot.


Video Answer


2 Answers

The following solutions work for me. The first places both lines in one legend, the second splits lines into two legends, similar to what you are trying above.

Here is my dataframe

ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list('ABCD'))

One legend solution, credit to this StackOverflow post

plt.figure(figsize=(12,5))
plt.xlabel('Number of requests every 10 minutes')

ax1 = df.A.plot(color='blue', grid=True, label='Count')
ax2 = df.B.plot(color='red', grid=True, secondary_y=True, label='Sum')

h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()


plt.legend(h1+h2, l1+l2, loc=2)
plt.show()

One legend matplotlib plot

Split legend solution

plt.figure(figsize=(12,5))
plt.xlabel('Number of requests every 10 minutes')

ax1 = df.A.plot(color='blue', grid=True, label='Count')
ax2 = df.B.plot(color='red', grid=True, secondary_y=True, label='Sum')

ax1.legend(loc=1)
ax2.legend(loc=2)

plt.show()

Split legend matplotlib plot

like image 51
Josh Avatar answered Oct 10 '22 18:10

Josh


It can be as simple as:

df.loc[:,['A','B']].plot(secondary_y=['B'], mark_right=False, figsize = (20,5), grid=True)

mark_right=False means that 'B' label is on the left axis.

like image 28
Sarah Avatar answered Oct 10 '22 18:10

Sarah