Python绘图函数中if-else数据判断逻辑异常求助
解决多图表条件绘制的问题
我明白你现在的困扰——想根据传入的数据是否存在来决定是否绘制对应的图表,但原来的判断逻辑要么不管用,要么报错。咱们一步步来解决这个问题:
问题根源
你遇到的两个问题本质上都是对pandas Series的判断逻辑错误:
- 当你用
cond == []判断时,如果你传入的是df['cond'](一个pandas Series),这个比较会返回一个和Series长度相同的布尔数组,而不是单个布尔值。但if语句需要的是单个布尔值,所以这个判断永远是False(因为数组和空列表不相等),导致即使你觉得“无数据”,代码还是会执行绘图。 - 当你把默认参数改成0后,
sal == 0同样会返回一个布尔Series,这时候if语句就会抛出ValueError: The truth value of a Series is ambiguous——因为Python不知道你是要判断所有元素为True,还是任意元素为True。
解决方案:用None作为默认参数+正确的空值判断
我们可以把函数的默认参数改成None,然后在函数内部判断参数是否被传入,并且传入的Series是否不为空。具体步骤如下:
- 修改函数参数的默认值为
None,而不是空列表或0; - 对每个参数,先判断是否不为
None,再判断对应的Series是否不为空(用not param.empty); - 只有当两个条件都满足时,才执行绘图逻辑。
修改后的完整代码
import matplotlib.pyplot as plt import pandas as pd import matplotlib.dates as md data = {'dates': [20200901,20200902,20200903,20200904,20200905,20200906,20200907,20200908,20200909,20200910], 'depth': [1,2,3,4,5,6,7,8,9,10], 'cond': [30.1,30.2,30.3,30.6,31,31.1,31.0,31.4,31.1,30.9] } df = pd.DataFrame(data, columns = ['dates', 'depth', 'cond']) df['pd_datetime'] = pd.to_datetime(df['dates']) # 创建一个空的Series用于测试无数据的情况 empty_sal = pd.Series([]) def ctd_plots_timeseries(time=None, cond=None, sal=None, temp=None, depth=None, density=None): #----------- # CONDUCTIVITY PLOT #----------- if cond is not None and not cond.empty: plt.scatter(time, depth, s=15, c=cond, marker='o', edgecolor='none') plt.title("Conductivity") plt.show() else: print("there is no data for cond") #----------- # SALINITY (PSU) PLOT #----------- if sal is not None and not sal.empty: plt.scatter(time, depth, s=15, c=sal, marker='o', edgecolor='none') plt.title("Salinity") plt.show() else: print('there is no salinity data') # 测试1:不传sal参数 print("测试1:不传sal参数") ctd_plots_timeseries(depth=df['depth'], time=df['pd_datetime'], cond=df['cond']) # 测试2:传入空的sal Series print("\n测试2:传入空的sal Series") ctd_plots_timeseries(depth=df['depth'], time=df['pd_datetime'], cond=df['cond'], sal=empty_sal)
额外优化建议
因为你还有4个类似的图表,重复的判断和绘图逻辑会让代码冗余,推荐两个优化方向:
- 封装辅助函数:把重复的绘图逻辑抽成一个小函数,减少代码重复:
然后在主函数里直接调用:def plot_timeseries(time, depth, data, title): plt.scatter(time, depth, s=15, c=data, marker='o', edgecolor='none') plt.title(title) plt.show()if cond is not None and not cond.empty: plot_timeseries(time, depth, cond, "Conductivity") else: print("there is no data for cond") - 使用子图布局:如果希望所有存在的图表都显示在同一个画布上,可以用
plt.subplots来创建子图,避免多次调用plt.show(),让用户可以一次性查看所有有效图表。
内容的提问来源于stack exchange,提问作者Nestly
相关产品推荐
相关产品推荐

