Как сказано в комментарии к ОП, обе шкалы не могут быть одновременно линейными, поскольку одну нельзя получить из другой с помощью линейного преобразования. Следовательно, вы должны признать, что один (или оба) имеют тики с нерегулярными интервалами.
Правильный способ сделать это
Применить преобразование к шкале, в результате чего matplotlib будет иметь неоднородную шкалу.
Документ для Axes.set_yscale приводит к тому примеру , который демонстрирует синтаксис ax1.set_xscale('function', functions=(forward, inverse))
. Здесь, в этом случае, функции преобразования просто
def forward(wn):
# cm^{-1} to μm
return 1.0e4 / wn
def reverse(lam):
# μm to cm^{-1}
return 1.0e4 / lam
Однако мой matplotlib застрял на версии 2.2.2, которая не имеет этой функции, поэтому я не могу привести рабочий пример.
Хакерский способ работы со старыми версиями
Дайте позиции и метки вручную, выполняя вычисления самостоятельно.
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
def lambda_to_wave(lam):
# μm to cm^{-1}
return 1.0e4 / lam
x_wave = np.linspace(2000.0, 3000.0)
y_arb = np.linspace(0.0, 1.0e6)
ticks_wavelength_values = np.linspace(3.5, 5.5, num=5)
ticks_labels = [str(lam) for lam in ticks_wavelength_values]
ticks_wavenumber_positions = lambda_to_wave(ticks_wavelength_values)
print ticks_wavelength_values
print ticks_wavenumber_positions
fig = plt.figure(1)
ax1 = plt.subplot(1,1,1) # wavenumber
ax2 = ax1.twiny() # wavelength
ax2.get_shared_x_axes().join(ax1, ax2) # https://stackoverflow.com/questions/42973223/how-share-x-axis-of-two-subplots-after-they-are-created
ax1.plot(x_wave, y_arb, 'c', label='Data')
ax1.set_xlabel('Wavenumber (cm$^{-1}$)')
ax1.set_ylabel('Relative Intensity')
ax2.set_xticks(ticks_wavenumber_positions)
ax2.set_xticklabels(ticks_labels)
ax2.set_xlabel('Wavelength ($\mu$m)')
ax1.set_xlim(left=1800.0, right=3000.0)
fig.legend(loc=2, bbox_to_anchor=(0,1), bbox_transform=ax1.transAxes)
plt.show()