Matplotlib如何使用CSV数据创建三维表面图(x,y,z,color)- 颜色不正确

3
如何读取四列数据以创建一个表面图,并使用第四个变量进行着色?在我的情况下,这组数据是使用四个嵌套的循环生成的,因此最右侧的列变化最频繁,而最左侧的列变化最少。
到目前为止我尝试过的是创建了一个单色图形,但颜色是错误的。
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import pylab
from scipy.interpolate import griddata

dat = open('ex.csv', 'w')
dat.write('x,y,z,c\n')
for x in range(20):
    for y in range(20):
             dat.write(','.join([str(s) for s in [x,y,x+y,x+y,'\n']]))
dat.close()

fig = matplotlib.pyplot.gcf()
subdat = np.genfromtxt('ex.csv', delimiter=',',skiprows=1)
X = subdat[:,0]
Y = subdat[:,1]
Z = subdat[:,2]
C = subdat[:,3]

xi = np.linspace(X.min(),X.max(),100)
yi = np.linspace(Y.min(),Y.max(),100)

zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic')
ci = griddata((X, Y), C, (xi[None,:], yi[:,None]), method='cubic')

ax1 = fig.add_subplot(111, projection='3d')

xig, yig = np.meshgrid(xi, yi)
surf = ax1.plot_surface(xig, yig, zi,facecolors=cm.rainbow(ci))

m = cm.ScalarMappable(cmap=cm.rainbow)
m.set_array(ci)
col = plt.colorbar(m)
plt.show()

enter image description here (颜色不正确,应与连续渐变的高程值相同)


你确定x、y、z点构成了一个单一的表面吗?而且你说“非结构化数据”,但是这些数据看起来高度结构化。你指的是什么? - tom10
我的意思是它不是按网格排列的。我会把它去掉,因为我看到这很令人困惑。 - kilojoules
确保重塑后的新尺寸与旧数据兼容。在这种情况下,您的 dat['var1'] 的大小为11,而您正在尝试将其重塑为3X5。也许您需要填补某些“var1”和“var2”的组合中缺失的值。 - hashmuke
@hashmuke 抱歉,我对问题进行了大量编辑,所以您的评论不再相关。感谢您的评论,它帮助我完善了我的问题。 - kilojoules
1个回答

2
这里的问题在于facecolors没有像预期的那样进行规范化。尝试使用以下方法来显式地进行规范化:
norm = matplotlib.colors.Normalize()
surf = ax1.plot_surface(xig, yig, zi, facecolors=cm.rainbow(norm(ci)))

enter image description here


谢谢!为什么这里有 j:grid_x, grid_y = np.mgrid[0:1:100j, 0:1:100j]?是否有一种方法可以对任何 X、Y 数据进行操作?看起来你的解决方案受限于我的示例范围。 - kilojoules
谢谢您的回答。我将其保留未勾选,因为我正在寻找解决这个普遍问题的方法。 - kilojoules
你的颜色条出现了某种原因导致的20倍偏差。 - kilojoules
@kilojoules:我已经更新了我的答案。在我的更新中,代码中的所有内容都与您的代码相同,除了显示的行。 (特别是,您的术语“(xi [None,:],yi [:,None])”,我最初认为是问题,似乎很好。) - tom10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接