效果:
代码:
import matplotlib.pyplot as plt
import numpy as npdef mountain_plot(data_dict, colors=None):if colors is None:colors = get_colors_from_map(len(data_dict), "Spectral")x = list(data_dict.keys())# Y轴位置y_positions = [2 * i for i in range(len(x))]# 创建图形fig, axs = plt.subplots(figsize=(8, 12))# 为每个月绘制核密度曲线,并水平错开显示for i, month in enumerate(list(data_dict.keys())):# 核密度估计density, bins = np.histogram(data_dict[month], bins=30, density=True)bins = 0.5 * (bins[1:] + bins[:-1]) # 转换为 bin 的中心# 每个月份的曲线位置偏移axs.fill_between(bins, y_positions[i] + density, y_positions[i], facecolor=colors[i], alpha=0.7)axs.plot(bins, y_positions[i] + density, color=colors[i], lw=1.5)# 设置月份作为Y轴标签axs.set_yticks(y_positions)axs.set_yticklabels(x)# 添加横轴的网格线axs.grid(axis='y', linewidth=1, color='gray', alpha=0.2)# 去掉边框线axs.spines['top'].set_visible(False)axs.spines['bottom'].set_visible(False)axs.spines['right'].set_visible(False)axs.spines['left'].set_visible(False)# 显示图像plt.tight_layout()plt.show()if __name__ == '__main__':# 模拟数据生成函数,基于正态分布def generate_trend_data(size=1000):np.random.seed(0)# 前半段平稳trend = np.linspace(0, 0.3, size // 2)# 后半段波动较大trend = np.concatenate([trend, np.random.normal(0.1, 0.5, size // 2)])return trenddef generate_normal_data(mean, std=1.2, size=1000):np.random.seed(6) # 固定随机数种子return np.random.normal(mean, std, size)# 月份months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']# 为每个月生成不同的正态分布数据data_dict = {}for i in range(6):data_dict[months[i]] = generate_normal_data(i * 2) / 10for i in range(6, 12):data_dict[months[i]] = generate_normal_data((11 - i) * 2) / 10mountain_plot(data_dict)