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

如何在Python中将数组变量名转为字符串用作图表标题?

自动将函数输入变量名设为图表标题的问题解决

问题背景

想要让函数自动把输入变量名作为图表标题,尝试用列表推导式从locals()中匹配变量值来获取变量名,但运行时报错。这种方法对单值变量(如整数)有效,但对数组类型的输入会触发ValueError,原因是数组元素过多导致比较结果的真值判断歧义。

原代码

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy.fftpack import hilbert, ihilbert

def mod_arg_plot(column, time):
    # 尝试获取变量名的代码,注释后可运行
    # title = [i for i, j in locals().items() if j == column][0]

    plt.plot(time, abs(ihilbert(column)), 'b-', time, np.angle(ihilbert(column)), 'r--')
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude / degrees')
    plt.legend(('Modulus', 'Argument'))
    # plt.title(title)
    plt.show()

报错信息

line 44, in mod_arg_plot
    title = [i for i, j in locals().items() if j == column][0]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
line 44, in <listcomp>
    title = [i for i, j in locals().items() if j == column][0]
                                               ^^^^^^^^^^^
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

问题原因

当column是NumPy数组时,j == column会返回一个布尔数组(逐元素比较的结果),而if条件需要单个布尔值来判断,因此Python抛出歧义错误。另外,即使两个数组内容完全相同,它们也可能是不同的对象,用==匹配值的方式本身就不可靠。

解决方案

方案1:显式传递标题参数(最稳定可靠)

直接在调用函数时传入标题,避免依赖变量名的自动推导,这种方式最清晰,也能处理任何输入场景(比如传递的是计算后的数组、切片等没有明确变量名的情况)。

修改后的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import ihilbert

def mod_arg_plot(column, time, title=None):
    # 如果没传标题,默认用'Column Data'
    plt_title = title if title is not None else 'Column Data'
    
    plt.plot(time, abs(ihilbert(column)), 'b-', time, np.angle(ihilbert(column)), 'r--')
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude / degrees')
    plt.legend(('Modulus', 'Argument'))
    plt.title(plt_title)
    plt.show()

# 调用示例
my_data = np.random.randn(100)
my_time = np.linspace(0, 10, 100)
mod_arg_plot(my_data, my_time, title='my_data')

方案2:利用inspect模块自动获取调用时的变量名

如果确实需要自动获取变量名,可以用inspect模块解析调用栈,提取传入参数的表达式。这种方式能自动获取简单变量名,但如果传入的是复杂表达式(比如my_data[::2]),得到的会是表达式字符串而非变量名。

修改后的代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import ihilbert
import inspect
import ast

def mod_arg_plot(column, time):
    # 获取调用栈,解析传入column的参数表达式
    frame = inspect.currentframe().f_back
    call_node = ast.walk(ast.parse(inspect.getframeinfo(frame).code_context[0])).__next__()
    # 找到column对应的参数值
    for arg in call_node.args:
        if isinstance(arg, ast.Name):
            title = arg.id
            break
    else:
        title = 'Column Data'

    plt.plot(time, abs(ihilbert(column)), 'b-', time, np.angle(ihilbert(column)), 'r--')
    plt.xlabel('Time (s)')
    plt.ylabel('Amplitude / degrees')
    plt.legend(('Modulus', 'Argument'))
    plt.title(title)
    plt.show()

# 调用示例
my_data = np.random.randn(100)
my_time = np.linspace(0, 10, 100)
mod_arg_plot(my_data, my_time)  # 标题会自动设为'my_data'

注意事项

  • 方案2的自动推导仅适用于简单变量传递场景,若传入的是表达式、匿名函数结果等,无法得到预期的变量名。
  • 依赖变量名的方式本质上不可靠,因为变量名只是引用,同一个值可能被多个变量引用,或者传递的是没有变量名的临时对象。

内容的提问来源于stack exchange,提问作者Dordini Balbozhia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:15:37