将Scatter转换为Contour,每个点都变成高地

时间:2017-11-14 00:21:23

标签: python numpy matplotlib interpolation

如何基于散点图构建轮廓图(特别是地形图),以便将每个散点图转换为圆形区域,该区域是给定半径中的最高区域,即任何相邻区域都低于原点的区域?

在示例性图像上,黄色邻接区域低于高地#6。请注意,我不是要构建数据密度图。

Exemplary image

所有输入散点都高于绿草水平。

我尝试使用问题Make contour of scatter中提出的matplotlib的griddata插入x,y和z坐标。 在第二个图中,您可以看到插值后生成的原始叠加散点图和等高线图。然而,点#6并不像第一张图像那样最高,而白雪皑皑的山峰则从原来的白点#1转移。

Superimposed Scatter and wrong Contour plots

这是我的坐标:

x = [34, 74, 34, 70, 4, 42, 10, 56, 50, 0, 15, 104, 53, 27]
y = [44, 52, 21, 25, 34, 54, 70, 77, 0, 50, 5, 53, 18, 86]
z = [0.9, 0.8, 0.8, 0.8, 0.7, 0.7, 0.7, 0.7, 0.7, 0.6, 0.6, 0.6, 0.6, 0.6]

任何想法都受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

我使用bivariate_normal函数来获取每个点的高程。以下是尝试的工作代码:

import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

# data
x = np.array([34, 74, 34, 70, 4, 42, 10, 56, 50, 0, 15, 104, 53, 27])
y = np.array([44, 52, 21, 25, 34, 54, 70, 77, 0, 50, 5, 53, 18, 86])
z = np.array([0.9, 0.8, 0.8, 0.9, 0.7, 0.7, 0.7, 0.7, 0.7, 0.6, 0.6, 0.6, 0.6, 0.6])

# the radius that needs to specified for each point
# radius = sigmax=sigmay for bivariate_normal
#rad = [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]  # OK
rad = [4, 6, 7, 3, 5, 5, 7, 6, 6, 7, 6, 7, 6, 7]   # better

# get limits of plot
xmin, xmax = x.min(), x.max()
ymin, ymax = y.min(), y.max()

# some settings
delta = 0.5

# create mesh grid for plotting area
xs = np.arange(xmin-delta, xmax+delta*2, delta)
ys = np.arange(ymin-delta, ymax+delta*2, delta)
XX, YY = np.meshgrid(xs, ys)

# compute elevation Z for each point in the grid mesh
ZZ=0
for mx, my, mz, mr in zip(x, y, z, rad):
    sigmax = mr
    sigmay = mr
    vm = mlab.bivariate_normal(0, 0, sigmax, sigmay, 0, 0)  # max value

    # mz and vm are used to correct the elevation obtained from bivar-normal
    ZZ += mlab.bivariate_normal(XX, YY, sigmax, sigmay, mx, my) * mz / vm

# prep fig, ax
fig = plt.figure(figsize=(9, 9))
ax = fig.add_subplot(111)

# choose cmap as you need
ctf=plt.contourf(XX, YY, ZZ, linewidth=1, cmap=cm.gist_earth_r)
plt.scatter(x, y, s=rad, color='r', zorder=10)

plt.xlim(xmin-delta, xmax+delta)
plt.ylim(ymin-delta, ymax+delta)

plt.colorbar(ctf)
plt.show()

结果图:

enter image description here