python/matplotlib-寄生双轴缩放 [英] python/matplotlib - parasite twin axis scaling

查看:64
本文介绍了python/matplotlib-寄生双轴缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Trying to plot a spectrum, ie, velocity versus intensity, with lower x axis = velocity, on the upper twin axis = frequency

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

The relationship between them (doppler formula) is

f = (1-v/c)*f_0 

其中,f是结果频率,v是速度,c是光速,f_0是v = 0时的频率,即.v_lsr.

where f is the resulting frequency, v the velocity, c the speed of light, and f_0 the frequency at v=0, ie. the v_lsr.

我试图通过查看 http://matplotlib.sourceforge解决此问题.net/examples/axes_grid/parasite_simple2.html ,这里解决了

I have tried to solve it by looking at http://matplotlib.sourceforge.net/examples/axes_grid/parasite_simple2.html , where it is solved by

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?

my problem is, how do I replace the pm_to_kms with my function for frequency?

有人知道怎么解决吗?

推荐答案

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

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.

找到了一个非常好的答案. 根据@ u55的评论更改了转换调用

这基本上涉及定义我们自己的转换/转换.由于出色的AstroPy Unit等效性,它变得更加易于理解和说明.

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:

这篇关于python/matplotlib-寄生双轴缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