python/matplotlib - parasite twin axis scaling

烂漫一生 提交于 2019-11-30 16:07:25

The solution I ended up using was:

ax_hz = ax_kms.twiny()
x_1, x_2 = ax_kms.get_xlim()
# i want the frequency in GHz so, divide by 1e9
ax_hz.set_xlim(calc_frequency(x_1,data.restfreq/1e9),calc_frequency(x_2,data.restfreq/1e9))

This works perfect, and much less complicated solution.

EDIT : Found a very fancy answer. EDIT2 : Changed the transform call according to the comment by @u55

This basically involves defining our own conversion/transform. Because of the excellent AstroPy Units equivalencies, it becomes even easier to understand and more illustrative.

from matplotlib import transforms as mtransforms
import astropy.constants as co
import astropy.units as un
import numpy as np 
import matplotlib.pyplot as plt 
plt.style.use('ggplot')
from mpl_toolkits.axes_grid.parasite_axes import SubplotHost 


class Freq2WavelengthTransform(mtransforms.Transform): 
    input_dims = 1 
    output_dims = 1 
    is_separable = False 
    has_inverse = True 

    def __init__(self):
        mtransforms.Transform.__init__(self)

    def transform_non_affine(self, fr): 
        return (fr*un.GHz).to(un.mm, equivalencies=un.spectral()).value 

    def inverted(self): 
        return Wavelength2FreqTransform() 

class Wavelength2FreqTransform(Freq2WavelengthTransform): 
    input_dims = 1 
    output_dims = 1 
    is_separable = False 
    has_inverse = True 

    def __init__(self):
        mtransforms.Transform.__init__(self)

    def transform_non_affine(self, wl): 
        return (wl*un.mm).to(un.GHz, equivalencies=un.spectral()).value 

    def inverted(self): 
        return Freq2WavelengthTransform() 



aux_trans = mtransforms.BlendedGenericTransform(Wavelength2FreqTransform(), mtransforms.IdentityTransform()) 

fig = plt.figure(2) 

ax_GHz = SubplotHost(fig, 1,1,1) 
fig.add_subplot(ax_GHz) 
ax_GHz.set_xlabel("Frequency (GHz)") 


xvals = np.arange(199.9, 999.9, 0.1) 

# data, noise + Gaussian (spectral) lines
data = np.random.randn(len(xvals))*0.01 + np.exp(-(xvals-300.)**2/100.)*0.5 + np.exp(-(xvals-600.)**2/400.)*0.5

ax_mm = ax_GHz.twin(aux_trans) 
ax_mm.set_xlabel('Wavelength (mm)') 
ax_mm.set_viewlim_mode("transform") 
ax_mm.axis["right"].toggle(ticklabels=False) 

ax_GHz.plot(xvals, data) 
ax_GHz.set_xlim(200, 1000) 

plt.draw() 
plt.show() 

This now produces the desired results:

Your "linear function" is a "simple scaling law" (with an offset). Just replace the pm_to_kms definition with your function.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!