loglog 图中的寄生虫 x 轴
Parasite x-axis in loglog plot
我有一张图表,其中 x 轴是以 GeV 为单位的温度,但我还需要以开尔文为单位提供温度参考,所以我想到了以 K 为单位放置寄生虫轴。尝试按照这个答案 How to add a second x-axis in matplotlib ,这是代码示例。我在图表的顶部有第二个轴,但它不是我需要的以 K 为单位的温度。
import numpy as np
import matplotlib.pyplot as plt
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
ax1.loglog(tt,yy)
ax1.set_xlabel('Temperature (GeV')
new_tick_locations = np.array([.2, .5, .9])
def tick_function(X):
V = X*1.16e13
return ["%.1f" % z for z in V]
ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(ax1Xs))
ax2.set_xlabel('Temp (Kelvin)')
plt.show()
这是我 运行 代码时得到的结果。
对数对数图
我需要寄生轴与原始 x 轴成比例。当任何人看到图表时,都可以很容易地读取开尔文温度。提前致谢。
问题如下:当您使用 ax2.set_xlim(ax1.get_xlim())
时,您基本上是将上 x 轴的限制设置为与下 x 轴的限制相同。现在,如果你这样做
print(ax1.get_xlim())
print(ax2.get_xlim())
你得到的两个轴的值与
相同
(6.309573444801943e-16, 158489319246.11108)
(6.309573444801943e-16, 158489319246.11108)
但您的下部 x 轴具有 对数 刻度。当您使用 ax2.set_xlim()
分配限制时,ax2
的限制是相同的 但 比例仍然是 线性 。这就是为什么当您将刻度设置为 [.2, .5, .9]
时,这些值显示为上部 x 轴最左侧的刻度,如图所示。
解决方法是将上面的x轴也设置为对数刻度。这是必需的,因为您的 new_tick_locations
对应于下方 x 轴上的 actual 值。您只想重命名这些值以在 Kelvin 中显示刻度标签。从您的变量名称可以清楚地看出 new_tick_locations
对应于新的刻度位置。我使用 new_tick_locations
的一些修改值来突出问题。
我正在使用科学格式 '%.0e'
因为 1 GeV = 1.16e13 K 所以 0.5 GeV 将是一个非常大的值,有很多零。
下面是一个示例答案:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
ax1.loglog(tt,yy)
ax1.set_xlabel('Temperature (GeV)')
new_tick_locations = np.array([0.000002, 0.05, 9000])
def tick_function(X):
V = X*1.16e13
return ["%.1f" % z for z in V]
ax2.set_xscale('log') # Setting the logarithmic scale
ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.xaxis.set_major_formatter(mtick.FormatStrFormatter('%.0e'))
ax2.set_xlabel('Temp (Kelvin)')
plt.show()
通用解决方案可能如下所示。因为你有一个非线性刻度,所以想法是找到开尔文刻度的位置,转换为 GeV,以 GeV 为单位设置位置,但以开尔文为单位标记它们。这听起来很复杂,但优点是您无需自己寻找刻度,只需依靠 matplotlib 即可找到它们。
不过,这需要的是两个尺度之间的函数依赖性,即 GeV 和 Kelvin 之间的转换及其倒数。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
plt.setp([ax1,ax2], xscale="log", yscale="log")
ax1.get_shared_x_axes().join(ax1, ax2)
ax1.plot(tt,yy)
ax1.set_xlabel('Temperature (GeV)')
ax2.set_xlabel('Temp (Kelvin)')
fig.canvas.draw()
# 1 GeV == 1.16 × 10^13 Kelvin
Kelvin2GeV = lambda k: k / 1.16e13
GeV2Kelvin = lambda gev: gev * 1.16e13
loc = mticker.LogLocator()
locs = loc.tick_values(*GeV2Kelvin(np.array(ax1.get_xlim())))
ax2.set_xticks(Kelvin2GeV(locs))
ax2.set_xlim(ax1.get_xlim())
f = mticker.ScalarFormatter(useOffset=False, useMathText=True)
g = lambda x,pos : "${}$".format(f._formatSciNotation('%1.10e' % GeV2Kelvin(x)))
fmt = mticker.FuncFormatter(g)
ax2.xaxis.set_major_formatter(mticker.FuncFormatter(fmt))
plt.show()
我有一张图表,其中 x 轴是以 GeV 为单位的温度,但我还需要以开尔文为单位提供温度参考,所以我想到了以 K 为单位放置寄生虫轴。尝试按照这个答案 How to add a second x-axis in matplotlib ,这是代码示例。我在图表的顶部有第二个轴,但它不是我需要的以 K 为单位的温度。
import numpy as np
import matplotlib.pyplot as plt
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
ax1.loglog(tt,yy)
ax1.set_xlabel('Temperature (GeV')
new_tick_locations = np.array([.2, .5, .9])
def tick_function(X):
V = X*1.16e13
return ["%.1f" % z for z in V]
ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(ax1Xs))
ax2.set_xlabel('Temp (Kelvin)')
plt.show()
这是我 运行 代码时得到的结果。
对数对数图
我需要寄生轴与原始 x 轴成比例。当任何人看到图表时,都可以很容易地读取开尔文温度。提前致谢。
问题如下:当您使用 ax2.set_xlim(ax1.get_xlim())
时,您基本上是将上 x 轴的限制设置为与下 x 轴的限制相同。现在,如果你这样做
print(ax1.get_xlim())
print(ax2.get_xlim())
你得到的两个轴的值与
相同(6.309573444801943e-16, 158489319246.11108)
(6.309573444801943e-16, 158489319246.11108)
但您的下部 x 轴具有 对数 刻度。当您使用 ax2.set_xlim()
分配限制时,ax2
的限制是相同的 但 比例仍然是 线性 。这就是为什么当您将刻度设置为 [.2, .5, .9]
时,这些值显示为上部 x 轴最左侧的刻度,如图所示。
解决方法是将上面的x轴也设置为对数刻度。这是必需的,因为您的 new_tick_locations
对应于下方 x 轴上的 actual 值。您只想重命名这些值以在 Kelvin 中显示刻度标签。从您的变量名称可以清楚地看出 new_tick_locations
对应于新的刻度位置。我使用 new_tick_locations
的一些修改值来突出问题。
我正在使用科学格式 '%.0e'
因为 1 GeV = 1.16e13 K 所以 0.5 GeV 将是一个非常大的值,有很多零。
下面是一个示例答案:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
ax1.loglog(tt,yy)
ax1.set_xlabel('Temperature (GeV)')
new_tick_locations = np.array([0.000002, 0.05, 9000])
def tick_function(X):
V = X*1.16e13
return ["%.1f" % z for z in V]
ax2.set_xscale('log') # Setting the logarithmic scale
ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.xaxis.set_major_formatter(mtick.FormatStrFormatter('%.0e'))
ax2.set_xlabel('Temp (Kelvin)')
plt.show()
通用解决方案可能如下所示。因为你有一个非线性刻度,所以想法是找到开尔文刻度的位置,转换为 GeV,以 GeV 为单位设置位置,但以开尔文为单位标记它们。这听起来很复杂,但优点是您无需自己寻找刻度,只需依靠 matplotlib 即可找到它们。 不过,这需要的是两个尺度之间的函数依赖性,即 GeV 和 Kelvin 之间的转换及其倒数。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
tt = np.logspace(-14,10,100)
yy = np.logspace(-10,-2,100)
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()
plt.setp([ax1,ax2], xscale="log", yscale="log")
ax1.get_shared_x_axes().join(ax1, ax2)
ax1.plot(tt,yy)
ax1.set_xlabel('Temperature (GeV)')
ax2.set_xlabel('Temp (Kelvin)')
fig.canvas.draw()
# 1 GeV == 1.16 × 10^13 Kelvin
Kelvin2GeV = lambda k: k / 1.16e13
GeV2Kelvin = lambda gev: gev * 1.16e13
loc = mticker.LogLocator()
locs = loc.tick_values(*GeV2Kelvin(np.array(ax1.get_xlim())))
ax2.set_xticks(Kelvin2GeV(locs))
ax2.set_xlim(ax1.get_xlim())
f = mticker.ScalarFormatter(useOffset=False, useMathText=True)
g = lambda x,pos : "${}$".format(f._formatSciNotation('%1.10e' % GeV2Kelvin(x)))
fmt = mticker.FuncFormatter(g)
ax2.xaxis.set_major_formatter(mticker.FuncFormatter(fmt))
plt.show()