有没有办法在这个网格中标记饼图的每个楔形?

Is there a way to label each wedge of pie chart in this grid?

我想在一个网格中有多个饼图。

每个饼图都有不同数量的楔形、值和标签。

下面的代码在一个饼图中显示了多个标签。

有没有办法在这个网格中标记饼图的每个楔形?

import matplotlib.pyplot as plt
import numpy as np

def heatmap_with_circles(data_array,row_labels,column_labels,ax=None, cmap=None, norm=None, cbar_kw={}, cbarlabel="", **kwargs):

    for row_index, row in enumerate(row_labels,0):
        for column_index, column in enumerate(column_labels,0):
            print('row_index: %d column_index: %d' %(row_index,column_index))
            if row_index==0 and column_index==0:
                colors=['indianred','orange','gray']
                values=[10,20,30]
            else:
                values=[45,20,38]
                colors=['pink','violet','green']

            wedges, text = plt.pie(values,labels=['0', '2', '3'],labeldistance = 0.25,colors=colors)
            print('len(wedges):%d wedges: %s, text: %s' %(len(wedges), wedges, text))
            radius = 0.45
            [w.set_center((column_index,row_index)) for w in wedges]
            [w.set_radius(radius) for w in wedges]

    # We want to show all ticks...
    ax.set_xticks(np.arange(data_array.shape[1]))
    ax.set_yticks(np.arange(data_array.shape[0]))

    fontsize=10
    ax.set_xticklabels(column_labels, fontsize=fontsize)
    ax.set_yticklabels(row_labels, fontsize=fontsize)

    #X axis labels at top
    ax.tick_params(top=True, bottom=False,labeltop=True, labelbottom=False,pad=5)
    plt.setp(ax.get_xticklabels(), rotation=55, ha="left", rotation_mode="anchor")

    # We want to show all ticks...
    ax.set_xticks(np.arange(data_array.shape[1]+1)-.5, minor=True)
    ax.set_yticks(np.arange(data_array.shape[0]+1)-.5, minor=True)

    ax.grid(which="minor", color="black", linestyle='-', linewidth=2)
    ax.tick_params(which="minor", bottom=False, left=False)

data_array=np.random.rand(3,4)
row_labels=['Row1', 'Row2', 'Row3']
column_labels=['Column1', 'Column2', 'Column3','Column4']

fig, ax = plt.subplots(figsize=(1.9*len(column_labels),1.2*len(row_labels)))
ax.set_aspect(1.0)
ax.set_facecolor('white')
heatmap_with_circles(data_array,row_labels,column_labels, ax=ax)
plt.tight_layout()
plt.show()

更新后heatmap_with_circles

def heatmap_with_circles(data_array,row_labels,column_labels,ax=None, cmap=None, norm=None, cbar_kw={}, cbarlabel="", **kwargs):
    labels = ['x', 'y', 'z']

    for row_index, row in enumerate(row_labels,0):
        for column_index, column in enumerate(column_labels,0):
            print('row_index: %d column_index: %d' %(row_index,column_index))
            if row_index==0 and column_index==0:
                colors=['indianred','orange','gray']
                values=[10,20,30]
            else:
                values=[45,20,38]
                colors=['pink','violet','green']

            # wedges, texts = plt.pie(values,labels=['0', '2', '3'],labeldistance = 0.45,colors=colors)
            wedges, texts = plt.pie(values,labeldistance = 0.25,colors=colors)
            print('text:%s len(wedges):%d wedges: %s' %(texts, len(wedges), wedges))
            radius = 0.45
            [w.set_center((column_index,row_index)) for w in wedges]
            [w.set_radius(radius) for w in wedges]
            [text.set_position((text.get_position()[0]+column_index,text.get_position()[1]+row_index)) for text in texts]
            [text.set_text(labels[text_index]) for text_index, text in enumerate(texts,0)]

我得到了下面的图片:)

您可以遍历每个饼图的文本,获取其 xy 位置,添加 column_index 和 row_index,并将其设置为新位置。

对现有代码的一些小改动:

  • ax.grid(which="minor", ..., clip_on=False) 确保粗线显示完整,也靠近边框
  • ax.set_xlim(xmin=-0.5) 设置限制
import matplotlib.pyplot as plt
import numpy as np

def heatmap_with_circles(data_array, row_labels, column_labels, ax=None):
    ax = ax or plt.gca()
    for row_index, row in enumerate(row_labels, 0):
        for column_index, column in enumerate(column_labels, 0):
            colors = np.random.choice(['indianred', 'orange', 'gray', 'pink', 'violet', 'green'], 3, replace=False)
            values = np.random.randint(10, 41, 3)
            wedges, text = plt.pie(values, labels=['1', '2', '3'], labeldistance=0.25, colors=colors)
            radius = 0.45
            for w in wedges:
                w.set_center((column_index, row_index))
                w.set_radius(radius)
                w.set_edgecolor('white')
                # w.set_linewidth(1)
            for t in text:
                x, y = t.get_position()
                t.set_position((x + column_index, y + row_index))

    # We want to show all ticks...
    ax.set_xticks(np.arange(data_array.shape[1]))
    ax.set_yticks(np.arange(data_array.shape[0]))

    fontsize = 10
    ax.set_xticklabels(column_labels, fontsize=fontsize)
    ax.set_yticklabels(row_labels, fontsize=fontsize)

    # X axis labels at top
    ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False, pad=5)
    plt.setp(ax.get_xticklabels(), rotation=55, ha="left", rotation_mode="anchor")

    # We want to show all minor ticks...
    ax.set_xticks(np.arange(data_array.shape[1] + 1) - .5, minor=True)
    ax.set_yticks(np.arange(data_array.shape[0] + 1) - .5, minor=True)
    ax.set_xlim(xmin=-.5)
    ax.set_ylim(ymin=-.5)

    ax.grid(which="minor", color="black", linestyle='-', linewidth=2, clip_on=False)
    ax.tick_params(axis="both", which="both", length=0) # hide tick marks

data_array = np.random.rand(3, 4)
row_labels = ['Row1', 'Row2', 'Row3']
column_labels = ['Column1', 'Column2', 'Column3', 'Column4']

fig, ax = plt.subplots(figsize=(1.9 * len(column_labels), 1.2 * len(row_labels)))
ax.set_aspect(1.0)
ax.set_facecolor('white')
heatmap_with_circles(data_array, row_labels, column_labels, ax=ax)
plt.tight_layout()
plt.show()