如何结合密度函数与时间序列图?求时序图叠加密度的绘制方法
混合绘制密度函数与时间序列的实现方法
嘿,这个可视化需求挺实用的!我来给你分享几种在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
相关产品推荐
相关产品推荐

