期刊复现 | Python实现扇形小提琴图

论文地址:

https://advanced.onlinelibrary.wiley.com/doi/10.1002/advs.202511030?af=R

论文题目:

Utilized Distributed Optical Fiber Sensor with Spiral-Serpentine Deployment Enabling High-Precision Full-Field Temperature Reconstruction and Thermal Management for Pouch Lithium-Ion Battery

复现图片:

图 1 径向小提琴图:该图展示多组样本数据的分布、中位数与最大值特征。极角方向代表不同类别,径向长度对应数值大小,不同填充色区分各类别小提琴分布形态,黑色线条标注四分位数与中位数,红色、蓝色虚线为参考弧线。图中标注各类别中位数与最大值数值,可直观对比各组数据分布差异与极值水平。正式图注:图 1 多组样本数据的径向小提琴分布特征。

配色方案:

python 复制代码
color_palettes = {
    1: {'cmap': plt.cm.viridis_r, 'max_val_color': '#c00000', 'median_color': 'black', 'outer_dash_color': '#c00000', 'inner_dash_color': '#0000FF'},
    2: {'cmap': plt.cm.Blues, 'max_val_color': '#00008B', 'median_color': 'black', 'outer_dash_color': '#00008B', 'inner_dash_color': '#1E90FF'},
    3: {'cmap': plt.cm.YlOrRd, 'max_val_color': '#8B0000', 'median_color': 'black', 'outer_dash_color': '#FF4500', 'inner_dash_color': '#DAA520'},
    4: {'cmap': plt.cm.Greys, 'max_val_color': 'black', 'median_color': 'black', 'outer_dash_color': '#363636', 'inner_dash_color': '#808080'},
    5: {'cmap': plt.cm.Spectral_r, 'max_val_color': '#D73027', 'median_color': 'black', 'outer_dash_color': '#D73027', 'inner_dash_color': '#4575B4'},
    6: {'cmap': plt.cm.cividis, 'max_val_color': '#2A788E', 'median_color': 'black', 'outer_dash_color': '#2A788E', 'inner_dash_color': '#FDE725'},
    7: {'cmap': plt.cm.plasma, 'max_val_color': '#7A0403', 'median_color': 'black', 'outer_dash_color': '#7A0403', 'inner_dash_color': '#F0F921'},
    8: {'cmap': plt.cm.inferno, 'max_val_color': '#570A0F', 'median_color': 'black', 'outer_dash_color': '#570A0F', 'inner_dash_color': '#FCFFA4'},
    9: {'cmap': plt.cm.magma, 'max_val_color': '#420A68', 'median_color': 'black', 'outer_dash_color': '#420A68', 'inner_dash_color': '#F0F921'},
    10: {'cmap': plt.cm.twilight_shifted, 'max_val_color': '#000060', 'median_color': 'black', 'outer_dash_color': '#000060', 'inner_dash_color': '#F0F0D0'},
    11: {'cmap': plt.cm.Pastel1, 'max_val_color': '#A65628', 'median_color': 'black', 'outer_dash_color': '#A65628', 'inner_dash_color': '#377EB8'},
    12: {'cmap': plt.cm.Paired, 'max_val_color': '#E31A1C', 'median_color': 'black', 'outer_dash_color': '#E31A1C', 'inner_dash_color': '#1F78B4'},
    13: {'cmap': plt.cm.Accent, 'max_val_color': '#3B3B3B', 'median_color': 'black', 'outer_dash_color': '#3B3B3B', 'inner_dash_color': '#7FC97F'},
    14: {'cmap': plt.cm.Set3, 'max_val_color': '#4C4C4C', 'median_color': 'black', 'outer_dash_color': '#4C4C4C', 'inner_dash_color': '#8DD3C7'},
    15: {'cmap': plt.cm.ocean, 'max_val_color': '#0000A0', 'median_color': 'white', 'outer_dash_color': '#0000A0', 'inner_dash_color': '#90FFFF'},
    16: {'cmap': plt.cm.terrain, 'max_val_color': '#333333', 'median_color': 'black', 'outer_dash_color': '#333333', 'inner_dash_color': '#A0A0A0'},
    17: {'cmap': plt.cm.gist_stern, 'max_val_color': '#FF0000', 'median_color': 'black', 'outer_dash_color': '#FF0000', 'inner_dash_color': '#00FFFF'},
    18: {'cmap': plt.cm.gist_earth, 'max_val_color': '#A67C52', 'median_color': 'black', 'outer_dash_color': '#A67C52', 'inner_dash_color': '#274488'},
    19: {'cmap': plt.cm.coolwarm, 'max_val_color': '#B2182B', 'median_color': 'black', 'outer_dash_color': '#B2182B', 'inner_dash_color': '#2166AC'},
    20: {'cmap': plt.cm.BrBG, 'max_val_color': '#8C510A', 'median_color': 'black', 'outer_dash_color': '#8C510A', 'inner_dash_color': '#01665E'}
}

完整代码:

python 复制代码
# ===================== 库导入 =====================
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os

# 绘图字体与格式设置
plt.rcParams['font.family'] = ['Times New Roman']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['pdf.fonttype'] = 42
plt.rcParams['ps.fonttype'] = 42

# ===================== 配色方案=====================
color_palettes = {
    1: {'cmap': plt.cm.viridis_r, 'max_val_color': '#c00000', 'median_color': 'black', 'outer_dash_color': '#c00000', 'inner_dash_color': '#0000FF'},
}

