【发布时间】:2018-01-26 10:18:03
【问题描述】:
我的目标是获得一个二维数组(即矩阵)的浮点数,它可以被可视化为具有平滑轮廓的数字高程模型(即等高线图) > 如下图所示,前提是我能够控制每次运行脚本时生成多少个白山以及它们之间的距离。
白色山脉表示 CSV 文件中包含大于 0.9 的值的单元格簇,如色标所示。在图中,我们看到两座山被低于 0.9 的区域划分。 这是我使用卷积过滤器创建这样一个图像的详细 cmets 的完整代码:
import numpy as np
import pandas as pd
from scipy import signal
import plotly
import plotly.graph_objs as go
def rndmtx():
"""Generate random 2d-array as a digital elevation model."""
nx = 100
ny = 100
dem1 = np.random.rand(nx, ny)
# Save array to csv file befor Gaussian filter.
# Comment the next two lines if reading from the csv file.
dafr = pd.DataFrame(dem1)
dafr.to_csv('G_dem1.csv', header=False, index=False)
# Uncomment the next two lines to read from csv file.
# dafr = pd.read_csv('G_dem1.csv', header=None)
# dem1 = dafr.values
# Apply the first Gaussian filter.
sizex = 5 # The less sizex and sizey the more highlands.
sizey = 5 # The more sizex and sizey the more water.
x, y = np.mgrid[-sizex:sizex+1, -sizey:sizey+1]
scale = 0.33 # The more scale the bigger the difference in elevation.
g = np.exp(-scale*(x**2/sizex+y**2/sizey))
filter1 = g/g.sum() # Normalise the Gaussian function.
dem_smooth = signal.convolve(dem1, filter1, mode='valid')
# Rescale so it lies between 0 and 1.
dem_smooth = ((dem_smooth - dem_smooth.min())
/ (dem_smooth.max() - dem_smooth.min()))
# Apply the second Gaussian filter to make the boundaries smoother.
sizex = 5
sizey = 5
x, y = np.mgrid[-sizex:sizex+1, -sizey:sizey+1]
g = np.exp(-0.33*(x**2/sizex+y**2/sizey))
filter2 = g/g.sum()
dem_smooth1 = signal.convolve(dem_smooth, filter2, mode='valid')
dem_smooth1 = ((dem_smooth1 - dem_smooth1.min())
/ (dem_smooth1.max() - dem_smooth1.min()))
return dem_smooth1
# Get the raw random array of the digital elevation model
# and assign it to the variable.
contour_xy = rndmtx()
# Save the array into CSV file in the working directory.
df = pd.DataFrame(contour_xy)
df.to_csv('last_data.csv', header=False, index=False)
data = [
go.Contour(
z=contour_xy,
colorscale=[
[0, 'rgb(0, 161, 233)'], [0.28, 'rgb(0, 161, 233)'],
[0.28, 'rgb(29, 210, 108)'], [0.50, 'rgb(29, 210, 108)'],
[0.50, 'rgb(141, 232, 130)'], [0.65, 'rgb(141, 232, 130)'],
[0.65, 'rgb(254, 254, 152)'], [0.75, 'rgb(254, 254, 152)'],
[0.75, 'rgb(192, 182, 122)'], [0.82, 'rgb(192, 182, 122)'],
[0.82, 'rgb(142, 110, 92)'], [0.88, 'rgb(142, 110, 92)'],
[0.88, 'rgb(171, 147, 142)'], [0.93, 'rgb(171, 147, 142)'],
[0.93, 'rgb(227, 219, 217)'], [0.97, 'rgb(227, 219, 217)'],
[0.97, 'rgb(255, 255, 255)'], [1, 'rgb(255, 255, 255)']
],
),
]
layout = go.Layout(
yaxis=dict(
autorange='reversed'
)
)
figure = go.Figure(data=data, layout=layout)
plotly.offline.plot(figure, filename='dem.html')
每次我运行脚本时,我都会得到一个唯一的随机数字数组。
如何控制要生成的白山的数量和距离?
例如,现在我想要在地块上放置 10 座白山,那么我只想要 2 座山,以此类推。
目前,我使用蛮力算法最终构建具有所需山脉数量的绘图,但我无法设置山脉的特定坐标来控制它们之间的距离。
高度赞赏慷慨的答案和指出正确的方向。喜欢玩代码!
【问题讨论】:
-
有一种非常粗暴的方法,当您生成数字时,最多只能生成 0.9(不包括在内),然后再以 0.9-1.0 的值重新计算,并覆盖地图上的许多随机空间。这里有一些极端情况,你可能会得到不太理想的输出,但严格来说你会得到你想要的。
标签: python arrays pandas numpy scipy