【问题标题】:Assign specific colours to data in Matplotlib pie chart为 Matplotlib 饼图中的数据分配特定颜色
【发布时间】:2016-05-14 09:00:46
【问题描述】:

我正在尝试使用matplotlib 创建饼图,其中每个类别的颜色都是固定的。

我有一个函数可以从一组值和类别数据中创建一个饼图。这是一个例子:

Category     Value
TI           65
Con          43
FR           40
TraI         40
Bug          38
Data         22
Int          15
KB           12
Other        8
Dep          7
PW           6
Uns          5
Perf         4
Dep          3

问题在于数据因一个实例而异,而这反过来又会改变类别的顺序。因此,每次我生成图表时,每个类别都会被标记为不同的颜色。我每次都可以按字母顺序对数据进行排序,但这会导致两个问题:某些数据集中缺少某些类别,而且我更希望它按大小排序,以便最小的楔形水平方向。

如何设置matplotlib 以根据pandas.Series 的索引分配颜色?

这是我用来生成饼图的代码:

import matplotlib.pyplot as plt

slices = [62, 39, 39, 38, 37, 21, 15,  9,  6,  7,  6,  5,  4, 3]

cmap = plt.cm.prism
colors = cmap(np.linspace(0., 1., len(slices)))

labels = [u'TI', u'Con', u'FR', u'TraI', u'Bug', u'Data', u'Int', u'KB', u'Other', u'Dep', u'PW', u'Uns', u'Perf', u'Dep']

fig = plt.figure(figsize=[10, 10])
ax = fig.add_subplot(111)

pie_wedge_collection = ax.pie(slices, colors=colors, labels=labels, labeldistance=1.05, autopct=make_autopct(slices))

for pie_wedge in pie_wedge_collection[0]:
    pie_wedge.set_edgecolor('white')

titlestring = 'Issues'

ax.set_title(titlestring)

编辑:我忘了解释 autopct 函数,它用于添加值和百分比标签:

def make_autopct(values):
    def my_autopct(pct):
        total = sum(values)
        val = int(round(pct*total/100.0))
        return '{p:.2f}%  ({v:d})'.format(p=pct,v=val)
    return my_autopct

【问题讨论】:

    标签: python python-2.7 matplotlib charts pie-chart


    【解决方案1】:

    这是一个您可以尝试的想法。根据您的标签和颜色制作字典,以便将每种颜色映射到一个标签。然后,在制作完饼图后,使用该字典将楔形的facecolor 分配进去。

    这是一段未经测试的代码,可能会满足您的需求:

    import numpy as np
    import matplotlib.pyplot as plt
    
    def mypie(slices,labels,colors):
    
        colordict={}
        for l,c in zip(labels,colors):
            print l,c
            colordict[l]=c
    
        fig = plt.figure(figsize=[10, 10])
        ax = fig.add_subplot(111)
    
        pie_wedge_collection = ax.pie(slices, labels=labels, labeldistance=1.05)#, autopct=make_autopct(slices))
    
        for pie_wedge in pie_wedge_collection[0]:
            pie_wedge.set_edgecolor('white')
            pie_wedge.set_facecolor(colordict[pie_wedge.get_label()])
    
        titlestring = 'Issues'
    
        ax.set_title(titlestring)
    
        return fig,ax,pie_wedge_collection
    
    slices = [37, 39, 39, 38, 62, 21, 15,  9,  6,  7,  6,  5,  4, 3]
    cmap = plt.cm.prism
    colors = cmap(np.linspace(0., 1., len(slices)))
    labels = [u'TI', u'Con', u'FR', u'TraI', u'Bug', u'Data', u'Int', u'KB', u'Other', u'Dep', u'PW', u'Uns', u'Perf', u'Dep']
    
    fig,ax,pie_wedge_collection = mypie(slices,labels,colors)
    
    plt.show()
    

    【讨论】:

    • 谢谢,我试试看。
    • 没有更简单的方法吗??
    • 它有效!此外,如果您想重复默认调色板,请为第一个饼图执行此操作:colordict[pie_wedge.get_label()] = pie_wedge.get_facecolor()
    • @RomainJouin 为了更简单的解决方案,您可以构建一个字典,将每个标签映射到一种颜色。然后,您可以将列表理解传递给plt.piecolors 参数。
    【解决方案2】:

    这是@tmdavison 答案的一个更简单的解决方案。

    让我们先看看 MWE 的问题:

    import matplotlib.pyplot as plt
    
    labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
    sizes = [15, 30, 45, 10]
    
    fig, ax = plt.subplots(1, 2)
    
    ax[0].pie(sizes, labels=labels)
    ax[1].pie(sizes[1:], labels=labels[1:])
    

    这会产生问题图:

    问题在于,在左侧图中,Hogs 被涂成橙色,但在右侧图中,Hogs 被涂成蓝色(Logs 和 @987654329 也有类似的混淆@)。

    我们希望两个图中的标签颜色相同。我们可以通过指定要使用的颜色字典来做到这一点:

    labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
    sizes = [15, 30, 45, 10]
    colours = {'Frogs': 'C0',
               'Hogs': 'C1',
               'Dogs': 'C2',
               'Logs': 'C3'}
    
    fig, ax = plt.subplots(1, 2)
    
    ax[0].pie(sizes,
              labels=labels,
              colors=[colours[key] for key in labels])
    
    ax[1].pie(sizes[1:],
              labels=labels[1:],
              colors=[colours[key] for key in labels[1:]])
    

    这可以创建情节:

    在这里,我们看到标签在两个图中用相同的颜色表示,正如所愿。

    如果您有很多类别,手动为每个类别设置颜色可能会很麻烦。在这种情况下,您可以将colours 字典构造为:

    colours = dict(zip(labels, plt.cm.tab10.colors[:len(labels)]))
    

    如果您有超过 10 个类别,您将改为使用:

    colours = dict(zip(labels, plt.cm.tab20.colors[:len(labels)]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多