使用 Matplotlib 将内插 3D 数据绘制为 2D 图像 [英] Plotting Interpolated 3D Data As A 2D Image using Matplotlib

查看:54
本文介绍了使用 Matplotlib 将内插 3D 数据绘制为 2D 图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据集由包含 pandas DataFrames 的列表 dfList 组成,每个 DataFrame 由该列组成 Y 和相同的 index 列.我正在尝试将所有DataFrame绘制为2D图,并用像素颜色表示 Y 值.

所需情节风格示例

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

我添加了一个链接到 dfListpickle.dump 以重现问题.任何帮助表示赞赏!

Matploblib图片

代码

导入scipy#网格xgrid = dfList [0] .index.tolist()ygrid = np.linspace(266, 1, 532)Xgrid,Ygrid = np.meshgrid(xgrid,ygrid)# 积分xo = dfList [0] .index.tolist()yo = [266, 300, 350, 400, 450, 500, 532] # 每个 DataFrame 一个点 = [ [x, y] for y in yo for x in xo]点= np.array(点)#值值= []对于 dfList 中的 df:values.extend(df ['Y'].real)#值= [用于df ['Y']的项.用于dfList中df的项]#折叠列表的更快方法值 = np.array(values)# 网格数据重新采样= scipy.interpolate.griddata(点,值,(Xgrid,Ygrid),method ='cubic')plt.imshow(重新采样的T,范围= [365,1099,266,532],原点=较低")

dfList:Pickle Dump

<小时>现在是问题及其解决方案.

步骤 1. 创建一个

步骤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)导入scipy.interpolate导入matplotlib.pyplot作为plt将熊猫作为pd导入a = np.random.rand(532,7)dfList = [pd.DataFrame(a[:,i], columns=["Y"]) for i in range(7)]#网格xgrid = dfList [0] .index.valuesygrid = np.arange(266,532)Xgrid,Ygrid = np.meshgrid(xgrid,ygrid)# 积分xo = dfList[0].index.tolist()yo = [266, 300, 350, 400, 450, 500, 532] # 每个 DataFrame 一个点 = [ [x, y] for y in yo for x in xo]点数 = np.array(点数)打印点.shape#值值= []对于dfList中的df:values.extend(df ['Y'].real)值 = np.array(values)#网格数据resampled = scipy.interpolate.griddata(points, values, (Xgrid.T, Ygrid.T), method='cubic')重新取样打印plt.imshow(resampled.T,范围= [365,1099,266,532],origin ='lower')#,plt.show()

The data set is made of a list dfList containing pandas DataFrames, each DataFrame consisting of the column Y and an identical index column. I am trying to plot all the DataFrames as a 2D plot with pixel color representing the Y values.

Example of the Style of Plot Needed

Problem: However, using scipy.interpolate.griddata with matplotlib.pyplot.imshow produces a blank plot! What might be the problem?

I have added a link to the pickle.dump of dfList for reproducing the problem. Any help appreciated!!

Matploblib Image

Code

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: Pickle Dump

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

解决方案

To make this answer somehow useful for other people, find here first a general explanation. Below there is a more concrete solution to the question.

The general explanation, np.meshgrid vs. np.mgrid in the use with scipy.interpolate.griddata.

I here provide an example which compares the use of np.meshgrid with np.mgrid when it comes to interpolation with scipy.interpolate.griddata. Gnerally speaking, the returns of np.meshgrid are the transposed returns of np.mgrid for the same grid.

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


Now to the question and its solution.

Step 1. Create a MCVE

(can be omitted, since more experienced users create those themselves when asking a question)

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

creates

Step 2. The Problem.

We see a blank plot with only a small line of dots in the left handside of the image, while we would expect the complete graph to be filled with an image of shape (266, 532).

Step 3. The solution.

Using scipy.interpolate.griddata we need to supply the grids to the xi argument as a tuple (Xgrid.T, Ygrid.T), where the grids are generated via numpy.meshgrid: Xgrid, Ygrid = np.meshgrid(xgrid, ygrid). Note that meshgrid is different from numpy.mgrid.

There are some other inconsistencies with the points of the meshgrid compared to the sample points, so here I assume that you want to have the values between 266 and 532 being interpolated.

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

这篇关于使用 Matplotlib 将内插 3D 数据绘制为 2D 图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