论文地址:
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)
数据获取
评论+私信获取
参考来源:python+遥感学习日志