Python Matplotlib: установить ось как приращение относительно одного значения - PullRequest
0 голосов
/ 20 ноября 2018

Иногда, когда график масштабируется в достаточной степени, меняется ось, поэтому отображается что-то вроде этого

enter image description here

, что означает, что значение x вв этом случае 1.565 + значение, показанное в тике.

Есть ли способ установить отметки оси в этом формате?И как только я могу установить смещение (1.565 в этом случае) и отформатировать галочки?

1 Ответ

0 голосов
/ 20 ноября 2018

A.Ручное размещение смещения

Я думаю, что самое простое решение - построить x-offset вместо x.Затем просто добавьте текстовое поле со смещением под осями.

import numpy as np
import matplotlib.pyplot as plt

x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]

plt.plot(x - np.pi/2, y)
plt.text(1, -0.07, "$+\pi / 2$", ha="right", va="top",
         transform=plt.gca().transAxes)

plt.show()

enter image description here

B.Использование фиксированного форматера

В качестве альтернативы вы можете использовать FixedFormatter и установить его метку смещения вручную.

import numpy as np
import matplotlib.pyplot as plt

x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]

plt.plot(x, y)

xticks = np.array([-0.02, -0.01, 0, 0.01, 0.02])

plt.gca().set(xticks = xticks + np.pi/2, 
              xticklabels = xticks)
plt.gca().xaxis.get_major_formatter().set_offset_string("$+\pi / 2$")

plt.show()

enter image description here

недостатком этого является то, что позиции тиков фиксированы, поэтому при масштабировании вы теряете удобную маркировку.

C.Использование пользовательского локатора и форматера с фиксированным смещением

Это возможно, но крайне сложно.Решение выглядело бы так же, как Установить научную нотацию с фиксированным показателем степени и значащими цифрами для нескольких вспомогательных участков , но также необходимо использовать локатор.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker

class OffsetLocator(matplotlib.ticker.AutoLocator):
    def __init__(self, offset=0):
        self.fixed_offset = offset
        matplotlib.ticker.AutoLocator.__init__(self)
    def tick_values(self, vmin, vmax):
        v = np.array([vmin,vmax])-self.fixed_offset
        ticks = matplotlib.ticker.AutoLocator.tick_values(self, *v)
        return ticks + self.fixed_offset

class OffsetFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, offset=0, offsettext = None, mathText=True):
        self.fixed_offset = offset
        self.offset_text = offsettext
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,
                                                   useMathText=mathText)
    def _set_orderOfMagnitude(self, nothing):
        self.orderOfMagnitude = 0
    def _compute_offset(self):
        return self.fixed_offset
    def get_offset(self):
        return self.offset_text or matplotlib.ticker.ScalarFormatter.get_offset(self)


x = np.array([-0.02+np.pi/2, +0.02+np.pi/2])
y = [1,1]

plt.plot(x, y)

plt.gca().xaxis.set_major_locator(OffsetLocator(np.pi/2))
plt.gca().xaxis.set_major_formatter(OffsetFormatter(np.pi/2, offsettext="$+\pi / 2$"))

plt.show()

enter image description here

Результат выглядит аналогично приведенному выше, но ведет себя совершенно естественно, как и во всех других случаях, когда некоторое смещениеиспользуется.Вероятно, различия будут наблюдаться только при игре с размером фигуры, масштабированием, панорамированием и т. Д.

...