Есть ли нематематическая версия matplotlib.ticker.LogFormatterSciNotation? - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь построить график с логарифмической осью Y, используя pgf_with_latex, т. Е. Все форматирование текста выполняется pdflatex. В моем параметре matplotlib rc я определяю шрифт, который будет использоваться. Вот моя проблема: в стандартном matplotlib.ticker.LogFormatterSciNotation форматере использовался математический текст и, следовательно, математический шрифт, который не подходит для остальных шрифтов (sans-serif).

Как я могу отформатировать метки оси Y с использованием средства форматирования из matplotlib.ticker, чтобы я получал метки, отформатированные как степени 10 с надстрочными знаками? Чтобы быть более конкретным: как мне отформатировать эти yticklabels таким же образом, но со шрифтом из xticklabels?

Я уже пытался использовать разные форматеры, предоставленные matplotlib.ticker, но ни у одного из них показатели не были написаны так, как я хочу.

Вот пример того, что я имею в виду под MWE ниже. example plot

import matplotlib as mpl

mpl.use('pgf')
pgf_with_latex = {
        "pgf.texsystem": "pdflatex",
        "font.family": "sans-serif",
        "text.usetex": False,
        "pgf.preamble": [
            r"\usepackage[utf8x]{inputenc}",
            r"\usepackage{tgheros}",  # TeX Gyre Heros sans serif
            r"\usepackage[T1]{fontenc}"
            ]
        }

mpl.rcParams.update(pgf_with_latex)
import matplotlib.pyplot as plt

fig = plt.figure(figsize=[3, 2])
ax = fig.add_subplot(111)
ax.set_yscale("log")
ax.minorticks_off()
ax.set_xlabel("sans-serif font label")
ax.set_ylabel("math font label")
plt.gca().set_ylim([1, 10000])
plt.gcf().tight_layout()


plt.savefig('{}.pdf'.format("test"))

Осторожно: в вашей системе должен быть установлен дистрибутив TeX. Я использовал MikTex 2.9. Также Python 3.6.2 и matplotlib 2.1.2.

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Вы можете определить свой собственный FuncFormatter, который выполняет научную запись в юникоде.

Почти полный преобразователь в верхний индекс был дан в этого ответа .Я только добавил минус.

Вот реализация:

# -*- coding: utf-8 -*-
from math import log10

SUPERSCRIPTS = dict(zip(u"-0123456789", u"⁻⁰¹²³⁴⁵⁶⁷⁸⁹"))
def unicode_sci_notation(x, pos):
    """Scientific notation of number with unicode"""
    power = int(log10(x))
    mantissa = x/(10**power)
    superscript = u''.join(SUPERSCRIPTS[c] for c in unicode(power))
    if mantissa == 1:
        return '10%s' % superscript
    else:
        return '%.2f x 10%s' % (mantissa, superscript)
formatter = mpl.ticker.FuncFormatter(unicode_sci_notation)

ax.yaxis.set_major_formatter(formatter)

Чтобы сделать это таким образом, вам нужно указать кодирование: utf-8 в верхней части вашего скрипта.Если вы не хотите этого, вы можете избежать символов Юникода, как объяснено в ответе, который я связал.

enter image description here

0 голосов
/ 15 сентября 2018

Вы можете создать подкласс LogFormatterExponent для форматирования тиков с помощью "10\textsuperscript{x}", где x - показатель степени.При этом не будет использоваться текст в математическом режиме, т. Е. Нет символов $ вокруг текста, и поэтому будет использоваться текстовый шрифт, указанный в преамбуле (в данном случае это шрифт без засечек).

import matplotlib as mpl
from matplotlib.ticker import LogFormatterExponent

mpl.use('pgf')
pgf_with_latex = {
        "pgf.texsystem": "pdflatex",
        "font.family": "sans-serif",
        "text.usetex": False,
        "pgf.preamble": [
            r"\usepackage[utf8x]{inputenc}",
            r"\usepackage{tgheros}",  # TeX Gyre Heros sans serif
            r"\usepackage[T1]{fontenc}"
            ]
        }
mpl.rcParams.update(pgf_with_latex)
import matplotlib.pyplot as plt

class LogFormatterTexTextMode(LogFormatterExponent):
    def __call__(self, x, pos=None):
        x = LogFormatterExponent.__call__(self, x,pos)
        s = r"10\textsuperscript{{{}}}".format(x)
        return s

fig = plt.figure(figsize=[3, 2])
ax = fig.add_subplot(111)
ax.set_yscale("log")
ax.yaxis.set_major_formatter(LogFormatterTexTextMode())
ax.minorticks_off()
ax.set_xlabel("sans-serif font label")
ax.set_ylabel("text mode tex label")
plt.gca().set_ylim([0.01, 20000])
plt.gcf().tight_layout()


plt.savefig('{}.pdf'.format("test"))

enter image description here

...