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

如何从DataFrame向含Datetime的散点图添加多个y误差棒?

问题

我有一个包含Area(区域)、Density(密度)和Standard Error(SE,标准误差)列的DataFrame,想要绘制带误差棒的散点图:

  • x轴为Datetime格式的日期
  • y轴为密度值
  • y方向误差棒(yerr)使用标准误差数据

但始终遇到yerr类型相关报错:yerr must be a scalar or a 1D or (2, n) array-like。尝试过多种方式提取误差值、手动创建列表、参考案例的循环方法都未成功,当前代码如下:

import pandas as pd
import matplotlib as matplotlib
import matplotlib.pyplot as plt
from matplotlib import pyplot
import datetime


#Creating dataframe for the StackOverflow Example
data = [['RN',0.0, 0.0], ['RO',26.52, 10.51], ['RN',12.43, 5.56], ['CS',0.0,0.0]]
dfvideo = pd.DataFrame(data, columns=['Area','Density', 'SE'])

#Selecting the area, i.e. "RN", that I want the density and yerror (SE) for.
RNvid = dfvideo.loc[(dfvideo["Area"]=="RN"),["Density"]]
RNvidSE = dfvideo.loc[(dfvideo["Area"]=="RN"),["SE"]]

#Converting dates in dataframe to DateTime
dfvideodate = pd.to_datetime(dfvideo["Date"], format='%Y-%m-%d')


#Trying to plot
fig, axis_1 = plt.subplots(figsize =(15, 4))
fig.subplots_adjust(bottom=0.2)

RNax2= axis_1.errorbar(dfvideodate.loc[[0,2]], RNvid, color="r",yerr=RNvidSE, fmt="-o",capsize=3, elinewidth=0.5, label = "RN Video") 



#Parameters for x-ticks and labels
years = plt.matplotlib.dates.YearLocator()
months = plt.matplotlib.dates.MonthLocator()
yearsFmt = plt.matplotlib.dates.DateFormatter('%Y')
monthsFmt = plt.matplotlib.dates.DateFormatter('%b')

axis_1.xaxis.set_major_locator(years)
axis_1.xaxis.set_major_formatter(yearsFmt)
axis_1.xaxis.set_minor_locator(months)
axis_1.xaxis.set_minor_formatter(monthsFmt)

axis_1.tick_params(axis="x", which="both", rotation=45)
axis_1.tick_params(axis="x", length=5, which='minor')
axis_1.tick_params(axis="x", length=24, which='major')
axis_1.set_xlim([datetime.date(2022, 4, 1), datetime.date(2023, 7, 1)])

m2 = r"$\mathrm{\mathsf{m}}^{-2}$"
axis_1.set_ylabel("Avg. Mussel density (ind/ "+m2+")", rotation=90)
axis_1.grid(color='#EEEEEE', which='both', axis='y',zorder=0)

解决思路与修正方案

核心问题

当前代码的两个关键错误:

  1. 提取的RNvid和RNvidSE是二维DataFrame(因使用双层方括号["Density"]),而errorbar要求yerr为一维数组/Series类型。
  2. 原示例DataFrame缺少Date列,导致日期转换步骤直接报错。

修正步骤

  1. 补充Date列数据:给示例DataFrame添加对应日期,保证日期转换流程正常。
  2. 提取一维数据:将筛选数据时的双层方括号改为单层,或用.to_numpy()/.values将DataFrame转为一维数组。
  3. 关联对应日期:根据Area筛选后,直接取筛选结果中的日期,避免手动索引行号导致的数据不匹配。

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
import datetime

# 补充Date列的完整示例DataFrame
data = [
    ['RN', 0.0, 0.0, '2022-05-01'],
    ['RO', 26.52, 10.51, '2022-08-01'],
    ['RN', 12.43, 5.56, '2023-03-01'],
    ['CS', 0.0, 0.0, '2023-06-01']
]
dfvideo = pd.DataFrame(data, columns=['Area', 'Density', 'SE', 'Date'])

# 筛选RN区域的数据,直接提取一维Series
RN_data = dfvideo[dfvideo["Area"] == "RN"]
RN_density = RN_data["Density"]
RN_se = RN_data["SE"]
RN_dates = pd.to_datetime(RN_data["Date"], format='%Y-%m-%d')

# 绘图
fig, axis_1 = plt.subplots(figsize=(15, 4))
fig.subplots_adjust(bottom=0.2)

# 使用一维Series作为y和yerr参数
axis_1.errorbar(RN_dates, RN_density, color="r", yerr=RN_se, fmt="-o", capsize=3, elinewidth=0.5, label="RN Video")

# x轴刻度设置
years = plt.matplotlib.dates.YearLocator()
months = plt.matplotlib.dates.MonthLocator()
yearsFmt = plt.matplotlib.dates.DateFormatter('%Y')
monthsFmt = plt.matplotlib.dates.DateFormatter('%b')

axis_1.xaxis.set_major_locator(years)
axis_1.xaxis.set_major_formatter(yearsFmt)
axis_1.xaxis.set_minor_locator(months)
axis_1.xaxis.set_minor_formatter(monthsFmt)

axis_1.tick_params(axis="x", which="both", rotation=45)
axis_1.tick_params(axis="x", length=5, which='minor')
axis_1.tick_params(axis="x", length=24, which='major')
axis_1.set_xlim([datetime.date(2022, 4, 1), datetime.date(2023, 7, 1)])

m2 = r"$\mathrm{\mathsf{m}}^{-2}$"
axis_1.set_ylabel(f"Avg. Mussel density (ind/ {m2})", rotation=90)
axis_1.grid(color='#EEEEEE', which='both', axis='y', zorder=0)
axis_1.legend()

plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:02:00