当前位置:首页>python>Python绘制绝美分组环形柱状图(附数据和代码)

Python绘制绝美分组环形柱状图(附数据和代码)

  • 2026-09-05 12:09:32
Python绘制绝美分组环形柱状图(附数据和代码)

©[悠悠智汇笔记] 版权所有

🙏请尊重劳动成果,守护每一份劳动心血;⚖️未经授权,不得以为任何方式转载、摘编或抄袭。🔄转载合作请后台联系授权,侵权必究。

前些期我分享过这个图在不写一行代码的情况下,也可以绘制出来,本期分享通过Python绘制这幅图,后续我也会更新R语言绘制这幅图。这是一种将多组数据按类别环绕排列的可视化方式,便于同时比较多个指标在不同处理条件下的表现。图中通过柱状高度、误差线和显著性标记综合展示均值、变异性和统计差异。适用于需要紧凑布局且强调多维对比的科研或数据分析场景。

01

导入库和设置全局参数

此步骤包括导入必要的Python库以及定义脚本中使用的全局变量和配置参数。

import matplotlibmatplotlib.use('Agg')  # 无GUI后端,适合服务器生成图片import matplotlib.pyplot as pltimport numpy as npfrom matplotlib.patches import Wedge# 全局绘图参数CONFIG = {    'num_groups': 10,    'inner_r': 0.3,    'outer_r': 1.0,    'gap_deg': 8.0,    'pad_side_deg': 0.5,    'start_offset': 90,    'bar_colors': ['#DCEDF7', '#C0DEF6', '#AAD6F0', '#73C6EC'],    'seg_colors': ['#F9F5E8', '#FCF2C6', '#FCD435', ...],  # 实际需10种颜色    'show_sig': True,    'error_cap_deg': 1.5}plt.rcParams.update({    'font.size': 10,    'font.sans-serif': ['Arial', 'DejaVu Sans'],    'axes.unicode_minus': False})

02

数据结构定义与预处理

将多个指标的均值、误差、显著性字母及数值范围整理成结构化格式,便于后续按扇区分发绘制。

# 每个元组代表一个生理/生化指标:# (指标名称, 各处理组均值, 误差, 显著性字母, 最小值, 最大值)RAW_DATA = [    ("Yield", [22, 28, 25, 30], [2.1, 3.0, 2.6, 3.2], ['a','c','b','c'], 20, 35),    ("Chlorophyll", [8, 5, 7, 10], [0.8, 0.5, 0.7, 1.2], ['b','a','a','c'], 0, 15),    ("qP", [19, 24, 21, 26], [1.9, 2.5, 2.1, 2.7], ['a','c','b','c'], 15, 30),    # ... 此处省略其余7组数据(共需10组以匹配 num_groups=10)]# 解包数据便于后续访问metrics = [item[0] for item in RAW_DATA]means_list = [item[1] for item in RAW_DATA]errors_list = [item[2] for item in RAW_DATA]sig_letters = [item[3] for item in RAW_DATA]min_vals = [item[4] for item in RAW_DATA]max_vals = [item[5] for item in RAW_DATA]

03

计算扇区角度布局

根据扇区数量和间隙角度,均匀分配每个扇区的起始角、结束角和中心角,确保图形对称美观。

def compute_segment_layout(n_segs, gap_deg, start_ang):    total_gap = n_segs * gap_deg    if total_gap >= 360:        raise ValueError("间隙角度总和不能超过360度")    seg_span = (360.0 - total_gap) / n_segs    centers = []    current = start_ang    for _ in range(n_segs):        centers.append(current)        current -= (seg_span + gap_deg)  # 顺时针方向排列    starts = [c - seg_span/2 for c in centers]    ends   = [c + seg_span/2 for c in centers]    return centers, starts, ends, seg_span# 调用函数compute_segment_layout(CONFIG['num_groups'], CONFIG['gap_deg'], CONFIG['start_offset'])

04

分配组内条形的角宽度

在每个扇区内,根据处理组数量和内部间隙因子,计算每个条形的角宽度及间隔,避免重叠。

def allocate_bar_angles(seg_deg, pad_deg, n_bars, gap_factor=0.1):    usable = seg_deg - 2 * pad_deg    if usable <= 0:        raise ValueError("扇区太窄,无法容纳条形")    total_units = n_bars + (n_bars - 1) * gap_factor    unit_width = usable / total_units    return unit_width, unit_width * gap_factor  # 条形宽, 间隙角# 假设已知 seg_span(来自上一步),但 seg_start_angles 未定义!bar_width, intra_gap = allocate_bar_angles(    seg_span, CONFIG['pad_side_deg'], len(CONFIG['bar_colors']))# 计算所有条形的起始角度bar_positions = []for seg_start in seg_start_angles:  # ← NameError!变量不存在    pos = seg_start + CONFIG['pad_side_deg']    for _ in range(len(CONFIG['bar_colors'])):        bar_positions.append(pos)        pos += bar_width + intra_gap

05

定义条形与误差棒

封装单个条形和误差线的绘制方法,支持自定义颜色、边框和误差帽大小。

def draw_radial_bar(ax, center_deg, width_deg, radius, color, inner_r):    """绘制一个径向楔形条形"""    wedge = Wedge(        center=(0, 0),        r=radius,        theta1=center_deg - width_deg/2,        theta2=center_deg + width_deg/2,        width=radius - inner_r,        facecolor=color,        edgecolor='black',        linewidth=0.5,        zorder=2    )    ax.add_patch(wedge)def draw_error_caps(ax, angle_deg, r_low, r_high, cap_size_deg):    """绘制误差线两端的横帽"""    rad = np.radians(angle_deg)    cap_half = np.radians(cap_size_deg / 2)

06

主绘图循环

整合前面所有模块,遍历每个指标扇区,依次绘制背景、条形、误差线、标签等元素。

fig, ax = plt.subplots(figsize=(10, 10))ax.set_aspect('equal')ax.axis('off')# 遍历每个指标(共10个)for i in range(CONFIG['num_groups']):    metric_name = metrics[i]    means = means_list[i]    errors = errors_list[i]    sigs = sig_letters[i]    # 获取当前扇区角度    theta1, theta2 = seg_starts[i], seg_ends[i]     # 绘制扇区背景(颜色循环)    bg_color = CONFIG['seg_colors'][i % len(CONFIG['seg_colors'])]    # 绘制每个处理组的条形    for j, (m, e) in enumerate(zip(means, errors)):        # 应调用 scale_value_to_radius 将 m 映射为 radius        # 再调用 draw_radial_bar 和 draw_error_caps        pass  # 实际逻辑被替换为 pass!# 保存结果plt.savefig('circular_chart.png', dpi=300, bbox_inches='tight')

🌿 今日的分享就到这里啦~如果这些内容有为你带来帮助,欢迎轻点右下角的【👍赞】和【👀在看】,也欢迎分享给更多需要的人,感恩~

THE

END

数据和代码怎么获取?

点击关注后,后台回复关键词:

2026_map_003可直接获取完整的示例数据和代码

如有帮助,您的点赞、评论、转发是我持续创作的动力~

猜您喜欢
往期精选▼

1. 顶刊同款绝美极坐标条形图,竟然不用写一行Python/R代码?

2. Python绘制绝美的分组径向柱状图(附数据和代码)

3. Python绘制Nature期刊同款环状热图(附数据和代码)

4. 不会 PS 也能搞定!R 画热图后,用 PPT 微调,科研绘图效率翻倍

#数据可视化#科研绘图 #环状图 #Python #Matplotlib

最新文章

随机文章