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

如何为分类值图表添加边际直方图或密度图?

给分类时间散点图添加边际密度/直方图的实现方案

当然可以给这类散点图添加边际密度图或直方图,下面提供两种实用的实现方式:

方法一:基于Matplotlib手动布局

通过gridspec划分画布,在主散点图顶部添加边际图(直方图或密度图),完全自定义布局细节:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.gridspec import GridSpec
import numpy as np
from scipy.stats import gaussian_kde

# 数据处理
source_data = [("user_1", "2023-11-24 10:30:00"), ("user_1", "2023-11-24 10:15:00"),
("user_1", "2023-11-24 09:55:00"), ("user_1", "2023-11-24 22:10:00"),
("user_1", "2023-11-24 15:55:00"), ("user_1", "2023-11-24 11:15:00"),
("user_1", "2023-11-24 09:30:00"), ("user_1", "2023-11-24 22:25:00"),
("user_1", "2023-11-24 17:20:00"), ("user_1", "2023-11-24 23:55:00")]

df = pd.DataFrame(source_data, columns=['user', 'time'])
df['time'] = pd.to_datetime(df['time'])

# 划分画布:顶部1行放边际图,底部4行放主散点图
fig = plt.figure(figsize=(9, 9))
gs = GridSpec(5, 1, height_ratios=[1, 4])

# 顶部边际图(直方图+密度曲线)
ax_marginal = fig.add_subplot(gs[0])
time_num = mdates.date2num(df['time'])
ax_marginal.hist(time_num, bins=10, alpha=0.5, color='b')
# 添加核密度估计曲线
kde = gaussian_kde(time_num)
xvals = np.linspace(time_num.min(), time_num.max(), 1000)
ax_marginal.plot(xvals, kde(xvals)*len(df)*np.diff(xvals)[0], color='darkblue', linewidth=2)
# 简化边际图样式
ax_marginal.set_yticks([])
ax_marginal.spines[['right', 'top', 'left']].set_visible(False)

# 主散点图
ax_main = fig.add_subplot(gs[1:], sharex=ax_marginal)
ax_main.scatter(x=df['time'], y=df['user'], marker='.', color='b', alpha=0.7)

# 设置时间轴格式
ax_main.xaxis.set_major_locator(mdates.HourLocator(byhour=range(0, 24, 2)))
ax_main.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M hr'))
plt.setp(ax_main.get_xticklabels(), rotation=45, ha='right')

fig.tight_layout()
plt.show()

方法二:用Seaborn快速生成(更简洁)

Seaborn的jointplot可以一键生成带边际图的联合分布图,适合快速可视化:

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

# 数据处理同前
source_data = [("user_1", "2023-11-24 10:30:00"), ("user_1", "2023-11-24 10:15:00"),
("user_1", "2023-11-24 09:55:00"), ("user_1", "2023-11-24 22:10:00"),
("user_1", "2023-11-24 15:55:00"), ("user_1", "2023-11-24 11:15:00"),
("user_1", "2023-11-24 09:30:00"), ("user_1", "2023-11-24 22:25:00"),
("user_1", "2023-11-24 17:20:00"), ("user_1", "2023-11-24 23:55:00")]

df = pd.DataFrame(source_data, columns=['user', 'time'])
df['time'] = pd.to_datetime(df['time'])

# 生成联合图,边际图同时显示直方图和密度曲线
g = sns.jointplot(
    x='time', y='user', data=df,
    kind='scatter', marker='.', color='b', alpha=0.7,
    marginal_kws={'fill': True, 'kde': True}
)

# 设置x轴时间格式
g.ax_joint.xaxis.set_major_locator(mdates.HourLocator(byhour=range(0, 24, 2)))
g.ax_joint.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M hr'))
plt.setp(g.ax_joint.get_xticklabels(), rotation=45, ha='right')

plt.tight_layout()
plt.show()

实用提示

  • 若存在多个用户,只需保留y轴的分类变量即可,边际图会自动对应用户的时间分布;多用户场景下可考虑为每个用户单独生成子图+边际图
  • 调整bins(直方图)或bw_method(密度图)参数,可优化边际图的粒度和平滑度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:25:20