使用Matplotlib将插值的3D数据绘制为2D图像

时间:2017-04-01 09:42:16

标签: python python-2.7 matplotlib plot scipy

数据集由包含dfList pandas的列表DataFrames组成,每个DataFrameY列和相同的index组成}列。我试图将所有DataFrames绘制为2D图,其中像素颜色代表Y值。

需要的绘图风格示例

enter image description here

问题:然而,将scipy.interpolate.griddatamatplotlib.pyplot.imshow一起使用会产生一个空白的情节!可能是什么问题?

我添加了pickle.dump dfList的链接以重现问题。任何帮助表示赞赏!!

Matploblib图片 enter image description here

代码

import scipy

# Meshgrid
xgrid = dfList[0].index.tolist()
ygrid = np.linspace(266, 1, 532)
Xgrid, Ygrid = np.meshgrid(xgrid, ygrid)

# Points
xo = dfList[0].index.tolist()
yo = [266, 300, 350, 400, 450, 500, 532]    # one for each DataFrame
points = [ [x, y] for y in yo for x in xo]
points = np.array(points)

# Values
values = []
for df in dfList:
    values.extend(df['Y'].real)
# values = [ item for item in df['Y'].real for df in dfList]    # faster way of collapsing list
values = np.array(values)

# Griddata
resampled = scipy.interpolate.griddata(points, values, (Xgrid, Ygrid), method='cubic')

plt.imshow(resampled.T, extent=[365,1099,266,532], origin='lower')

dfList:泡菜转储

https://gist.githubusercontent.com/anonymous/06076ecda9afcacfffd92b965996fe3e/raw/658e6157388ddedfe8882c2ad6c8f89af1eee5ac/dfList%2520(pickle%2520dump)

1 个答案:

答案 0 :(得分:1)

为了使这个答案在某种程度上对其他人有用,请先在此处找到一般性解释。下面是一个更具体的问题解决方案。

使用np.meshgrid时的一般解释,np.mgridscipy.interpolate.griddata

我在这里提供了一个示例,用于比较np.meshgridnp.mgrid在使用scipy.interpolate.griddata进行插值时的使用情况。一般来说,np.meshgrid的回报是np.mgrid对同一网格的转置回报。

import numpy as np; np.random.seed(0)
import scipy.interpolate
import matplotlib.pyplot as plt

# np. meshgrid
xgrid = np.arange(21)[::2]
ygrid = np.linspace(0,5,6)
Xgrid, Ygrid = np.meshgrid(xgrid, ygrid)

# np. mgrid
Xgrid2, Ygrid2 = np.mgrid[0:20:11j,0:5:6j]

# points for interpolation
points = np.random.rand(200, 2)
points[:,0] *= 20 
points[:,1] *= 5

# values
f = lambda x,y: np.sin(x)+ y
values = f(points[:,0], points[:,1])

# initerpolation using grid defined with np.meshgrid
resampled = scipy.interpolate.griddata(points, values, (Xgrid2, Ygrid2), method='cubic')

# interpolation using grid defined with np.mgrid
resampled2 = scipy.interpolate.griddata(points, values, (Xgrid.T, Ygrid.T), method='cubic')


fig, (ax1, ax2, ax3) = plt.subplots(3,1)
kws = dict( extent=[-1,21,-0.5,5.5], vmin=-1, vmax=6, origin="lower")
ax1.set_title("function evaluated on grid")
ax1.imshow(f(Xgrid, Ygrid), **kws)

ax2.set_title("interpolation using grid defined with np.meshgrid")
ax2.imshow(resampled.T, **kws)

ax3.set_title("interpolation using grid defined with np.mgrid")
ax3.imshow(resampled2.T, **kws)

for ax in (ax1, ax2, ax3):
    ax.set_yticks(range(6))
    ax.set_xticks(range(21)[::2])

plt.tight_layout()
plt.show()

enter image description here

<小时/> 现在问题及其解决方案。

步骤1.创建MCVE

(可省略,因为更有经验的用户在提问时自己创建)

import numpy as np; np.random.seed(0)
import scipy.interpolate
import matplotlib.pyplot as plt
import pandas as pd

a = np.random.rand(532, 7)
dfList = [pd.DataFrame(a[:,i], columns=["Y"]) for i in range(7)]

# Meshgrid
xgrid = dfList[0].index.tolist()
ygrid = np.linspace(266, 1, 532)
Xgrid, Ygrid = np.meshgrid(xgrid, ygrid)

# Points
xo = dfList[0].index.tolist()
yo = [266, 300, 350, 400, 450, 500, 532]    # one for each DataFrame
points = [ [x, y] for y in yo for x in xo]
points = np.array(points)

# Values
values = []
for df in dfList:
    values.extend(df['Y'].real)

values = np.array(values)

# Griddata
resampled = scipy.interpolate.griddata(points, values, (Xgrid, Ygrid), method='cubic')

plt.imshow(resampled.T, extent=[365,1099,266,532], origin='lower')
plt.show()

创建

enter image description here

第2步。问题。

我们看到一个空白的情节,图像的左侧只有一小部分点,而我们希望整个图形填充一个形状为(266, 532)的图像。

第3步。解决方案。

使用scipy.interpolate.griddata我们需要将网格作为元组xi提供给(Xgrid.T, Ygrid.T)参数,其中网格是通过numpy.meshgridXgrid, Ygrid = np.meshgrid(xgrid, ygrid)生成的。请注意,meshgridnumpy.mgrid不同。

与样本点相比,meshgrid的点存在一些其他不一致性,因此我假设您希望插入266和532之间的值。

import numpy as np; np.random.seed(0)
import scipy.interpolate
import matplotlib.pyplot as plt
import pandas as pd

a = np.random.rand(532, 7)
dfList = [pd.DataFrame(a[:,i], columns=["Y"]) for i in range(7)]

# Meshgrid
xgrid = dfList[0].index.values
ygrid = np.arange(266,532)
Xgrid, Ygrid = np.meshgrid(xgrid, ygrid)

# Points
xo = dfList[0].index.tolist()
yo = [266, 300, 350, 400, 450, 500, 532]    # one for each DataFrame
points = [ [x, y] for y in yo for x in xo]
points = np.array(points)
print points.shape

# Values
values = []
for df in dfList:
    values.extend(df['Y'].real)
values = np.array(values)

# Griddata
resampled = scipy.interpolate.griddata(points, values, (Xgrid.T, Ygrid.T), method='cubic')
print resampled.T.shape
plt.imshow(resampled.T, extent=[365,1099,266,532], origin='lower') #, 

plt.show()

enter image description here