I would like to adjust the height of the errorbars as shown in the matplotlib legend, so as to avoid that they are bumping into each other (shown below).
I'm aware of this post Matplotlib: Don't show errorbars in legend that discusses how to remove the errorbars, but I don't know what to do to adjust the handler so that the error bars are still there, just shortened.
A working example with overlapping errorbars is:
import matplotlib
font = {'family' : 'serif',
'serif': 'Computer Modern Roman',
'weight' : 'medium',
'size' : 19}
matplotlib.rc('font', **font)
matplotlib.rc('text', usetex=True)
fig,ax1=plt.subplots()
h0=ax1.errorbar([1,2,3],[1,2,3],[1,2,1],c='b',label='$p=5$')
h1=ax1.errorbar([1,2,3],[3,2,1],[1,1,1],c='g',label='$p=5$')
hh=[h0,h1]
ax1.legend(hh,[H.get_label() for H in hh],bbox_to_anchor=(0.02, 0.9, 1., .102),loc=1,labelspacing=0.01, handlelength=0.14, handletextpad=0.4,frameon=False, fontsize=18.5)
I'm using version 1.5.1 of matplotlib, but I don't think that that's the issue.
You can use the handler_map
kwarg to ax.legend
to control the legend handles.
In this case, you want to use the HandlerErrorbar
handler from matplotlib.legend_handler
, and set the xerr_size
option. By default, this is 0.5, so we just need to reduce that number to something approriate for the plot.
Taking guidance from the legend guide, we can see how to use handler_map
. To just change one of the errorbar handles, we could do this:
handler_map={h0: HandlerErrorbar(xerr_size=0.3)}
Assuming you want to change all of the errorbar handles in the same way, you can change h0
to type(h0)
:
handler_map={type(h0): HandlerErrorbar(xerr_size=0.3)}
Note that this is just a quick way to tell handler_map
how to change all Errorbars
. Note that this is equivalent to doing the following:
from matplotlib.container import ErrorbarContainer
...
ax1.legend(...
handler_map={ErrorbarContainer: HandlerErrorbar(xerr_size=0.3)}
...)
Using the type(h0)
shorthand just means you don't need to have the extra import of ErrorbarContainer
.
Putting this together in your minimal example:
import matplotlib
import matplotlib.pyplot as plt
# Import the handler
from matplotlib.legend_handler import HandlerErrorbar
font = {'family' : 'serif',
'serif': 'Computer Modern Roman',
'weight' : 'medium',
'size' : 19}
matplotlib.rc('font', **font)
matplotlib.rc('text', usetex=True)
fig,ax1=plt.subplots()
h0=ax1.errorbar([1,2,3],[1,2,3],[1,2,1],c='b',label='$p=5$')
h1=ax1.errorbar([1,2,3],[3,2,1],[1,1,1],c='g',label='$p=5$')
hh=[h0,h1]
ax1.legend(
hh, [H.get_label() for H in hh],
handler_map={type(h0): HandlerErrorbar(xerr_size=0.3)}, # adjust xerr_size to suit the plot
bbox_to_anchor=(0.02, 0.9, 1., .102),
loc=1, labelspacing=0.01,
handlelength=0.14, handletextpad=0.4,
frameon=False, fontsize=18.5)
plt.show()
For proof this has worked, you can compare this to the original image, before I adjusted the errorbar sizes: