Matplotlib:在第二轴上twinx()错误的值 [英] Matplotlib: twinx() wrong values on second axis

查看:308
本文介绍了Matplotlib:在第二轴上twinx()错误的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试绘制主要ln(x)-axis的次要x轴时,我遇到了matplotlib.pyplotplt.twinx()函数的问题.它们应显示相应的值,但刻度不同.为了清楚起见,这是我到目前为止在MWE中尝试过的内容:

I ran into a problem with the plt.twinx() function of matplotlib.pyplot when I tried to plot a secondary x-axis for a primary ln(x)-axis. They should show corresponding values, but with different ticks. For clarity here is what I tried so far in a MWE:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

fig = plt.figure(1)
ax1 = fig.add_subplot(111)

ax1.set_xlabel(r'$ln(\sigma)$')
ax1.set_xticks([5.2,5.3,5.4,5.5,5.6,5.7,5.8])
ax1.set_xlim([5.2,5.8])
ax1.plot(5.6,0.5,'o')

ax2 = ax1.twiny()
ax2.set_xlabel(r'$\sigma$')
ax2.set_xlim(np.exp(ax1.get_xlim()))
ax2.xaxis.set_major_locator(MultipleLocator(base=25))

plt.show()

这将产生以下图,该图起初看起来像期望的,但存在问题,即次要X线错误.

This produces the following plot, which looks as desired at first but has the problem, that the secondary x-ticks are wrong.

使用错误的辅助x值绘制的图

该点位于x1 = 0.5,但相应的辅助x值位于x2 =~ 280,但毕竟应该位于x2 = math.exp(5.6) =~ 270

The point is located at x1 = 0.5 but the corresponding secondary x-value is at x2 =~ 280 but should be after all at x2 = math.exp(5.6) =~ 270

我不确定这是一个绘图问题还是一个使用不同比例尺的更深层次的数学问题.

I'm not really sure if this is a plotting problem or a deeper-going mathematical problem with the different scales.

当我未设置ax2.xlim()但仅将主要x-ticks设置为两倍并使用matplotlib.ticker.FuncFormatter将次要x-ticks格式化为np.exp(ax1.get_xticlocs())时,它就起作用了,但是次要ticks处于奇怪的"值

It works when I don't set the ax2.xlim() but just double the primary x-ticks and use matplotlib.ticker.FuncFormatter to format the secondary x-ticks to np.exp(ax1.get_xticlocs()) but then the secondary ticks are at "strange" values.

推荐答案

这是怎么回事

这是因为两个x刻度之间的映射是非线性的(是指数/对数的).实际上,您将一个轴作为对数刻度,将另一个轴作为法向刻度.两者在终结点上重合,具体取决于您如何定义限制,但并非介于两者之间.下面说明了这个想法. x2的映射值"相对于x1值绘制在y轴上.我标记为仅端点"的蓝线是您所期望的,但是全域"映射是实际发生的情况.

Here's what's going wrong

It's because the mapping between your two x-scales is non-linear (it's exponential/logarithmic). In effect you've got one axis as a log scale and the other as a normal scale. The two coincide at the endpoints based on how you defined your limits, but not in between. This idea is demonstrated below. The "mapped value" of x2 is plotted on the y-axis versus your x1 values. The blue line which I labeled "endpoints only" is what you expect, but the "full domain" mapping is what happens in reality.

import matplotlib.pyplot as plt
import numpy as np

# Endpoints only
x01 = np.array([5.2,5.8])
y01 = np.exp(x01)

# Full domain
x = np.linspace(5.2,5.8,100)
y = np.exp(x)

plt.plot(x01,y01,label='endpoints only')
plt.plot(x,y, label='full domain')
plt.legend()
plt.show()

在对数刻度上实例化两个轴.在您的情况下,您需要自然对数,因此我们传递basex=np.e.然后,您需要手动指定两个轴上的刻度位置.在ax1中,我们仅使用预先指定的位置.对于ax2,您可以使用指定MultipleLocator之后生成的位置.

Instantiate both axes on log scales. In your case you want natural log, so we pass basex=np.e. You then need to manually specify the tick locations on both axes. In ax1 we just use the pre-specified locations; for ax2 you can use the locations generated after specifying the MultipleLocator.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_xscale('log', basex=np.e)

# Array of tick locations...use the true value (not log value)
locs = np.exp(np.array([5.2,5.3,5.4,5.5,5.6,5.7,5.8]))

ax1.set_xlabel(r'$ln(\sigma)$')
ax1.set_xlim([locs[0],locs[-1]])
ax1.set_xticks(locs)
ax1.set_xticklabels(np.log(locs))

ax2 = ax1.twiny()
ax2.set_xscale('log', basex=np.e)
ax2.set_xlabel(r'$\sigma$')
ax2.set_xlim((ax1.get_xlim()))
ax2.xaxis.set_major_locator(MultipleLocator(base=25))
# Manually set the tick labels to match the positions your set with the locator
ax2.set_xticklabels(['{:.0f}'.format(k) for k in ax2.get_xticks()])  

ax1.plot(locs,locs*0+.4,'o')
ax2.plot(locs,locs*0+.6,'o',color='C1')
ax1.set_ylim([0,1])

plt.show()

这篇关于Matplotlib:在第二轴上twinx()错误的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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