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

3

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

import matplotlib.pyplot as plt
from matplotlib.pyplot import savefig
import numpy as np
import matplotlib.gridspec as gridspec

plt.clf()
plt.cla()
plt.close()
labels_b = ["Negative",  "Positive"]
dev_sentences_b = [428, 444]
test_sentences_b = [912, 909]
train_sentences_b = [3310, 3610]

gs = gridspec.GridSpec(2, 2)
ax1= plt.subplot(gs[0, 0])
ax1.pie(train_sentences_b,  autopct='%1.1f%%',
        shadow=True, startangle=90)
ax1.axis('equal')
ax1.set_title("Train")

ax2= plt.subplot(gs[0, 1])
ax2.pie(dev_sentences_b, autopct='%1.1f%%',
        shadow=True, startangle=90)
ax2.axis('equal')
ax2.set_title("Dev")

ax3 = plt.subplot(gs[1, 1])
ax3.pie(test_sentences_b, autopct='%1.1f%%',
        shadow=True, startangle=90)
ax3.axis('equal')
ax3.set_title("Test")

ax3.legend(labels=labels_b, bbox_to_anchor=(-1,1), loc="upper left")

plt.savefig('sstbinary', format='pdf')

结果
彩色图片
彩色饼图
和灰度图
灰度图

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


1
在饼图中使用白色字体来显示数字可能是一个解决方案。请参考以下链接:https://dev59.com/Sl4c5IYBdhLWcg3wdKKT 和 https://matplotlib.org/examples/pylab_examples/pie_demo2.html - Nikos Tavoularis
2个回答

4
从问题中并不清楚您是想在黑白模式下创建图表还是先制作彩色图表再转换为黑白。但无论哪种情况,策略可能都是相同的: 您可以使用色图中的颜色创建新的颜色循环。 此处提供了可能的色图参考。当然,您也可以使用自己的颜色列表。 例如:从gray色图中创建5种颜色,介于0.2(深灰色)到0.8(浅灰色)之间:
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


我应该把代码放在哪里(我的源代码中),因为它不起作用。什么都没有改变。 - Haha TTpro
在第五行,您的导入语句下方。 - ImportanceOfBeingErnest

3
假设您正在保存彩色图像,并稍后将其转换为灰度图像,您可以执行以下操作:
  1. Define your colours in a list from your favourite colormap. [It's also worth noting here that using one of the new 4 colormaps (available since matplotlib 1.5: viridis, magma, plasma, inferno) means that the colours will still be distinguishable when the image is converted to grayscale].

    colors = plt.cm.plasma(np.linspace(0., 1., 5))
    
  2. Then, we can define a function to convert those colors to their equivalent grayscale value:

    rgb2gray = lambda rgb: np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
    
  3. If that value is greater than 0.5, the colour is a light shade, and thus we can use black text, otherwise, change the text to a light colour. We can save those text colours in a list using the following list comprehension:

    textcol = ['k' if rgb2gray(color) > 0.5 else 'w' for color in colors ]
    
  4. When you plot the pie chart, use the colors=colors kwarg to use the colours you defined earlier. matplotlib returns three things from ax.pie: the patches that make up the pie chart, the text labels, and the autopct labels. The latter are the ones we want to modify.

    p, t, at = ax1.pie(train_sentences_b,  autopct='%1.1f%%',
            shadow=True, startangle=90, colors=colors)
    
  5. Lets define a function to loop through the text labels, and set their colours depending on the list we made earlier:

    def fix_colors(textlabels, textcolors):
        for text, color in zip(textlabels, textcolors):
            text.set_color(color)
    
  6. We then call this after each pie chart is plotted using:

    fix_colors(at, textcol)
    
将所有这些内容放在您的脚本中(我添加了一些额外的数据以获取饼图上的所有5个类别):
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')

以下是生成的图像:

在此输入图像描述

转换为灰度后:

在此输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接