如何(重新)缩放 x 轴以适合图中的某些点?
How to (re)scale the x-axis to fit certain points in the graph?
我想重新调整我的(定性)x 轴,使两个峰值(图中可见)与其实际值(即 500 keV 和 1274 MeV)相关。
我该怎么做?
import numpy as np
import matplotlib.pyplot as plt
def read_from_file(filename):
return np.loadtxt(filename)
data = list(read_from_file("calibration.txt"))
print(data.index(max(data[:2000])))#x value 500kev
print(data.index(max(data[2000:])))#x value 1274
fig = plt.figure()
ax = fig.add_subplot(111)
x = range(len(data))
plt.plot(x, data)
plt.xlim(0, 5000)
plt.ylim(0, 7000)
plt.title("$^{22}$Na Spectrum")
plt.xlabel("Energy")
plt.ylabel("Amount of Photons")
plt.grid()
ax.annotate("500 keV", xy = (1450, 6541), xytext = (1600, 6500))
ax.annotate("1274 MeV", xy = (3500, 950), xytext = (3700, 1100))
plt.show()
使用numpy
,你可以使用argmax
.
找到两个尖峰的索引(即不需要将数据转换为列表)
然后,您可以使用以下方法缩放 x 值:
xnew = val1 + (x - max1) / (max2 - max1) * (val2 - val1)
其中 val1
和 val2
是峰值的值,max1
和 max2
是这些峰值的索引。
下面是一些应该有效的代码:
import numpy as np
import matplotlib.pyplot as plt
# Fake some data approximately in your range. You can ignore this bit!
# Random numbers for noise
data = 1000. + np.random.rand(5000) * 100.
x = np.arange(len(data))
# Add the first spike
mu1, sd1 = 1450., 300.
pdf1 = (1./(sd1*2.*np.pi) * np.exp(-(x - mu1)**2 / sd1**2)) * 1e7
data += pdf1
# Add the second spike
mu2, sd2 = 3500., 200.
pdf2 = (1./(sd2*2.*np.pi) * np.exp(-(x - mu2)**2 / sd2**2)) * 1e6
data += pdf2
# End of fake data generation
# Find the index of the first maximum (using your '2000' cutoff)
cutoff = 2000
max1 = float(np.argmax(data[:cutoff]))
# Find the index of the second cutoff
max2 = float(np.argmax(data[cutoff:]) + cutoff)
# The actual values of the two spikes
val1, val2 = 500., 1274
# Scale the xvalues
xnew = val1 + (x - max1) / (max2 - max1) * (val2 - val1)
# Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xnew, data)
ax.set_ylim(0, 7000)
ax.set_title("$^{22}$Na Spectrum")
ax.set_xlabel("Energy")
ax.set_ylabel("Number of Photons")
ax.grid()
# Add some lines at the actual spikes to check scaling worked
ax.axvline(val1)
ax.axvline(val2)
plt.show()
有趣的是你应该问这个问题。我目前正在尝试将一个示例推送到 MatPlotLib 中,以准确显示如何执行此操作。您可以在这里查看食谱:https://github.com/madphysicist/matplotlib/blob/7b05223c85741120019b81e1248c20f9bc090c61/examples/ticks_and_spines/tick_transform_formatter.py
您不需要示例中的整个代码(或使用它的刻度格式化程序),但映射函数将帮助您创建缩放的 x-array(另外,使用 np.argmax
而不是index(max(...))
:
ind500 = np.argmaxmax(data[:2000]))
ind1274 = np.argmax(data[2000:])) + 2000
x_scaled = (x - ind500) * (1274 - 500) / (ind1274 - ind500) + 500
您可以像往常一样使用x_scaled
绘图:
plt.plot(x_scaled, data)
...
将它们组合在一起(并进行一些调整以使用 OO API 而不是 pyplot):
import numpy as np
from matplotlib import pyplot as plt
data = np.loadtxt("calibration.txt") # Don't convert this back to a list
ind500 = np.argmaxmax(data[:2000]))
ind1274 = np.argmax(data[2000:])) + 2000
x = (np.arange(len(data)) - ind500) * (1274 - 500) / (ind1274 - ind500) + 500
fig, ax = plt.subplots()
ax.plot(x, data)
plt.title("$^{22}$Na Spectrum")
plt.xlabel("Energy")
plt.ylabel("Photons Counts")
plt.grid()
ax.annotate("500 keV", xy = (500, data[ind500]), xytext = (550, data[ind500] + 100))
ax.annotate("1274 keV", xy = (1274, data[ind1274]), xytext = (1324, data[ind1274] + 100))
plt.show()
我链接到的示例将允许您以完全不同的单位显示 x-axis,而无需实际修改您的 x-array。
我想重新调整我的(定性)x 轴,使两个峰值(图中可见)与其实际值(即 500 keV 和 1274 MeV)相关。 我该怎么做?
import numpy as np
import matplotlib.pyplot as plt
def read_from_file(filename):
return np.loadtxt(filename)
data = list(read_from_file("calibration.txt"))
print(data.index(max(data[:2000])))#x value 500kev
print(data.index(max(data[2000:])))#x value 1274
fig = plt.figure()
ax = fig.add_subplot(111)
x = range(len(data))
plt.plot(x, data)
plt.xlim(0, 5000)
plt.ylim(0, 7000)
plt.title("$^{22}$Na Spectrum")
plt.xlabel("Energy")
plt.ylabel("Amount of Photons")
plt.grid()
ax.annotate("500 keV", xy = (1450, 6541), xytext = (1600, 6500))
ax.annotate("1274 MeV", xy = (3500, 950), xytext = (3700, 1100))
plt.show()
使用numpy
,你可以使用argmax
.
然后,您可以使用以下方法缩放 x 值:
xnew = val1 + (x - max1) / (max2 - max1) * (val2 - val1)
其中 val1
和 val2
是峰值的值,max1
和 max2
是这些峰值的索引。
下面是一些应该有效的代码:
import numpy as np
import matplotlib.pyplot as plt
# Fake some data approximately in your range. You can ignore this bit!
# Random numbers for noise
data = 1000. + np.random.rand(5000) * 100.
x = np.arange(len(data))
# Add the first spike
mu1, sd1 = 1450., 300.
pdf1 = (1./(sd1*2.*np.pi) * np.exp(-(x - mu1)**2 / sd1**2)) * 1e7
data += pdf1
# Add the second spike
mu2, sd2 = 3500., 200.
pdf2 = (1./(sd2*2.*np.pi) * np.exp(-(x - mu2)**2 / sd2**2)) * 1e6
data += pdf2
# End of fake data generation
# Find the index of the first maximum (using your '2000' cutoff)
cutoff = 2000
max1 = float(np.argmax(data[:cutoff]))
# Find the index of the second cutoff
max2 = float(np.argmax(data[cutoff:]) + cutoff)
# The actual values of the two spikes
val1, val2 = 500., 1274
# Scale the xvalues
xnew = val1 + (x - max1) / (max2 - max1) * (val2 - val1)
# Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xnew, data)
ax.set_ylim(0, 7000)
ax.set_title("$^{22}$Na Spectrum")
ax.set_xlabel("Energy")
ax.set_ylabel("Number of Photons")
ax.grid()
# Add some lines at the actual spikes to check scaling worked
ax.axvline(val1)
ax.axvline(val2)
plt.show()
有趣的是你应该问这个问题。我目前正在尝试将一个示例推送到 MatPlotLib 中,以准确显示如何执行此操作。您可以在这里查看食谱:https://github.com/madphysicist/matplotlib/blob/7b05223c85741120019b81e1248c20f9bc090c61/examples/ticks_and_spines/tick_transform_formatter.py
您不需要示例中的整个代码(或使用它的刻度格式化程序),但映射函数将帮助您创建缩放的 x-array(另外,使用 np.argmax
而不是index(max(...))
:
ind500 = np.argmaxmax(data[:2000]))
ind1274 = np.argmax(data[2000:])) + 2000
x_scaled = (x - ind500) * (1274 - 500) / (ind1274 - ind500) + 500
您可以像往常一样使用x_scaled
绘图:
plt.plot(x_scaled, data)
...
将它们组合在一起(并进行一些调整以使用 OO API 而不是 pyplot):
import numpy as np
from matplotlib import pyplot as plt
data = np.loadtxt("calibration.txt") # Don't convert this back to a list
ind500 = np.argmaxmax(data[:2000]))
ind1274 = np.argmax(data[2000:])) + 2000
x = (np.arange(len(data)) - ind500) * (1274 - 500) / (ind1274 - ind500) + 500
fig, ax = plt.subplots()
ax.plot(x, data)
plt.title("$^{22}$Na Spectrum")
plt.xlabel("Energy")
plt.ylabel("Photons Counts")
plt.grid()
ax.annotate("500 keV", xy = (500, data[ind500]), xytext = (550, data[ind500] + 100))
ax.annotate("1274 keV", xy = (1274, data[ind1274]), xytext = (1324, data[ind1274] + 100))
plt.show()
我链接到的示例将允许您以完全不同的单位显示 x-axis,而无需实际修改您的 x-array。