Reputation: 129
I have 2 DFs describing 2 objects with 2 factors they have in common. How do I build 2 charts with a single common legend ?
I try with matplotlib subplots, but i dont' understand how works the legend.
inport pandas as pd
the 1st DF describing Jup :
df1=pd.DataFrame({'Dates' : pd.date_range('2002-02-04',periods=3),
'fac1' : [1,1.02,0.98],
'fac2':[2,2.05,2.06]
})
the 2d DF describing Tit
df2=pd.DataFrame({'Dates' : pd.date_range('2002-02-04',periods=3),
'fac1' : [1,0.95,1.10],
'fac2':[0.5,0.6,0.55]
})
I can plot this separately like this :
df1.plot(x=df1.iloc[:,0].name,
y=df1.iloc[:,1:3].columns,
legend=True,title='jup')
and this :
df2.plot(x=df2.iloc[:,0].name,
y=df2.iloc[:,1:3].columns,
legend=True,title='tit')
But how do this with a matplotlib style subplots with a common and single legend ?
Upvotes: 1
Views: 5832
Reputation: 39072
This is an alternate way to do it. The idea is to create two axis objects and then pass them to plot the two DataFrames. Then use legend=False
for the first plot as the legends of both the plots are the same. Now you can set the position of the common legend outside the figure using loc
.
Complete working answer
import pandas as pd
import matplotlib.pyplot as plt
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(9, 3))
df1=pd.DataFrame({'Dates' : pd.date_range('2002-02-04',periods=3),
'fac1' : [1,1.02,0.98],'fac2':[2,2.05,2.06]})
df2=pd.DataFrame({'Dates' : pd.date_range('2002-02-04',periods=3),
'fac1' : [1,0.95,1.10], 'fac2':[0.5,0.6,0.55]})
df1.plot(x=df1.iloc[:,0].name, y=df1.iloc[:,1:3].columns, legend=False, title='jup', ax=ax[0])
df2.plot(x=df2.iloc[:,0].name, y=df2.iloc[:,1:3].columns, legend=True, title='tit', ax=ax[1])
ax[1].legend(loc=(1.1, 0.5))
plt.show()
Upvotes: 1
Reputation: 227
Checkout this recipe from Matplotlib docs. The key is that you need to create your figure and axes first with subplots
and add your legend to the figure instead of the axes instances:
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1) # change layout to (1, 2) for side-by-side plots
l1 = ax1.plot(df1.set_index('Dates'))
l2 = ax2.plot(df2.set_index('Dates'))
fig.legend(l1, ['fac1', 'fac2']) # You only need to add one set of lines and labels
ax1.set_title('jup')
ax2.set_title('tit')
Also you only need to set Dates
as index on the dataframes, and pandas
and matplotlib
will handle the rest nicely.
Upvotes: 0