You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 06:12:01