使用pcolormesh时如何通过插值平滑?

Posted

技术标签:

【中文标题】使用pcolormesh时如何通过插值平滑?【英文标题】:How to smooth by interpolation when using pcolormesh? 【发布时间】:2016-10-15 19:55:25 【问题描述】:

我有一张世界底图,它使用 pcolormesh 填充了数据 (lintrends_mean)。因为数据有比较大的网格框,所以我想平滑绘图。但是,我无法弄清楚如何做到这一点。在绘图函数中设置 shading='gouraud' 会模糊网格框的边缘,但我想要比这更好看的东西,因为数据仍然出现斑点。

这里有一个类似的问题,并给出了答案,但我不明白答案,尤其是“newdepth”的来源。由于我缺乏声誉,因此我也无法对此发表评论以进行澄清。 interpolation with matplotlib pcolor

#Set cmap properties
bounds = np.array([0.1,0.2,0.5,1,2,3,4,6,9,13,20,35,50])
norm = colors.LogNorm(vmin=0.01,vmax=55) #creates logarithmic scale
#cmap.set_under('#000099') # I want to use this- edit in Paint
cmap.set_over('#660000')  # everything above range of colormap

fig = plt.figure(figsize=(15.,10.))                     #create figure & size
m = Basemap(projection='cyl',llcrnrlat=-90,urcrnrlat=90,llcrnrlon=0,urcrnrlon=360.,lon_0=180.,resolution='c') #create basemap & specify data area & res
m.drawcoastlines(linewidth=1)
m.drawcountries(linewidth=1)
m.drawparallels(np.arange(-90,90,30.),linewidth=0.3)
m.drawmeridians(np.arange(-180.,180.,90.),linewidth=0.3)            
meshlon,meshlat = np.meshgrid(lon,lat)                           #meshgrid turns lats & lons into 2D arrays
x,y = m(meshlon,meshlat)                                         #assign 2D arrays to new variables
trend = m.pcolormesh(x,y,lintrends_mean,cmap=plt.get_cmap('jet'),norm=norm) #plot the data & specify colormap & color range
cbar=m.colorbar(trend,size="3%", label='Linear Trend (mm/day/decade)',ticks=bounds,extend="max")
cbar.set_ticklabels(bounds)
plt.title('Linear Trends of PR (CanESM2 1979-2014)',fontsize=16)
plt.xlabel('Longitude',fontsize=10)
plt.ylabel('Latitude',fontsize=10)
plt.show()

【问题讨论】:

看起来块状的可能被认为是一个功能,而不是一个错误。它不会让您的数据看起来比实际更精细。 我知道阻塞不是错误。我的研究顾问刚刚建议我出于演示的原因平滑网格,我不喜欢仅应用 gouraud 着色的样子。 我建议在绘制比之前进行插值。它为您提供更多控制权。 【参考方案1】:

你有一些变体:

    pcolormesh 使用特殊阴影。 使用imshow 允许插值数据。 使用scipy.interpolate 插值数据并使用pcolormesh 绘图。

看例子:

import matplotlib.pylab as plt
import numpy as np
from scipy.interpolate import interp2d

data = np.random.random((30,30))
X = np.arange(0, 30, 1)
Y = np.arange(0, 30, 1)
X, Y = np.meshgrid(X, Y)

# colormesh original
plt.subplot(3, 2, 1)
plt.pcolormesh(X, Y, data, cmap='RdBu')

# pcolormesh with special shading
plt.subplot(3, 2, 2)
plt.pcolormesh(X, Y, data, cmap='RdBu',shading='gouraud')

# imshow bilinear interp.
plt.subplot(3, 2, 3)
plt.imshow(data, cmap='RdBu', interpolation = 'bilinear')

# imshow bicubic interp.
plt.subplot(3, 2, 4)
plt.imshow(data, cmap='RdBu', interpolation = 'bicubic')

# scipy interp. cubic
f = interp2d(X, Y, data, kind='cubic')
xnew = np.arange(0, 30, .1)
ynew = np.arange(0, 30, .1)
data1 = f(xnew,ynew)
Xn, Yn = np.meshgrid(xnew, ynew)
plt.subplot(3, 2, 5)
plt.pcolormesh(Xn, Yn, data1, cmap='RdBu')

plt.show()

【讨论】:

我无法使用 imshow 方法,因为这会导致我的数据无法跨越整个底图。在您的最后一个子图中,您的 X & Y in f = interp2d(X, Y, data, kind='cubic') 是否对应于我的 meshlon 和 meshlat? 是的,但它们必须是相同大小的二维数组 这种方法对我来说效果不太好。我在获取插值方案以很好地处理我的数据时遇到问题。对于三次插值,我收到错误“运行时警告:由于 B 样条的数量,不能再添加节点。系数已经超过数据点的数量 m。可能的原因:s 或 m 太小。”我不完全确定这意味着什么,但结果是一种靠近我的最高值的未填充数据的检查板。这是我的数据值的影响吗?不同的插值方法会更好吗? 另外,对于一些应该允许的插值,我得到了“不支持的插值类型”,比如“最近”、“双线性”和“双三次”,尽管“线性”可以正常工作。我正在使用 Python 2.7。我需要更新软件包吗?

以上是关于使用pcolormesh时如何通过插值平滑?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 ggplot2 geom_raster 中的插值/平滑

MATLAB画图怎么平滑?

如果我想要随机非结构化数据的 3D 样条/平滑插值怎么办?

如何在matlab中用样条函数平滑曲线

Python 自然平滑样条曲线

单击 pcolormesh 正方形的中心时使用 matplotlib 选择事件触发?