Python+Matplotlib:使用Arial字体时图例上下标垂直间距对齐问题
I've run into this exact issue before—Arial's default metrics don't play nicely with Matplotlib's math text rendering, leading to wonky superscript/subscript positioning. Here's how you can fix it while keeping Arial as your font:
1. Tweak Matplotlib's Math Text RC Parameters
Matplotlib has hidden parameters to adjust how superscripts and subscripts are positioned. Add these lines to your rcParams setup to align with Arial's baseline:
# Adjust math text superscript/subscript positioning for Arial rcParams['mathtext.superscript'] = (0.7, -0.25) # (scale factor, vertical offset) rcParams['mathtext.subscript'] = (0.7, 0.1) # (scale factor, vertical offset) rcParams['mathtext.default'] = 'regular' # Ensure math text uses Arial
- The first value in each tuple scales the superscript/subscript to match Arial's proportional size
- The second value adjusts vertical position: negative values pull superscripts down, positive values lift subscripts to eliminate awkward gaps.
2. Modified MWE with Fixed Spacing
Here's your updated code with the above parameters, plus a fix for the label indexing bug (you had ion-1 which would cause an index error on the first iteration):
import numpy as np import matplotlib as mpl from matplotlib import rcParams import matplotlib.pyplot as plt # ------------------------------------------------------------------- rcParams['font.family'] = 'sans-serif' rcParams['font.sans-serif'] = ['Arial'] rcParams['font.size'] = 15 # Fix math text positioning for Arial rcParams['mathtext.superscript'] = (0.7, -0.25) rcParams['mathtext.subscript'] = (0.7, 0.1) rcParams['mathtext.default'] = 'regular' label_list=["[MX_4(^AY)_4]^-", "[MX(^AY)_4]^-"] # Self-contained data (no external file needed) output_array = np.array([ [0.000000000000000000e+00, 4.127290260366441865e-01, 5.872709739633558135e-01], [1.000000000000000000e+00, 2.891558566042558565e-01, 7.108441433957440880e-01], [2.000000000000000000e+00, 1.979585968947671082e-01, 8.020414031052328641e-01], [3.000000000000000000e+00, 1.238903898108838220e-01, 8.761096101891161503e-01], [4.000000000000000000e+00, 6.903086085544125894e-02, 9.309691391445586994e-01], [5.000000000000000000e+00, 3.809897879025923167e-02, 9.619010212097407475e-01], [6.000000000000000000e+00, 2.185727788279773209e-02, 9.781427221172023234e-01], [7.000000000000000000e+00, 1.441899915182357980e-02, 9.855810008481764584e-01], [8.000000000000000000e+00, 9.900990099009901110e-03, 9.900990099009900902e-01], [9.000000000000000000e+00, 1.037181996086105652e-02, 9.896281800391389938e-01], [1.000000000000000000e+01, 1.068883610451306330e-02, 9.893111638954869003e-01], [1.100000000000000000e+01, 4.562043795620437589e-03, 9.954379562043795815e-01], [1.200000000000000000e+01, 1.573033707865168634e-02, 9.842696629213483206e-01], [1.300000000000000000e+01, 1.270588235294117622e-02, 9.872941176470588776e-01], [1.400000000000000000e+01, 1.210121012101210078e-02, 9.878987898789879374e-01], [1.500000000000000000e+01, 8.961911874533233513e-03, 9.910380881254667873e-01], [1.600000000000000000e+01, 2.255639097744360777e-02, 9.774436090225563367e-01], [1.700000000000000000e+01, 2.549575070821529649e-02, 9.745042492917846966e-01], [1.800000000000000000e+01, 2.564102564102564014e-02, 9.743589743589743390e-01], [1.900000000000000000e+01, 5.647058823529411964e-02, 9.435294117647058387e-01], [2.000000000000000000e+01, 4.780876494023904300e-02, 9.521912350597609986e-01], [2.000000000000000000e+01, 1.010452961672473893e-01, 8.989547038327526662e-01], [1.800000000000000000e+01, 4.583333333333333010e-02, 9.541666666666667185e-01], [1.600000000000000000e+01, 1.441812564366632375e-02, 9.855818743563337092e-01], [1.400000000000000000e+01, 2.482678983833718281e-02, 9.751732101616628068e-01], [1.200000000000000000e+01, 1.406309388065374311e-02, 9.859369061193462569e-01], [1.000000000000000000e+01, 5.292405398253506588e-03, 9.947075946017465142e-01], [8.000000000000000000e+00, 9.794507393892835923e-03, 9.902054926061071294e-01], [6.000000000000000000e+00, 2.557103864387300779e-02, 9.744289613561269991e-01], [4.000000000000000000e+00, 7.076957695769577061e-02, 9.292304230423041878e-01], [2.000000000000000000e+00, 1.996676820825256105e-01, 8.003323179174743895e-01], [0.000000000000000000e+00, 4.226958309964479188e-01, 5.773041690035520812e-01] ]) for ion in range(len(label_list)): plt.plot(output_array[:,0], output_array[:,ion+1], marker="s",label=r"$\mathregular{%s}$" % (label_list[ion])) plt.legend() plt.show()
3. Fine-Tuning Individual Characters (If Needed)
If the global parameters still don't match your GIMP-adjusted ideal, use LaTeX commands like \raisebox and \scalebox for pixel-perfect control:
label_list=[ r"[MX_4(\raisebox{-0.15ex}{\scalebox{0.7}{A}}Y)_4]\raisebox{-0.1ex}{\scalebox{0.7}{-}}", r"[MX(\raisebox{-0.15ex}{\scalebox{0.7}{A}}Y)_4]\raisebox{-0.1ex}{\scalebox{0.7}{-}}" ]
This lets you adjust the 'A' superscript and negative sign independently to match your target look.
Why This Works
Arial is a system font, not a TeX-native font—Matplotlib's default math text metrics (built for Computer Modern) don't align with Arial's baseline and character heights. By adjusting the superscript/subscript offsets and scaling, we're forcing Matplotlib to render these characters in a way that matches Arial's natural spacing.
内容的提问来源于stack exchange,提问作者TeXnician

