Matplotlib 对数刻度刻度标签,乳胶字体中的减号太长

2022-01-24 00:00:00 python matplotlib latex

问题描述

我在 matplotib 中使用 'text.usetex': True.这对于具有线性比例的绘图非常有用.然而,对于对数刻度,y 刻度如下所示:

I'm using 'text.usetex': True in matplotib. This is nice for plots with a linear scale. For a log-scale however, the y-ticks looks like this:

指数中的减号在图中占用了大量的水平空间,这不是很好.我希望它看起来像这样:

The minus signs in the exponents take a lot of horizontal space in a plot, which is not very nice. I want it to rather look like that:

那个来自gnuplot,它没有使用tex-font.我想使用 matplotlib,让它在 tex 中渲染,但 10^{-n} 中的减号应该更短.这可能吗?

That one is from gnuplot, and it's not using the tex-font. I would like to use matplotlib, have it rendered in tex, but the minus signs in 10^{-n} should be shorter. Is that possible?


解决方案

Dietrich 给了你一个很好的答案,但是如果你想保留所有的功能(非基数 10,非整数指数) 的 LogFormatter,那么您可以创建自己的格式化程序:

Dietrich gave you a nice answer, but if you want to keep all the functionality (non-base 10, non-integer exponents) of LogFormatter, then you might create your own formatter:

import matplotlib.ticker
import matplotlib
import re

# create a definition for the short hyphen
matplotlib.rcParams["text.latex.preamble"].append(r'mathchardefmhyphen="2D')

class MyLogFormatter(matplotlib.ticker.LogFormatterMathtext):
    def __call__(self, x, pos=None):
        # call the original LogFormatter
        rv = matplotlib.ticker.LogFormatterMathtext.__call__(self, x, pos)

        # check if we really use TeX
        if matplotlib.rcParams["text.usetex"]:
            # if we have the string ^{- there is a negative exponent
            # where the minus sign is replaced by the short hyphen
            rv = re.sub(r'^{-', r'^{mhyphen', rv)

        return rv

这真正做的唯一一件事就是获取通常格式化程序的输出,找到可能的负指数并将数学减号的 LaTeX 代码更改为其他内容.当然,如果你用 scalebox 或类似的东西发明了一些有创意的 LaTex,你可以这样做.

The only thing this really does is to grab the output of the usual formatter, find the possible negative exponents and change the LaTeX code of the math minus into something else. Of course, if you invent some creative LaTex with scalebox or something equivalent, you may do so.

这个:

import matplotlib.pyplot as plt
import numpy as np

matplotlib.rcParams["text.usetex"] = True
fig = plt.figure()
ax = fig.add_subplot(111)
ax.semilogy(np.linspace(0,5,200), np.exp(np.linspace(-2,3,200)*np.log(10)))
ax.yaxis.set_major_formatter(MyLogFormatter())
fig.savefig("/tmp/shorthyphen.png")

创建:

这个解决方案的好处是它尽可能少地改变输出.

The good thing about this solution is that it changes the output as minimally as possible.

相关文章