山峦型核密度曲线绘制

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

plt.rcParams['font.sans-serif'] = ['SimSun']  # 修改为宋体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 读取Excel数据文件
file_path = r"C:\Users.xlsx"
df = pd.read_excel(file_path)

# 数据清洗
df['year'] = df['year'].astype(int)
df['value'] = pd.to_numeric(df['value'], errors='coerce')
df = df.dropna()

# 设置绘图参数
years = sorted(df['year'].unique())
n_years = len(years)
offset_step = 5 # 初始层间距
x_margin = 0.5 # 缩小横向留白
line_alpha = 1

# 创建紧凑画布
plt.figure(figsize=(7, 5), dpi=120)  # 进一步缩小画布
ax = plt.gca()

# 动态计算坐标范围
global_min = df['value'].min()
global_max = df['value'].max()
x_range = global_max - global_min
x = np.linspace(global_min - x_margin * x_range,
                global_max + x_margin * x_range,
                2000)

max_y_total = 0  # 记录最大高度
year_labels = []  # 存储年份标签位置

# 绘制密度曲线
for idx, year in enumerate(years):
    year_data = df[df['year'] == year]['value'].values
    kde = gaussian_kde(year_data)
    y = kde.evaluate(x)
    vertical_offset = idx * offset_step

    # 动态调整层间距
    current_peak = y.max() + vertical_offset
    if current_peak > max_y_total:
        max_y_total = current_peak

    # 控制曲线边界不接触坐标轴
    mask = y > 0.005  # 仅显示密度>0.5%的区域
    filtered_x = x[mask]
    filtered_y = y[mask]

    ax.fill_between(filtered_x,
                    vertical_offset,
                    filtered_y + vertical_offset,
                    color='#f0f0f0',
                    alpha=0.8,
                    edgecolor='none')

    ax.plot(filtered_x,
            filtered_y + vertical_offset,
            color='k',
            lw=0.8,
            alpha=line_alpha)

    year_labels.append(vertical_offset + offset_step / 2)  # 标签居中位置

# 设置坐标轴边界
ax.set_xlim(x.min(), x.max())
ax.set_ylim(0, max_y_total * 1.08)  # 自动适配顶部空间

# 设置X轴刻度(关键修改)
xticks = np.linspace(0, x.max(), 5)  # 从0开始生成刻度
ax.set_xticks(xticks)
ax.set_xticklabels([f"{t:.2f}" if t != 0 else "0" for t in xticks])  # 格式化标签

# 设置年份刻度
ax.set_yticks(year_labels)
ax.set_yticklabels(years)
ax.tick_params(axis='y', labelsize=8)
ax.set_ylabel("年份", fontsize=9, labelpad=5)

# 优化其他元素
plt.xlabel("哈哈哈", fontsize=9, labelpad=6)
plt.tight_layout()

# 显示图形
plt.show()

这是山峦型核密度曲线的绘制代码,分享出来欢迎探讨优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值