Reputation: 99
I'm trying to make a combined legend in a Jupiter Notebook. When I try various codes from examples, I get an empty legend. The examples work fine copied, but something goes wrong when I implement it into my own code. Any ideas?
Result:
Code:
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(15,10))
l1 = ax1.plot(time[18206:18226],tpm2[18206:18226], 'r', label='Chilbolton 2')
ax1.set_title('Difference in Hydrometeor Count Per Minute Over Time')
ax1.set_ylim([0,14000])
ax1.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l2 = ax2.plot(time[18206:18226],tpm1[18206:18226], 'b', label='Chilbolton 2')
ax2.set_ylim([0,14000])
ax2.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l3 = ax3.plot(time[18206:18226],diff[18206:18226], 'k', label='D.P.M.')
ax3.plot(time[18206:18226],np.zeros(20),'k--')
ax3.set_xlabel('Time (10th February to 29th April)')
ax3.set_ylim([-3000,3000])
ax3.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
#plt.legend( handles=[l1, l2, l3], labels=['l1','l2','l3'],loc="upper left", bbox_to_anchor=[0, 1],
# ncol=2, shadow=True, title="Legend", fancybox=True)
fig.legend((l1, l2, l3), ('Line 1', 'Line 2', 'Line 3'), 'upper left')
# ('Chilbolton 2','Chilbolton 2','D.P.M.'), loc = (0.5, 0), ncol=1 )
plt.ylabel('Hydrometeor Count (#)')
# Fine-tune figure; make subplots close to each other and hide x ticks for
# all but bottom plot.
#f.subplots_adjust(hspace=0)
plt.setp([a.get_xticklabels() for a in f.axes[-1:]], rotation=90, visible=True)
plt.show()
Upvotes: 1
Views: 3413
Reputation: 1814
ax.plot()
returns a list of line artists, even if you are only plotting just one line. So when you write l1 = ax1.plot(...)
, a list of length-1 is assigned to l1
. Ditto for l2
and l3
. This causes a problem for fig.legend()
, which needs just the line artist objects.
You can fix this problem in a number of ways. The most commonly-used method is syntax like:
l1, = ax1.plot(...
Inserting the comma assigns the only element of the returned list to l1
. You could also do l1 = ax1.plot(...)[0]
. Or, in your case, you could modify your legend call to fig.legend((l1[0],l2[0],l3[0]),...)
.
So,
import maptlotlib.pyplot as plt
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(15,10))
l1, = ax1.plot([0,1],[0,14000])
ax1.set_title('Difference in Hydrometeor Count Per Minute Over Time')
ax1.set_ylim([0,14000])
ax1.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l2, = ax2.plot([0,1],[0,14000])
ax2.set_ylim([0,14000])
ax2.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l3, = ax3.plot([0,1],[-3000,3000])
ax3.plot(time[18206:18226],np.zeros(20),'k--')
ax3.set_xlabel('Time (10th February to 29th April)')
ax3.set_ylim([-3000,3000])
ax3.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
fig.legend((l1, l2, l3), ('Line 1', 'Line 2', 'Line 3'), 'upper left')
Upvotes: 1
Reputation: 46759
As a workaround, you could create your own custom legend using Patch
:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import random
tx = range(20)
t1 = np.random.randint(0, 14000, 20)
t2 = np.random.randint(0, 14000, 20)
t3 = np.random.randint(-3000, 3000, 20)
labels = ['Chilbolton 2', 'Chilbolton 2', 'D.P.M.']
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True, figsize=(15,10))
l1 = ax1.plot(tx, t1, 'r', label=labels[0])
ax1.set_title('Difference in Hydrometeor Count Per Minute Over Time')
ax1.set_ylim([0,14000])
ax1.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l2 = ax2.plot(tx,t2, 'b', label=labels[1])
ax2.set_ylim([0,14000])
ax2.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
l3 = ax3.plot(tx,t3, 'k', label=labels[2])
ax3.plot(tx,np.zeros(20),'k--')
ax3.set_xlabel('Time (10th February to 29th April)')
ax3.set_ylim([-3000,3000])
ax3.grid(b=True, which='major', color='k', linestyle='--', alpha=0.5)
# Create custom legend
leg1 = mpatches.Patch(color='r')
leg2 = mpatches.Patch(color='b')
leg3 = mpatches.Patch(color='k')
fig.legend(handles=[leg1, leg2, leg3], labels=labels, loc="upper left")
plt.ylabel('Hydrometeor Count (#)')
# Fine-tune figure; make subplots close to each other and hide x ticks for
# all but bottom plot.
#f.subplots_adjust(hspace=0)
plt.setp([a.get_xticklabels() for a in fig.axes[-1:]], rotation=90, visible=True)
plt.show()
Giving you:
Upvotes: 0