图片是一种非常重要的表达方式,在数据分析的很多场景,也需要借助显示一些图片,来形象化抽象数据,以此传达数据的深层次含义。那么在 matplotlib 里是怎么样来显示图片呢?如何绘制出如下图片呢?
幸运的是 matplotlib 通过调用函数 imshow()
轻松实现显示图片的功能。不过此函数由于参数非常多,要想一下子地理解它,是困难的,也是不可能的。因此今天通过介绍参数及做一些简单的应用,来加深印象。
Axes.imshow(X, cmap=None, norm=None, *,
aspect=None, interpolation=None,
alpha=None, vmin=None, vmax=None,
origin=None, extent=None,
interpolation_stage=None,
filternorm=True, filterrad=4.0,
resample=None, url=None,
data=None, **kwargs)
-前两个维度(M,N)定义了行和列图片,即图片的高和宽;RGB(A)值应该在浮点数[0, ..., 1]的范围内,或者整数[0, ... ,255]。超出范围的值将被剪切为这些界限。
interpolation = 'none'
,则不执行插值热力图是一种数据的图形化表示,具体而言,就是将二维数组中的元素用颜色表示。热力图之所以非常有用,是因为它能够从整体视角上展示数据,更确切的说是数值型数据。
使用imshow()函数可以非常容易地制作热力图。
# 标签和数据略
vegetables = [...]
farmers = [...]
harvest = np.array([...])
# 定义画布
fig, ax = plt.subplots()
im = ax.imshow(harvest)
# 显示所有的勾号,并用相应的列表条目为它们标上标签
ax.set_xticks(np.arange(len(farmers))labels=farmers)
ax.set_yticks(np.arange(len(vegetables)), labels=vegetables)
# 旋转标记标签并设置它们的对齐方式。
plt.setp(ax.get_xticklabels(), rotation=45,
ha="right", rotation_mode="anchor")
# 循环数据维度并创建文本注释。
for i in range(len(vegetables)):
for j in range(len(farmers)):
text = ax.text(j, i, harvest[i, j],
ha="center", va="center", color="w")
更加复杂的热图绘制:
计算图形大小,以便像素宽度是数据点数量的倍数,以防止插值伪影。此外,它 Axes
被定义为跨越整个图形并且全部Axis
关闭。
数据本身是imshow
使用渲染的。
code.reshape(1, -1)
将数据转换为一行的二维数组。imshow(..., aspect='auto')
允许非方形像素。imshow(..., interpolation='nearest')
以防止边缘模糊。code = np.array([1,0,1,0... 0, 1])
ax.imshow(code.reshape(1, -1),
cmap='binary', aspect='auto',
interpolation='nearest')
with matplotlib.cbook.get_sample_data('@公众号:数据STUDIO.jpg') as image_file:
image = plt.imread(image_file)
fig, ax = plt.subplots()
ax.imshow(image)
im = ax.imshow(image)
patch = matplotlib.patches.Circle((1200, 900), radius=800, transform=ax.transData)
im.set_clip_path(patch)
ax.axis('off')
plt.show()
重写imshow函数,以应用平移、缩放和旋转,并使用随机值调用该函数多次。当然,这里还需要掌握Matplotlib坐标轴系统,运用其坐标轴变换,以改变图像的旋转。 具体可见:Matplotlib 可视化之图表坐标系统
def imshow(ax, I, position=(0, 0), scale=1, angle=0, zorder=10):
# print(I.shape)
height, width, channel = I.shape
extent = scale * np.array([-width / 4, width / 4, -height / 4, height / 4])
im = ax.imshow(I, extent=extent, zorder=zorder, cmap="cividis")
transform = transforms.Affine2D().rotate_deg(angle).translate(*position)
trans_data = transform + ax.transData
im.set_transform(trans_data)
x1, x2, y1, y2 = im.get_extent()
ax.plot(
[x1, x2, x2, x1, x1],
[y1, y1, y2, y2, y1],
"white",
alpha=0,
linewidth=25 * scale,
transform=trans_data,
zorder=zorder - 0.1,
)
随机角度,随机大小
I = imageio.imread("../data/数据STUDIO-02.png")
for i in range(10):
ind = random.choice([0, 1, 2, 3])
position = np.random.uniform(-100, 1100, 2)
scale = np.random.uniform(0.20, 0.25)
angle = np.random.uniform(-75, +75)
imshow(ax, I, position, scale, angle, zorder=10 + i)
一堆云朵君
更多应用可以参见imshow函数[1]。
[1]
imshow函数: https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.axes.Axes.imshow.html
[2]
https://www.jianshu.com/p/694afb0db7d5
[3]
热图: https://matplotlib.org/3.5.0/gallery/images_contours_and_fields/image_annotated_heatmap.html
[4]
插值: https://matplotlib.org/3.5.0/gallery/images_contours_and_fields/interpolation_methods.html