In [1]:
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import matplotlib.pyplot as plt
import xarray as xr
import matplotlib.image as image
import numpy as np
import metpy
import metpy.calc as mpcalc
from metpy.plots import ctables
from metpy.cbook import get_test_data
from metpy.units import units
import os
import scipy.integrate as integrate
import datetime as dt
import glob
import json
from datetime import datetime
from datetime import timedelta
from metpy.plots import ctables
from matplotlib.colors import Normalize
from matplotlib.colors import ListedColormap, LinearSegmentedColormap, BoundaryNorm

#import wrf
import scipy
#import xcape
In [2]:
file_dir = '/data/icond2/meteograms'

# Changing the directory
os.chdir(file_dir)

#data_uv = xr.open_dataset('arome_uv.nc').sel(longitude=slice(-1,12,1),latitude=slice(53,45,1))
data = xr.open_dataset('icond2_sfc.nc')
data_clcl = xr.open_dataset('icond2_clcl.nc')
data_clcm = xr.open_dataset('icond2_clcm.nc')
data_clch = xr.open_dataset('icond2_clch.nc')

file_dir = '/data/icond2/meteograms'

# Changing the directory
os.chdir(file_dir)

# View a summary of the Dataset
print(data)

file_dir = '/home/lmathias/Documents/metpy/icond2'

# Changing the directory
os.chdir(file_dir)


im = image.imread('meteolux.jpg')
im2 = image.imread('dwd.png')


file_dir = '/data/icond2/meteograms'

# Changing the directory
os.chdir(file_dir)
<xarray.Dataset>
Dimensions:    (longitude: 1215, latitude: 746, time: 48)
Coordinates:
  * longitude  (longitude) float32 -3.94 -3.92 -3.9 -3.88 ... 20.3 20.32 20.34
  * latitude   (latitude) float32 43.18 43.2 43.22 43.24 ... 58.04 58.06 58.08
  * time       (time) datetime64[ns] 2023-07-13T04:00:00 ... 2023-07-15T03:00:00
Data variables:
    sde        (time, latitude, longitude) float32 ...
    tp         (time, latitude, longitude) float32 ...
    r2         (time, latitude, longitude) float32 ...
    t2m        (time, latitude, longitude) float32 ...
    d2m        (time, latitude, longitude) float32 ...
    t          (time, latitude, longitude) float32 ...
    u10        (time, latitude, longitude) float32 ...
    v10        (time, latitude, longitude) float32 ...
    gust       (time, latitude, longitude) float32 ...
    WW         (time, latitude, longitude) float32 ...
Attributes:
    Conventions:  CF-1.6
    history:      2023-07-13 04:43:25 GMT by grib_to_netcdf-2.22.1: grib_to_n...
In [3]:
# To parse the full dataset, we can call parse_cf without an argument, and assign the returned Dataset.

data = data.metpy.parse_cf()

x, y = data['tp'].metpy.coordinates('x', 'y')

time = data['tp'].metpy.time

timeinit = time[0]
timeinit = datetime.utcfromtimestamp(timeinit.item()/1e9)-timedelta(hours=1)
print(timeinit)

lon = data['tp'].metpy.longitude
lat = data['tp'].metpy.latitude

dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat)
dx = dx[None, :]
dy = dy[None, :]

tp = data['tp']
tg = data['t']
ww = data['WW']
t = data['t2m']
td = data['d2m']
r = data['r2']
u = data['u10']
fg = data['gust']
v = data['v10']
hs = data['sde']
clcl = data_clcl['ccl']
clcm = data_clcm['ccl']
clch = data_clch['ccl']

lat = 49.62
lon = 6.2
    
#msl = msl.metpy.loc[{'latitude': lat, 'longitude': lon}]/100   #convert to hPa
t = t.metpy.loc[{'latitude': lat, 'longitude': lon}]-273.15 
td = td.metpy.loc[{'latitude': lat, 'longitude': lon}]-273.15 
tg = tg.metpy.loc[{'latitude': lat, 'longitude': lon}]-273.15 #convert to °C
u = u.metpy.loc[{'latitude': lat, 'longitude': lon}]
fg = fg.metpy.loc[{'latitude': lat, 'longitude': lon}]
v = v.metpy.loc[{'latitude': lat, 'longitude': lon}]
tp = tp.metpy.loc[{'latitude': lat, 'longitude': lon}]   
#sp = sp.metpy.loc[{'latitude': lat, 'longitude': lon}]  
r = r.metpy.loc[{'latitude': lat, 'longitude': lon}]  
ww = ww.metpy.loc[{'latitude': lat, 'longitude': lon}]  
clcl = clcl.metpy.loc[{'latitude': lat, 'longitude': lon}]  
clcm = clcm.metpy.loc[{'latitude': lat, 'longitude': lon}]  
clch = clch.metpy.loc[{'latitude': lat, 'longitude': lon}]  
hs = hs.metpy.loc[{'latitude': lat, 'longitude': lon}]*100 # convert to cm

