In [1]:
import sys, os
import math, random
import numpy as np
import pandas as pd
import operator
from scipy.sparse import csr_matrix, lil_matrix
from scipy.sparse.csgraph import dijkstra
from tqdm import tqdm
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import matplotlib.lines as ml
%matplotlib inline
In [2]:
palette = [
"#000000", "#0019ff", "#0080ff",
"#00e5ff", "#00ff4d", "#19fe00",
"#80ff00", "#e6ff00", "#ffff00",
"#ffe53c", "#ffdb77", "#ffe0b2",
]
n = len(palette)
In [3]:
cmap = mc.ListedColormap(palette, 'indexed')
im = plt.imshow([range(n)], interpolation='none', cmap=cmap)
plt.show()
In [4]:
class Raster(np.ndarray):
def __new__(cls, input_array, cellsize, xllcorner, yllcorner):
obj = np.asarray(input_array).view(cls)
obj.cellsize = cellsize
obj.xllcorner = xllcorner
obj.yllcorner = yllcorner
# 1-D list of the raster's values
v = obj.flatten()
obj.values = v[~np.isnan(v)]
return obj
@classmethod
def load(cls, filename):
data = [ ]
attrs = { }
with open(filename) as f:
for i in range(6):
key,value = next(f).strip().split()
attrs[key] = value
NODATA_value = attrs.get("NODATA_value", "-9999")
for line in f:
row = list(map(lambda x: np.nan if x == NODATA_value else float(x), line.split()))
row = [ x if x < 1e3 else np.nan for x in row ]
if row:
data.append(row)
return Raster(np.asarray(data), float(attrs["cellsize"])
, float(attrs["xllcorner"])
, float(attrs["yllcorner"]))
In [5]:
%%time
I = Raster.load("../bb450_final.asc")
In [6]:
%%time
R = Raster.load("../../BB450/bb_resist450.asc")
In [7]:
nodes = Raster.load("../../BB450/bb_nodes450.asc")
nodes = np.argwhere(~np.isnan(nodes))+1 # only care about the indicies
len(nodes)
Out[7]:
In [8]:
lo = float(np.min(I.values))
hi = float(np.max(I.values))
mu = float(np.mean(I.values))
sigma = float(np.std(I.values))
In [9]:
print("""
Size: {} x {}
Cell size: {}
No. Cells: {}
Min Value: {}
Max Value: {}
Mean Value: {}
Std Dev: {}
Colors: {}
""".format(I.shape[0], I.shape[1], I.cellsize, len(I.values), lo, hi, mu, sigma, n))
In [10]:
divs = [0.] + [ (i*sigma+mu)/hi for i in range(1,n-1) ] + [1.]
cmap = mc.LinearSegmentedColormap.from_list("", list(zip(divs, palette)))
fig = plt.figure(figsize=(10,10))
img = plt.imshow(I, origin="upper", cmap=cmap)
cy,cx = nodes[135]
maxdist = 0
mindist = 1e9
for y,x in nodes:
dist = math.hypot(cx - x, cy - y)
if dist > 0:
maxdist = max(maxdist, dist)
mindist = min(mindist, dist)
print(mindist,maxdist)
for y,x in nodes:
dist = math.hypot(cx - x, cy - y)
dist = (dist - mindist) / (maxdist - mindist) # dist is [0,1]
alpha = (0.8 * (1. - dist)) + 0.05 # map maxdist to 0.1 and mindist to .9
l = ml.Line2D([cx,x], [cy,y], color="#FF69B4", alpha=alpha)
img.axes.add_artist(l)
for y,x in nodes:
img.axes.add_artist(plt.Circle((x,y), 4, color='#FFB6C1'))
#img.axes.add_artist(plt.Circle((cx,cy), 14, color='r'))
fig.colorbar(img)
Out[10]:
In [11]:
N = len(I.values)
print("N = {:,}\nsqr(N) = {:,}\n9N = {:,}".format(N, N**2, 9*N))
In [12]:
%%time
indices = { (int(x),int(y)):index for index,(x,y) in enumerate(np.argwhere(~np.isnan(I))) }
print(len(indices))
In [13]:
%%time
coordinates = [ (int(x),int(y)) for (x,y) in np.argwhere(~np.isnan(I)) ]
In [14]:
list(indices.items())[0]
Out[14]:
In [15]:
coordinates[374264]
Out[15]:
In [16]:
G1 = lil_matrix((N, N))
for (i,j),id1 in tqdm(indices.items()):
try:
id2 = indices[i+1,j]
value = (R[i,j] + R[i+1,j]) / 2.
G1[id1,id2] = value
G1[id2,id1] = value
except KeyError:
pass
try:
id2 = indices[i,j+1]
value = (R[i,j] + R[i,j+1]) / 2.
G1[id1,id2] = value
G1[id2,id1] = value
except KeyError:
pass
G1
Out[16]:
In [17]:
%%time
G = csr_matrix(G1)
In [18]:
G
Out[18]:
In [19]:
nindices = [ indices[(y,x)] for y,x in nodes ]
In [20]:
%%time
dist_matrix,predecessors = dijkstra(G, directed=False, return_predecessors=True, indices=nindices)
In [25]:
def plot_paths(origin):
lines = [ ]
for index,start in enumerate(nindices):
if index == origin:
continue
i = start
lines.append((dist_matrix[origin][i], [ ], [ ]))
while i != -9999:
lines[-1][1].append(coordinates[i][1])
lines[-1][2].append(coordinates[i][0])
i = predecessors[origin][i]
rmin = min(map(operator.itemgetter(0), lines))
rmax = max(map(operator.itemgetter(0), lines))
divs = [0.] + [ (i*sigma+mu)/hi for i in range(1,n-1) ] + [1.]
cmap = mc.LinearSegmentedColormap.from_list("", list(zip(divs, palette)))
fig = plt.figure(figsize=(10,10))
img = plt.imshow(I, origin="upper", cmap=cmap)
for rdist,xs,ys in lines:
alpha = (0.5 * (1. - (rdist - rmin) / (rmax - rmin))) + 0.1 # map maxdist to 0.1 and mindist to .6
l = ml.Line2D(xs, ys, color="#FF69B4", alpha=alpha)
img.axes.add_artist(l)
for y,x in nodes:
img.axes.add_artist(plt.Circle((x,y), 6, color='#FFB6C1'))
return fig.colorbar(img)
In [26]:
plot_paths(0)
Out[26]:
In [27]:
plot_paths(135)
Out[27]:
In [28]:
plot_paths(244)
Out[28]:
In [ ]: