目录
前言
某时某地,阳光明媚。我十指相扣,枕于脑后,伸着腰、抖着腿,仰望天空,似乎有些慵懒。但,当时只有一个想法,就像误入黑体空腔的那个可怜光子,在脑海中反复横跳 —— “是谁乱扔的香蕉皮”?
那么问题来了,“如何用python画色块”?
比较直觉的、简单的想法是,把它当做图片来处理,用imshow()方法,即:每张图片相当于一个数组,其中每个像素的数值大小分布为0 ~ 1(float),或者0 ~ 255(uint8)。每个像素点可看做一个色块,只需要改变其数值大小,就能对色块颜色进行调整。
此外,偷懒之心作祟,“是否已存在封装好的函数” 可直接调用,完成类似的操作。于是本着 “遇事不决,求助doc” 的原则,果然一顿操作之后,
在 matplotlib 官网 doc 中找到相似的案例,例如:pcolor、pcolormesh、pcolorfast。
此篇Blog用以记录本次探索学习的笔记和总结。
imshow 数组即是图像
imshow 是image show 的缩写, 所以给 imshow() 传入 2d 数组或RBG数据,该方法可渲染出相应图片。
这里用 x、y 定义渲染的边界,随机生成 2d 数组 z。渲染的颜色在参数 cmap 修改1,可直接传入名字(str),或者传入对应的属性,例如 plt.cm.Blues
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1, 1.5, 0.5)
y = np.arange(-1, 1.5, 0.5)
extent = np.min(x), np.max(x), np.min(y), np.max(y)
np.random.seed(666)
z = np.random.randn(2,2)
fig, ax = plt.subplots(1,2)
ax[0].imshow(z, cmap=plt.cm.Blues, extent=extent)
ax[1].imshow(z, cmap="gray", extent=extent)
plt.subplots_adjust(wspace=0.5)
plt.xticks(x)
plt.yticks(y)
pcolor 家族
pcolor、pcolormesh、pcolorfast。看到这三个名字的一瞬间,有些恍惚,这 “马什么梅” ?
首先,这三者的共同点,是皆可以用以绘制矩形网格。
而不同点在于2:
- 对于 pcolor 和 pcolormesh 而言,前者返回的是 “PolyCollection” 对象,而 pcolormesh 返回的是 “QuadMesh” 对象。大多数情况下(特别是面对大型数组时),后者的效率更高一些,所以官方更推荐使用 pcolormesh
- 而 pcolorfast 不支持部分功能。例如网格着色方案只支持 “flat”、其坐标轴不支持 log 缩放。
# 随便定义一个函数,用来生成二维数组
def func(x, y):
func = np.sin(x) - np.cos(y)
return func
x = np.arange(-1, 1.2, 0.2)
y = np.arange(-1, 1.2, 0.2)
X, Y = np.meshgrid(x, y)
Z = func(X, Y)
fig = plt.figure()
plt.pcolormesh(X, Y, Z, cmap="Blues", shading="auto")
plt.xticks(np.arange(-1, 1.5, 0.5))
plt.yticks(np.arange(-1, 1.5, 0.5))
学以致玩儿
学以致用方为学。这里稍微修改了上文 func 函数,加上时间参数,再利用 animation.FuncAnimation 函数,让网格动起来。关于 animation.FuncAnimation 函数的使用可以查阅官方 doc3,或者我的上一篇blog,点这里传送门。
def model(t, k, w):
x = np.arange(-1, 1.2, 0.2)
y = np.arange(-1, 1.2, 0.2)
X, Y = np.meshgrid(x, y)
# 二维波函数
Z = np.sin(k*X - w*t) - np.cos(k*Y - w*t)
im = plt.pcolormesh(X, Y, Z, cmap="Blues", shading="auto")
return im
# 设置初始值
k = 0.2
w = 0.8
t = np.linspace(0, 5, 20)
fig, ax = plt.subplots()
ani = animation.FuncAnimation(fig, model, frames=t, fargs=(k, w))
plt.title("pcolormesh")
plt.xticks(np.arange(-1, 1.5, 0.5))
plt.yticks(np.arange(-1, 1.5, 0.5))
ani.save('colorBlocks.gif',writer='pillow')
总结
今天出于好奇,了解了一些网格的画法,特别是 imshow 和 pcolormesh 这两个函数。同时定义了个二维波函数,让网格动起来,也挺有趣的。
此外,一个新脑洞,能否做成 3D 版本的,类似奥运开幕式上,活字印刷术动画的那种效果。
https://matplotlib.org/stable/gallery/color/colormap_reference.html#sphx-glr-gallery-color-colormap-reference-py ↩︎
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.pcolormesh.html#differences-pcolor-pcolormesh ↩︎
https://matplotlib.org/stable/api/_as_gen/matplotlib.animation.FuncAnimation.html ↩︎