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

子图中secondary_xaxis用全局变量致副轴异常的解决问询

问题描述

我在绘制展示不同光谱多普勒速度的图形时,脚本因使用全局变量出现异常:只有最后一次赋值的全局变量会作用于所有子图的secondary_xaxis,导致前序子图副轴显示异常(比如顶部子图没有0刻度)。因为找不到向secondary_xaxis的转换函数传递参数的方法,才用了全局变量,现在求可行的替代方案。

最小可复现代码
import numpy as np
import matplotlib.pyplot as plt

def doppler(wavelengths):
    c = 299792.458  # 光速,单位km/s
    lambda_0 = linecore  # 中心波长,单位埃
    doppler_shifts = c * ((wavelengths - lambda_0) / lambda_0)
    return doppler_shifts

def idoppler(doppler_shifts):
    c = 299792.458  # 光速,单位km/s
    lambda_0 = linecore  # 中心波长,单位埃
    wavelengths = lambda_0 * (1 + doppler_shifts / c) - linecore
    return wavelengths

global linecore

plt.subplot(221)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
linecore = 6000
ax1 = plt.gca()  # 获取当前轴(即刚创建的轴)
ax1a = ax1.secondary_xaxis('top', functions=(doppler, idoppler))
ax1a.set_xticks([-50,0,50])

plt.subplot(222)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
linecore = 6000
ax2 = plt.gca()  # 获取当前轴(即刚创建的轴)
ax2a = ax2.secondary_xaxis('top', functions=(doppler, idoppler))
ax2a.set_xticks([-50,0,50])

plt.subplot(223)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
linecore = 8000
ax3 = plt.gca()  # 获取当前轴(即刚创建的轴)
ax3a = ax3.secondary_xaxis('top', functions=(doppler, idoppler))
ax3a.set_xticks([-50,0,50])

plt.subplot(224)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
linecore = 8000
ax4 = plt.gca()  # 获取当前轴(即刚创建的轴)
ax4a = ax4.secondary_xaxis('top', functions=(doppler, idoppler))
ax4a.set_xticks([-50,0,50])

plt.tight_layout()
plt.show()
异常效果

副轴显示异常截图

解决方案

核心思路是为每个子图创建独立的转换函数,避免全局变量的共享问题,以下是两种可行方案:

方案1:使用闭包

定义外层函数传入中心波长lambda_0,返回专属的多普勒转换函数,确保每个子图的函数绑定独立参数:

import numpy as np
import matplotlib.pyplot as plt

def create_doppler_functions(lambda_0):
    c = 299792.458  # 光速,单位km/s
    def doppler(wavelengths):
        return c * ((wavelengths - lambda_0) / lambda_0)
    def idoppler(doppler_shifts):
        return lambda_0 * (1 + doppler_shifts / c) - lambda_0
    return doppler, idoppler

# 绘制子图
plt.subplot(221)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
ax1 = plt.gca()
doppler1, idoppler1 = create_doppler_functions(6000)
ax1a = ax1.secondary_xaxis('top', functions=(doppler1, idoppler1))
ax1a.set_xticks([-50,0,50])

plt.subplot(222)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
ax2 = plt.gca()
doppler2, idoppler2 = create_doppler_functions(6000)
ax2a = ax2.secondary_xaxis('top', functions=(doppler2, idoppler2))
ax2a.set_xticks([-50,0,50])

plt.subplot(223)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
ax3 = plt.gca()
doppler3, idoppler3 = create_doppler_functions(8000)
ax3a = ax3.secondary_xaxis('top', functions=(doppler3, idoppler3))
ax3a.set_xticks([-50,0,50])

plt.subplot(224)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
ax4 = plt.gca()
doppler4, idoppler4 = create_doppler_functions(8000)
ax4a = ax4.secondary_xaxis('top', functions=(doppler4, idoppler4))
ax4a.set_xticks([-50,0,50])

plt.tight_layout()
plt.show()

方案2:使用functools.partial

通过partial工具为转换函数绑定固定的lambda_0参数,实现每个子图的函数独立:

import numpy as np
import matplotlib.pyplot as plt
from functools import partial

def doppler(wavelengths, lambda_0):
    c = 299792.458
    return c * ((wavelengths - lambda_0) / lambda_0)

def idoppler(doppler_shifts, lambda_0):
    c = 299792.458
    return lambda_0 * (1 + doppler_shifts / c) - lambda_0

plt.subplot(221)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
ax1 = plt.gca()
doppler_partial = partial(doppler, lambda_0=6000)
idoppler_partial = partial(idoppler, lambda_0=6000)
ax1a = ax1.secondary_xaxis('top', functions=(doppler_partial, idoppler_partial))
ax1a.set_xticks([-50,0,50])

plt.subplot(222)
plt.plot(np.linspace(-1,1,10)+6000, np.random.random([10]))
ax2 = plt.gca()
doppler_partial = partial(doppler, lambda_0=6000)
idoppler_partial = partial(idoppler, lambda_0=6000)
ax2a = ax2.secondary_xaxis('top', functions=(doppler_partial, idoppler_partial))
ax2a.set_xticks([-50,0,50])

plt.subplot(223)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
ax3 = plt.gca()
doppler_partial = partial(doppler, lambda_0=8000)
idoppler_partial = partial(idoppler, lambda_0=8000)
ax3a = ax3.secondary_xaxis('top', functions=(doppler_partial, idoppler_partial))
ax3a.set_xticks([-50,0,50])

plt.subplot(224)
plt.plot(np.linspace(-1,1,10)+8000, np.random.random([10]))
ax4 = plt.gca()
doppler_partial = partial(doppler, lambda_0=8000)
idoppler_partial = partial(idoppler, lambda_0=8000)
ax4a = ax4.secondary_xaxis('top', functions=(doppler_partial, idoppler_partial))
ax4a.set_xticks([-50,0,50])

plt.tight_layout()
plt.show()

内容的提问来源于Stack Exchange,提问作者Coolcrab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:16:25