Reputation: 2332
What I'm trying to do is control the fontsize of individual entries in a legend in pyplot. That is, I want the first entry to be one size, and the second entry to be another. This was my attempt at a solution, which does not work.
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1,5,0.5)
plt.figure(1)
plt.plot(x,x,label='Curve 1')
plt.plot(x,2*x,label='Curve 2')
leg = plt.legend(loc = 0, fontsize = 'small')
leg.get_texts()[0].set_fontsize('medium')
plt.show()
My expectation is that the default size for all legend entries would 'small'. I then get a list of the Text objects, and change the fontsize for only a single Text object to medium. However, for some reason this changes all Text object fontsizes to medium, rather than just the single one I actually changed. I find this odd since I can individually set other properties such as text color in this manner.
Ultimately, I just need some way to change an individual entry's fontsize for a legend.
Upvotes: 7
Views: 5976
Reputation: 2514
A much easier method is possible, if you activate LaTeX for the text rendering in your plots. You achieve that effortless, with an extra command line after your 'imports':
plt.rc('text', usetex=True)
Now you can change the size of any particular string by specifying with an r
at the beginning of the string that is to be processed with LaTeX, and add your desired size command for LaTeX inside (\small, \Large, \Huge,
etc.).
For example:
r'\Large Curve 1'
Look at your adapted code. It took only minor changes!
import numpy as np
import matplotlib.pyplot as plt
plt.rc('text', usetex=True) #Added LaTeX processing
x = np.arange(1,5,0.5)
plt.figure(1)
#Added LaTeX size commands on the formatted String
plt.plot(x,x,label=r'\Large Curve 1')
plt.plot(x,2*x,label=r'\Huge Curve 2')
plt.legend(loc = 0, fontsize = 'small')
#leg.get_texts()[0].set_fontsize('medium')
plt.show()
So you get this:
Upvotes: 1
Reputation: 20695
It appears that the font of each legend entry is managed by an instance of matplotlib.font_manager.FontProperties
. The thing is: each entry doesn't have its own FontProperties
... they all share the same one. This is verified by writing:
>>> t1, t2 = leg.get_texts()
>>> t1.get_fontproperties() is t2.get_fontproperties()
True
So if you change the size of the first entry, the size of the second entry is automatically changed along with it.
The "hack" to get around this is to simply create a distinct instance of FontProperties
for each legend entry:
x = np.arange(1,5,0.5)
plt.figure(1)
plt.plot(x,x,label='Curve 1')
plt.plot(x,2*x,label='Curve 2')
leg = plt.legend(loc = 0, fontsize = 'small')
t1, t2 = leg.get_texts()
# here we create the distinct instance
t1._fontproperties = t2._fontproperties.copy()
t1.set_size('medium')
plt.show()
And now the sizing is correct:
Upvotes: 9