#python-3.x #matplotlib
#python-3.x #matplotlib
Вопрос:
Мне нужно немного места до и после последнего расположения галочки на оси. Я бы просто использовал axis.set_xlim()
, например, но это мешает моему (пользовательскому) локатору и перезапускает генерацию тиков. Я нашел и перезаписал view_limits()
метод классов-локаторов, но они, похоже, не вызываются автоматически, а при вызове вручную они не оказывают никакого влияния на результирующий график. Я искал документы и источник, но не нашел решения. Я что-то упустил?
Для большей картины я хочу иметь локатор, который дает мне некоторое пространство до и после тиков и выбирает точки тиков, кратные «base», например, MultipleLocator, но автоматически масштабирует базу, если количество тиков превышает указанное значение. Если есть другой способ добиться этого без подкласса локатора, я весь внимание :).
Вот мой пример кода для подкласса locator с перезаписанным view_limits
методом:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
class MyLocator(MaxNLocator):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def view_limits(self, dmin, dmax):
bins = self.bin_boundaries(dmin, dmax)
step = bins[1] - bins[0]
result = np.array([bins[0] - step, bins[-1] step])
print(result)
return result
a = 10.0
b = 99.0
t = np.arange(a, b, 0.1)
s = np.sin(0.1*np.pi*t)*np.exp(-t*0.01)
loc = MyLocator(9)
fig, ax = plt.subplots()
plt.plot(t, s)
ax.xaxis.set_major_locator(loc)
loc.autoscale() # results in [ 0. 110.] but doesnt change the plot
plt.show()
Ответ №1:
Не уверен, полностью ли я понял, в чем ваша проблема, но если вы хотите только добавить дополнительное пространство, вы все равно можете использовать MaxNLocator и добавить это пространство вручную, как здесь:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
a = 10.0
b = 99.0
t = np.arange(a, b, 0.1)
s = np.sin(0.1*np.pi*t)*np.exp(-t*0.01)
loc = MaxNLocator(9)
fig, ax = plt.subplots()
plt.plot(t, s)
ax.xaxis.set_major_locator(loc)
ticks = ax.get_xticks()
newticks = np.zeros(len(ticks) 2)
newticks[0] = ticks[0]- (ticks[1]-ticks[0])
newticks[-1] = ticks[-1] (ticks[1]-ticks[0])
newticks[1:-1] = ticks
ax.set_xticks(newticks)
plt.show()
Комментарии:
1. спасибо за этот трюк! Я могу с этим работать. Я все же предпочел бы знать, почему весь view_limits-метод работает не так, как ожидалось.
Ответ №2:
Одно слегка хакерское решение, позволяющее избежать тиков вблизи краев графика, заключается в следующем:
class PaddedMaxNLocator(mp.ticker.MaxNLocator):
def __init__(self, *args, protected_width=0.25, **kwargs):
# `prune` edge ticks that might now become visible
super().__init__(*args, **kwargs, prune='both')
# Clamp to some reasonable range
self.protected_width = min(0.5, protected_width)
def tick_values(self, vmin, vmax):
diff = (vmax - vmin) * self.protected_width / 2
return super().tick_values(vmin diff, vmax - diff)