Nic*_*ams 5 python matplotlib contour
我在matplotlib中生成地下水高程轮廓和streamplot
轮廓表明许多地区的海拔正在下降,但地下水流(streamplot)指向上坡.我已经盘旋了似乎指向错误方向的箭头.
朝向地图底部的箭头似乎指向正确的方向.有谁知道为什么会这样?

以下是生成此图的大部分代码:
#create empty arrays to fill up!
x_values = []
y_values = []
z_values = []
#iterate over wells and fill the arrays with well data
for well in well_arr:
x_values.append(well['xpos'])
y_values.append(well['ypos'])
z_values.append(well['value'])
#initialize numpy array as required for interpolation functions
x = np.array(x_values, dtype=np.float)
y = np.array(y_values, dtype=np.float)
z = np.array(z_values, dtype=np.float)
#create a list of x, y coordinate tuples
points = zip(x, y)
#create a grid on which to interpolate data
xi, yi = np.linspace(0, image['width'], image['width']),
np.linspace(0, image['height'], image['height'])
xi, yi = np.meshgrid(xi, yi)
#interpolate the data with the matlab griddata function
zi = griddata(x, y, z, xi, yi, interp='nn')
#create a matplotlib figure and adjust the width and heights
fig = plt.figure(figsize=(image['width']/72, image['height']/72))
#create a single subplot, just takes over the whole figure if only one is specified
ax = fig.add_subplot(111, frameon=False, xticks=[], yticks=[])
#create the contours
kwargs = {}
if groundwater_contours:
kwargs['colors'] = 'b'
CS = plt.contour(xi, yi, zi, linewidths=linewidth, **kwargs)
#add a streamplot
dx, dy = np.gradient(zi)
plt.streamplot(xi, yi, dx, dy, color='c', density=1, arrowsize=3)
Run Code Online (Sandbox Code Playgroud)
Joe*_*ton 18
我猜,但你的问题可能是因为你有一个固有的转置正在进行.2D numpy数组被索引为行,列."x,y"索引是列,行.在这种情况下,numpy.gradient基本上将返回dy,dx而不是dx,dy.
尝试更改线路:
dx, dy = np.gradient(zi)
Run Code Online (Sandbox Code Playgroud)
至:
dy, dx = np.gradient(zi)
Run Code Online (Sandbox Code Playgroud)
此外,如果您的深度定义为正向,则应为:
dy, dx = np.gradient(-zi)
Run Code Online (Sandbox Code Playgroud)
但是,我假设你有正向深度约定,所以我将留下以下部分示例.(因此,在下面的示例数据中,假设更高的值更深/更低,并且水将流向高值.)
例如,如果我们修改您使用随机数据的代码并填写一些来自代码示例范围之外的变量(以便它是一个独立的示例):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.mlab import griddata
# Generate some reproducible but random data
np.random.seed(1981)
width, height = 200, 300
x, y, z = np.random.random((3,10))
x *= width
y *= height
#create a list of x, y coordinate tuples
points = zip(x, y)
#create a grid on which to interpolate data
xi, yi = np.linspace(0, width, width), np.linspace(0, height, height)
xi, yi = np.meshgrid(xi, yi)
#interpolate the data with the matlab griddata function
zi = griddata(x, y, z, xi, yi, interp='nn')
#create a matplotlib figure and adjust the width and heights
fig = plt.figure()
#create a single subplot, just takes over the whole figure if only one is specified
ax = fig.add_subplot(111, frameon=False, xticks=[], yticks=[])
#create the contours
CS = plt.contour(xi, yi, zi, linewidths=1, colors='b')
#add a streamplot
dx, dy = np.gradient(zi)
plt.streamplot(xi, yi, dx, dy, color='c', density=1, arrowsize=3)
plt.show()
Run Code Online (Sandbox Code Playgroud)
结果将如下所示:

请注意,有许多地方的流线不垂直于轮廓.这是一个更容易的指标,而不是错误的箭头方向,这是错误的.(尽管"垂直"假设绘图的纵横比为1,除非您设置它,否则这些绘图并不完全正确.)
如果我们只是改变线
dx, dy = np.gradient(zi)
Run Code Online (Sandbox Code Playgroud)
至:
dy, dx = np.gradient(zi)
Run Code Online (Sandbox Code Playgroud)
我们会得到正确的结果:

另外,griddata在这种情况下,这是一个糟糕的选择.
首先,它不是"平滑"插值方法.它使用delaunay三角剖分,在三角形边界处形成"尖锐"的脊.这导致这些位置的异常梯度.
其次,它限制了对数据点的凸包的插值,这可能是也可能不是一个好的选择.
径向基函数(或任何其他平滑插值)是插值的更好选择.
例如,如果我们修改您的代码段以使用RBF:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf
# Generate data
np.random.seed(1981)
width, height = 200, 300
x, y, z = np.random.random((3,10))
x *= width
y *= height
#create a grid on which to interpolate data
xi, yi = np.mgrid[0:width:1j*width, 0:height:1j*height]
#interpolate the data with the matlab griddata function
interp = Rbf(x, y, z, function='linear')
zi = interp(xi, yi)
#create a matplotlib figure and adjust the width and heights
fig, ax = plt.subplots(subplot_kw=dict(frameon=False, xticks=[], yticks=[]))
#create the contours and streamplot
CS = plt.contour(xi, yi, zi, linewidths=1, colors='b')
dy, dx = np.gradient(zi.T)
plt.streamplot(xi[:,0], yi[0,:], dx, dy, color='c', density=1, arrowsize=3)
plt.show()
Run Code Online (Sandbox Code Playgroud)

(你会注意到由于绘图的不相等的宽高比,交点不是很垂直.如果我们将绘图的纵横比设置为1,它们都是90度.)
作为两种方法的并排比较:

| 归档时间: |
|
| 查看次数: |
3137 次 |
| 最近记录: |