I'm struggling to pass the list of my subplots with different scales on sides using plt.twinx()
in each subplot to show all labels in a single legend box, but I get the following error:
AttributeError: 'list' object has no attribute 'get_label'
I have tried the following:
import matplotlib
print('matplotlib: {}'.format(matplotlib.__version__))
#matplotlib: 3.2.2
#Generate data
import pandas as pd
df = pd.DataFrame(dict(
Date = [1,2,3],
Male = [10,20,30],
Female = [20,30,10],
Others = [700,500,200]
))
print(df)
# Date Male Female Others
#0 1 10 20 700
#1 2 20 30 500
#2 3 30 10 200
# Create pandas stacked line plot
import numpy as np
import matplotlib.pyplot as plt
Userx = 'foo'
fig, ax = plt.subplots(nrows=2, ncols=1 , figsize=(20,10))
plt.subplot(211)
linechart1 = plt.plot(df['Date'], df['Male'], color='orange', marker=".", markersize=5, label=f"Leg1 for {Userx}" ) #, marker="o"
scatterchart2 = plt.scatter(df['Date'], df['Female'], color='#9b5777', marker='d', s=70 , label=f"Leg2 for {Userx}" )
plt.legend( loc='lower right', fontsize=15)
plt.ylabel('Scale1', fontsize=15)
plt.twinx()
linechart3, = plt.plot(df['Date'], df['Others'], color='black', marker=".", markersize=5, label=f"Leg3 for {Userx}" ) #, marker="o"
#lns123 = [linechart1,scatterchart2,linechart3]
#plt.legend(handles=lns123, loc='best', fontsize=15)
plt.legend( loc='best', fontsize=15)
plt.ylabel('Scale2', fontsize=15)
plt.xlabel('Timestamp [24hrs]', fontsize=15, color='darkred')
plt.ticklabel_format(style='plain')
#lns123 = [linechart1,scatterchart2,linechart3]
#plt.legend(handles=lns123, loc='best', fontsize=15)
#plt.legend(handles=[linechart1[0],scatterchart2[0],linechart3[0]], loc='best', fontsize=15)
plt.subplot(212)
barchart1 = plt.bar(df['Date'], df['Male'], color='green', label=f"Leg1 for {Userx}" , width=1, hatch='o' ) #, marker="o"
barchart2 = plt.bar(df['Date'], df['Female'], color='blue', label=f"Leg2 for {Userx}" , width=0.9, hatch='O') #, marker="o"
plt.ticklabel_format(style='plain')
plt.ylabel('Scale1', fontsize=15)
plt.twinx()
barchart3 = plt.bar(df['Date'], df['Others'], color='orange', label=f"Leg3 for {Userx}", width=0.9 , hatch='/', alpha=0.1 ) #, marker="o"
plt.ylabel('Scale2', fontsize=15)
plt.ticklabel_format(style='plain')
plt.xlabel('Timestamp [24hrs]', fontsize=15, color='darkred')
bar123 = [barchart1,barchart2,barchart3]
plt.legend(handles=bar123, loc='best', fontsize=15)
#plt.show(block=True)
plt.show()
I have tried the following solutions unsuccessfully:
- ref1
- ref2
- using
,
- How do I make a single legend for many subplots? This is not my answer or I couldn't figure it out how I can handle the labels with
plt.twinx()
since it gathered all legends of subplots to a single legend box, while I want to include/integrate into individual legends for each subplot as I marked in the photo.
currently, I just use/duplicate plt.legend( loc='lower right', fontsize=15)
in subplot(211)
:
plt.subplot(211)
chart1 = ...
chart2 = ...
#here
plt.twinx()
chart3, = ...
#here
plt.subplot(212)
barchart1 = ...
barchart2 = ...
plt.twinx()
barchart3, = ...
bar123 = [barchart1,barchart2,barchart3]
plt.legend(handles=bar123, loc='best', fontsize=15)
and get the below output:
The interesting is I don't have this problem for bar plots
plt.bar()
.