首页 > 解决方案 > plt scatter 未显示与具有相同数据的 imshow 相同的点

问题描述

我正在尝试将散点图上显示良好的点和值叠加到图像中。我有一个大小为 (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.shape 1,img.shape[0]),并移动到 uv_new[y,x] = z .

在此处输入图像描述

标签: pythonnumpymatplotlibgraphscatter

解决方案


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

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

编辑:这是一个随机生成数据的实际示例。前两个图与您所做的相似,只是使用了interpolation关键字 for imshow。最后一个图与第二个图相似,但背景颜色发生了变化,以尝试与第一个图匹配,并且散点的大小减小了。看看第一个和最后一个图像如何相互相似?我认为这大致解释了为什么你没有得到与 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()

在此处输入图像描述


推荐阅读