为什么“imshow”以彩色显示2D(非RGB)数组,如何将这种彩色图像导出到.png文件?

2024-05-20 12:10:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我生成了一个Mandelbrot图形作为10000x1000像素numpy数组:

[[ 100.  100.  100. ...,   12.   12.   13.]
 [ 100.  100.  100. ...,   12.   13.   14.]
 [ 100.  100.  100. ...,   12.   12.   14.]
 ..., 
 [   3.    3.    3. ...,    3.    3.    3.]
 [   3.    3.    3. ...,    3.    3.    3.]
 [   3.    3.    3. ...,    3.    3.    3.]]

如果使用matplotlib显示数组:

^{pr2}$

我得到了一个非常好的彩色图像。在

但是为什么要这样呢?在

除此之外,如果我尝试将其导出到.png我会得到一个黑白图像:

import PIL.Image as im
iimg = im.fromarray(arr)
iimg = iimg.convert("RGB") # std was "F", but it didn't work
iimg.save("img_mandelbrot.png")

with matplotlib

exported via PIL

有没有办法将这种彩色图像导出到png? matplotlib似乎不是一个可行的选择,因为分辨率太差。在


Tags: 图像importnumpy图形pilpngmatplotlib像素
2条回答

^{}传递二维数组时,强度值将映射到RGBA值。这是根据一个名为colormap的查找表来完成的,该表可以通过cmap=关键字参数指定。例如,要以灰度绘制Mandelbrot数组,可以选择'gray'颜色贴图:

plt.imshow(arr, cmap='gray')

如果不传递cmap=参数,matplotlib将使用默认值,您也可以在^{}文件中进行修改。对于当前版本matplotlib的干净安装,默认值是一个名为'jet'的colormap,如下所示:

enter image description here

^{} is a pretty terrible colormap for many purposes,和will soon be replaced as the default colormap in matplotlib v2.0。您可以在official documentation中阅读有关选择颜色贴图的更多信息。在

您还可以将一个3D数组传递给imshow,其中最终维度的大小为3或4。在这种情况下,最终尺寸被解释为每个像素的RGB(A)值。由于颜色信息已经包含在数组中,因此不需要查找表,因此cmap=参数将被忽略。在


为了解决问题的第二部分,将数组保存为彩色映射的全分辨率.png图像的一个简单方法是使用^{},这也需要一个cmap=参数:

^{pr2}$

plt.imsave只导出数组中的原始像素,因此10000x1000输入数组将生成一个正好为10000x1000像素的.png图像。在

相反,^{}呈现整个图形画布(包括边距、轴、其他绘图元素等),并根据(1)图形的大小(以英寸为单位)和(2)关键字参数dpi=来缩放。尽管只需将DPI设置为比需要的大得多就可以获得足够高的分辨率,但是使用此方法以实际大小渲染数组将更加困难,因为您需要调整图形大小和/或DPI以及轴的位置和大小等

正如我在上面的评论中提到的,savefig有一个dpi选项

例如:

import numpy as np
import matplotlib.pyplot as plt

plt.figure(figsize=(10,10)) #
arr = np.random.random((10000,10000)) # my array
plt.imshow(arr)

plt.savefig('fig.png', dpi=1000)

我不能发布原始的PNG(大约200兆字节),但这给了你想要的任何细节。上面脚本输出的一些缩放屏幕截图:

zoom_1zoom_2

注意,通过这种方式,图形(包括边框、轴标签等)是10000x1000像素,因此您仍然无法单独看到来自arr的实际10000x1000像素。如果你不介意没有轴标记、滴度等,ali嫒m的解决方案确实解决了这个问题。在

相关问题 更多 >