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

如何使用seaborn或matplotlib绘制与crosstab效果一致的折线图

问题描述

我有一个包含三列的DataFrame,需要针对其中两列绘制关联可视化:两列数据类型分别为datetime和object,datetime类型列名为started_at,object类型列名为member_casual。我希望x轴展示started_at提取的小时维度,y轴展示member_casual各分类的对应计数。

我的DataFrame(df)样例如下:

rideable_type        started_at             member_casual
electric_bike    2021-06-13 14:31:28            casual
classic_bike     2021-06-04 11:18:02            member
classic_bike     2021-06-04 09:49:35            casual
calssic_bike     2021-06-04 09:55:34            casual
electric_bike    2021-06-04 14:05:51            casual    
classic_bike     2021-06-04 14:09:59            member
electric_bike    2021-06-03 19:32:01            casual
electric_bike    2021-06-10 16:30:10            member
   ...                ...                         ...
   ...                ...                         ...

目前我使用如下pandas内置绘图代码可以实现需求:生成x轴为小时维度、y轴为member_casual分类计数的折线图:

pd.crosstab(df.started_at.dt.hour,df.member_casual).plot(kind='line', ax = ax)

核心疑问

如何使用seaborn或matplotlib绘制出完全相同的图表?

我是Python可视化初学者,自行尝试了两种写法均运行报错,尝试代码如下:

尝试写法1

plt.plot(df.started_at.dt.hour, df.member_casual)

尝试写法2

sns.lineplot(df.started_at.dt.hour, hue = df.member_casual)

报错原因

两种写法报错的核心原因是未提前对数据做分组聚合统计:直接传入原始明细行的话,绘图函数无法自动按小时统计两类用户的数量,自然无法输出预期的计数折线图。

实现方案

无论使用matplotlib还是seaborn,都需要先完成和pd.crosstab一致的聚合计算,再传入绘图函数。

第一步:数据预处理

先提取小时字段,统计每个小时下两类用户的骑行次数:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 从时间列提取小时
df['hour'] = df['started_at'].dt.hour
# 生成小时-用户类型的计数交叉表,和原有逻辑完全一致
count_df = pd.crosstab(df['hour'], df['member_casual'])

方法1:纯Matplotlib实现

逐类绘制折线即可得到和pandas原生绘图完全一致的效果:

fig, ax = plt.subplots(figsize=(10, 6))
# 遍历每个用户分类绘制折线
for user_type in count_df.columns:
    ax.plot(count_df.index, count_df[user_type], label=user_type)

ax.set_xlabel('Hour of Day')
ax.set_ylabel('Ride Count')
ax.legend(title='member_casual')
plt.show()

方法2:Seaborn实现

Seaborn的lineplot需要输入长表格式数据,先转换表结构再绘图即可:

# 宽表转长表,适配Seaborn输入格式
count_long = count_df.reset_index().melt(
    id_vars='hour', 
    var_name='member_casual', 
    value_name='count'
)

fig, ax = plt.subplots(figsize=(10, 6))
sns.lineplot(data=count_long, x='hour', y='count', hue='member_casual', ax=ax)
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:45:18