Matplotlib:如何在对数图中设置孪晶轴的刻度

时间:2013-12-05 09:32:39

标签: python matplotlib

在我的绘图中,辅助x轴用于显示某些数据的另一个变量的值。现在,原始轴是按比例缩放的。不幸的是,孪生轴使得刻度(和标签)指的是原始轴的线性刻度,而不是指向对数刻度。怎么能克服这个?

这里的代码示例应该将孪生轴的刻度位于与原始轴相同(绝对轴)的位置:

    def conv(x):
        """some conversion function"""
        # ...
        return x2

    ax = plt.subplot(1,1,1)
    ax.set_xscale('log')

    # get the location of the ticks of ax
    axlocs,axlabels = plt.xticks()

    # twin axis and set limits as in ax
    ax2 = ax.twiny()
    ax2.set_xlim(ax.get_xlim())

    #Set the ticks, should be set referring to the log scale of ax, but are set referring to the linear scale
    ax2.set_xticks(axlocs)

    # put the converted labels
    ax2.set_xticklabels(map(conv,axlocs))

另一种方法是(蜱然后没有设置在同一位置,但这没关系):

    from matplotlib.ticker import FuncFormatter

    ax = plt.subplot(1,1,1)
    ax.set_xscale('log')

    ax2 = ax.twiny()
    ax2.set_xlim(ax.get_xlim())
    ax2.xaxis.set_major_formatter(FuncFormatter(lambda x,pos:conv(x)))  

只要不使用对数刻度,这两种方法都能很好地工作。

也许存在一个简单的解决方法。我在文档中遗漏了什么吗?

作为一种解决方法,我试图获得ax的刻度的ax.transAxes坐标,并将刻度线放在ax2中的相同位置。但是不存在类似

的东西
    ax2.set_xticks(axlocs,transform=ax2.transAxes)
    TypeError: set_xticks() got an unexpected keyword argument 'transform'

2 个答案:

答案 0 :(得分:1)

这个问题已经问了一段时间,但是我偶然遇到了同样的问题。

我最终通过引入对数缩放(semilogx)透明(alpha=0)虚拟图来解决了这个问题。

示例:

import numpy as np
import matplotlib.pyplot as plt

def conversion_func(x):  # some arbitrary transformation function
    return 2 * x**0.5        # from x to z

x = np.logspace(0, 5, 100)
y = np.sin(np.log(x))

fig = plt.figure()

ax = plt.gca()
ax.semilogx(x, y, 'k')
ax.set_xlim(x[0], x[-1])  # this is important in order that limits of both axes match
ax.set_ylabel("$y$")
ax.set_xlabel("$x$", color='C0')
ax.tick_params(axis='x', which='both', colors='C0')
ax.axvline(100, c='C0', lw=3)

ticks_x = np.logspace(0, 5, 5 + 1)  # must span limits of first axis with clever spacing
ticks_z = conversion_func(ticks_x)
ax2 = ax.twiny()  # get the twin axis
ax2.semilogx(ticks_z, np.ones_like(ticks_z), alpha=0)  # transparent dummy plot
ax2.set_xlim(ticks_z[0], ticks_z[-1])
ax2.set_xlabel("$z \equiv f(x)$", color='C1')
ax2.xaxis.label.set_color('C1')
ax2.tick_params(axis='x', which='both', colors='C1')
ax2.axvline(20, ls='--', c='C1', lw=3)  # z=20 indeed matches x=100 as desired

fig.show()

matplotlib plot with second (twin) axis with different, logarithmic scale.

在上面的示例中,垂直线演示了第一轴和第二轴确实确实根据需要相互偏移。 x = 100转移到z = 2*x**0.5 = 20。颜色只是为了澄清哪个垂直线和哪个轴。

答案 1 :(得分:0)

不需要遮盖它们,只需消除壁虱!

d= [7,9,14,17,35,70];
j= [100,80,50,40,20,10];

plt.figure()
plt.xscale('log')
plt.plot(freq, freq*spec)  #plot some spectrum

ax1 = plt.gca()  #define my first axis 
ax1.yaxis.set_ticks_position('both')
ax1.tick_params(axis='y',which='both',direction='in');
ax1.tick_params(axis='x',which='both',direction='in');

ax2 = ax1.twiny()  #generates second axis (top) 
ax2.set_xlim(ax1.get_xlim());  #same limits
plt.xscale('log')  #make it log

ax2.set_xticks(freq[d]); #my own 'major' ticks OVERLAPS!!! 
ax2.set_xticklabels(j);  #change labels

ax2.tick_params(axis='x',which='major',direction='in'); 
ax2.tick_params(axis='x',which='minor',top=False); #REMOVE 'MINOR' TICKS
ax2.grid()