【问题标题】:python/matplotlib - parasite twin axis scalingpython/matplotlib - 寄生虫双轴缩放
【发布时间】:2010-06-30 11:33:50
【问题描述】:

尝试绘制频谱,即速度与强度的关系,下 x 轴 = 速度,上双轴 = 频率

它们之间的关系(多普勒公式)是

f = (1-v/c)*f_0 

其中 f 是产生的频率,v 是速度,c 是光速,f_0 是 v=0 时的频率,即。 v_lsr。

我试图通过查看 http://matplotlib.sourceforge.net/examples/axes_grid/parasite_simple2.html 来解决它,它是通过

pm_to_kms = 1./206265.*2300*3.085e18/3.15e7/1.e5
aux_trans = matplotlib.transforms.Affine2D().scale(pm_to_kms, 1.)
ax_pm = ax_kms.twin(aux_trans)
ax_pm.set_viewlim_mode("transform")

我的问题是,如何用我的频率函数替换 pm_to_kms?

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: python matplotlib axes


    【解决方案1】:

    我最终使用的解决方案是:

    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))
    

    这很完美,解决方案也不那么复杂。

    编辑:找到了一个非常奇特的答案。 EDIT2:根据@u55 的评论更改了转换调用

    这基本上涉及定义我们自己的转换/转换。由于具有出色的 AstroPy Units 等效性,它变得更容易理解且更具说明性。

    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() 
    

    这会产生预期的结果:

    【讨论】:

    • 这碰巧可以正常工作,因为频率和波长之间的转换方程 (νλ = c) 关于频率和波长的交换是对称的。但是,对于一般转换,这将给出不正确的结果。您应该在以下行中将Freq2WavelengthTransform() 替换为Wavelength2FreqTransform()aux_trans = mtransforms.BlendedGenericTransform(Freq2WavelengthTransform(), mtransforms.IdentityTransform())
    【解决方案2】:

    您的“线性函数”是一个“简单的缩放定律”(带有偏移量)。只需将 pm_to_kms 定义替换为您的函数即可。

    【讨论】:

    • 嗯是的...所以你的意思是我做了两个变换,一个缩放和一个平移?比如 kms_to_deltafreq = -f0/c deltafreq_to_freq = f0 matplotlib.transforms.Affine2D().scale(kms_to_deltafreq, 1.).translate(deltafreq_to_freq,1) ax_freq = ax_kms.twin(aux_trans) ax_freq.set_viewlim_mode("transform") ??
    • 所以现在这里有一个答案:matplotlib.1069221.n5.nabble.com/…如果时间允许,我会在这里写一个合适的。
    猜你喜欢
    • 2015-04-23
    • 2017-09-02
    • 1970-01-01
    • 2021-05-28
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多