221 lines
7.4 KiB
Python
221 lines
7.4 KiB
Python
import xarray as xr
|
|
import rioxarray as rio
|
|
from matplotlib import cm
|
|
import numpy as np
|
|
import time
|
|
import matplotlib
|
|
import matplotlib.image as imgg
|
|
import os
|
|
|
|
|
|
def write_png(data,name, origin='upper', colormapD=None):
|
|
"""
|
|
Transform an array of data into a PNG string.
|
|
This can be written to disk using binary I/O, or encoded using base64
|
|
for an inline PNG like this:
|
|
|
|
>>> png_str = write_png(array)
|
|
>>> "data:image/png;base64,"+png_str.encode('base64')
|
|
|
|
Inspired from
|
|
https://stackoverflow.com/questions/902761/saving-a-numpy-array-as-an-image
|
|
|
|
Parameters
|
|
----------
|
|
data: numpy array or equivalent list-like object.
|
|
Must be NxM (mono), NxMx3 (RGB) or NxMx4 (RGBA)
|
|
|
|
origin : ['upper' | 'lower'], optional, default 'upper'
|
|
Place the [0,0] index of the array in the upper left or lower left
|
|
corner of the axes.
|
|
|
|
colormap : callable, used only for `mono` image.
|
|
Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
|
|
for transforming a mono image into RGB.
|
|
It must output iterables of length 3 or 4, with values between
|
|
0. and 1. Hint: you can use colormaps from `matplotlib.cm`.
|
|
|
|
Returns
|
|
-------
|
|
PNG formatted byte string
|
|
|
|
"""
|
|
|
|
if colormapD is None:
|
|
def colormapD(x):
|
|
return (x, x, x, 1)
|
|
arr = np.atleast_3d(data)
|
|
height, width, nblayers = arr.shape
|
|
if nblayers not in [1, 3, 4]:
|
|
raise ValueError('Data must be NxM (mono), '
|
|
'NxMx3 (RGB), or NxMx4 (RGBA)')
|
|
assert arr.shape == (height, width, nblayers)
|
|
if nblayers == 1:
|
|
arr = np.array(list(map(colormapD, arr.ravel())))
|
|
nblayers = arr.shape[1]
|
|
if nblayers not in [3, 4]:
|
|
raise ValueError('colormap must provide colors of r'
|
|
'length 3 (RGB) or 4 (RGBA)')
|
|
arr = arr.reshape((height, width, nblayers))
|
|
assert arr.shape == (height, width, nblayers)
|
|
if nblayers == 3:
|
|
arr = np.concatenate((arr, np.ones((height, width, 1))), axis=2)
|
|
nblayers = 4
|
|
assert arr.shape == (height, width, nblayers)
|
|
assert nblayers == 4
|
|
# Normalize to uint8 if it isn't already.
|
|
if arr.dtype != 'uint8':
|
|
with np.errstate(divide='ignore', invalid='ignore'):
|
|
arr = arr * 255./np.array([1., 1., 1., 1.]).reshape((1, 1, 4))
|
|
arr[~np.isfinite(arr)] = 0
|
|
arr = arr.astype('uint8')
|
|
# Eventually flip the image.
|
|
if origin == 'upper':
|
|
arr = arr[::-1, :, :]
|
|
r3 = arr.copy(order='C')
|
|
matplotlib.image.imsave(name, r3)
|
|
|
|
|
|
def image_to_url(image,name, colormapD=None, origin='lower'):
|
|
"""
|
|
Infers the type of an image argument and transforms it into a URL.
|
|
|
|
Parameters
|
|
----------
|
|
image: string, file or array-like object
|
|
* If string, it will be written directly in the output file.
|
|
* If file, it's content will be converted as embedded in the
|
|
output file.
|
|
* If array-like, it will be converted to PNG base64 string and
|
|
embedded in the output.
|
|
origin: ['upper' | 'lower'], optional, default 'upper'
|
|
Place the [0, 0] index of the array in the upper left or
|
|
lower left corner of the axes.
|
|
colormap: callable, used only for `mono` image.
|
|
Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
|
|
for transforming a mono image into RGB.
|
|
It must output iterables of length 3 or 4, with values between
|
|
0. and 1. You can use colormaps from `matplotlib.cm`.
|
|
|
|
"""
|
|
|
|
if 'ndarray' in image.__class__.__name__:
|
|
img = write_png(image, origin=origin, colormapD=colormapD,name=name)
|
|
|
|
def get_colorD(x,Tempcm,Min,Max,np):#*
|
|
"""Calculate color of pixel
|
|
Args:
|
|
x (float): Value of pixel
|
|
Tempcm (array): Colormap values
|
|
Min (float): min value
|
|
Max (float): max value
|
|
ls (_type_): linear interpolation function
|
|
decimals (_type_): number of decimals
|
|
np (_type_): library numpy
|
|
|
|
Returns:
|
|
array (4x1): array of color rbga
|
|
"""
|
|
import numpy as np
|
|
try:
|
|
if x <= 0:
|
|
x = 0
|
|
else:
|
|
x = x+1
|
|
if x > 21:
|
|
x = 21
|
|
x = int(np.fix(x))
|
|
except:
|
|
return Tempcm[-1]
|
|
|
|
return Tempcm[x]
|
|
|
|
def ExtractMapImage(file,colormap,countyear,name,nc,geometry=""):
|
|
import matplotlib as mpl
|
|
nc = nc.rio.write_crs(4326)
|
|
if geometry=="":
|
|
try:
|
|
nc = nc.rio.clip(geometries)
|
|
except:
|
|
pass
|
|
else:
|
|
pass
|
|
bounds=[[float(nc.lat.min().values),float(nc.lon.min().values)],[float(nc.lat.max().values),float(nc.lon.max().values)]]
|
|
i=countyear
|
|
|
|
year=int(nc.time[i].values)
|
|
print(i,year)
|
|
ncVar=nc.DHW_q99
|
|
data = ncVar[i,:,:].values
|
|
|
|
|
|
if colormap=="noaa":
|
|
Min=np.around(np.nanmin(data),0)
|
|
Max=np.around(np.nanmax(data),0)
|
|
cmap=np.array([[200, 250, 250, 255],
|
|
[ 69, 49, 120, 255],
|
|
[ 99, 79, 149, 255],
|
|
[129, 110, 179, 255],
|
|
[159, 140, 209, 255],
|
|
[255, 252, 0, 255],
|
|
[253, 220, 0, 255],
|
|
[251, 185, 0, 255],
|
|
[251, 149, 1, 255],
|
|
[248, 2, 1, 255],
|
|
[209, 1, 0, 255],
|
|
[159, 1, 0, 255],
|
|
[110, 0, 0, 255],
|
|
[229, 125, 69, 255],
|
|
[179, 90, 39, 255],
|
|
[125, 60, 31, 255],
|
|
[ 84, 45, 19, 255],
|
|
[239, 33, 239, 255],
|
|
[200, 25, 200, 255],
|
|
[159, 18, 159, 255],
|
|
[120, 10, 120, 255],
|
|
[ 49, 2, 49, 255],
|
|
[200, 250, 250, 255],
|
|
[ 49, 2, 49, 255],
|
|
[ 0, 0, 0, 0]], dtype=np.uint8)
|
|
image_to_url(data, name,colormapD=lambda x: get_colorD(x,cmap,Min,Max,np), origin='upper')
|
|
|
|
|
|
def ProcessAllImage(ssp,model,Colorpalete,ExportDirectory,DataDirectory):
|
|
cc=0
|
|
Var="DHW"
|
|
for i in ssp:
|
|
for j in model:
|
|
ff=DataDirectory+"%s_%s_%s_DHW.nc"%(Var,i,j)
|
|
for CM in Colorpalete:
|
|
for countyear in range(115):
|
|
nc = xr.open_dataset(ff, decode_coords="all")
|
|
year=int(nc.time[countyear].values)
|
|
Evaluado=ExportDirectory+"%s_%s"%(CM,ff.split("/")[-1].replace(".nc","_%s.png"%(year)))
|
|
if not os.path.isfile(Evaluado):
|
|
cc=cc+1
|
|
|
|
Total=cc
|
|
start=time.time()
|
|
cc=0
|
|
for i in ssp:
|
|
for j in model:
|
|
ff=DataDirectory+"%s_%s_%s_DHW.nc"%(Var,i,j)
|
|
for CM in Colorpalete:
|
|
for countyear in range(115):
|
|
nc = xr.open_dataset(ff, decode_coords="all")
|
|
year=int(nc.time[countyear].values)
|
|
Evaluado=ExportDirectory+"%s_%s"%("noaa",ff.split("/")[-1].replace(".nc","_%s.png"%(year)))
|
|
if not os.path.isfile(Evaluado):
|
|
ExtractMapImage(ff,"noaa",countyear,Evaluado,nc)
|
|
cc=cc+1
|
|
now=time.time()
|
|
print(cc,(start-now)/cc,(start-now)/cc*(Total-cc))
|
|
|
|
ssp=("ssp245","ssp370","ssp585")
|
|
model=("ensemble5","ensemble8","BCC-CSM2-MR","CESM2","CanESM5","EC-Earth3","IPSL-CM6A-LR","MIROC6","MRI-ESM2-0","NorESM2-MM")
|
|
Colorpalete=['CRW-NOAA']
|
|
ExportDirectory="img/"
|
|
DataDirectory="../Data/"
|
|
|
|
ProcessAllImage(ssp,model,Colorpalete,ExportDirectory,DataDirectory)
|