问题描述
数据集由包含 pandas
DataFrames
的列表 dfList
组成,每个 DataFrame
由该列组成 Y
和相同的 index
列.我正在尝试将所有DataFrame绘制为2D图,并用像素颜色表示 Y
值.
所需情节风格示例
问题:但是,将 scipy.interpolate.griddata
与 matplotlib.pyplot.imshow
一起使用会生成空白图!可能是什么问题?
我添加了一个链接到 dfList
的 pickle.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
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 图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!