Проблема в том, что и прямая, и обратная функции вызываются для значений, которые немного выходят за пределы диапазона заданных значений x. Например, они используются для xlims. (Можно добавить print(x)
внутри этих функций, чтобы увидеть, как они вызываются.)
Если эти функции записаны как простое линейное преобразование, такое как в примере deg2rad
, проблем нет. Функция работает одинаково за пределами своих границ. Но у np.interp
нет хорошей подсказки вне его диапазона, поэтому он возвращает свой нижний или верхний предел. Это отсечение вызывает нежелательную маркировку тиков.
Для детали это можно исправить, установив жесткую ось X, поэтому без заполнения, которое происходит по умолчанию:
plt.autoscale(enable=True, axis='x', tight=True)
Но даже тогда всплывает нежелательный тик 400.
Лучшее решение состоит в том, чтобы сделать диапазон для обеих функций немного шире, чем пределы, показанные на старой оси x, включая отступ. Например, установка
xold = np.linspace(x[0]-0.5, x[-1]+0.5, 100)
xnew = xold * 180 / np.pi
Обратите внимание, что в связанном примере они устанавливают xold = np.arange(0, 11, 0.2)
, но затем выполняют только график, начиная с третьего индекса, чтобы создать достаточно места для заполнения. : ax.plot(xold[3:], xnew[3:])
.
Полный пример может выглядеть следующим образом:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(constrained_layout=True)
x = np.linspace(0, 2*np.pi, 1000)
y = np.sin(x)
ax.plot(x, y)
xold = np.linspace(x[0]-0.5, x[-1]+0.5, 100)
xnew = xold * 180 / np.pi
def forward(x):
return np.interp(x, xold, xnew)
def inverse(x):
return np.interp(x, xnew, xold)
secax = ax.secondary_xaxis('top', functions=(forward,inverse))
plt.show()