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

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_gap05

定义条形与误差棒

封装单个条形和误差线的绘制方法,支持自定义颜色、边框和误差帽大小。
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可直接获取完整的示例数据和代码
如有帮助,您的点赞、评论、转发是我持续创作的动力~

