4

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.

3
  • 2
    Use latex syntax with a superscript, text $^\mathrm{small text}$. Commented Jan 15, 2022 at 9:39
  • @AndrasDeak This doesn't work for me, as I use string formatting and I get the error message unexpected '{' in field name. Commented Jan 15, 2022 at 9:45
  • 2
    You have to escape braces, as usual. rf'text $^\mathrm{{{a.shape[0]}}}$'. A pair of braces is a literal brace, third one is for the format. Commented Jan 15, 2022 at 9:53

1 Answer 1

3

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry, the second part of my answer doesn't actually work. I've deleted it for now.
Ah, what a pity. I just tried your comment, and - if I might say so - it does not really look good with the ^. But if you find sth without (e.g. you get \fontsize etc. running), I'd be curious to know about it.
@Hermi this is how your question looks on mobile (where I first saw it, which is why I only left a comment): i.sstatic.net/YGPga.jpg . It looks just like the superscript version :) I've found a way to set the font size but honestly it doesn't look much better. I'll update my answer in a moment.
@Hermi scratch that, we don't need math mode for this to work and the result looks OK. Answer updated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.