plt scatter 未显示与具有相同数据的 imshow 相同的点

plt scatter not showing same points as imshow with same data

我正在尝试将散点图上显示良好的点和值叠加到图像中。我有一个大小为 (1200,1920,3) 的图像,以及一个组织为 (x,y,value) 的点列表,我称之为 uv,大小为 (3,16425)。当我在散点图上显示这些点时,它们会按照我希望的方式显示。但是,当我尝试在大小为 (1200,1920) 的数组中显示这些点,然后使用 imshow 显示时,不仅大部分点没有显示,而且尺寸也向后。我不知道发生了什么,因为在这两种情况下都是相同的数据。任何帮助将不胜感激。

代码:

uv_new = np.zeros((img.shape[0],img.shape[1]))
max_depth = np.max((uv[2,:]).astype(np.float64)) # just a normalizer
uv_int = uv.astype(int) # Since I'm putting it in an array, I need integer x,y coordinates
print(img.shape)
x = (uv_int[0]/np.max(uv_int[0])*(img.shape[0]-1)).astype(int) # Normalize x coordinates
y = (uv_int[1]/np.max(uv_int[1])*(img.shape[1]-1)).astype(int) # Normalize y coordinates
z = 1-uv[2]/max_depth # The color values I want to show
uv_new[x,y] = z # Set the image I want to show with the color values
plt.imshow(uv_new,origin='lower') # Show this image which should contain all the points, but doesn't
print(np.count_nonzero(uv_new)) 
print(np.count_nonzero(z)) # Comparing these two just to show that no data is lost
plt.figure(figsize=(8,5))
#plt.imshow(img)
cm = plt.cm.get_cmap('jet')
scat = plt.scatter(x,y, c=z, s=1, cmap=cm) # What I want, but is different from the image above, even though it is the exact same data
#plt.axis('off')
plt.show()

结果:

编辑: 根据对答案的最新评论,这是更新后的结果切换,因此 uv_new 现在的形状为 (img.shape1,img.shape[0]),并且移动到 uv_new[y,x] = z.

我相信你的代码片段中有一些错误。

  • 您不需要 uv_int,因为当您计算 x 和 y 时,您将它们转换为带有 astype(int) 的整数。
  • count_nonzero returns 两个不同值的原因可能是您在执行归一化时为 z 的多个非零值得到了一些重复的坐标 (x, y)。应用前一点可能有助于丢弃一些重复项。
  • 此调用 uv_new[x,y] = z 是您的 imshow 情节被转置的原因。是的,x 代表 X 轴,y 代表 Y 轴,但请记住,就显示矩阵而言,(rows, cols) 实际上等同于 (y, x)。因此,请更新您对 uv_new[y, x] = z 的调用并更改 uv_new.
  • 的形状
  • 对每个绘图使用相同的颜色图。也请避免使用喷射或彩虹。 Matplotlib 有 viridis、inferno、magma、plasma 和 cividis,这些都是你应该使用的很棒的颜色图。例如,只需在 imshowscatter 的两个调用中添加关键字 cmap='plasma'

编辑: 这是一个随机生成数据的实际示例。前两个图与您所做的相似,只是使用 imshowinterpolation 关键字。最后一个图与第二个图相似,但背景颜色发生了变化,以尝试与第一个图匹配,并且散点的大小减小了。看看第一张和最后一张图片有多相似?我认为这大致解释了为什么您无法使用 imshow 和 scatter 获得相同的图。下面的代码片段和图片(由于尺寸限制,图片质量很差,所以请在您的机器上执行代码片段以获得更好质量的图像)。

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng()
uv = rng.random(size=(3, 16425))
uv_new = np.zeros((1920, 1200))
x = (uv[0] / np.amax(uv[0]) * (uv_new.shape[1] - 1)).astype(int)
y = (uv[1] / np.amax(uv[1]) * (uv_new.shape[0] - 1)).astype(int)
z = 1 - uv[2] / np.amax(uv[2])
uv_new[y, x] = z
fig, (ax, bx, cx) = plt.subplots(nrows=1, ncols=3, num=0, figsize=(20, 10))
ax.imshow(uv_new, origin='lower', cmap='plasma', interpolation='bilinear')
bx.scatter(x, y, c=z, s=1, cmap='plasma')
cx.scatter(x, y, c=z, s=0.02, cmap='plasma')
cx.set_facecolor('xkcd:royal blue')
ax.set_aspect('equal')
ax.autoscale(enable=True, axis='both', tight=True)
bx.set_aspect('equal')
bx.autoscale(enable=True, axis='both', tight=True)
cx.set_aspect('equal')
cx.autoscale(enable=True, axis='both', tight=True)
fig.tight_layout()
fig.savefig('/home/thomas/so.png', bbox_inches='tight', dpi=200)
plt.show()