Python Matplotlib绘制波长能量双X轴光吸收图问题求解
Python绘制波长-能量双X轴光吸收谱的实现方案
我需要在Python中绘制带两个非线性相关X轴的光吸收数据图:底部X轴显示波长(单位:nm),顶部X轴显示对应的光子能量(单位:eV),二者为反比例关系而非线性关联。我最初写的最小可复现代码如下:
import numpy as np import matplotlib.pyplot as plt import scipy.constants as constants # 波长(nm)转能量(eV) def WLtoE(wl): # E = h*c/wl h = constants.h # 普朗克常数 c = constants.c # 光速 J_eV = constants.e # 焦耳与电子伏特转换系数 wl_nm = wl * 10**(-9) # 波长单位从nm转换为m E_J = (h*c) / wl_nm # 计算得到能量,单位J E_eV = E_J / J_eV # 能量单位转换为eV return E_eV x = np.arange(200,2001,5) x_mod = WLtoE(x) y = 2*x + 3 fig, ax1 = plt.subplots() ax2 = ax1.twiny() ax1.plot(x, y, color='red') ax2.plot(x_mod, y, color = 'green') ax1.set_xlabel('波长 (nm)', fontsize = 'large', color='red') ax1.set_ylabel('吸光度 (a.u.)', fontsize = 'large') ax1.tick_params(axis='x', colors='red') ax2.set_xlabel('能量 (eV)', fontsize='large', color='green') ax2.tick_params(axis='x', colors='green') ax2.spines['top'].set_color('green') ax2.spines['bottom'].set_color('red') plt.tight_layout() plt.show()
运行后输出结果接近预期,但存在两个需要解决的问题:
- 轴方向不匹配:高波长对应低能量,但当前两个X轴都是递增方向,没有体现对应关系,尝试使用
x_mod = WLtoE(x)[::-1]没有解决问题。 - 刻度对应错误:当前图中1000nm位置大致对应3eV,但实际1000nm对应的光子能量是1.24eV,需要调整轴缩放让上下轴数值对应正确,且两条曲线重合。
编辑:该问题已得到解决,我仅对绘图逻辑做了小幅调整,修改后的完整绘图代码如下:
import numpy as np import matplotlib.pyplot as plt import scipy.constants as constants from matplotlib.ticker import FormatStrFormatter # 波长(nm)转能量(eV) def WLtoE(wl): h = constants.h # 普朗克常数 c = constants.c # 光速 J_eV = constants.e # 焦耳与电子伏特转换系数 wl_nm = wl * 10**(-9) # 波长单位从nm转换为m E_J = (h*c) / wl_nm # 计算得到能量,单位J E_eV = E_J / J_eV # 能量单位转换为eV return E_eV # 能量(eV)转波长(nm),与WLtoE互为逆函数 def EtoWL(E): h = constants.h c = constants.c J_eV = constants.e E_J = E * J_eV wl_m = (h * c) / E_J return wl_m * 1e9 # 避免除0错误 def preventDivisionByZero(E_ticks): return E_ticks[E_ticks > 0] x = np.arange(200,2001,5) y = 2*x + 3 fig, ax1 = plt.subplots() ax1.plot(WLtoE(x), y) ax1.set_xlabel('能量 (eV)', fontsize = 'large') ax1.set_ylabel('吸光度 (a.u.)', fontsize = 'large') # 在顶部创建第二个X轴,显示波长,通过转换函数关联两个轴 ax2 = ax1.secondary_xaxis('top', functions=(EtoWL, WLtoE)) ax2.set_xlabel('波长 (nm)', fontsize='large') # 反转波长轴,满足长波长对应低能量的对应关系 ax2.invert_xaxis() # 获取能量轴的刻度,过滤掉0值避免除0错误 E_ticks = ax1.get_xticks() E_ticks = preventDivisionByZero(E_ticks) # 自定义波长轴刻度,取常用的整数值,不需要线性等距 wl_ticks = np.asarray([200, 250, 300, 350, 400, 500, 600, 750, 1000, 2000]) ax2.set_xticks(wl_ticks) # 波长轴刻度显示为整数 ax2.xaxis.set_major_formatter(FormatStrFormatter('%i')) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者quantum girl
相关产品推荐
相关产品推荐

