以灰度模式保存matplotlib绘图

26

我有一些彩色图形需要保存为灰度。是否有一种简单的方法可以在不改变绘图格式的情况下完成?


4
有一些讨论围绕着如何将彩色图像转换为黑白/灰度图像,参见convert figure from color to BW/grayscale。不知道在最新版的matplotlib中是否可用 set_gray 属性。 - chl
你可以在之后使用imagemagick:convert -type Grayscale old.png new.png 我认为在SO上已经有相关内容了,参见链接 - Pierre Guilbert
6个回答

14

有一个简单的解决方案:

plt.imsave(filename, image, cmap='gray')

9
目前直接从matplotlib实现这个功能还有些麻烦,但是在“未来”,他们计划在图形上支持一个名为set_gray(True)的调用(请参见邮件列表线程here)。您最好的选择是将其保存为彩色并进行转换,可以使用PIL在python中实现:
import Image
Image.open('color.png').convert('L').save('bw.png')

或者使用ImageMagick从命令行进行转换:

convert -type Grayscale color.png bw.png

1
和其他答案一样,这个答案也不是很令人满意,因为它将图表转换为光栅图。 - Ian Goodfellow

5

实际上,这个问题之前已经被问过。以下是一个非常好的答案,它在谷歌搜索中排名第二(截至今天):
使用matplotlib将图像显示为灰度

而且解决方案与Suki的非常相似...

哦,好吧,我很无聊,所以我也发了一段完整的代码:

import numpy as np
import pylab as p
xv=np.ones(4)*.5
yv=np.arange(0,4,1)
xv1=np.ones(4)*-.5
yv1=np.arange(0,4,1)

#red vertical line on the right
yv2=np.arange(0,1.5,0.1)
xv2=np.ones_like(yv2)*.7

#red vertical line on the left
yv3=np.arange(0,2,0.01)
xv3=np.ones_like(yv3)*-0.7

###
xc=np.arange(-1.4,2,0.05)
yc=np.ones_like(xc)*1

fig = p.figure()
ax1 = fig.add_subplot(111)
#adjustprops = dict(left=0.12, bottom=0.2, right=0.965, top=0.96, wspace=0.13, hspace=0.37)
#fig.subplots_adjust(**adjustprops)
ax1.plot(xv,yv, color='blue', lw=1, linestyle='dashed')
ax1.plot(xv1,yv1, 'green', linestyle='dashed')
ax1.plot(np.r_[-1:1:0.2],np.r_[-1:1:0.2],'red')
ax1.plot(xc,yc, 'k.', markersize=3)

p.savefig('colored_image.png')

import matplotlib.image as mpimg
import matplotlib.cm as cm
import Image

figprops = dict(figsize=(10,10), dpi=100)
fig1 = p.figure(**figprops)
#fig1 = p.figure()
#ax1 = fig.add_subplot(111)
adjustprops = dict()
image=Image.open('colored_image.png').convert("L")
arr=np.asarray(image)
p.figimage(arr,cmap=cm.Greys_r)
p.savefig('grayed.png')
p.savefig('grayed.pdf',papertype='a4',orientation='portrait')

这将产生一张彩色图表,然后将其转换为灰度,并保存为png和pdf格式。

3
这个答案不是很好,因为它需要将图形和其中的任何字体转换为光栅化格式。当您将其转换为 .png 格式时,会发生光栅化。更好的做法是将 PDF 文件写入文件系统,然后使用 Ghostscript 将其转换为灰度图。 - Ian Goodfellow
"import Image" 不再可用。请改用 "from PIL import Image"。 - warunapww

4

我也遇到了这个问题。据我所知,matplotlib不支持直接转换为灰度图,但你可以保存为彩色pdf文件,然后使用ghostscript将其转换为灰度图:

gs -sOutputFile=gray.pdf -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dNOPAUSE -dBATCH -dAutoRotatePages=/None color.pdf

为什么不直接使用灰度样式表?http://matplotlib.org/examples/style_sheets/plot_grayscale.html - Paul H
那实际上并没有将彩色图转换为灰度图。它只是默认将一些元素变为灰色。我有一些图形,我想将其导出为网页用的彩色图和打印用的灰度图。 - Ian Goodfellow
您可以在上下文管理器中使用样式表。将非数据处理绘图函数的调用与其包装起来。 - Paul H
我不理解这个建议。为什么上下文管理器有帮助?数据处理如何相关? - Ian Goodfellow
如果你的绘图函数需要进行大量的数据处理,多次调用它将会减缓程序的流程。但是预处理数据,然后在一个彩色和灰度样式上下文管理器中调用一个更简单的绘图函数应该是相当可控的。 - Paul H

0

另外,补充一下Mu Mind的解决方案:

如果由于某种原因你想避免将其写入文件,你可以使用StringIO来像文件一样操作:


 import Image
 import pylab
 from StringIO import StringIO

 pylab.plot(range(10),[x**2 for x in range(10)])

 IO = StringIO()
 pylab.savefig(IO,format='png')
 IO.seek(0)

 #this, I stole from Mu Mind solution
 Image.open(IO).convert('L').show()

和其他答案一样,这个答案也不是很令人满意,因为它将图表转换为光栅图。 - Ian Goodfellow

0
从Ian Goodfellow的回答中开发出来的,这是一个生成并运行ghostscript命令将PDF转换为灰度的Python脚本。与将其栅格化为PNG的答案相比,它更可取,因为它保留了图形的矢量表示。
import subprocess
import sys 

def pdf_to_grayscale(input_pdf, output_pdf):
    try:
        # Ghostscript command to convert PDF to grayscale
        ghostscript_cmd = [
            "gs",
            "-sDEVICE=pdfwrite",
            "-sColorConversionStrategy=Gray",
            "-sProcessColorModel=DeviceGray",
            "-dCompatibilityLevel=1.4",
            "-dNOPAUSE",
            "-dQUIET",
            "-dBATCH",
            f"-sOutputFile={output_pdf}",
            input_pdf
        ]

        # Execute Ghostscript command using subprocess
        subprocess.run(ghostscript_cmd, check=True)

        print("PDF converted to grayscale successfully.")
    except subprocess.CalledProcessError:
        print("Error occurred during PDF conversion to grayscale.")

if __name__ == "__main__":
    assert len(sys.argv) == 3, "Two args: input pdf and output pdf"    
    pdf_to_grayscale(sys.argv[1], sys.argv[2])

将其保存为to_gray.py并像这样运行:

python to_gray.py test.pdf gray.pdf

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