Matplotlib: Change the fontsize "midway" in text

I am aware of this question, which discusses how to "gloabally" change the fontsize in matplotlib. My use case is slightly different: I want the output to be sth like

Array 1 (number of elements: 100)

Array 1 (number of elements: 250)

So an MWE would be:

import numpy as np
from matplotlib import pyplot as plt

a = np.random.rand(100)
b = np.random.rand(250)
plt.hist(a, bins=100, label='Array 1 (number of elements: {})'.format(a.shape[0]))
plt.hist(b, bins=100, label='Array 2 (number of elements: {})'.format(b.shape[0]))
plt.legend()
plt.show()
plt.close()

How can the fontsize be changed only "locally" in matplotlib?

EDIT: Sorry if the output looks confusing, but the part in small fontsize should not be upper or lower, it should just be smaller.


I doubt that you can use matplotlib directly to change font size mid-label, but you can use LaTeX syntax to add superscripts like so:

import numpy as np
from matplotlib import pyplot as plt

a = np.random.rand(100)
b = np.random.rand(250)
plt.hist(a, bins=100, label=r'Array 1 $^\mathrm{{(number of elements:\ {})}}$'.format(a.shape[0]))
plt.hist(b, bins=100, label=r'Array 1 $^\mathrm{{(number of elements:\ {})}}$'.format(b.shape[0]))
plt.legend()
plt.show()

Note the need for double braces to get a literal brace in a format string, and the added '\ ' that is needed in math mode. (The font might actually the different this way if you use LaTeX rendering: \mathrm{} gives you a serif font. You could try \mathsf{} for sans instead, or put the whole label text in math mode with \mathrm{} to get a consistent look. This doesn't seem to matter with the default rendering engine.)

If you don't want to offset the baseline of the small text you can use latex size specifiers e.g. \scriptsize, \footnotesize, \tiny etc. (in math mode you'd have \scriptstyle and \scriptscriptstyle according to this answer on tex.SE). You need to enable LaTeX rendering for this to work, which will affect all of your subsequent figures:

# enable TeX rendering for all subsequent figures
plt.rc('text', usetex=True)

plt.hist(a, bins=100, label=r'Array 1 \footnotesize (number of elements: {})'.format(a.shape[0]))
plt.hist(b, bins=100, label=r'Array 2 \scriptsize (number of elements: {})'.format(b.shape[0]))
plt.legend()
plt.show()

Of the two options above \scriptsize might be what you're looking for:

two demo histograms with footnotesized and scriptsized labels

And some side notes, unrelated to your question:

  1. Use a.size instead of a.shape[0] for a 1d array.
  2. Consider using f-strings (added in Python 3.6), they usually make code more readable: rf"Array 2 \scriptsize (number of elements: {b.size})".

(Interestingly the expected result looks differently depending on how you look at the question: this is from desktop and this is mobile. The latter looks like superscripts are required.)