Customising legend in Matplotlib - python

I’m trying to customise individual legend labels. In the example below, the legend contains two items. I’d like to make the text bold for only the second legend label.
Here’s a general outline of the code:
leg = plt.legend()
for text in leg.get_texts():
text.set_fontweight...
Here’s a runnable example:
import matplotlib.pyplot as plt
X=range(10)
Y=range(100,110)
Z=range(105,115)
plt.plot(X,Y,label='normal')
plt.plot(X,Z,label='bold')
fontweights=['normal','bold']
leg=plt.legend()
for fw,text in zip(fontweights,leg.get_texts()):
text.set_fontweight(fw)
plt.show()
Here's the output:
enter image description here
The plot produced shows that set_fontweight() changes both labels to bold. So is this a bug with set_fontweight(), or am I doing something wrong?
Similar functions, such as text.set_color(), can be used to modify legend labels individually.
Lastly, I’m using matplotlib version 3.2.2.
Thanks!

I have matplotlib 3.3.4 running, and get a bold and unbold legend entry - see attached image - so I think an upgrade should fix the problem.

Related

Is there a way to have a size/radius legend in Bokeh?

I'd like to create a scatter plot in Bokeh. Right now, I am using bokeh.plotting.figure.circle to create one. If I set the radius=radvar argument, where radvar is a valid string for my source, can I add some kind of legend so the viewer can see the scale?
Here's an example of what I'm doing now:
p=figure(tools=TOOLS)
p.circle(
x=xvar,
y=yvar,
radius=radvar,
radius_units='screen',
color={
'field':colorvar,
'transform':color_mapper},
source=data)
Seaborn has support for this kind of legend. Here's an example I found on the internet:
I'm not picky with howthe scale is shown. It could be just outlines, for example.
for legend, as far as i know, no. but for glyphs, yes. points.glyph.size (points name refers to points = p.scatter(...),) you could create size in data and create different sizes.
`

How to save a fig with a title above?

I created two graphs with a title for each ("petit titre") and a large title for both of them ("GRAND TITRE"). To nicely display the graph on my jupyter notebook, I anchored them as follow:
ax.set_title('petit titre A', pad=25, loc='left')
and
fig.suptitle("GRAND TITRE", y=1.10)
Then, jupyter displays this following graph:
Now, and here is my trouble, I would like to save it:
fig.savefig(os.path.join(path_img, 'Fig1.png'), dpi=600)
fig.savefig(os.path.join(path_img, 'Fig1.pdf'))
However, what I finaly get is this:
I do understand that, cause of my title anchored with an y-value = 1.1, I'm above the fig. But, it seems to me the only way to nicely organise my graph. How can I do to ask a plot taking into account the "grand titre" ? Idem if I have a legend box?
In advance, thanks for your help.
Best,
Try plt.figure(constrained_layout=True) when creating the figure and not anchoring the subtitle (i.e. just fig.suptitle("GRAND TITRE")). https://matplotlib.org/stable/tutorials/intermediate/constrainedlayout_guide.html#suptitle
Or, if you really want to anchor outside the figure, try fig.savefig(os.path.join(path_img, 'Fig1.png'), dpi=600, bbox_inches='tight') (https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure.savefig)

Legend title pad in matplotlib

I would like the title in the legend of my matplotlib figure to be more distant from the content of the legend. Currently, I have the following:
I see the set_title function of the Legend class accepts a prop dictionary, which should be the one described in the text properties page. This one contains the field bbox, where a pad property could be added. But when I try something like the following
legend.set_title('Legend', prop={'bbox':{'pad':somepad}})
python complains that bbox is not an accepted parameter.
I'm using matplotlib 2.1.0 under Python 3.6.3 on Arch Linux.
An obvious workaround would be add a linebreak, like this:
legend.set_title('Legend\n ')
Although one might like the result, matplotlib has the great advantage that everything can be configured to the slightest detail, so I'm looking for a solution which gives me more fine-grained control over this spacing.
Of course introducing a linebreak in the title text as legend.set_title('Legend\n ') is a valid option.
If you don't like that you can set the separation between title and legend handle box manually as
legend._legend_box.sep = 20
Complete example:
import matplotlib.pyplot as plt
plt.plot([1,2], label="some")
plt.plot([1,3], label="label")
legend = plt.legend(title="Legend title", ncol=2)
legend._legend_box.sep = 20
plt.show()
The default separation is labelspacing * fontsize, hence
plt.rcParams["legend.labelspacing"] * plt.rcParams["font.size"] == 0.5 * 10 == 5

python matplotlib make everything bold

Well , I am making some plots and wants to make everything in bold font. I can can use weight="bold" to make bold font of label to ticks. Can also use the prop={'weight':'bold'} to make the legends lines bold, but I can't make the legend title bold. So, 1st question is there a way to make the legend title bold?
2nd,I tried to used matplotlib latex support to make the title bold, that did it but if I use rc('text', usetex=True) I cant use weight=bold and have to use \textbf{} everytime, also how do I make the ticks bold in this way.
3rd , If I use latex support then the font changes that I don't like. How do use the normal matplotlib font with using latex?
Making everything bold is rather easy. Just add
plt.rcParams["font.weight"] = "bold"
plt.rcParams["axes.labelweight"] = "bold"
at the top of the script.
import matplotlib.pyplot as plt
plt.rcParams["font.weight"] = "bold"
plt.rcParams["axes.labelweight"] = "bold"
plt.plot([2,3,1], label="foo")
plt.plot([3,1,3], label="bar")
plt.legend(title="Legend Title")
plt.xlabel("xLabel")
plt.show()
You should be able to pass parameters into the plt.legend using the prop argument
legend_prop = {'weight':'bold'}
plt.plot(x, y, label='some label')
plt.legend(prop=legend_prop)
This would give you bold labels. Is this not what you're looking for?

How to change legend fontname in matplotlib

I would like to display a font in Times New Roman in the legend of a matplotlib plot.
I have changed all other tick labels/axis labels/titles to Times New Roman, and have searched the documentation but I can only find how to change the font size in a legend using the prop
argument in pyplot.legend()
Of course straight after posting, I found the answer. Solution for anyone else with the same issue:
import matplotlib as mpl
mpl.rc('font',family='Times New Roman')
This wasn't showing up in google results so I'm going to post it as an answer. The rc parameters for font can be used to set a single default font.
Solution for anyone else with the same issue:
import matplotlib as mpl
mpl.rc('font',family='Times New Roman')
The .rc solution given changes the default font for all drawing.
Here is a solution for doing this when you don't want to change all the fonts, but just the font properties of the legend of this particular graph (a legend belonging to a particular axis object):
L = ax.legend()
plt.setp(L.texts, family='Consolas')
This allows you to choose a different font for the legend and the axes. I found this helpful when I needed a monospace font for my legend, but not for the axes -- allowing me to create a neat legend like this:
Note how the title is a different font than the legend - this gives me an alignment of numbers that would otherwise be hard to achieve.
I think this is the better way.
import matplotlib.font_manager as fm
## your font directory
font_path = '/Users/frhyme/Library/Fonts/BMDOHYEON_otf.otf'
## font_name
font_name = fm.FontProperties(fname=font_path).get_name()
plt.legend(prop={'family':font_name, 'size':20})

Categories

Resources