在 matplotlib imshow 中调整网格线和刻度线
Adjusting gridlines and ticks in matplotlib imshow
我正在尝试绘制一个值矩阵,并想添加网格线以使值之间的边界更清晰。
不幸的是,imshow 决定将刻度线定位在每个体素的中间。可以
a) 移除刻度但将标签留在同一位置并且
b) 在像素边界之间添加网格线?
import matplotlib.pyplot as plt
import numpy as np
im = plt.imshow(np.reshape(np.random.rand(100), newshape=(10,10)),
interpolation='none', vmin=0, vmax=1, aspect='equal');
ax = plt.gca();
ax.set_xticks(np.arange(0, 10, 1));
ax.set_yticks(np.arange(0, 10, 1));
ax.set_xticklabels(np.arange(1, 11, 1));
ax.set_yticklabels(np.arange(1, 11, 1));
没有网格线且刻度线位置错误的图像
ax.grid(color='w', linestyle='-', linewidth=2)
图像的网格线位置错误:
尝试移动轴刻度:
ax = plt.gca()
ax.set_xticks(np.arange(-.5, 10, 1))
ax.set_yticks(np.arange(-.5, 10, 1))
ax.set_xticklabels(np.arange(1, 12, 1))
ax.set_yticklabels(np.arange(1, 12, 1))
Serenity 建议的解决方案代码:
plt.figure()
im = plt.imshow(np.reshape(np.random.rand(100), newshape=(10,10)),
interpolation='none', vmin=0, vmax=1, aspect='equal')
ax = plt.gca();
# Major ticks
ax.set_xticks(np.arange(0, 10, 1))
ax.set_yticks(np.arange(0, 10, 1))
# Labels for major ticks
ax.set_xticklabels(np.arange(1, 11, 1))
ax.set_yticklabels(np.arange(1, 11, 1))
# Minor ticks
ax.set_xticks(np.arange(-.5, 10, 1), minor=True)
ax.set_yticks(np.arange(-.5, 10, 1), minor=True)
# Gridlines based on minor ticks
ax.grid(which='minor', color='w', linestyle='-', linewidth=2)
结果图像:
人们会发现它更易于使用 plt.pcolor
or plt.pcolormesh
:
data = np.random.rand(10, 10)
plt.pcolormesh(data, edgecolors='k', linewidth=2)
ax = plt.gca()
ax.set_aspect('equal')
不过,它们和plt.imshow
有一些区别,最明显的是图像被Y轴交换了(你可以通过添加ax.invert_yaxis()
though). For further discussion see here: When to use imshow over pcolormesh?[=来轻松反转它) 18=]
您可以通过将 extent
参数传递给 imshow
来移动像素。 extent
是标量的 4 元素列表(左、右、下、上):
foo = np.random.rand(35).reshape(5, 7)
# This keeps the default orientation (origin at top left):
extent = (0, foo.shape[1], foo.shape[0], 0)
_, ax = plt.subplots()
ax.imshow(foo, extent=extent)
ax.grid(color='w', linewidth=2)
ax.set_frame_on(False)
这是一种 hack,但我喜欢使用它,因为它不需要我移动 xticks 或 yticks。
import numpy as np
import matplotlib.pyplot as plt
plt.matshow(np.random.random(size=(10,10)))
plt.hlines(y=np.arange(0, 10)+0.5, xmin=np.full(10, 0)-0.5, xmax=np.full(10, 10)-0.5, color="black")
plt.vlines(x=np.arange(0, 10)+0.5, ymin=np.full(10, 0)-0.5, ymax=np.full(10, 10)-0.5, color="black")
plt.show()
我正在尝试绘制一个值矩阵,并想添加网格线以使值之间的边界更清晰。 不幸的是,imshow 决定将刻度线定位在每个体素的中间。可以
a) 移除刻度但将标签留在同一位置并且
b) 在像素边界之间添加网格线?
import matplotlib.pyplot as plt
import numpy as np
im = plt.imshow(np.reshape(np.random.rand(100), newshape=(10,10)),
interpolation='none', vmin=0, vmax=1, aspect='equal');
ax = plt.gca();
ax.set_xticks(np.arange(0, 10, 1));
ax.set_yticks(np.arange(0, 10, 1));
ax.set_xticklabels(np.arange(1, 11, 1));
ax.set_yticklabels(np.arange(1, 11, 1));
没有网格线且刻度线位置错误的图像
ax.grid(color='w', linestyle='-', linewidth=2)
图像的网格线位置错误:
尝试移动轴刻度:
ax = plt.gca()
ax.set_xticks(np.arange(-.5, 10, 1))
ax.set_yticks(np.arange(-.5, 10, 1))
ax.set_xticklabels(np.arange(1, 12, 1))
ax.set_yticklabels(np.arange(1, 12, 1))
Serenity 建议的解决方案代码:
plt.figure()
im = plt.imshow(np.reshape(np.random.rand(100), newshape=(10,10)),
interpolation='none', vmin=0, vmax=1, aspect='equal')
ax = plt.gca();
# Major ticks
ax.set_xticks(np.arange(0, 10, 1))
ax.set_yticks(np.arange(0, 10, 1))
# Labels for major ticks
ax.set_xticklabels(np.arange(1, 11, 1))
ax.set_yticklabels(np.arange(1, 11, 1))
# Minor ticks
ax.set_xticks(np.arange(-.5, 10, 1), minor=True)
ax.set_yticks(np.arange(-.5, 10, 1), minor=True)
# Gridlines based on minor ticks
ax.grid(which='minor', color='w', linestyle='-', linewidth=2)
结果图像:
人们会发现它更易于使用 plt.pcolor
or plt.pcolormesh
:
data = np.random.rand(10, 10)
plt.pcolormesh(data, edgecolors='k', linewidth=2)
ax = plt.gca()
ax.set_aspect('equal')
不过,它们和plt.imshow
有一些区别,最明显的是图像被Y轴交换了(你可以通过添加ax.invert_yaxis()
though). For further discussion see here: When to use imshow over pcolormesh?[=来轻松反转它) 18=]
您可以通过将 extent
参数传递给 imshow
来移动像素。 extent
是标量的 4 元素列表(左、右、下、上):
foo = np.random.rand(35).reshape(5, 7)
# This keeps the default orientation (origin at top left):
extent = (0, foo.shape[1], foo.shape[0], 0)
_, ax = plt.subplots()
ax.imshow(foo, extent=extent)
ax.grid(color='w', linewidth=2)
ax.set_frame_on(False)
这是一种 hack,但我喜欢使用它,因为它不需要我移动 xticks 或 yticks。
import numpy as np
import matplotlib.pyplot as plt
plt.matshow(np.random.random(size=(10,10)))
plt.hlines(y=np.arange(0, 10)+0.5, xmin=np.full(10, 0)-0.5, xmax=np.full(10, 10)-0.5, color="black")
plt.vlines(x=np.arange(0, 10)+0.5, ymin=np.full(10, 0)-0.5, ymax=np.full(10, 10)-0.5, color="black")
plt.show()