matplotlib 朝阳/扇形图

cu6pst1q  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(113)

我对在matplotlib中为二叉搜索树(例如在家谱中使用的二叉搜索树)开发一个自定义的朝阳图很感兴趣。我试图实现以下目标:

正如你所看到的,它是一个sunburst chart(如Plotly提供的),带有一个移除的楔形。

fruv7luv

fruv7luv1#

这里有一些东西至少可以让你开始。你可以使用matplotlib的pie图表来制作嵌套的饼图。你也可以删除特定的楔形,如https://stackoverflow.com/a/63881380/1862861所示。使用这些信息,你可以做:

from matplotlib import pyplot as plt

ninner = 2  # number of inner wedge
width = 0.15  # width of inner wedges
radius = 0.5  # radius of inner wedges
gap = 100  # size of missing wedge

ngap = 300 - gap  # total size of filled wedges (missing gap will be 1/3 of total)

fig, ax = plt.subplots()

for i in range(8):
    if i > 0:
        # expand pie chart radius and shrink wedge width
        width *= 0.85
        radius += width
    
    # create data
    data = [gap]
    data.extend([ngap / 2**(i+1)] * ninner)
    colors = ["lightgrey"] * len(data)  # for now they are all grey!
    ninner *= 2
    
    # create pie chart
    wedges, _ = ax.pie(
        data,
        radius=radius,
        colors=colors,
        wedgeprops={"width": width, "edgecolor": "w", "linewidth": 0.25},
        startangle=-150,  # shift start angle
    )
    wedges[0].set_visible(False)  # make gap invisible

fig.tight_layout()
fig.show()

其产生:

很明显,这并没有给给予颜色,但这是一个开始。

更新

以下是添加了一些颜色的版本:

from matplotlib import pyplot as plt
import numpy as np

def get_colours(N):
    # use the tab20c colour map and get an array of colours

    # Note: the "16" in this is due to the 16 colours in the tab20c colour map
    cmap = plt.colormaps["tab20c"]
    cs = cmap(np.arange(16))
    if N <= 16:
        step = 16 // N
        colours = np.array([cs[i] for i in range(0, 16, step)])
    else:
        s = N // 16
        colours = np.array([cs[int(np.floor(i / s))] for i in range(N)])

    return colours

ninner = 2  # number of inner wedge
width = 0.15  # width of inner wedges
radius = 0.5  # radius of inner wedges
gap = 100  # size of missing wedge

ngap = 300 - gap  # total size of filled wedges (missing gap will be 1/3 of total)

fig, ax = plt.subplots()

for i in range(8):
    if i > 0:
        # expand pie chart radius and shrink wedge width
        width *= 0.85
        radius += width
    
    # create data
    data = [gap]
    data.extend([ngap / 2**(i+1)] * ninner)
    colours = np.array([[0.8, 0.8, 0.8, 1.0] for _ in range(len(data))])  # initialise as all grey

    wcolours = get_colours(ninner)

    # this part will depend on your data!
    # let's colour fill all the inner wedges
    if i < 5:
        colours[1:] = wcolours
    else:
        # choose some values to fill in
        nfill = int(np.sqrt(ninner))
        if nfill > 0:
            wfill = np.zeros(ninner)
            wfill[np.random.choice(np.arange(ninner), nfill, replace=False)] = 1.0
            cv = colours[1:]
            cv[wfill.astype(bool)] = wcolours[wfill.astype(bool)]

    ninner *= 2

    # create pie chart
    wedges, _ = ax.pie(
        data,
        radius=radius,
        colors=colours,
        wedgeprops={"width": width, "edgecolor": "w", "linewidth": 0.25},
        startangle=-150,  # shift start angle
    )
    wedges[0].set_visible(False)  # make gap invisible

fig.tight_layout()
fig.show()

其产生:

相关问题