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

求助:使用Matplotlib绘制日期为X、时间为Y的三元变量图时遇类型错误

解决Matplotlib绘制三元变量图的时间类型错误问题

我尝试用Matplotlib基于如下结构的Pandas数据框绘制三元变量图(第三列数值用绿到红表示从低到高):

Date       Time     Value
2023-11-01 11:22:34 59.0
2023-11-01 11:25:26 65.0
...

但始终无法成功绘图,报错提示时间值必须为浮点数等类型错误。我的数据处理代码如下:

import pandas as pd
import datetime

x = pandas.read_xml('/Users/steven/Downloads/apple_health_export/export.xml', xpath='//Record', attrs_only=True,parse_dates=["creationDate","startDate","endDate"])
x.value=pandas.to_numeric(x.value,errors='coerce')
x = x[x.value.notnull()]
data = x[x.type == 'HKQuantityTypeIdentifierHeartRate']
data['Date']=[datetime.datetime.date(d) for d in data['endDate']]
data['Time']=[datetime.datetime.time(d) for d in data['endDate']]

问题原因

报错核心是Matplotlib无法直接识别datetime.time类型的坐标轴数据,它要求坐标轴输入为数值类型(比如浮点数、整数)。你提取的Time列是时间对象,不符合绘图要求。

解决方案

把时间转换成一天内的秒数/小时数(数值类型),日期转换成可映射的数值索引,再用散点图实现三元变量可视化(颜色对应心率值)。

完整可运行代码

import pandas as pd
import matplotlib.pyplot as plt

# 读取并预处理数据
x = pd.read_xml(
    '/Users/steven/Downloads/apple_health_export/export.xml',
    xpath='//Record',
    attrs_only=True,
    parse_dates=["creationDate","startDate","endDate"]
)
x['value'] = pd.to_numeric(x['value'], errors='coerce')
x = x[x['value'].notnull()]
data = x[x['type'] == 'HKQuantityTypeIdentifierHeartRate']

# 转换日期和时间为绘图可用格式
# 用Pandas内置方法提取日期,比列表推导式更高效规范
data['Date'] = data['endDate'].dt.date
# 将时间转为一天中的秒数(数值类型)
data['Time_seconds'] = data['endDate'].dt.hour * 3600 + data['endDate'].dt.minute * 60 + data['endDate'].dt.second

# 把日期映射为数值索引(方便y轴显示日期标签)
date_list = data['Date'].unique()
date_to_num = {date: idx for idx, date in enumerate(date_list)}
data['Date_num'] = data['Date'].map(date_to_num)

# 绘制三元变量散点图
plt.figure(figsize=(12, 6))
# c指定颜色对应value,cmap用反转的黄绿红配色(绿=低心率,红=高心率)
scatter = plt.scatter(
    data['Time_seconds'],
    data['Date_num'],
    c=data['value'],
    cmap='RdYlGn_r',
    alpha=0.7
)

# 设置坐标轴
plt.yticks(ticks=range(len(date_list)), labels=date_list)
plt.xlabel('一天中的秒数')
plt.ylabel('日期')
plt.title('心率随日期和时间的变化')

# 添加颜色条说明
plt.colorbar(scatter, label='心率值')

plt.tight_layout()
plt.show()

关键优化点

  1. 用dt属性替代手动循环提取日期时间,避免链式赋值警告,代码更简洁
  2. Time_seconds把时间转为数值,解决Matplotlib的类型要求
  3. Date_num将日期映射为连续数值,既满足绘图要求,又能通过yticks显示原始日期标签
  4. RdYlGn_r配色正好实现“低数值绿、高数值红”的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 15:31:08