2010-06-30 48 views
3

想要绘制的光谱,即,速度与强度,具有较低的x轴=速度,在上部双轴=频率蟒/ matplotlib - 寄生虫双轴缩放

它们(多普勒式)之间的关系是其中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解决呢?

任何人都知道如何解决这个问题?

回答

4

我结束了使用的解决方案是:

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

现在,这产生了预期的效果: enter image description here

+0

偶然发生这种情况是正确的,因为频率和波长(νλ= c)之间的转换方程关于频率和波长的交换是对称的。但是,对于一般转换,这会产生不正确的结果。 此时应更换'Freq2WavelengthTransform()'和'Wavelength2FreqTransform()'该行: 'aux_trans = mtransforms.BlendedGenericTransform(Freq2WavelengthTransform(),mtransforms.IdentityTransform())'。 – u55 2016-10-13 06:03:37

0

你的“线性函数”是一个“简单标度律”(带有偏移量)。只需用您的功能替换pm_to_kms定义。

+0

好是... 所以你的意思是我做两个变换,一个换算,一个翻译? 像 kms_to_deltafreq = -f0/C deltafreq_to_freq = F0 matplotlib.transforms.Affine2D()。刻度(kms_to_deltafreq,1)。平移(deltafreq_to_freq,1) ax_freq = ax_kms.twin(aux_trans) ax_freq.set_viewlim_mode( “变换”) ?? – 2010-07-02 10:56:57

+0

所以现在的答案现在存在:http://matplotlib.1069221.n5.nabble.com/Dual-x-axes-with-transformation-td10865.html如果时间允许,我会在这里写一个适当的答案。 – 2015-02-17 12:57:51