簡體   English   中英

如何(重新)縮放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)

其中val1val2是峰值, max1max2是這些峰值的指數。

這里有一些應該有用的代碼:

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

您不需要示例中的整個代碼(或使用它的tick格式化程序),但映射函數將幫助您創建縮放的x數組(同樣,使用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軸,而無需實際修改x陣列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM