效果:

代码:

import matplotlib.pyplot as plt
import numpy as np


def 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 trend


    def 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) / 10
    for i in range(6, 12):
        data_dict[months[i]] = generate_normal_data((11 - i) * 2) / 10
        
    mountain_plot(data_dict)

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部