如何从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)
解决思路与修正方案
核心问题
当前代码的两个关键错误:
- 提取的
RNvid和RNvidSE是二维DataFrame(因使用双层方括号["Density"]),而errorbar要求yerr为一维数组/Series类型。 - 原示例DataFrame缺少
Date列,导致日期转换步骤直接报错。
修正步骤
- 补充Date列数据:给示例DataFrame添加对应日期,保证日期转换流程正常。
- 提取一维数据:将筛选数据时的双层方括号改为单层,或用
.to_numpy()/.values将DataFrame转为一维数组。 - 关联对应日期:根据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
相关产品推荐
相关产品推荐

