You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带可变子分段的嵌套饼图:零填充Jagged Array颜色排序问题

动态生成嵌套饼图的主/子段匹配色调(自动适配Jagged Array输入)

直接上可复用的解决方案,解决你之前硬编码颜色的问题,完全适配任意输入的Jagged Array(经过pad_sequences处理后的矩阵):

核心逻辑

给每个主饼段分配一个基础色调,然后为该主段下的所有子饼段生成同色调、不同明度的颜色——既保证主副段颜色关联,又能通过亮度区分子项,而且全程自动根据输入结构生成,不用手动写颜色列表。

完整实现代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import to_rgb, to_hex
from tensorflow.keras.utils import pad_sequences as ps

# 工具函数:调整颜色明度,保持色调不变
def adjust_color_lightness(color, lightness_factor):
    rgb = np.array(to_rgb(color))
    max_rgb, min_rgb = rgb.max(), rgb.min()
    delta = max_rgb - min_rgb

    # 计算HSL参数
    if delta == 0:
        h = 0
    elif max_rgb == rgb[0]:
        h = ((rgb[1] - rgb[2]) / delta) % 6
    elif max_rgb == rgb[1]:
        h = (rgb[2] - rgb[0]) / delta + 2
    else:
        h = (rgb[0] - rgb[1]) / delta + 4
    h *= 60

    l = (max_rgb + min_rgb) / 2
    s = delta / (1 - abs(2 * l - 1)) if delta != 0 else 0

    # 调整明度(限制在0-1之间,避免过暗/过亮)
    new_l = np.clip(l * lightness_factor, 0, 1)

    # HSL转回RGB
    def hsl_to_rgb(h, s, l):
        c = (1 - abs(2 * l - 1)) * s
        x = c * (1 - abs((h / 60) % 2 - 1))
        m = l - c / 2
        if 0 <= h < 60:
            r, g, b = c, x, 0
        elif 60 <= h < 120:
            r, g, b = x, c, 0
        elif 120 <= h < 180:
            r, g, b = 0, c, x
        elif 180 <= h < 240:
            r, g, b = 0, x, c
        elif 240 <= h < 300:
            r, g, b = x, 0, c
        else:
            r, g, b = c, 0, x
        return (r + m, g + m, b + m)

    return to_hex(hsl_to_rgb(h, s, new_l))

# 处理你的输入数据
jagged_data = [[9.0, 8.0, 8.0], [2.0, 7.0, 8.0, 8.0], [6.0, 6.0, 8.0, 5.0], [2.0, 4.0, 10.0, 4.0, 5.0]]
vals = ps(jagged_data)

# 生成外层饼图颜色(选tab20c间隔色调,保证区分度)
tab20c = plt.color_sequences["tab20c"]
outer_colors = [tab20c[i] for i in [0, 4, 8, 12]]

# 动态生成内层饼图颜色
inner_colors = []
# 明度从0.7到1.3渐变,子项越多,渐变越细腻
lightness_steps = np.linspace(0.7, 1.3, vals.shape[1])

for base_color in outer_colors:
    # 给当前主段的每个子项生成对应明度的颜色
    for step in lightness_steps:
        inner_colors.append(adjust_color_lightness(base_color, step))

# 绘制嵌套饼图(和官方示例逻辑一致)
outer_sizes = [len(row) for row in jagged_data]
inner_sizes = vals.flatten().tolist()

fig, ax = plt.subplots()
ax.pie(outer_sizes, radius=1, colors=outer_colors, wedgeprops=dict(width=0.3, edgecolor='white'))
ax.pie(inner_sizes, radius=0.7, colors=inner_colors, wedgeprops=dict(width=0.3, edgecolor='white'))

ax.set(aspect="equal")
plt.show()

为什么这方案能解决你的问题?

  1. 完全动态适配:不管你的Jagged Array有多少组、每组有多少元素,只要经过pad_sequences处理,代码会自动对应生成颜色列表,不用硬编码
  2. 颜色关联清晰:每个主段的子项都用主段色调的明度变体,一眼就能看出子项属于哪个主分类
  3. 可自定义调整:如果觉得明度范围不合适,直接改lightness_steps的数值就行(比如改成np.linspace(0.6, 1.4, ...)),或者调整外层颜色的选取逻辑

内容的提问来源于stack exchange,提问作者Signor Pizza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 23:14:51