dd = mpcalc.wind_direction(u*units('m/s'), v*units('m/s'), convention='from')
ff = mpcalc.wind_speed(u*units('m/s'), v*units('m/s'))
td_calc = mpcalc.dewpoint_from_relative_humidity(t*units.degC,r)
#print(td.data.magnitude)

size = np.size(t)

plt.rcParams['axes.xmargin'] = 0

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d/%m\n%Hh')
loc = mdates.HourLocator(np.arange(0,24,2))
loc2 = mdates.HourLocator(np.arange(1,25,2))


fig, (ax1, ax2, ax3, ax4, ax5, ax6) = plt.subplots(6,1,figsize=(15,15))
ax1.plot(time[0:size], t[0:size], '-r', linewidth=3,zorder=5)
ax1.plot(time[0:size], td[0:size], '-g', linewidth=3)
ax1.set_ylabel('°C', fontsize=14)
ax1.set_yticks(np.arange(np.round(np.min(td))-2, np.round(np.max(t))+2,2))
ax1.set_ylim(np.round(np.min(td)-1),np.round(np.max(t)+2))
ax1.xaxis.set_major_locator(loc)
ax1.xaxis.set_minor_locator(loc2)
ax1.xaxis.set_major_formatter(myFmt)
ax1.tick_params(axis='both', which='major', labelsize=12)
ax1.legend(['Température 2 m','Point de rosée 2 m'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
         fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax1.grid(which='both', linestyle='--', linewidth='1',zorder=1)

#ax2.plot(time[6:size], td[6:size], '-g', linewidth=3)
ax2.plot(time[0:size], tg[0:size], 'tab:brown', linewidth=3,zorder=5)
ax2.set_ylabel('°C', fontsize=14)
ax2.set_ylim(np.round(np.min(tg)-2),np.round(np.max(tg)+2))
ax2.set_yticks(np.arange(np.round(np.min(tg))-2, np.round(np.max(tg))+2,2))
ax2.xaxis.set_major_locator(loc)
ax2.xaxis.set_minor_locator(loc2)
ax2.xaxis.set_major_formatter(myFmt)
ax2.tick_params(axis='both', which='major', labelsize=12)
ax2.legend(['Température près du sol'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax2.grid(which='both', linestyle='--', linewidth='1',zorder=1)

# ax3.plot(time[0:size], ff[0:size]*1.94384, '-k', linewidth=3,zorder=5)
# ax3.plot(time[0:size], fg[0:size]*1.94384, '--k', linewidth=3, zorder=5)
# ax3.set_ylabel('noeuds', fontsize=14)
# #ax3.set_yticks(np.arange(np.round(np.min(ff)), np.round(np.max(fg)),2))
# ax3.set_ylim(0,np.round(np.max(fg)+1))
# ax3.xaxis.set_major_locator(loc)
# ax3.xaxis.set_minor_locator(loc2)
# ax3.xaxis.set_major_formatter(myFmt)
# ax3.tick_params(axis='both', which='major', labelsize=12)
# ax3.legend(['Vent moyen 10 m','Rafales 10 m'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
#                 fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
# ax3.grid(which='both', linestyle='--', linewidth='1', zorder=1)


for i in range(0,48):
    ax3.bar(time[i], clcl[i], width=0.02, color='dimgrey',zorder=5)
    ax3.bar(time[i], clcm[i], width=0.02, color='darkgrey',zorder=4)
    ax3.bar(time[i], clch[i], width=0.02, color='lightgrey',zorder=3)
ax3.set_ylabel('%', fontsize=14)
#ax3.set_yticks([0,10,20,30,40,50,60,70,80,90,100])
ax3.set_yticks([0,20,40,60,80,100])
ax3.xaxis.set_major_locator(loc)
ax3.xaxis.set_minor_locator(loc2)
ax3.xaxis.set_major_formatter(myFmt)
ax3.tick_params(axis='both', which='major', labelsize=12)
ax3.legend(['Nébulosité basse (0-2 km)','Nébulosité moyenne (2-7 km)','Nébulosité haute (> 7 km)'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax3.grid(which='both', linestyle='--', linewidth='1',zorder=1)


rr = np.array(0)

for i in range(0,size):
    if i==0:
        ax4.bar(time[i], tp[i], width=0.02, color='b',zorder=5)
    else:
        rr = np.append(rr, tp[i]-tp[i-1])
        ax4.bar(time[i], tp[i]-tp[i-1], width=0.02, color='b',zorder=5)
rr.astype(float)
print(np.nanmax(rr))
ax4.set_ylabel('mm', fontsize=14)
ax4.set_ylim(0,np.ceil(np.nanmax(rr)))
ax4.xaxis.set_major_locator(loc)
ax4.xaxis.set_minor_locator(loc2)
ax4.xaxis.set_major_formatter(myFmt)
ax4.tick_params(axis='both', which='major', labelsize=12)
ax4.legend(['Précipitations'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax4.grid(which='both', linestyle='--', linewidth='1',zorder=1)

ax5.plot(time[0:size], hs[0:size], 'purple', linewidth=3)
ax5.set_ylabel('cm', fontsize=14)
ax5.set_ylim(0,np.round(np.max(hs)+1))
#ax2.set_yticks([0,10,20,30,40,50,60,70,80,90,100])
ax5.xaxis.set_major_locator(loc)
ax5.xaxis.set_minor_locator(loc2)
ax5.xaxis.set_major_formatter(myFmt)
ax5.tick_params(axis='both', which='major', labelsize=12)
ax5.legend(['Couche de neige au sol'],bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax5.grid(which='both', linestyle='--', linewidth='1',zorder=1)


for i in range(0,size):
    if np.round(ww[i])==71 or np.round(ww[i])==73 or np.round(ww[i])==75 or np.round(ww[i])==85 or np.round(ww[i])==86 :
        ax6.plot(time[i], 0, color='purple', marker='.', markersize=25, zorder=5)
    elif np.round(ww[i])==66 or np.round(ww[i])==67 or np.round(ww[i])==56 or np.round(ww[i])==57  :
        ax6.plot(time[i], 0, color='red', marker='.', markersize=25, zorder=5)
    elif np.round(ww[i])==61 or np.round(ww[i])==63 or np.round(ww[i])==65 or np.round(ww[i])==51 or np.round(ww[i])==53 or np.round(ww[i])==55  or np.round(ww[i])==80  or np.round(ww[i])==81 or np.round(ww[i])==82 :
        ax6.plot(time[i], 0, color='green', marker='.', markersize=25, zorder=5)
    elif np.round(ww[i])==45:
        ax6.plot(time[i], 0, color='gold', marker='.', markersize=25, zorder=5)
    elif np.round(ww[i])==48:
        ax6.plot(time[i], 0, color='darkorange', marker='.', markersize=25, zorder=5)
    else:
        ax6.plot(time[i], 0, color='white', marker='.', markersize=25, zorder=1)
#ax6.plot(time[0:size], ww[0:size], color='k', marker='.', markersize=15, zorder=5)
ax6.set_ylabel('SIGWW', fontsize=14)
ax6.set_ylim(-0.1,0.1)
ax6.xaxis.set_major_locator(loc)
ax6.xaxis.set_minor_locator(loc2)
ax6.xaxis.set_major_formatter(myFmt)
ax6.tick_params(axis='both', which='major', labelsize=12)
ax6.set_yticks([])
from matplotlib.lines import Line2D
colors = ['green', 'red', 'purple', 'gold','darkorange']
lines = [Line2D([0], [0], color=c, marker='.', markersize=15, linestyle='None') for c in colors]
labels = ['Pluie/Bruine', 'Pluie/Bruine verglaçante', 'Neige', 'Brouillard', 'Brouillard givrant']
ax6.legend(lines,labels,bbox_to_anchor=(0,1.02,1,0.2), loc="lower left",
                fancybox=True, shadow=True, borderaxespad=0, ncol=3, fontsize=11)
ax6.grid(which='both', linestyle='--', linewidth='1', zorder=1)
ax6.set_xlabel('Date/Heure (UTC)', fontsize=14)


ax7 = fig.add_axes([0.05,0.9,0.20,0.25])
ax7.axis('off')
ax7.imshow(im, aspect='equal', origin='upper', zorder=6)

ax1.set_title(timeinit.strftime('Base de données: Modèle ICON-D2 (Deutscher Wetterdienst) | ' + timeinit.strftime('Init: %d.%m.%Y %H:%M UTC')+'\nCoordonnées: 49.62°N, 6.2°E (Aéroport Luxembourg-Findel)\n'), fontsize=18)

fig.tight_layout()

plt.savefig('icond2_winterops.jpeg', format="jpeg", bbox_inches='tight', dpi=100)
plt.savefig('icond2_winterops.pdf', format="pdf", bbox_inches='tight', dpi=100)
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
Found valid latitude/longitude coordinates, assuming latitude_longitude for projection grid_mapping variable
2023-07-13 03:00:00
0.0
/tmp/ipykernel_10677/4036542127.py:136: UserWarning: Attempting to set identical bottom == top == 0 results in singular transformations; automatically expanding.
  ax4.set_ylim(0,np.ceil(np.nanmax(rr)))
/tmp/ipykernel_10677/4036542127.py:195: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  fig.tight_layout()
In [ ]:
 
In [ ]: