When mixing labels that have subscripts with labels without them, they do not vertically align properly in the legend. Since matplotlib determines bounding boxes internally based on printing characters, using a vphantom
character does not work to align these legend labels, and I have not had any luck changing the vertical alignment of the labels with set_va
, either.
Below is a MWE that illustrates problem I am trying to solve. I would like the labels to align to the text baseline if at all possible, otherwise to the text top.
import numpy as np
import matplotlib as mpl
mpl.rcParams['text.usetex'] = True
import matplotlib.pyplot as plt
x = np.arange(10)
plt.plot(x, np.random.uniform(size=(10,)), c='red', label=r'test')
plt.scatter(x, np.random.uniform(size=(10,)), c='blue', label=r'test${}_{xy}$')
plt.legend(ncol=2)
plt.show()
Set the text.latex.preview
parameter to True
:
import numpy as np
import matplotlib as mpl
mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preview'] = True
import matplotlib.pyplot as plt
x = np.arange(10)
plt.plot(x, np.random.uniform(size=(10,)), c='red', label=r'test')
plt.scatter(x, np.random.uniform(size=(10,)), c='blue', label=r'test${}_{xy}$')
plt.legend(ncol=2)
plt.show()
For the effect of the preview
argument, also refer to this example.
You can have a look on Text alignment in a Matplotlib legend.
Or you can just shift down the second legend text,
h_legend = plt.legend(ncol=2)
y_shift = -2.5
h_legend.texts[1].set_position((0, y_shift))
You can peak your shift distance based on the extent of the legend window using something like:
h_legend = plt.legend(ncol=2)
renderer = plt.gcf().canvas.get_renderer()
y_shift = -0.2*h_legend.texts[0].get_window_extent(renderer).height
h_legend.texts[1].set_position((0, y_shift))
this will shift the second text by 20% of the full legend window height.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With