2010-06-30 50 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