【问题标题】:Two corresponding y-axis两个对应的y轴
【发布时间】:2014-06-20 10:30:47
【问题描述】:

我正在尝试用两个对应的 y 轴绘制一个图。我想要的是在左侧 y 轴(例如米)上有一个单位的值,在左侧 y 轴上有另一个单位(例如英寸)的相应值。 在这种情况下,我设法用米和英寸做到了这一点。

但是,当转换不像乘以一样明显时,事情就不会那么容易了。 就我而言,我正在尝试绘制通量和幅度。从通量到幅度的公式是: 23.9 - 对数(通量)。

当我绘制米和英寸时起作用的方法不再起作用了。 这是我的代码:

host = host_subplot(111)
host.set_xlim((0.1,5)) 
host.set_ylim((1.,50.))

par1 = host.twinx()
par1.set_ylim((23.899999999999999, 19.652574989159952)) # Converting the ylim from flux to mag

host.set_xlabel('Wavelength (Microns)')
host.set_ylabel('Flux density ($\mu$Jy)')
par1.set_ylabel("Magnitude ")

host.errorbar(x, flux, fmt='rx' , xerr=errx, yerr = errorFlux)
par1.errorbar(x, mag, fmt='bx', xerr=errx, yerr=errorMag)

如果这有效,则两个图应该重叠,但它们不会(同样,我在做类似从米到英寸的事情时做了这项工作)。我怀疑这与日志有关,但是在将比例设置为日志时,情况会更糟。

【问题讨论】:

标签: python matplotlib


【解决方案1】:

试试这个,取自:http://matplotlib.org/examples/api/two_scales.html 我将我的示例版本放在下面。

我刚刚制作了一些呈指数增长的数据集。当然,可以更精确地调整坐标轴,例如创建自己的刻度、范围和刻度线;您所要做的就是花一些时间从网上做示例并阅读 API 文档。另外,我会向您指出此资源 http://nbviewer.ipython.org/github/jrjohansson/scientific-python-lectures/blob/master/Lecture-4-Matplotlib.ipynb 以获得一些很好的示例。

from numpy import *
import matplotlib.pyplot as plt


x_data = arange(0,100,.1)
y1_data = x_data**10
y2_data = x_data**4


fig, ax1 = plt.subplots(nrows=1, ncols=1)
ax1.set_yscale('linear')
ax1.plot(x_data,y1_data,'b-')
ax1.set_xlabel("Unitless X's")

ax1.set_ylabel('Linear Scale', color='b')
for tl in ax1.get_yticklabels():
    tl.set_color('b')

ax2 = ax1.twinx()
ax2.plot(x_data,y2_data,'r.')
ax2.set_ylabel("Log Scale", color='r')
ax2.set_yscale('log')
for tl in ax2.get_yticklabels():
    tl.set_color('r')
plt.show()

【讨论】:

    【解决方案2】:

    所以我终于设法通过在 matplotlib 中创建一个新比例来做到这一点。它可以改进,但这是我的类定义,基于http://matplotlib.org/examples/api/custom_scale_example.html

    import numpy as np
    import matplotlib.pyplot as plt
    
    from matplotlib import scale as mscale
    from matplotlib import transforms as mtransforms
    
    class MagScale(mscale.ScaleBase):
        name = 'mag'
    
        def __init__(self, axis, **kwargs):
            mscale.ScaleBase.__init__(self)
            self.thresh = None #thresh
    
        def get_transform(self):
            return self.MagTransform(self.thresh)
    
        def set_default_locators_and_formatters(self, axis):
            pass
    
        class MagTransform(mtransforms.Transform):
            input_dims = 1
            output_dims = 1
            is_separable = True
    
            def __init__(self, thresh):
                mtransforms.Transform.__init__(self)
                self.thresh = thresh
    
            def transform_non_affine(self, mag):
                return 10**((np.array(mag) -1)/(-2.5))
    
            def inverted(self):
                return MagScale.InvertedMagTransform(self.thresh)
    
        class InvertedMagTransform(mtransforms.Transform):
            input_dims = 1
            output_dims = 1
            is_separable = True
    
            def __init__(self, thresh):
                mtransforms.Transform.__init__(self)
                self.thresh = thresh
    
            def transform_non_affine(self, flux):
                return -2.5 * np.log10(np.array(flux)) + 1.
    
            def inverted(self):
                return MagScale.MagTransform(self.thresh)
    
    
    
    def flux_to_mag(flux):
        return  -2.5 * np.log10(flux) + 1
    
    
    mscale.register_scale(MagScale)
    

    这是一个工作示例:

    x    = np.arange(20.)
    flux = x * 2 + 1
    mag  = flux_to_mag(flux)
    
    MagTransform = MagScale.InvertedMagTransform(0)
    
    
    fig = plt.figure()
    ax_flux = fig.add_subplot(111)
    
    ax_flux.plot(x, flux,'-')
    ax_flux.set_ylim([1,40])
    ax_flux.set_ylabel('flux')
    
    ax_mag  = ax_flux.twinx()
    ax_mag.set_ylim(MagTransform.transform_non_affine(ax_flux.get_ylim())) #There may be an easier to do this.
    ax_mag.set_yscale('mag')
    
    ax_mag.plot(x,mag,'+')
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多