【问题标题】:Plotting Interpolated 3D Data As A 2D Image using Matplotlib使用 Matplotlib 将插值的 3D 数据绘制为 2D 图像
【发布时间】:2017-08-26 13:59:44
【问题描述】:

数据集由包含pandasDataFrames的列表dfList组成,每个DataFrame由Y列和一个相同的index列组成。我正在尝试将所有 DataFrame 绘制为 2D 图,像素颜色代表 Y 值。

所需的情节风格示例

问题:但是,将scipy.interpolate.griddata 与matplotlib.pyplot.imshow 一起使用会产生空白图!可能是什么问题?

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

Matploblib 图像

代码

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)

【问题讨论】:

  • 这个问题真的和一些腌制的数据框有关吗?或者它可以be reproduced使用一些模型数据吗?
  • @ImportanceOfBeingErnest 我腌制了数据dfList,以便可以复制。使用酸洗前的原始数据存在问题。

标签: python python-2.7 matplotlib plot scipy


【解决方案1】:

为了让这个答案对其他人有用,请先在此处找到一般解释。下面有一个更具体的问题解决方案。

一般解释,np.meshgrid vs. np.mgrid 与scipy.interpolate.griddata 一起使用。

我在这里提供了一个示例,它比较了np.meshgrid 和np.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()


现在是问题及其解决方案。

步骤 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()

创造

第 2 步。问题。

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

第 3 步。解决方案。

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

与采样点相比,网格网格的点还存在一些其他不一致之处,因此我假设您希望对 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()

【讨论】:

  • 谢谢。这救了我的命!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 2021-12-12
  • 2014-05-21
  • 2016-01-21
  • 1970-01-01
相关资源
最近更新 更多