Matplotlib:如何在对数图中设置双轴刻度 [英] Matplotlib: how to set ticks of twinned axis in log plot

查看:77
本文介绍了Matplotlib:如何在对数图中设置双轴刻度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的图中,辅助 x 轴用于显示某些数据的另一个变量的值.现在,原始轴被对数缩放.不幸的是,孪生轴将刻度(和标签)放在原始轴的线性刻度上,而不是对数刻度.如何克服?

In my plot, a secondary x axis is used to display the value of another variable for some data. Now, the original axis is log scaled. Unfortunaltely, the twinned axis puts the ticks (and the labels) referring to the linear scale of the original axis and not as intended to the log scale. How can this be overcome?

下面的代码示例应将孪生轴的刻度线放置在与原始轴相同的位置(绝对轴)上:

Here the code example that should put the ticks of the twinned axis in the same (absolute axes) position as the ones for the original axis:

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

另一种方法是(刻度不会设置在同一位置,但这没关系):

An alternative way would be (the ticks are then not set in the same position, but that doesn't matter):

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

只要不使用对数标度,这两种方法都可以正常工作.

Both approaches work well as long as no log scale is used.

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

Perhaps there exists an easy fix. Is there something I missed in the documentation?

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

As a workaround, I tried to obtain the ax.transAxes coordinates of the ticks of ax and put the ticks at the very same position in ax2. But there does not exist something like

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

推荐答案

前一段时间有人问过这个问题,但是我偶然遇到了同样的问题.

This has been asked a while ago, but I stumbled over it with the same question.

我最终设法通过引入对数刻度( semilogx )透明( alpha = 0 )虚拟图来解决了这个问题.

I eventually managed to solve the problem by introducing a logscaled (semilogx) transparent (alpha=0) dummy plot.

示例:

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

在上面的例子中,垂直线表明第一个和第二个轴确实根据需要相互移动.x = 100 被转移到 z = 2*x**0.5 = 20.颜色只是为了说明哪条垂直线对应哪条轴.

In the above example the vertical lines demonstrate that first and second axis are indeed shifted to one another as wanted. x = 100 gets shifted to z = 2*x**0.5 = 20. The colours are just to clarify which vertical line goes with which axis.

这篇关于Matplotlib:如何在对数图中设置双轴刻度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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