92

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

让我们尝试一个例子。在这里,我将暗物质质量绘制为膨胀因子的函数,定义为 1/(1+z),范围从 0 到 1。

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

我想在我的绘图顶部有另一个 x 轴,显示扩展因子的某些值对应的 z。那可能吗?如果是,我怎样才能拥有 xtics 斧头

4

6 回答 6

134

我从@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()

在此处输入图像描述

于 2012-05-09T13:49:02.177 回答
31

您可以使用 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()

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

输出: 在此处输入图像描述

于 2012-05-09T11:24:54.013 回答
17

如果您希望上轴成为下轴刻度值的函数,您可以执行以下操作。请注意:有时get_xticks()会有超出可见范围的刻度,转换时必须允许。

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()
ax2.set_xticks( ax1.get_xticks() )
ax2.set_xbound(ax1.get_xbound())
ax2.set_xticklabels([x * 2 for x in ax1.get_xticks()])

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

给出:

在此处输入图像描述

于 2014-05-23T14:44:59.693 回答
13

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

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

于 2012-05-09T14:07:47.673 回答
13

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

于 2019-12-17T17:17:38.833 回答
2

由于声誉低下,我被迫将其发布为答案而不是评论。我遇到了与 Matteo 类似的问题。不同之处在于我没有从第一个 x 轴到第二个 x 轴的映射,只有 x 值本身。所以我想直接在我的第二个 x 轴上设置数据,而不是刻度,但是,没有axes.set_xdata. 我可以使用 Dhara 的答案进行修改:

ax2.lines = []

而不是使用:

ax2.cla()

使用时也清除了我的情节ax1

于 2015-01-28T02:32:24.203 回答