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

如何结合密度函数与时间序列图?求时序图叠加密度的绘制方法

混合绘制密度函数与时间序列的实现方法

嘿,这个可视化需求挺实用的!我来给你分享几种在Python和R里实现「时间序列+密度图混合绘制」的具体方法,不管是双轴叠加还是分面展示都能搞定~

方法一:Python(Matplotlib + Seaborn)双轴叠加

最直观的方式是用双轴布局,把时间序列作为主图,密度图放在右侧y轴,或者直接在时间序列下方做共享x轴的子图,两种思路都给你示例:

双轴叠加代码示例

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

# 生成模拟数据(替换成你的真实数据即可)
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', periods=100)
ts_data = np.cumsum(np.random.randn(100)) + 50  # 模拟时间序列
density_data = np.random.normal(loc=50, scale=5, size=100)  # 对应密度数据

df = pd.DataFrame({'date': dates, 'time_series': ts_data, 'density_vals': density_data})

# 创建画布和主坐标轴
fig, ax1 = plt.subplots(figsize=(12,6))

# 绘制时间序列折线
ax1.plot(df['date'], df['time_series'], color='tab:blue', linewidth=2, label='Time Series')
ax1.set_xlabel('Date')
ax1.set_ylabel('Time Series Value', color='tab:blue')
ax1.tick_params(axis='y', labelcolor='tab:blue')
ax1.legend(loc='upper left')

# 创建右侧副坐标轴,绘制核密度估计图
ax2 = ax1.twinx()
sns.kdeplot(df['density_vals'], ax=ax2, color='tab:red', shade=True, alpha=0.3, label='Density')
ax2.set_ylabel('Density', color='tab:red')
ax2.tick_params(axis='y', labelcolor='tab:red')
ax2.legend(loc='upper right')

plt.title('Time Series with Overlaid Density Plot')
plt.tight_layout()
plt.show()

共享x轴的分面子图(更清晰的对比)

如果觉得双轴有点拥挤,可以把密度图放在时间序列下方,共享x轴:

fig, (ax1, ax2) = plt.subplots(2,1, figsize=(12,8), sharex=True)

# 上方时间序列
ax1.plot(df['date'], df['time_series'], color='tab:blue')
ax1.set_ylabel('Time Series Value')
ax1.set_title('Time Series & Corresponding Density')

# 下方密度图
sns.kdeplot(df['time_series'], ax=ax2, shade=True, color='tab:red')
ax2.set_xlabel('Date')
ax2.set_ylabel('Density')

plt.tight_layout()
plt.show()

方法二:R语言(ggplot2)实现叠加效果

如果你用R,用ggplot2可以轻松实现类似的效果,这里用缩放密度值的方式让它适配时间序列的y轴范围:

library(ggplot2)
library(dplyr)
library(lubridate)

# 模拟数据
set.seed(42)
dates <- seq(as.Date("2023-01-01"), by="day", length.out=100)
ts_data <- cumsum(rnorm(100)) + 50
density_data <- rnorm(100, mean=50, sd=5)

df <- data.frame(date=dates, time_series=ts_data, density_vals=density_data)

# 绘制叠加图
ggplot(df, aes(x=date)) +
  geom_line(aes(y=time_series, color="Time Series"), linewidth=1) +
  # 缩放密度值适配时间序列范围,实现叠加
  geom_density(aes(y=..scaled..*10 + 40, color="Density"), fill="red", alpha=0.2) +
  scale_color_manual(values=c("Time Series"="blue", "Density"="red")) +
  labs(x="Date", y="Time Series Value", color="Legend") +
  theme_minimal() +
  ggtitle("Time Series with Density Overlay")

进阶:滑动窗口动态密度展示

如果想要展示时间序列上局部区间的密度变化,可以用滑动窗口计算每个时间点附近的密度,然后映射到图上:

# 滑动窗口大小设为7天
window_size = 7
# 对每个窗口内的时间序列数据计算密度,取当前点对应的密度值
df['rolling_density'] = df['time_series'].rolling(window=window_size).apply(
    lambda x: sns.kdeplot(x, bw_method=0.5).get_lines()[0].get_data()[1][
        np.argmin(np.abs(sns.kdeplot(x, bw_method=0.5).get_lines()[0].get_data()[0] - x.iloc[-1]))
    ]
)

fig, ax = plt.subplots(figsize=(12,6))
ax.plot(df['date'], df['time_series'], color='blue', label='Time Series')
# 缩放密度值后用散点展示局部密度
ax.scatter(df['date'], df['rolling_density']*15 + 35, color='red', alpha=0.6, label='Rolling Window Density')
ax.legend()
plt.title('Time Series with Dynamic Local Density')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:54:57