3

Here's the bottom line: I need to make publication-quality plots with Greek letters and subscripts in axis labels. Yet, in some rather specific cases, the label gets cut off near the tick labels. For example, I really need a label of $\alpha_-$ for some plots, but the bottom of the $\alpha$ gets cut off. Interestingly, this is not a problem for $\alpha_+$ (or many other labels).

On one hand, this seems like a display issue when using default font sizes -- the label is cut off when looking at output from Matplotlib, but looks ok after plt.savefig(). On the other hand, I need nice large font sizes for publication, and apparently the issue persists after doing plt.savefig() with large font size (say 22 pt).

I am aware of some previous posts that may seem related (e.g. overlaps, savefig cutoff, second axis), but they aren't quite what I'm asking about here.

A very short MRE shows what I'm getting at (Matplotlib version 3.5.1):

import matplotlib.pyplot as plt
plt.rc("axes", labelsize=22)
plt.plot([0,1],[0,1])
plt.ylabel(r"$\alpha_-$")
plt.show()

MRE plot

A few things I've tried:

  • Include plt.tight_layout() to adjust things automatically. Not helpful in this case.
  • Increase padding, e.g. plt.rc('axes', labelpad=10). This simply puts a large space between the deformed label and tick labels / axis. (Plus, this affects any x-axis label as well.)
  • Insert a new line, e.g. plt.ylabel(r"$\alpha_-$" + "\n"). Similarly, just results in some whitespace without fixing the label.

I also noticed an odd behavior from a typo version of the last point: keeping the newline '\n' with the raw text block, plt.ylabel(r"$\alpha_-$\n"), shows the label as expected. But, obviously, I don't want some '\n' in my label. I realize I could possibly just save that figure and crop out the unwanted '\n' -- that would be a forced workaround and certainly not ideal.

This is clearly a very specific question -- I cannot reproduce the issue with any character or subscript besides $\alpha_-$. But what's going on? Why does Matplotlib understand how to display $\gamma_-$ (and so many other choices) yet not the label I really need? Could this be fixed with a different version of Matplotlib? Since padding adjustment doesn't fix the issue, what can I do?

tdy
  • 36,675
  • 19
  • 86
  • 83
theory-guy
  • 33
  • 2
  • I don't see this issue with matplotlib 3.5.3 on Google Colab. – user2357112 Feb 28 '23 at 23:42
  • I have now tried with a couple of other versions of Matplotlib, including 3.5.3 and the new stable 3.7.0, to no avail. Any chance it has something to do with using Python 3.10.1? – theory-guy Mar 01 '23 at 17:39

1 Answers1

1

If there is a "bigger" subscript, it seems to work better

import matplotlib.pyplot as plt
plt.rc("axes", labelsize=22)
plt.plot([0,1],[0,1])
plt.ylabel(r"$\alpha_{x}$")
plt.show()

enter image description here

It's when the subscript is "-" that we get problems

enter image description here

If you become desperate, here is a hack that makes the whole alpha visible

plt.ylabel(r"$\alpha_{-_{_{_{.}}}}$")

enter image description here

Only if you look very closely do you see the tiny "."!

If that is still too large, you could add more layers of _{}.

Or you could find a character that appears blank. However the space charactor does not work for this purpose - I guess TeX is clever enough to know that it doesn't print any pixels.

One-off workaround

With your character being a minus, it does look like an underscore. So why not print it as a (non-subscripted) underscore? Would that make you feel dirty? If not:

import matplotlib.pyplot as plt
plt.rc("axes", labelsize=22)
plt.plot([0,1],[0,1])
plt.ylabel(r"$\alpha\_$")
plt.show()

enter image description here

ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
  • 1
    Thanks for responding to my silly question! I think using an underscore is the best workaround, with minimal dirty feeling. Small note: it seems your last block of code doesn't actually show the underscore approach. I am still mystified as to the source of this issue... – theory-guy Mar 01 '23 at 17:43