我有X和Y的数据集,我绘制这些数据集.对于X的每个值,我都有另一个数据集.我想在matplotlib中绘制2个x轴.问题是x的数据集并不相互依赖.

我试了this StackOverflow solution次.当我没有x-LIMS时,它工作得很好.

import matplotlib.pyplot as plt
import numpy as npfig, ax = plt.subplots(constrained_layout=True)
    
x_upper = np.array([2.379618e-29,5.895669e-29,1.018725e-28,
                    1.413803e-28,1.780809e-28,2.080620e-28,
                    2.287013e-28,2.603605e-28,2.810124e-28])
    
x_lower = np.array([20,30,40,50,60,70,80,100,120])

y = np.array([-1.333526e-16,-8.841676e-16,-2.803599e-15,
              -5.300285e-15,-7.723194e-15,-9.906261e-15,
              -1.124626e-14,-1.238456e-14,-1.193596e-14])
ax.plot(x_lower, y)
    
xold = x_lower
xnew = x_upper
    
def forward(x):
    return np.interp(x, xold, xnew)
    
def inverse(x):
    return np.interp(x, xnew, xold)
    
secax = ax.secondary_xaxis('top', functions=(forward,inverse))
plt.autoscale(enable=True, axis='x', tight=True)

Without x-lim

但是,在较高的x轴上,始终显示值03e-28.如何摆脱它们?

下一个问题是当我更改轴下限时:

ax.set_xlim(15, 125)

这些值仍然存在,但现在下x轴和上x轴与它们的值不匹配.你能帮我修一下吗?

With x-lim

推荐答案

要处理1e-28后缀,因为这些值很小,所以我要放大它们,然后适当地注释轴标签:

enter image description here

更改:

plt.rcParams["mathtext.fontset"] = "dejavuserif" #<--- serif math text

...

x_upper = np.array([2.379618e-29,5.895669e-29,1.018725e-28,
                    1.413803e-28,1.780809e-28,2.080620e-28,
                    2.287013e-28,2.603605e-28,2.810124e-28]) * 1e28  #<--- scale

y = np.array([-1.333526e-16,-8.841676e-16,-2.803599e-15,
              -5.300285e-15,-7.723194e-15,-9.906261e-15,
              -1.124626e-14,-1.238456e-14,-1.193596e-14]) * 1e15    #<--- scale
...

#Label axes
ax.set_ylabel(r'$y~(\times10^{15})$')           
secax.set_xlabel(r'$x_{new}~(\times 10^{28})$')  
plt.gcf().set_size_inches(6, 2.5)
plt.show()

至于第二个问题,当你将边界扩展到x_old之外时,x_new变得不对齐-这是因为你正在外推数据的范围,所以默认情况下np.interp只会复制边缘值,因为它不能处理范围之外的值.

要解决这个问题,可以用一些外推数据填充原始值,这样np.interp就可以在填充的范围内执行内插.这是设置ax.set_xlim(15, 125)时的新结果:

enter image description here

import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["mathtext.fontset"] = "dejavuserif" #<--- serif math text

fig, ax = plt.subplots(constrained_layout=True)

x_upper = np.array([2.379618e-29,5.895669e-29,1.018725e-28,
                    1.413803e-28,1.780809e-28,2.080620e-28,
                    2.287013e-28,2.603605e-28,2.810124e-28]) * 1e28  #<--- scale

y = np.array([-1.333526e-16,-8.841676e-16,-2.803599e-15,
              -5.300285e-15,-7.723194e-15,-9.906261e-15,
              -1.124626e-14,-1.238456e-14,-1.193596e-14]) * 1e15    #<--- scale

x_lower = np.array([20,30,40,50,60,70,80,100,120])

#for tick labels - pad outside data bounds
pad_n_pts = 5

dUp_dLow = np.gradient(x_upper, x_lower)
x_upper_padded = np.insert(
    x_upper,
    [0, len(x_upper)],
    [x_upper[0] - pad_n_pts * np.diff(x_lower)[0] * dUp_dLow[0],
     x_upper[-1] + pad_n_pts * np.diff(x_lower)[-1] * dUp_dLow[-1]]
)

#for tick labels - pad outside data bounds
dLow_dUp = np.gradient(x_lower, x_upper)
x_lower_padded = np.insert(
    x_lower,
    [0, len(x_lower)],
    [x_lower[0] - pad_n_pts * np.diff(x_upper)[0] * dLow_dUp[0],
     x_lower[-1] + pad_n_pts * np.diff(x_upper)[-1] * dLow_dUp[-1]]
)

ax.plot(x_lower, y)

#Use padded x for interpolation
def forward(x):
    return np.interp(x, x_lower_padded, x_upper_padded)
    
def inverse(x):
    return np.interp(x, x_upper_padded, x_lower_padded)

secax = ax.secondary_xaxis('top', functions=(forward,inverse))

ax.set_xlim(15, 125)

#Label axes
ax.set_ylabel(r'$y~(\times10^{15})$')           
secax.set_xlabel(r'$x_{new}~(\times 10^{28})$')  
plt.gcf().set_size_inches(6, 2.5)
plt.show()

下图显示了原始数据点和外推点之间的关系.你set_xlim到蓝色点之外只有一点点,所以下面的可能是一个足够好的近似值.如果你在蓝点之外set_xlim个地方外推就不太准确了.

enter image description here

#View padding in relation to original
plt.scatter(x_lower_padded, x_upper_padded, label='original')
plt.scatter(
    x_lower_padded[[0, -1]], x_upper_padded[[0, -1]],
    marker='*', s=200, c='tab:orange', label=f'extrapolated {pad_n_pts} points'
)
plt.gca().set(xlabel='$x_{lower}$', ylabel='$x_{upper}$')
plt.gcf().set_size_inches(5, 2.5)
plt.gcf().legend(loc='right', fontsize=9)
plt.gca().set_title('Original vs. extrapolated axis bounds')

Python相关问答推荐

通过优化空间在Python中的饼图中添加标签

Pandas 第二小值有条件

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

Polars:用氨纶的其他部分替换氨纶的部分

将输入聚合到统一词典中

在pandas中使用group_by,但有条件

Pandas Loc Select 到NaN和值列表

使用Python从URL下载Excel文件

无法连接到Keycloat服务器

在代码执行后关闭ChromeDriver窗口

基于多个数组的多个条件将值添加到numpy数组

Discord.py -

解决Geopandas和Altair中的正图和投影问题

Matplotlib中的曲线箭头样式

遍历列表列表,然后创建数据帧

多索引数据帧到标准索引DF

如何在不不断遇到ChromeDriver版本错误的情况下使用Selify?

按最大属性值Django对对象进行排序

为什么在安装了64位Python的64位Windows 10上以32位运行?

生产者/消费者-Queue.get by list