93

How can I add a newline to a plot's label (e.g. xlabel or ylabel) in matplotlib? For example,

plt.bar([1, 2], [4, 5])
plt.xlabel("My x label")
plt.ylabel(r"My long label with $\Sigma_{C}$ math \n continues here") 

Ideally I'd like the y-labeled to be centered too. Is there a way to do this? It's important that the label have both TeX (enclosed in '$') and the newline.

BrechtDeMan
  • 6,589
  • 4
  • 24
  • 25

5 Answers5

134

You can have the best of both worlds: automatic "escaping" of LaTeX commands and newlines:

plt.ylabel(r"My long label with unescaped {\LaTeX} $\Sigma_{C}$ math"
           "\n"  # Newline: the backslash is interpreted as usual
           r"continues here with $\pi$")

(instead of using three lines, separating the strings by single spaces is another option).

In fact, Python automatically concatenates string literals that follow each other, and you can mix raw strings (r"…") and strings with character interpolation ("\n").

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
  • Just a quick comment--this was the perfect solution for an easy way to label subplots with an (a), (b), etc. when that label should be below the plot and centered with the xlabel. This way plt.tight_layout() also sees the whole label and adjusts accordingly. – SeanM Jul 01 '17 at 21:19
  • 4
    This should be the accepted answer. Also note that it works with Python string formatting, e.g. `r"$\alpha$ : {0} " "\n" r"$\beta$ : {1}".format(a, b)` – berkelem Sep 24 '18 at 06:27
51

Your example is exactly how it's done, you use \n. You need to take off the r prefix though so python doesn't treat it as a raw string

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
  • 10
    You might want to proactively double-escape LaTeX commands to make sure they are not interpreted by Python: `xlabel('$\\Sigma$')` – Benjamin Bannier Apr 17 '10 at 22:54
  • 9
    This answer is not correct. You *either* double escape the latex `\` in a normal string (no r) *or* you follow @EOLs [answer](http://stackoverflow.com/a/2666270/1157089) – aaren Sep 18 '13 at 15:02
  • 2
    regarding centering: `ylabel('this is vertical\ntest', multialignment='center')` from http://matplotlib.org/examples/pylab_examples/multiline.html – Faber Dec 02 '14 at 19:15
  • 2
    Unfortunately none of the proposed solutions work with the option `rcParams["text.usetex"] = True` – Samuel Jul 25 '19 at 15:08
18
plt.bar([1, 2], [4, 5])
plt.xlabel("My x label")
plt.ylabel(r"My long label with $\Sigma_{C}$ math" + "\n" + "continues here")

Just concatenate the strings with a newline that isn't in raw string form.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Brothaman
  • 199
  • 1
  • 5
3

The following matplotlib python script creates text with new line

ax.text(10, 70, 'shock size \n $n-n_{fd}$')

The following does not have new line. Notice the r before the text

ax.text(10, 70, r'shock size \n $n-n_{fd}$')
Ranaivo
  • 1,578
  • 12
  • 6
0

In case anyone wants TeX (e.g. for partly bold text) and a new line AND has a percentage sign in it (I struggled longer than I wanted):

import matplotlib.pyplot as plt

plt.plot([10, 20], [10, 20])  # dummy plot
value = 20  # dummy value

bold_text_base = f"Value = %u\ \%%"  # "\ " for protected space, "\%%" for percentage sign that survives formatting and math mode
regular_text = "(2nd line here)"
bold_text = bold_text_base % value
_ = plt.ylabel(r"$\bf{{{x}}}$".format(x=bold_text) + f"\n%s" % regular_text )  # suppress output with "_ = "

Returns:

Matplotlib plot with TeX, newline and percentage sign in title

Matthias Luh
  • 503
  • 6
  • 11