Convert Scatter to Contour, every dot turns into a highland

╄→尐↘猪︶ㄣ 提交于 2020-01-16 09:11:31

问题


How to build a Contour plot (specifically, topographic map) based on a Scatter plot, so that every scatter dot is converted into a circular area being the highest one in a given radius, i.e., any adjoining area is lower than the original dot’s area?

On the exemplary image, the yellow adjoining area is lower than the highland #6. Note, I am not trying to build a data density plot.

All input scatter dots are higher than the green grass level.

I tried to interpolate the x, y, and z coordinates using matplotlib’s griddata as proposed in question Make contour of scatter. On the second figure you see the original superimposed scatter plot and contour plot generated after interpolation. However, the dot #6 is not the highest one like it is on the first image, and the snow-capped mountain is shifted from the original white dot #1.

Here are my coordinates:

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]

Any ideas are highly appreciated.


回答1:


I use bivariate_normal function to get elevation for each point. Here is the working code to try:

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

The resulting plot:



来源:https://stackoverflow.com/questions/47275712/convert-scatter-to-contour-every-dot-turns-into-a-highland

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!