繁体   English   中英

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

[英]Make pie chart with percentage readable in grayscale

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

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')

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

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

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

例如,从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)

在此输入图像描述

同样,您可以使用彩色地图(例如magma ),这些地图在之后转换为灰度时仍然看起来很好。

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

在此输入图像描述

改变颜色范围,例如在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)

在此输入图像描述

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

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

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

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

在此输入图像描述

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

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

     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) 

将这些全部放在你的脚本中(我添加了一些额外的数据来获取饼图上的所有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')

这给出了以下图像:

在此输入图像描述

转换为灰度后:

在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM