Python / Matplotlib - 双线性插值的轮廓图

时间:2013-09-11 20:25:13

标签: python matplotlib interpolation

我想制作一个2D数据图,其中的值由双线性插值确定。作为初步测试,我决定只使用维基百科页面中的示例: http://en.wikipedia.org/wiki/File:Bilininterp.png

但是,一般情况下,我需要将其用于任何数据集,因此仅适用于此特殊情况的解决方案无用。稍微复杂的例子在下面的数据中,被注释为“另一个例子”。

以下是我迄今为止所做的几次尝试,其中的评论提到了为什么它不起作用:

import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

# http://en.wikipedia.org/wiki/File:Bilininterp.png
xi = np.array([0.0, 1.0])
yi = np.array([0.0, 1.0])
zi = np.array([[0.0, 1.0], [1.0, 0.5]])

# Another example
#xi = np.array([0.0, 0.25, 1.0])
#yi = np.array([0.0, 0.75, 1.0])
#zi = np.array([[0.0, 0.5, 1.0], [0.5, 0.7, 0.5], [1.0, 1.0, 1.0]])

# I want 20 "levels" to be shown
contour_breaks = 20
ticks = np.linspace(zi.min(), zi.max(), contour_breaks, endpoint=True)

# Attempt #1 (contour does not use bilinear interpolation)
fig = plt.figure()
axes = fig.add_subplot(111, aspect='equal')
axes.contour(xi, yi, zi, ticks[1:-1], colors='k')
fill = axes.contourf(xi, yi, zi, ticks, cmap=cm.jet)
fig.colorbar(fill, ticks=ticks)

# Attempt 2 (colors are weird for imshow -- they don't seem to be jet.  I can't
#            make it use ticks to make constant color zones/levels.  The contour
#            lines are the same as before (no bilinear).  Also, you cannot input
#            xi and yi, so the data would have to be interpolated to a regular
#            grid - see the second set of example data above for an example
#            where the data isn't regularly spaced)
fig = plt.figure()
axes = fig.add_subplot(111, aspect='equal')
axes.contour(xi, yi, zi, ticks[1:-1], colors='k')
fill = axes.imshow(zi, interpolation='bilinear', cmap=cm.jet,
                   extent=(0.,1.,0.,1.))
fig.colorbar(fill, ticks=ticks)

# Attempt 3 (griddata doens't do bilinear interpolation)
fig = plt.figure()
axes = fig.add_subplot(111, aspect='equal')
xi1, yi1 = np.meshgrid(xi, yi)
xi1 = xi1.flatten()
yi1 = yi1.flatten()
zi1 = zi.flatten()
xi2 = np.linspace(0., 1., 100)
yi2 = np.linspace(0., 1., 100)
zi2 = griddata((xi1, yi1), zi1, (xi2[None,:], yi2[:,None]), method='linear')
axes.contour(xi2, yi2, zi2, ticks[1:-1], colors='k')
fill = axes.contourf(xi2, yi2, zi2, ticks, cmap=cm.jet)
fig.colorbar(fill, ticks=ticks)

# Show the plots
plt.show()

1 个答案:

答案 0 :(得分:1)

这个似乎有效。

import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
from scipy.interpolate import interp2d

# http://en.wikipedia.org/wiki/File:Bilininterp.png
xi = np.array([0.0, 1.0])
yi = np.array([0.0, 1.0])
zi = np.array([[0.0, 1.0], [1.0, 0.5]])

# Another example
xi = np.array([0.0, 0.25, 1.0])
yi = np.array([0.0, 0.75, 1.0])
zi = np.array([[0.0, 0.5, 1.0], [0.5, 0.7, 0.5], [1.0, 1.0, 1.0]])

# I want 20 "levels" to be shown
contour_breaks = 20
ticks = np.linspace(zi.min(), zi.max(), contour_breaks, endpoint=True)

# Attempt 4 (interp2d does to correct bilinear interpolation)
fig = plt.figure()
axes = fig.add_subplot(111, aspect='equal')
f = interp2d(xi, yi, zi, kind='linear')
xi2 = np.linspace(0., 1., 100)
yi2 = np.linspace(0., 1., 100)
zi2 = f(xi2, yi2)
axes.contour(xi2, yi2, zi2, ticks[1:-1], colors='k')
fill = axes.contourf(xi2, yi2, zi2, ticks, cmap=cm.jet)
fig.colorbar(fill, ticks=ticks)

# Show the plots
plt.show()