【问题标题】:Python/Matplotlib - Contour Plot with Bilinear InterpolationPython/Matplotlib - 双线性插值的等高线图
【发布时间】:2013-09-11 20:25:13
【问题描述】:

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

但是,一般来说,我需要它适用于任何数据集,因此仅适用于这种特殊情况的解决方案是没有用的。下面的数据中有一个稍微复杂的示例,注释为“另一个示例”。

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

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

【问题讨论】:

  • 你有什么问题?
  • 另外,我认为 2D 数据的“线性”插值是双线性的。
  • 我最初认为 2D 上的线性插值也是双线性的。但实际上,双线性并不是线性的,因为它是两个线性函数相乘的结果。如果您查看图表,结果是不正确的(与维基百科的链接图像不同,我已经确认是正确的)。我的问题是如何正确制作这个情节。

标签: python matplotlib interpolation


【解决方案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()

【讨论】:

  • ticks[1:-1] 的目的是什么?是不是相当于level?
  • 刻度是一个列表,所以这里不包括第一个和最后一个点,它们是Z方向的最小和最大点。轮廓函数的第 4 个参数是绘制水平线的位置,因此没有理由在最小和最大点绘制它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
相关资源
最近更新 更多