制作具有灰度可读百分比的饼图

时间:2017-08-04 04:46:06

标签: python matplotlib pie-chart grayscale

我有一个生成饼图的源代码

stdi

结果
彩色图片
color-pie-chart
和灰度
grayscale

灰度版本有点难以阅读。有没有建议在黑白打印中使灰度饼图可读?

2 个答案:

答案 0 :(得分:3)

从问题中不清楚您是想要创建黑白图表还是生成彩色图表,然后将其转换。两种情况下的策略可能是相同的: 您可以使用色彩图中的颜色创建新的色彩循环。 给出了可能的色彩映射的参考here。当然,您也可以使用自己的颜色列表。

E.g。从gray(深灰色)到0.2(浅灰色)之间的0.8色彩图创建5种颜色:

from cycler import cycler
colors = plt.cm.gray(np.linspace(0.2,0.8,5))
plt.rcParams['axes.prop_cycle'] = cycler(color=colors)

enter image description here

同样,您可以使用色彩鲜明的地图(例如magma),当之后转换为灰度时,它仍然看起来不错。

from cycler import cycler
colors = plt.cm.magma(np.linspace(0.2,0.8,5))
plt.rcParams['axes.prop_cycle'] = cycler(color=colors)

enter image description here

更改颜色范围,例如0.40.95之间的颜色范围较浅,

from cycler import cycler
colors = plt.cm.magma(np.linspace(0.4,0.95,5))
plt.rcParams['axes.prop_cycle'] = cycler(color=colors)

enter image description here

请注意,您可以(而不是定义颜色循环)将颜色直接应用于每个饼图

ax.pie(..., colors=colors, ...)

最后,为了区分灰度图像中的形状,通常应用的技术是使用阴影线。参见例如this example

pie = ax.pie(..., autopct='%1.1f%%', pctdistance=1.3,
              colors=colors, ...)
for patch, hatch in zip(pie[0],hatches):
    patch.set_hatch(hatch)

enter image description here

答案 1 :(得分:3)

假设您将保存为彩色图形,然后转换为灰度图像,则可以执行以下操作:

  1. 在您喜欢的色彩映射表的列表中定义颜色。 [这里也值得注意的是,使用新的4个彩色地图之一(自matplotlib 1.5以来可用:绿色,岩浆,等离子,地狱)意味着当图像转换为灰度时,颜色仍然可以区分。]

    colors = plt.cm.plasma(np.linspace(0., 1., 5))
    
  2. 然后,我们可以定义一个函数将这些颜色转换为等效的灰度值:

    rgb2gray = lambda rgb: np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
    
  3. 如果该值大于0.5,则颜色为浅色,因此我们可以使用黑色文本,否则,将文本更改为浅色。我们可以使用以下列表理解将这些文本颜色保存在列表中:

    textcol = ['k' if rgb2gray(color) > 0.5 else 'w' for color in colors ]
    
  4. 绘制饼图时,使用colors=colors kwarg来使用之前定义的颜色。 matplotlibax.pie返回三件事:构成饼图的修补程序,文本标签和autopct标签。后者是我们想要修改的。

    p, t, at = ax1.pie(train_sentences_b,  autopct='%1.1f%%',
            shadow=True, startangle=90, colors=colors)
    
  5. 让我们定义一个循环文本标签的函数,并根据我们之前制作的列表设置颜色:

    def fix_colors(textlabels, textcolors):
        for text, color in zip(textlabels, textcolors):
            text.set_color(color)
    
  6. 然后在使用以下方法绘制每个饼图后调用此方法:

    fix_colors(at, textcol)
    
  7. 将所有这些放在你的脚本中(我添加了一些额外的数据来获取饼图上的所有5个catagories):

    import matplotlib.pyplot as plt
    from matplotlib.pyplot import savefig
    import numpy as np
    import matplotlib.gridspec as gridspec
    
    colors = plt.cm.plasma(np.linspace(0., 1., 5))
    
    rgb2gray = lambda rgb: np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
    
    textcol = ['k' if rgb2gray(color) > 0.5 else 'w' for color in colors ]
    
    def fix_colors(textlabels, textcolors):
        for text, color in zip(textlabels, textcolors):
            text.set_color(color)
    
    plt.clf()
    plt.cla()
    plt.close()
    
    labels_b = ["Very Negative", "Negative",  "Neutral", "Positive", "Very Positive"]
    dev_sentences_b = [428, 444, 430, 500, 320]
    test_sentences_b = [912, 909, 890, 900, 900]
    train_sentences_b = [3310, 3610, 3200, 3500, 3321]
    
    gs = gridspec.GridSpec(2, 2)
    ax1= plt.subplot(gs[0, 0])
    p, t, at = ax1.pie(train_sentences_b,  autopct='%1.1f%%',
            shadow=True, startangle=90, colors=colors)
    fix_colors(at, textcol)
    
    ax1.axis('equal')
    ax1.set_title("Train")
    
    ax2= plt.subplot(gs[0, 1])
    p, t, at = ax2.pie(dev_sentences_b, autopct='%1.1f%%',
            shadow=True, startangle=90, colors=colors)
    ax2.axis('equal')
    ax2.set_title("Dev")
    fix_colors(at, textcol)
    
    ax3 = plt.subplot(gs[1, 1])
    p, t, at = ax3.pie(test_sentences_b, autopct='%1.1f%%',
            shadow=True, startangle=90, colors=colors)
    ax3.axis('equal')
    ax3.set_title("Test")
    fix_colors(at, textcol)
    
    ax3.legend(labels=labels_b, bbox_to_anchor=(-1,1), loc="upper left")
    
    plt.savefig('sstbinary', format='pdf')
    

    其中给出了以下图像:

    enter image description here

    转换为灰度后:

    enter image description here