如何在matplotlib中添加第二个x轴

Bri*_*ian 73 python matplotlib

我有一个非常简单的问题.我需要在我的绘图上有第二个x轴,我希望这个轴有一定数量的抽搐,对应于第一个轴的某个位置.

我们来试试吧.在这里,我正在绘制暗物质质量作为扩展因子的函数,定义为1 /(1 + z),范围从0到1.

semilogy(1/(1+z),mass_acc_massive,'-',label='DM')
xlim(0,1)
ylim(1e8,5e12)
Run Code Online (Sandbox Code Playgroud)

我想在我的图的顶部有另一个x轴,显示扩展因子的某些值的相应z.那可能吗?如果是的话,我怎么能有xtics斧头

Hoo*_*ked 102

我从@Dhara的回答中得到了一个提示,听起来你想要设置new_tick_locations一个函数列表,从旧的x轴到新的x轴.在tick_function下面发生在点的numpy的阵列,它们映射到一个新的值,并且将它们格式化:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

X = np.linspace(0,1,1000)
Y = np.cos(X*20)

ax1.plot(X,Y)
ax1.set_xlabel(r"Original x-axis: $X$")

new_tick_locations = np.array([.2, .5, .9])

def tick_function(X):
    V = 1/(1+X)
    return ["%.3f" % z for z in V]

ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.set_xlabel(r"Modified x-axis: $1/(1+X)$")
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 此示例"偶然"工作,因为xlims介于0和1之间(默认值).为了使这个工作适用于任意限制,还需要确保两个轴的限制匹配像``ax2.set_xlim(ax1.get_xlim())``否则顶部的``X``和`底部的`X``将是不同的. (5认同)
  • 如果您还想添加标题,请参阅此问题:http://stackoverflow.com/questions/12750355/python-matplotlib-figure-title-overlaps-axes-label-when-using-twiny (2认同)
  • @tiago我现在无法检查,但是`ax.set_yscale('log')`是否有效? (2认同)
  • Matplotlib 实现了添加辅助轴的本机方法。在这里查看他们的示例:https://matplotlib.org/3.1.0/gallery/subplots_axes_and_figures/secondary_axis.html (2认同)

Dha*_*ara 25

您可以使用twiny来创建2个x轴刻度.例如:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))

ax1.plot(range(60), a)
ax2.plot(range(100), np.ones(100)) # Create a dummy plot
ax2.cla()
plt.show()
Run Code Online (Sandbox Code Playgroud)

参考:http://matplotlib.sourceforge.net/faq/howto_faq.html#multiple-y-axis-scales

输出: 在此输入图像描述


Ado*_*obe 12

如果您希望您的上轴是下轴刻度值的函数:

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots()

ax1 = fig.add_subplot(111)

ax1.plot(range(5), range(5))

ax1.grid(True)

ax2 = ax1.twiny()
ax1Xs = ax1.get_xticks()

ax2Xs = []
for X in ax1Xs:
    ax2Xs.append(X * 2)

ax2.set_xticks(ax1Xs)
ax2.set_xbound(ax1.get_xbound())
ax2.set_xticklabels(ax2Xs)

title = ax1.set_title("Upper x-axis ticks are lower x-axis ticks doubled!")
title.set_y(1.1)
fig.subplots_adjust(top=0.85)

fig.savefig("1.png")
Run Code Online (Sandbox Code Playgroud)

得到:

在此输入图像描述


car*_*rla 10

在Dhara的答案评论中回答你的问题:" 我想在第二个x轴上显示这些抽搐:(7,8,99)对应于x轴位置10,30,40.这在某种程度上是可能的吗? "是的, 它是.

import numpy as np
import matplotlib.pyplot as plt

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

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))
ax1.plot(range(60), a)

ax1.set_xlim(0, 60)
ax1.set_xlabel("x")
ax1.set_ylabel("y")

ax2 = ax1.twiny()
ax2.set_xlabel("x-transformed")
ax2.set_xlim(0, 60)
ax2.set_xticks([10, 30, 40])
ax2.set_xticklabels(['7','8','99'])

plt.show()
Run Code Online (Sandbox Code Playgroud)

你会得到: 在此输入图像描述


小智 10

从 matplotlib 3.1 开始,您可以使用 ax.secondary_xaxis

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1,13, num=301)
y = (np.sin(x)+1.01)*3000

# Define function and its inverse
f = lambda x: 1/(1+x)
g = lambda x: 1/x-1

fig, ax = plt.subplots()
ax.semilogy(x, y, label='DM')

ax2 = ax.secondary_xaxis("top", functions=(f,g))

ax2.set_xlabel("1/(x+1)")
ax.set_xlabel("x")
plt.show()
Run Code Online (Sandbox Code Playgroud)