简体   繁体   English

matplotlib绘制小图像,无需重新采样

[英]matplotlib plot small image without resampling

I'm trying to plot a small image in python using matplotlib and would like the displayed axes to have the same shape as the numpy array it was generated from, ie the data should not be resampled. 我正在尝试使用matplotlib在python中绘制一个小图像,并希望显示的轴具有与它生成的numpy数组相同的形状,即数据不应重新采样。 In other words, each entry in the array should correspond to a pixel (or thereabouts) on the screen. 换句话说,数组中的每个条目应对应于屏幕上的像素(或其左侧)。 This seems trivial, but even after trawling the internet for while, I can't seem to get it to work: 这看起来微不足道,但即使在网上拖网一段时间之后,我似乎无法让它起作用:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

X = np.random.rand(30,40)

fig = plt.figure()
fig.add_axes(aspect="equal",extent=[0, X.shape[1], 0, X.shape[0]])
ax = fig.gca()
ax.autoscale_view(True, False, False)
ax.imshow(X, cmap = cm.gray)

plt.show()

I've had the same problem myself. 我自己也有同样的问题。 If the interpolation='nearest' option to imshow isn't good enough, well if your main objective is to see raw, un-scaled, non-interpolated, un-mucked about pixels in matplotlib, then you can't beat figimage IMHO. 如果imshowinterpolation='nearest'选项不够好,那么如果你的主要目标是在matplotlib中看到原始的,未缩放的,非插值的,未figimage像素,那么你就无法击败figimage恕我直言。 Demo: 演示:

import numpy as np
import numpy.random
import matplotlib.pyplot as plt

a=256*np.random.rand(64,64)

f0=plt.figure()
plt.imshow(a,cmap=plt.gray())
plt.suptitle("imshow")

f1=plt.figure()
plt.figimage(a,cmap=plt.gray())
plt.suptitle("figimage")

plt.show()

Of course it means giving up the axes (or drawing them yourself somehow). 当然这意味着放弃轴(或以某种方式自己绘制)。 There are some options to figimage which let you move the image around the figure so I suppose it might be possible to manoeuvre them on top of some axes created by other means. 有一些figimage选项可以让你在图形周围移动图像,所以我想可以在其他方法创建的某些轴上操纵它们。

You can use the following code snippet to convert an array into a PIL ( Python Imaging Library ). 您可以使用以下代码段将数组转换为PIL( Python Imaging Library )。 The resulting image will have the same size as the input array. 生成的图像将具有与输入数组相同的大小。 It can be displayed or saved as an image. 它可以显示或保存为图像。

from PIL import Image
from numpy import linspace, array, fromfunction, sin, cos
from matplotlib import cm


# scale array between vmin and vmax and encode it to uint8 (256 values)
def scale(arr, vmin, vmax):
    return (255*(arr - vmin)/(vmax - vmin)).clip(0, 255).astype('uint8')

# convert a matplotlib colormap into a PIL palette
def getpalette(cmap):
    return (255.*array(map(lambda x: cmap(x)[0:3], linspace(0., 1.,256))).ravel()).astype('int')


# a sample array
data = fromfunction(lambda i,j: cos((i+j)/50)*sin(i/50.), (200, 300), dtype='float')

# convert the float array to a PIL image
im = Image.fromarray(scale(data, 0, 1))
im.putpalette(getpalette(cm.jet))
im.save('test.png') # or im.show()

The only thing is that im.show() is not very good, because it requires to have the image viewer xv and it writes a temporary image. 唯一的问题是im.show()不是很好,因为它需要拥有图像查看器xv并且它会写一个临时图像。 So you can as well write a file and load it with your favorite image viewer. 因此,您也可以编写一个文件并使用您喜欢的图像查看器加载它。

I'm not sure I completely understand your question. 我不确定我完全理解你的问题。 Does this mean you want the x axis between 0 and X.shape[1] and the y axis between 0 and X.shape[0]? 这是否意味着您希望x轴介于0和X.shape [1]之间,y轴介于0和X.shape [0]之间? In this case, this code should do the trick: 在这种情况下,此代码应该可以解决问题:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

X = np.random.rand(30,40)

fig = plt.figure()

plt.xlim(0, X.shape[1])
plt.ylim(0, X.shape[0])

ax = fig.gca()
ax.autoscale_view(True, False, False)
ax.imshow(X, cmap = cm.gray)

plt.show()

Hope it helps 希望能帮助到你

If you know the native resolution of your image, you can set the dpi argument to what you want in the plt.figure(dpi=value) . 如果您知道图像的原始分辨率,则可以在plt.figure(dpi=value)中将dpi参数设置为您想要的plt.figure(dpi=value)

You can find more information about adjusting image size on this link . 您可以在此链接上找到有关调整图像大小的更多信息。

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

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