I have a problem about defining many color in legend part of bar graph.
After I've done some essential process, I draw a figure by using the code shown below.
ax = df.plot(kind='bar', stacked=True,figsize=(13,10))
plt.title('Title List', fontsize=20)
leg = ax.legend(loc='center right', bbox_to_anchor=(1.3, 0.5), ncol=1)
plt.tight_layout()
plt.savefig('images/image1.png', bbox_inches = "tight")
plt.show()
When I run the code, some colors are the same.
How can I define unique colors in legend part?
Here is the screenshot
My answer:
After I defining colormap as rainbow, All defined colors in legend parts became unique.
Change to code
ax = df.plot(kind='bar', stacked=True,figsize=(13,10))
to
ax = df.plot(kind='bar', stacked=True,figsize=(13,10), colormap='rainbow')
I would like to create a plot, consisting of lines and markers, but using different colors for both. My approach was to use two averlapped plots:
#!/usr/bin/env python3
import matplotlib.pyplot as plt
fig,ax1 = plt.subplots()
x=[0,1,2,3]
y=[10,20,40,80]
ax1.plot(x, y,color='#FF0000', alpha=0.5, linewidth=2.2,label='Example line',zorder=9)
ax1.scatter(x, y ,marker='o',s=80,color='black',alpha=1,label='Example marker',zorder=10)
ax1.set_ylim([0,150])
ax1.set_xlim([0,5])
ax1.legend(loc='upper right')
plt.show()
plt.close()
Output:
The problem here is that, naturally, line (----) and marker (X) are showed separately in legend.
Would you know a way to show both marker and line together in legend, that is to say, in a composed line and marker (---X---) label?
Perhaps just specify your marker attributes in the first plot call... e.g.
ax1.plot(x, y,color='#FF0000', linewidth=2.2, label='Example line',
marker='o', mfc='black', mec='black', ms=10)
I'm trying to create a parallelogram in PyPlot. I'm not up to drawing the parallelogram--first I'm putting in the vector arrows--using the following code:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.axis([-5,5,-5,5])
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.grid()
plt.arrow(0,0, 3,1, head_width=0.2, color='r', length_includes_head=True, label='u')
plt.arrow(0,0, 1,3, head_width=0.2, color='r', length_includes_head=True, label='v')
plt.arrow(0,0, 4,4, head_width=0.2, color='r', length_includes_head=True, label='u+v')
plt.legend()
This returns the following error:
No handles with labels found to put in legend.
I'm not sure why, because, based on the documentation for plt.arrow(), label is an acceptable kwarg, and plt.legend() should ostensibly be reading that. The rest of the figure draws fine; it's just missing the legend.
It might be late but for anyone with the same issue the solution is using the method legend() for the corresponding ax not as for plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.axis([-5,5,-5,5])
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.grid()
plt.arrow(0,0, 3,1, head_width=0.2, color='r', length_includes_head=True, label='u')
plt.arrow(0,0, 1,3, head_width=0.2, color='r', length_includes_head=True, label='v')
plt.arrow(0,0, 4,4, head_width=0.2, color='r', length_includes_head=True, label='u+v')
ax.legend()
You can explicitly define the elements in the legend.
For full control of which artists have a legend entry, it is possible to pass an iterable of legend artists followed by an iterable of legend labels respectively. Reference
Example:
arr1 = plt.arrow(0,0, 3,1, head_width=0.2, color='r', length_includes_head=True)
arr2 = plt.arrow(0,0, 1,3, head_width=0.2, color='g', length_includes_head=True)
arr3 = plt.arrow(0,0, 4,4, head_width=0.2, color='b', length_includes_head=True)
plt.xlim(0,5)
plt.ylim(0,5)
plt.legend([arr1, arr2, arr3], ['u','v','u+v'])
The error is thrown because you haven't specified the label text
Either do something like this
plt.hist([x01, x02,x03], color=["lightcoral","lightskyblue","slategrey"], stacked=True,
label=['Supressed','Active','Resolved'])
plt.legend()
Or
Do not use plt.legend() if you haven't specified the label text as in the following WRONG example:
plt.hist([x01])
plt.legend()
The above will throw the same error, so either remove legend function or provide what it needs -> label.
Side note: Here x01 is just a list of number for which I am creating a histogram, in the first example they are three list of numbers to create stacked bar chart
The bottom line is this error is thrown because of not specifying legend text and calling/initializing a legend
I had this error when using labels which started with an underscore
plt.plot(x, y, label = '_bad_name')
Removing the front underscore from the labels solved the issue
Assuming you have 2 plots ax and ax2, we can:
get the labels from each y-axis via ax.get_label()
.legend allows an array to be ingested
fig.legend([ax.get_ylabel(), ax2.get_ylabel()], loc='upper right')
I had this same issue and solved it with an understanding that .legend() function has to be after all the instructions that deal with the label attribute. This includes both plt and ax.
So moving ax.legend(*) as the last command.
I hope this helps you too.
Change
ax.plot(-trip_df.stop_lat, -trip_df.stop_lon, label = trip_id)
plt.legend()
to
ax.plot(-trip_df.stop_lat, -trip_df.stop_lon, label = trip_id)
ax.legend()
plt.legend()
I face similar problem like No handles with labels found to put in legend.
First My code look like
figure, axis = pyplot.subplots(nrows=1,ncols=2, figsize=(15, 6), tight_layout=True)
axis[0].legend(title='Country', title_fontsize = 12) #this line
axis[0].pie(x=piechart_result['value_eur'],labels=piechart_result['short_name'])
axis[1].pie(x=piechart_result['value_eur'],labels=piechart_result['short_name')
pyplot.show()
Then I changed to
figure, axis = pyplot.subplots(nrows=1,ncols=2, figsize=(15, 6), tight_layout=True)
axis[0].pie(x=piechart_result['value_eur'],labels=piechart_result['short_name'])
axis[0].legend(title='Country', title_fontsize = 12) # this line
axis[1].pie(x=piechart_result['value_eur'],labels=piechart_result['short_name')
pyplot.show()
this work for me in colab notebook
I have a errorbar plot with only one data point (i.e. one errorbar) per data set. Therefore I would like to have a single errorbar symbol in the legend as well.
The single one can be achieved by legend(numpoints=1). Using this in the following code:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.errorbar(x=[0.3], y=[0.7], xerr=[0.2], marker='+', markersize=10, label='horizontal marker line')
ax.errorbar(x=[0.7], y=[0.3], yerr=[0.2], marker='+', markersize=10, label='is too long')
ax.set_xlim([0,1])
ax.set_ylim([0,1])
ax.legend(numpoints=1) # I want only one symbol
plt.show()
results in these symbols in the legend:
As you see, the errorbars are mixed up with horizontal lines, that make sense when there are more than one error bars to be connected (using legend(numpoints=2) or higher), but look ugly in my case.
How can I get rid of the lines in the legend markers without loosing the errorbars?
This is due to the default settings in matplotlib. At the start of your code you can change them by changing the settings using rcParams:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['legend.handlelength'] = 0
mpl.rcParams['legend.markerscale'] = 0
fig, ax = plt.subplots()
ax.errorbar(x=[0.3], y=[0.7], xerr=[0.2], marker='+', markersize=10, label='horizontal marker')
ax.errorbar(x=[0.7], y=[0.3], yerr=[0.2], marker='+', markersize=10, label='is gone')
ax.set_xlim([0,1])
ax.set_ylim([0,1])
ax.legend(numpoints=1)
plt.show()
Note: This changes the settings for all the graphs that will be plotted in the code.
I have the same problem as in this post: Where the user wants to delete repeated entries in the legend:
Stop matplotlib repeating labels in legend
The answer works for me as well, however, when I use it, the legend format is completely lost. This happens when I apply the ax.legend(handles, labels) method. The following code (copied from http://matplotlib.org/examples/pylab_examples/legend_demo.html) illustrates this issue:
# Example data
a = np.arange(0,3, .02)
b = np.arange(0,3, .02)
c = np.exp(a)
d = c[::-1]
# Create plots with pre-defined labels.
# Alternatively, you can pass labels explicitly when calling `legend`.
fig, ax = plt.subplots()
ax.plot(a, c, 'k--', label='Model length')
ax.plot(a, d, 'k:', label='Data length')
ax.plot(a, c+d, 'k', label='Total message length')
# Now add the legend with some customizations.
legend = ax.legend(loc='upper center', shadow=True)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels )
# The frame is matplotlib.patches.Rectangle instance surrounding the legend.
frame = legend.get_frame()
frame.set_facecolor('0.90')
# Set the fontsize
for label in legend.get_texts():
label.set_fontsize('large')
for label in legend.get_lines():
label.set_linewidth(1.5) # the legend line width
plt.show()
Result without using 'ax.legend(handles, labels)':
Resul using 'ax.legend(handles, labels)':
Any advice would be most welcomed
EDIT 1: Typo 'without' corrected
You have issued legend() call twice and the second time it is called without formatting arguments, replace:
legend = ax.legend(loc='upper center', shadow=True)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels )
with
handles, labels = ax.get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
ax.legend(by_label.values(), by_label.keys(), loc='upper center', shadow=True)
Should do the trick.