# 选择配色方案
selected_palette = 1
selected_scheme = color_palettes[selected_palette]

# ===================== 自动创建输出文件夹 =====================
save_dir = "图表"
os.makedirs(save_dir, exist_ok=True)

# ===================== 数据读取函数 =====================
def load_data_from_excel(filename):
    df = pd.read_excel(filename)
    categories = df.columns.tolist()
    data_raw = [df[col].dropna().values for col in categories]
    return data_raw, categories

# ===================== 绘图函数 =====================
def draw_radial_violin_plot(data_raw, categories, color_scheme):
    medians = [np.median(d) for d in data_raw]
    max_vals = [np.max(d) for d in data_raw]
    n_categories = len(categories)

    # 提取配色
    cmap = color_scheme['cmap']
    max_val_color = color_scheme['max_val_color']
    median_color = color_scheme['median_color']
    outer_dash_color = color_scheme['outer_dash_color']
    inner_dash_color = color_scheme['inner_dash_color']

    # 角度设置
    angles = np.linspace(np.deg2rad(10), np.deg2rad(170), n_categories)
    data_plot = [d + 0.012 for d in data_raw]

    # 初始化极坐标图
    fig, ax = plt.subplots(figsize=(12, 7), subplot_kw={'projection': 'polar'})

    # 绘制小提琴图
    violin_parts = ax.violinplot(
        data_plot, positions=angles, widths=0.2,
        quantiles=[[0.25, 0.5, 0.75]] * n_categories,
        showextrema=False
    )

    # 自定义样式
    colors = cmap(np.linspace(0.1, 0.9, n_categories))
    for i, pc in enumerate(violin_parts['bodies']):
        pc.set_facecolor(colors[i])
        pc.set_edgecolor('black')
        pc.set_alpha(1)
    violin_parts['cquantiles'].set_edgecolor('black')
    lines = violin_parts['cquantiles'].get_segments()
    new_widths = [1.5 if i % 3 == 1 else 1 for i in range(len(lines))]
    violin_parts['cquantiles'].set_linewidths(new_widths)

    # 坐标轴设置
    ax.set_ylim(-0.01, 0.08)
    ax.set_rticks([])
    ax.set_yticklabels([])
    ax.grid(False)
    ax.set_theta_zero_location('E')
    ax.set_theta_direction(1)
    ax.set_thetamin(0)
    ax.set_thetamax(360)
    ax.set_xticklabels([])
    ax.spines['polar'].set_visible(False)

    # 标注
    for i in range(n_categories):
        ang_rad = angles[i]
        ang_deg = np.degrees(ang_rad)
        rot_tan = ang_deg - 90
        rot_rad = ang_deg - 180

        ax.text(ang_rad, 0.075, categories[i], ha='center', va='center', fontsize=12, fontweight='bold', rotation=rot_tan)
        ax.text(ang_rad, 0.065, f'{max_vals[i]:.3f}', ha='center', va='center', fontsize=9, color=max_val_color, rotation=rot_tan)
        ax.text(ang_rad, 0.005, f'{medians[i]:.3f}', ha='center', va='center', fontsize=9, color=median_color, rotation=rot_rad)

    # 弧线
    arc_angs = np.linspace(np.deg2rad(10), np.deg2rad(170), 100)
    ax.plot(arc_angs, [0.07]*100, 'k-', lw=1)
    ax.plot(arc_angs, [0.06]*100, color=outer_dash_color, ls='--', lw=1.5)
    ax.plot(arc_angs, [0.01]*100, color=inner_dash_color, ls='--', lw=1.5)
    ax.plot(arc_angs, [0.009]*100, 'k-', lw=1)

    plt.tight_layout()
    save_path = os.path.join(save_dir, f"violin_{selected_palette}.png")
    plt.savefig(save_path, dpi=300, bbox_inches='tight')
    plt.close(fig)

# ===================== 主程序 =====================
if __name__ == "__main__":
    # 读取根目录下的 data.xlsx
    raw_data, CATEGORIES = load_data_from_excel("data.xlsx")
    # 绘图
    draw_radial_violin_plot(raw_data, CATEGORIES, selected_scheme)

数据获取

评论+私信获取

VX获取:期刊复现 | Python实现扇形小提琴图

参考来源:python+遥感学习日志

相关推荐
2401_873479401 小时前
如何用IP离线库批量清洗订单IP,自动标注省市区?
开发语言·网络·python
godspeed_lucip2 小时前
LLM和Agent——专题5: LLM Ops 入门(2)
人工智能·python
技术钱2 小时前
RAG 开发 6 个阶段优化策略分析
python
QFIUNE2 小时前
使用 MMseqs2 计算多个 DTI 数据集的蛋白序列相似度
linux·python·ubuntu
念恒123062 小时前
Python 函数完全指南:定义与调用
开发语言·python
大数据魔法师2 小时前
Streamlit(十二)- API 参考文档(五)- 输入组件
python·web
涛声依旧-底层原理研究所2 小时前
Node.js在高并发低延迟场景中的优势
java·人工智能·python·node.js
凯丨2 小时前
200 行 Python 训练一个 GPT:Karpathy 的极简主义 AI 教育实验
人工智能·python·gpt
Mr. zhihao2 小时前
BM25 混合检索详解:为什么向量检索不够,还要加一个关键词检索
python·rag·bm25