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