Spaces:
Runtime error
Runtime error
Include app and source code
Browse files- README.md +25 -0
- app.py +76 -0
- requirements.txt +3 -0
- source/fields.py +168 -0
- source/maps.py +91 -0
- source/visualization_tools.py +68 -0
README.md
CHANGED
@@ -11,4 +11,29 @@ license: mit
|
|
11 |
short_description: Generate procedural geographic maps from random fields
|
12 |
---
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
11 |
short_description: Generate procedural geographic maps from random fields
|
12 |
---
|
13 |
|
14 |
+
# MapGenerator
|
15 |
+
|
16 |
+
Generate procedural geographic maps from random fields.
|
17 |
+
|
18 |
+
## Map generation
|
19 |
+
|
20 |
+
The process of map generation is as follows:
|
21 |
+
|
22 |
+
1. Generate a random field, choosing from the list of available random fields
|
23 |
+
2. Normalize the field between 0 and 1
|
24 |
+
3. Smooth the field with a gaussian filter
|
25 |
+
4. Retain only the mainland above a certain threshold
|
26 |
+
|
27 |
+
## Random fields
|
28 |
+
|
29 |
+
The available random fields are:
|
30 |
+
|
31 |
+
- `gauss`: Random gaussian field, with a given power spectrum, computed using the package [powerbox](https://powerbox.readthedocs.io/en/latest/index.html)
|
32 |
+
- `perlin`: Perlin noise, computed using the package [noise](https://pypi.org/project/noise/)
|
33 |
+
- `warped_perlin`: Perlin noise with domain warping, computed using the package [noise](https://pypi.org/project/noise/)
|
34 |
+
- `cos`: Sinusoidal noise (to be improved)
|
35 |
+
- `fbm`: Fractional Brownian Field
|
36 |
+
|
37 |
+
**See complete source code [here](https://github.com/PabloVD/MapGenerator/tree/master)**
|
38 |
+
|
39 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from source.visualization_tools import single_map
|
3 |
+
from PIL import Image
|
4 |
+
import io
|
5 |
+
import random
|
6 |
+
|
7 |
+
# Threshold for the sea level
|
8 |
+
threshold = 0.6
|
9 |
+
# Sigma for the gaussian smoothing
|
10 |
+
sigma = 5.
|
11 |
+
|
12 |
+
def generate_maps(kind_noise,boxsize,index,scale,octaves,persistence,lacunarity,make_island,deterministic):
|
13 |
+
|
14 |
+
if kind_noise=="gauss":
|
15 |
+
params = index
|
16 |
+
else:
|
17 |
+
params = [scale,octaves,persistence,lacunarity,boxsize]
|
18 |
+
|
19 |
+
if deterministic:
|
20 |
+
seeds = range(3)
|
21 |
+
else:
|
22 |
+
seeds = random.sample(range(1000),3)
|
23 |
+
|
24 |
+
images = []
|
25 |
+
|
26 |
+
for llavor in seeds:
|
27 |
+
fig = single_map(kind_noise,boxsize,llavor,params,sigma,threshold,make_island=make_island)
|
28 |
+
img_buf = io.BytesIO()
|
29 |
+
fig.savefig(img_buf, format='png')
|
30 |
+
|
31 |
+
img = Image.open(img_buf)
|
32 |
+
images.append(img)
|
33 |
+
|
34 |
+
return images
|
35 |
+
|
36 |
+
md ="""
|
37 |
+
# Map generator
|
38 |
+
|
39 |
+
Generate procedural geographic maps from random fields.
|
40 |
+
"""
|
41 |
+
|
42 |
+
|
43 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
44 |
+
|
45 |
+
gr.Markdown(md)
|
46 |
+
|
47 |
+
with gr.Accordion("General settings", open=True):
|
48 |
+
|
49 |
+
with gr.Row():
|
50 |
+
kind_noise = gr.Dropdown(["gauss", "perlin", "warped_perlin"], label="Random field", value="gauss")
|
51 |
+
boxsize = gr.Slider(100, 1000, value=500, label="Box size")#, info="Box size"),
|
52 |
+
make_island = gr.Checkbox(label="Island", info="Mark to ensure that boundaries are sea")
|
53 |
+
deterministic = gr.Checkbox(label="Deterministic", info="Mark to employ the same random seed")
|
54 |
+
|
55 |
+
with gr.Accordion("Gaussian field settings", open=False):
|
56 |
+
index = gr.Slider(-5, -1, value=-3, label="Spectral index")#, info="Spectral index"),
|
57 |
+
|
58 |
+
with gr.Accordion("Perlin field settings", open=False):
|
59 |
+
with gr.Row():
|
60 |
+
scale = gr.Slider(100, 1000, value=500, label="Scale")
|
61 |
+
octaves = gr.Slider(1, 10, value=6, label="Octaves", step=1)
|
62 |
+
persistence = gr.Slider(0, 1, value=0.5, label="Persistence")
|
63 |
+
lacunarity = gr.Slider(0.1, 10, value=2, label="Lacunarity")
|
64 |
+
|
65 |
+
|
66 |
+
inputs = [kind_noise,boxsize,index,scale,octaves,persistence,lacunarity,make_island,deterministic]
|
67 |
+
|
68 |
+
btn = gr.Button("Generate maps", scale=1)
|
69 |
+
|
70 |
+
gallery = gr.Gallery(label="Generated maps", show_label=False, elem_id="gallery", columns=[3], rows=[1], height="20vw")
|
71 |
+
|
72 |
+
btn.click(generate_maps, inputs=inputs, outputs=gallery)
|
73 |
+
|
74 |
+
|
75 |
+
if __name__ == "__main__":
|
76 |
+
demo.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
powerbox
|
2 |
+
noise
|
3 |
+
scipy
|
source/fields.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#---------------------------
|
2 |
+
# Field generator module
|
3 |
+
# PabloVD
|
4 |
+
# Started: 11/5/20
|
5 |
+
#---------------------------
|
6 |
+
|
7 |
+
"""
|
8 |
+
Collection of noise fields for generating maps.
|
9 |
+
Noises included are:
|
10 |
+
"gauss": Random gaussian field, with a given power spectrum, computed using the package powerbox
|
11 |
+
"perlin": Perlin noise, computed using the package noise
|
12 |
+
"warped_perlin": Perlin noise with domain warping, computed using the package noise
|
13 |
+
"cos": Sinusoidal noise (to be improved)
|
14 |
+
"fbm": Fractional Brownian Field
|
15 |
+
"""
|
16 |
+
|
17 |
+
import numpy as np
|
18 |
+
import powerbox as pbox
|
19 |
+
import noise
|
20 |
+
|
21 |
+
# Define power spectrum as a power law with an spectral index indexlaw
|
22 |
+
# With lower the spectral indexes (redder noise), small structures are removed
|
23 |
+
def powerspec(k,indexlaw=-3.):
|
24 |
+
return k**indexlaw
|
25 |
+
|
26 |
+
# Generate a Gaussian field with a power law power spectrum
|
27 |
+
def gaussian_field(boxsize,seed,indexlaw=-3.):
|
28 |
+
field = pbox.PowerBox(boxsize, lambda k: powerspec(k,indexlaw), dim=2, boxlength=1.,seed=seed).delta_x()
|
29 |
+
return field
|
30 |
+
|
31 |
+
# Generate a Perlin field
|
32 |
+
def perlin_field(boxsizex,seed,scale,octaves,persistence,lacunarity,boxsizey=None):
|
33 |
+
|
34 |
+
if boxsizey==None: boxsizey=boxsizex
|
35 |
+
shape = (boxsizex,boxsizey)
|
36 |
+
|
37 |
+
field = np.zeros(shape)
|
38 |
+
for i in range(shape[0]):
|
39 |
+
for j in range(shape[1]):
|
40 |
+
field[i,j] = noise.pnoise2(i/scale,
|
41 |
+
j/scale,
|
42 |
+
octaves=octaves,
|
43 |
+
persistence=persistence,
|
44 |
+
lacunarity=lacunarity,
|
45 |
+
#repeatx=1024,
|
46 |
+
#repeaty=1024,
|
47 |
+
base=seed)
|
48 |
+
return field
|
49 |
+
|
50 |
+
# 2D cosinus (see Hill noise for something similar but better https://blog.bruce-hill.com/hill-noise)
|
51 |
+
def cos_noise(X,Y,amp,frecx,frecy,phase):
|
52 |
+
return amp*np.cos( frecx*X +frecy*Y + phase)
|
53 |
+
#return Amp*(np.cos( frecx*X) +np.cos(frecy*Y + phase))
|
54 |
+
|
55 |
+
# Generate a noise using superposition of cosinus
|
56 |
+
def cos_field(boxsizex,seed,scale,octaves,persistence,lacunarity,boxsizey=None):
|
57 |
+
|
58 |
+
if boxsizey==None: boxsizey=boxsizex
|
59 |
+
np.random.seed(seed=seed)
|
60 |
+
|
61 |
+
frec0 = 5.
|
62 |
+
|
63 |
+
x, y = np.linspace(0,boxsizex,num=boxsizex), np.linspace(0,boxsizey,num=boxsizey)
|
64 |
+
X, Y = np.meshgrid(x,y)
|
65 |
+
|
66 |
+
noise_tot = np.zeros((boxsizex,boxsizey))
|
67 |
+
|
68 |
+
for oct in range(octaves):
|
69 |
+
Amp, frecx, frecy, phase = np.random.random(), 2.*np.pi*frec0*random.uniform(-1.,1.), 2.*np.pi*frec0*random.uniform(-1.,1.), 2.*np.pi*np.random.random()
|
70 |
+
noise_tot += persistence**oct*cos_noise(X/scale,Y/scale,Amp,frecx*lacunarity**oct,frecy*lacunarity**oct,phase)
|
71 |
+
|
72 |
+
return noise_tot
|
73 |
+
|
74 |
+
# Generate a Perlin field with warping domain (see e.g. https://iquilezles.org/www/articles/warp/warp.htm)
|
75 |
+
def warped_perlin_field(boxsizex,seed,scale,octaves,persistence,lacunarity,amplitude=None,boxsizey=None):
|
76 |
+
|
77 |
+
if boxsizey==None: boxsizey=boxsizex
|
78 |
+
shape = (boxsizex,boxsizey)
|
79 |
+
|
80 |
+
if amplitude==None: amplitude = np.random.uniform(0.,30.)
|
81 |
+
|
82 |
+
field = np.zeros(shape)
|
83 |
+
for i in range(shape[0]):
|
84 |
+
for j in range(shape[1]):
|
85 |
+
vec = np.random.rand(2)
|
86 |
+
ii = noise.pnoise2(i/scale,j/scale,octaves=octaves,persistence=persistence,lacunarity=lacunarity,base=seed)
|
87 |
+
jj = noise.pnoise2(i/scale,j/scale,octaves=octaves,persistence=persistence,lacunarity=lacunarity,base=seed)
|
88 |
+
field[i,j] = noise.pnoise2(i/scale + amplitude*ii,j/scale + amplitude*jj,octaves=octaves,persistence=persistence,lacunarity=lacunarity,base=seed)
|
89 |
+
return field
|
90 |
+
|
91 |
+
# Embedding of covariance function on a [0,R]^2 grid for fractional Brownian field
|
92 |
+
# From https://gist.github.com/radarsat1/6f8b9b50d1ecd2546d8a765e8a144631
|
93 |
+
def rho(x,y,R,alpha):
|
94 |
+
|
95 |
+
if alpha <= 1.5:
|
96 |
+
# alpha=2*H, where H is the Hurst parameter
|
97 |
+
beta = 0
|
98 |
+
c2 = alpha/2
|
99 |
+
c0 = 1-alpha/2
|
100 |
+
else:
|
101 |
+
# parameters ensure piecewise function twice differentiable
|
102 |
+
beta = alpha*(2-alpha)/(3*R*(R**2-1))
|
103 |
+
c2 = (alpha-beta*(R-1)**2*(R+2))/2
|
104 |
+
c0 = beta*(R-1)**3+1-c2
|
105 |
+
|
106 |
+
# create continuous isotropic function
|
107 |
+
r = np.sqrt((x[0]-y[0])**2+(x[1]-y[1])**2)
|
108 |
+
if r<=1:
|
109 |
+
out=c0-r**alpha+c2*r**2
|
110 |
+
elif r<=R:
|
111 |
+
out=beta*(R-r)**3/r
|
112 |
+
else:
|
113 |
+
out=0
|
114 |
+
|
115 |
+
return out, c0, c2
|
116 |
+
|
117 |
+
# Fractional Brownian surface
|
118 |
+
# The main control is the Hurst parameter: H should be between 0 and 1, where 0 is very noisy, and 1 is smoother.
|
119 |
+
# From https://gist.github.com/radarsat1/6f8b9b50d1ecd2546d8a765e8a144631
|
120 |
+
def brownian_surface(boxsizex, H=0.8):
|
121 |
+
N = 2*boxsizex
|
122 |
+
R = 2 # [0,R]^2 grid, may have to extract only [0,R/2]^2
|
123 |
+
|
124 |
+
# size of grid is m*n; covariance matrix is m^2*n^2
|
125 |
+
M = N
|
126 |
+
|
127 |
+
# create grid for field
|
128 |
+
tx = np.linspace(0, R, M)
|
129 |
+
ty = np.linspace(0, R, N)
|
130 |
+
rows = np.zeros((M,N))
|
131 |
+
|
132 |
+
|
133 |
+
for i in range(N):
|
134 |
+
for j in range(M):
|
135 |
+
# rows of blocks of cov matrix
|
136 |
+
rows[j,i] = rho([tx[i],ty[j]],
|
137 |
+
[tx[0],ty[0]],
|
138 |
+
R, 2*H)[0]
|
139 |
+
|
140 |
+
BlkCirc_row = np.vstack(
|
141 |
+
[np.hstack([rows, rows[:,-1:1:-1]]),
|
142 |
+
np.hstack([rows[-1:1:-1,:], rows[-1:1:-1, -1:1:-1]])])
|
143 |
+
|
144 |
+
# compute eigen-values
|
145 |
+
lam = np.real(np.fft.fft2(BlkCirc_row))/(4*(M-1)*(N-1))
|
146 |
+
lam = np.sqrt(lam)
|
147 |
+
|
148 |
+
# generate field with covariance given by block circular matrix
|
149 |
+
Z = np.vectorize(complex)(np.random.randn(2*(M-1), 2*(M-1)),
|
150 |
+
np.random.randn(2*(M-1), 2*(M-1)))
|
151 |
+
F = np.fft.fft2(lam*Z)
|
152 |
+
F = F[:M, :N] # extract sub-block with desired covariance
|
153 |
+
|
154 |
+
out,c0,c2 = rho([0,0],[0,0],R,2*H)
|
155 |
+
|
156 |
+
field1 = np.real(F) # two independent fields
|
157 |
+
#field2 = np.imag(F)
|
158 |
+
#field1 = field1 - field1[0,0] # set field zero at origin
|
159 |
+
#field2 = field2 - field2[0,0] # set field zero at origin
|
160 |
+
|
161 |
+
# make correction for embedding with a term c2*r^2
|
162 |
+
field1 = field1 + np.kron(np.array([ty]).T * np.random.randn(), np.array([tx]) * np.random.randn())*np.sqrt(2*c2)
|
163 |
+
#field2 = field2 + np.kron(np.array([ty]).T * np.random.randn(), np.array([tx]) * np.random.randn())*np.sqrt(2*c2)
|
164 |
+
#X,Y = np.meshgrid(tx,ty)
|
165 |
+
|
166 |
+
field1 = field1[:N//2, :M//2]
|
167 |
+
#field2 = field2[:N//2, :M//2]
|
168 |
+
return field1
|
source/maps.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#---------------------------
|
2 |
+
# Field generator module
|
3 |
+
# PabloVD
|
4 |
+
# Started: 11/5/20
|
5 |
+
#---------------------------
|
6 |
+
|
7 |
+
import numpy as np
|
8 |
+
from scipy import interpolate, ndimage
|
9 |
+
from source.fields import gaussian_field, perlin_field, warped_perlin_field, brownian_surface, cos_field
|
10 |
+
|
11 |
+
# Filter the field with a gaussian window
|
12 |
+
def smooth_field(field,sigmagauss,gridsize=None):
|
13 |
+
|
14 |
+
if gridsize==None: gridsize=field.shape[0]
|
15 |
+
|
16 |
+
x, y = np.linspace(0,field.shape[0],num=field.shape[0]), np.linspace(0,field.shape[1],num=field.shape[1])
|
17 |
+
|
18 |
+
# Interpolation
|
19 |
+
f = interpolate.interp2d(x,y,field,kind="linear")
|
20 |
+
|
21 |
+
qx = np.linspace(x[0],x[-1], num = gridsize)
|
22 |
+
qy = np.linspace(y[0],y[-1], num = gridsize)
|
23 |
+
|
24 |
+
# Filtering
|
25 |
+
smooth = ndimage.filters.gaussian_filter(f(qx,qy),sigmagauss)
|
26 |
+
return smooth
|
27 |
+
|
28 |
+
# Remove regions below sea level
|
29 |
+
def mainland(field,threshold):
|
30 |
+
for i, row in enumerate(field):
|
31 |
+
for j, el in enumerate(row):
|
32 |
+
if el<threshold: field[i,j]=0.
|
33 |
+
return field
|
34 |
+
|
35 |
+
# Normalize the values of the field between 0 and 1
|
36 |
+
def normalize_field(field):
|
37 |
+
min, max = np.amin(field), np.amax(field)
|
38 |
+
newfield = (field-min)/(max-min)
|
39 |
+
return newfield
|
40 |
+
|
41 |
+
# A gaussian function
|
42 |
+
def central_gaussian(x,y,x_c,y_c,sig):
|
43 |
+
return np.exp(-((x-x_c)**2.+(y-y_c)**2.)/2./sig**2.)
|
44 |
+
|
45 |
+
# Multiply the field by a gaussian mask to ensure an island in the center of the image
|
46 |
+
def masked_field(field,sig=None):
|
47 |
+
a, b = field.shape[0], field.shape[1]
|
48 |
+
if sig==None: sig = a/2.
|
49 |
+
x, y = np.linspace(0,a-1,num=a), np.linspace(0,b-1,num=b)
|
50 |
+
X, Y = np.meshgrid(x,y)
|
51 |
+
mask = central_gaussian(X,Y,a/2,b/2,sig)
|
52 |
+
field = field*mask
|
53 |
+
return field
|
54 |
+
|
55 |
+
# Generate a map of islands applying different processes:
|
56 |
+
# 1. Generate a random field, either gaussian or perlin
|
57 |
+
# 2. Normalize the field between 0 and 1
|
58 |
+
# 3. Smooth the field with a gaussian filter
|
59 |
+
# 4. Retain only the mainland above a certain threshold
|
60 |
+
def generate_map(kind_noise,boxsize,llavor,params,sigma,threshold,boxsizey=None,make_island=0):
|
61 |
+
|
62 |
+
if boxsizey==None: boxsizey=boxsize
|
63 |
+
np.random.seed(seed=llavor)
|
64 |
+
|
65 |
+
if kind_noise=="gauss":
|
66 |
+
indexlaw = params
|
67 |
+
field = gaussian_field(boxsize,llavor,indexlaw)
|
68 |
+
elif kind_noise=="perlin":
|
69 |
+
scale,octaves,persistence,lacunarity,boxsizey = params
|
70 |
+
field = perlin_field(boxsize,llavor,scale,octaves,persistence,lacunarity,boxsizey=boxsizey)
|
71 |
+
#field = perlin_field(boxsize,llavor,*params)
|
72 |
+
elif kind_noise=="warped_perlin":
|
73 |
+
scale,octaves,persistence,lacunarity,boxsizey = params
|
74 |
+
field = warped_perlin_field(boxsize,llavor,scale,octaves,persistence,lacunarity,boxsizey=boxsizey)
|
75 |
+
elif kind_noise=="fbm":
|
76 |
+
hurst = params
|
77 |
+
field = brownian_surface(boxsize, H=hurst)
|
78 |
+
elif kind_noise=="cos":
|
79 |
+
scale,octaves,persistence,lacunarity,boxsizey = params
|
80 |
+
field = cos_field(boxsize,llavor,scale,octaves,persistence,lacunarity,boxsizey=boxsizey)
|
81 |
+
else:
|
82 |
+
print("Kind of noise not valid.")
|
83 |
+
return np.zeros((boxsize,boxsizey))
|
84 |
+
|
85 |
+
field = normalize_field(field)
|
86 |
+
if make_island:
|
87 |
+
field = masked_field(field)
|
88 |
+
field = smooth_field(field,sigma,gridsize=2*boxsize)
|
89 |
+
field = mainland(field,threshold)
|
90 |
+
|
91 |
+
return field
|
source/visualization_tools.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#---------------------------
|
2 |
+
# Tools for visualization
|
3 |
+
# PabloVD
|
4 |
+
# Started: 11/5/20
|
5 |
+
#---------------------------
|
6 |
+
|
7 |
+
import matplotlib.pyplot as plt
|
8 |
+
from source.maps import generate_map
|
9 |
+
|
10 |
+
# Modify gist_earth color map to have a dark blue as the minimum value, instead of black
|
11 |
+
def modified_gist_earth():
|
12 |
+
|
13 |
+
cmap = plt.get_cmap("gist_earth")
|
14 |
+
# Color maps defined for 256 values
|
15 |
+
num = 256
|
16 |
+
# Location of the color I want to be the lowest value
|
17 |
+
ind_blue = 5 #
|
18 |
+
|
19 |
+
blue_list = []
|
20 |
+
for i in range(ind_blue):
|
21 |
+
blue_list.append(cmap(ind_blue))
|
22 |
+
|
23 |
+
newcmap = cmap.from_list('modified_gist_earth',blue_list+list(map(cmap,range(ind_blue,num))), N=num)
|
24 |
+
return newcmap
|
25 |
+
|
26 |
+
# Creates a random map
|
27 |
+
def single_map(kind_noise,boxsize,llavor,params,sigma,threshold,make_island=0,cmap=modified_gist_earth(),axissize=6):
|
28 |
+
|
29 |
+
figsize = (axissize,axissize)
|
30 |
+
fig, ax = plt.subplots(figsize=figsize)
|
31 |
+
margins = { # vvv margin in inches
|
32 |
+
"left" : 0.,
|
33 |
+
"bottom" : 0.,
|
34 |
+
"right" : 1.,
|
35 |
+
"top" : 1.}
|
36 |
+
fig.subplots_adjust(**margins)
|
37 |
+
|
38 |
+
field = generate_map(kind_noise,boxsize,llavor,params,sigma,threshold,make_island=make_island)
|
39 |
+
ax.imshow(field,vmin=0.,vmax=1.,cmap=cmap)
|
40 |
+
|
41 |
+
ax.set_axis_off()
|
42 |
+
|
43 |
+
return fig
|
44 |
+
|
45 |
+
|
46 |
+
# Create (num_plots)x(num_plots) different maps of random islands, with different random seeds
|
47 |
+
def plot_grid(kind_noise,boxsize,params,sigma,threshold,num_plots=3,make_island=0,cmap=modified_gist_earth()):
|
48 |
+
|
49 |
+
fig, axes = plt.subplots(num_plots,num_plots, figsize=(9.,9.))
|
50 |
+
fig.subplots_adjust(wspace = 0.1, hspace = 0.1)
|
51 |
+
|
52 |
+
llavor = 0
|
53 |
+
|
54 |
+
for axx in axes:
|
55 |
+
for ax in axx:
|
56 |
+
|
57 |
+
field = generate_map(kind_noise,boxsize,llavor,params,sigma,threshold,make_island=make_island)
|
58 |
+
ax.imshow(field,vmin=0.,vmax=1.,cmap=cmap)
|
59 |
+
|
60 |
+
ax.set_xlim([0,field.shape[0]])
|
61 |
+
ax.set_ylim([field.shape[0],0])
|
62 |
+
ax.set_axis_off()
|
63 |
+
llavor+=1
|
64 |
+
|
65 |
+
plt.axis('off')
|
66 |
+
fig.savefig("images/gridmap_noise_{:}_threshold_{:.1f}_sigma_{:.1f}.png".format(kind_noise,threshold,sigma), bbox_inches='tight')
|
67 |
+
#plt.close(fig)
|
68 |
+
|