Regional wind distribution

Introduction

Beaufort Wind Scale
0 1 2 3 4 5 6 7 8 9 10 11 12
Calm Light Air Light Breeze Gentle Breeze Moderate Breeze Fresh Breeze Strong Breeze Near Gale Gale Strong Gale Storm Violent Storm Hurricane Force
Light Winds High Winds Gale-force Storm-force Hurricane-force
<1 mph
<1 knot
<0.3 m/s
1–3 mph
1–3 knots
0.3–1.5 m/s
4–7 mph
4–6 knots
1.6–3.3 m/s
8–12 mph
7–10 knots
3.4–5.5 m/s
13–18 mph
11–16 knots
5.5–7.9 m/s
18–24 mph
17–21 knots
8.0–10.7 m/s
25–31 mph
22–27 knots
10.8–13.8 m/s
31–38 mph
28–33 knots
13.9–17.1 m/s
39–46 mph
34–40 knots
17.2–20.7 m/s
47-54 mph
41–47 knots
20.8–24.4 m/s
55–63 mph
48–55 knots
24.5–28.4 m/s
64–72 mph
56–63 knots
28.5–32.6 m/s
≥73 mph
≥63 knots
≥32.7 m/s
Vindens virkning på fjellet
Navn Symbol m/s knop Kjennetegn
Stille 0,0-0,2 0-1 Snøfiller daler omtrent rett ned, gjerne i en pendlende bevegelse.
Flau vind 0,3-1,5 1-3 Så vidt følbar. Det er tydelig at snøfillene driver med vinden.
Svak vind 1,6-3,3 4-6 Godt følbar i sterk kulde. Snøfillene beveger seg mer horisontalt enn vertikalt.
Lett bris 3,4-5,4 7-10 Vinden merkes tydelig og kan sjenere. Fallende snø synes å bevege seg meget raskere horisontalt enn vertikalt.
Laber bris 5,5-7,9 11-16 Er ubehagelig i kaldt vær og gir merkbar motstand. Fallende snø hvirvler av sted med vinden. Snødrevet mot ansiktet er meget sjenerende.
Frisk bris 8,0-10,7 17-21 Det blir tungt å gå på ski mot været. Fokksnø som driver langs bakken, hvirvles så høyt at synsvidden nedsettes. Snødrevet pisker i ansiktet.
Liten kuling 10,8-13,8 22-27 Det er meget slitsomt å ta seg fram mot været. Snøfokk setter ned sikten til under 1 km. Vanskelig å holde ubeskyttet ansikt mot vinden i lengre tid. Folk flest bør ikke legge ut på tur over snaufjellet ved denne og høyere vindstyrker.
Stiv kuling 13,9-17,1 28-33 I motvind må en lute seg fram over skiene og legge stor kraft i stavtakene, selv på flat mark. Det kan være vanskelig å holde bena i vindrossene. Snøfokk setter ned sikten til få hundre meter. Vanskelig å orientere seg i terrenget. En skitur i fjellet ved vindstyrke 7 er en stor påkjenning for de fleste.
Sterk kuling 17,2-20,7 34-40 Fjellet står i kok. Kvister og lav fra trærne driver med vinden. Meget vanskelig å gå på skiene. Nesten umulig å bære skiene på nakken. Snøfokk setter ned sikten til under 100 m. Umulig å orientere seg i terrenget. Meget vanskelig å følge selv godt kvistede løyper. Legg ikke ut på tur!
Liten storm 20,8-24,4 41-47 Vind og snøfokk gjør det umulig å ta seg fram på ski over fjellet. Selv i klarvær og lite snøfokk kan påkjenningen bli så stor at en snøhule eller hytte er eneste redning.
Full storm 24,5-28,4 48-55 Denne og høyere vindstyrker vil de fleste aldri komme ut for. Trær velter over ledninger for telefon og strøm. Det knaker i tømmervegger. Lette småhus rives av grunnmuren.
Sterk storm 28,5-32,6 56-63 Veier og jernbanelinjer blokkeres. Det er kaos på telefon- og strømnettet. Skog blir rasert.
Orkan 32,6- 64- Hvis bebyggelse rammes blir det en naturkatastrofe som gjerne vil kreve flere menneskeliv.

Imports


In [1]:
# -*- coding: utf-8 -*-
%matplotlib inline

import matplotlib.patches as patches
import pylab as plt
plt.rcParams['figure.figsize'] = (14, 6)

import datetime
import numpy as np
import netCDF4


from windrose import WindroseAxes

import warnings
warnings.filterwarnings("ignore")


C:\ProgramData\Anaconda3\lib\site-packages\windrose\windrose.py:29: MatplotlibDeprecationWarning: 
The Appender class was deprecated in Matplotlib 3.1 and will be removed in 3.3.
  addendum = docstring.Appender(msg, "\n\n")
C:\ProgramData\Anaconda3\lib\site-packages\windrose\windrose.py:30: MatplotlibDeprecationWarning: 
The copy_dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use docstring.copy() and cbook.dedent() instead.
  return lambda func: addendum(docstring.copy_dedent(base)(func))
C:\ProgramData\Anaconda3\lib\site-packages\windrose\windrose.py:30: MatplotlibDeprecationWarning: 
The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.getdoc() instead.
  return lambda func: addendum(docstring.copy_dedent(base)(func))
C:\ProgramData\Anaconda3\lib\site-packages\windrose\windrose.py:30: MatplotlibDeprecationWarning: 
The dedent function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use inspect.cleandoc instead.
  return lambda func: addendum(docstring.copy_dedent(base)(func))

Classification


In [2]:
# Classify by Beaufort scale
def classify_wind(wind_speed_f, wind_dir_f, js_str=True):
    len_wind = len(wind_speed_f)

    # Seperate by wind direction
    N = wind_speed_f[np.where((wind_dir_f>-22.5) & (wind_dir_f<=22.5))]

    NE = wind_speed_f[np.where((wind_dir_f>22.5) & (wind_dir_f<=67.5))]

    E = wind_speed_f[np.where((wind_dir_f>67.5) & (wind_dir_f<=112.5))]

    SE = wind_speed_f[np.where((wind_dir_f>112.5) & (wind_dir_f<=167.5))]

    S = wind_speed_f[np.where((wind_dir_f>167.5) & (wind_dir_f<=180.0) | (wind_dir_f>-167.5) & (wind_dir_f<=-180.0))]

    SW = wind_speed_f[np.where((wind_dir_f>-167.5) & (wind_dir_f<=-112.5))]

    W = wind_speed_f[np.where((wind_dir_f>-112.5) & (wind_dir_f<=-67.5))]

    NW = wind_speed_f[np.where((wind_dir_f>-67.5) & (wind_dir_f<=-22.5))]


    # Seperate by wind speed
    gentle_breeze = 5.5
    strong_breeze = 13.8
    gale = 20.7
    storm = 32.6

    N_gentle_breeze = len(N[np.where(N<gentle_breeze)]) / len_wind * 100
    N_strong_breeze = len(N[np.where((N>=gentle_breeze) & (N<strong_breeze))]) / len_wind * 100
    N_gale = len(N[np.where((N>=strong_breeze) & (N<gale))]) / len_wind * 100
    N_storm = len(N[np.where((N>=gale) & (N<storm))]) / len_wind * 100
    N_hurricane = len(N[np.where((N>=storm))]) / len_wind * 100

    NE_gentle_breeze = len(NE[np.where(NE<gentle_breeze)]) / len_wind * 100
    NE_strong_breeze = len(NE[np.where((NE>=gentle_breeze) & (NE<strong_breeze))]) / len_wind * 100
    NE_gale = len(NE[np.where((NE>=strong_breeze) & (NE<gale))]) / len_wind * 100
    NE_storm = len(NE[np.where((NE>=gale) & (NE<storm))]) / len_wind * 100
    NE_hurricane = len(NE[np.where((NE>=storm))]) / len_wind * 100

    E_gentle_breeze = len(E[np.where(E<gentle_breeze)]) / len_wind * 100
    E_strong_breeze = len(E[np.where((E>=gentle_breeze) & (E<strong_breeze))]) / len_wind * 100
    E_gale = len(E[np.where((E>=strong_breeze) & (E<gale))]) / len_wind * 100
    E_storm = len(E[np.where((E>=gale) & (E<storm))]) / len_wind * 100
    E_hurricane = len(E[np.where((E>=storm))]) / len_wind * 100

    SE_gentle_breeze = len(SE[np.where(SE<gentle_breeze)]) / len_wind * 100
    SE_strong_breeze = len(SE[np.where((SE>=gentle_breeze) & (SE<strong_breeze))]) / len_wind * 100
    SE_gale = len(SE[np.where((SE>=strong_breeze) & (SE<gale))]) / len_wind * 100
    SE_storm = len(SE[np.where((SE>=gale) & (SE<storm))]) / len_wind * 100
    SE_hurricane = len(SE[np.where((SE>=storm))]) / len_wind * 100

    S_gentle_breeze = len(S[np.where(S<gentle_breeze)]) / len_wind * 100
    S_strong_breeze = len(S[np.where((S>=gentle_breeze) & (S<strong_breeze))]) / len_wind * 100
    S_gale = len(S[np.where((S>=strong_breeze) & (S<gale))]) / len_wind * 100
    S_storm = len(S[np.where((S>=gale) & (S<storm))]) / len_wind * 100
    S_hurricane = len(S[np.where((S>=storm))]) / len_wind * 100

    SW_gentle_breeze = len(SW[np.where(SW<gentle_breeze)]) / len_wind * 100
    SW_strong_breeze = len(SW[np.where((SW>=gentle_breeze) & (SW<strong_breeze))]) / len_wind * 100
    SW_gale = len(SW[np.where((SW>=strong_breeze) & (SW<gale))]) / len_wind * 100
    SW_storm = len(SW[np.where((SW>=gale) & (SW<storm))]) / len_wind * 100
    SW_hurricane = len(SW[np.where((SW>=storm))]) / len_wind * 100

    W_gentle_breeze = len(W[np.where(W<gentle_breeze)]) / len_wind * 100
    W_strong_breeze = len(W[np.where((W>=gentle_breeze) & (W<strong_breeze))]) / len_wind * 100
    W_gale = len(W[np.where((W>=strong_breeze) & (W<gale))]) / len_wind * 100
    W_storm = len(W[np.where((W>=gale) & (W<storm))]) / len_wind * 100
    W_hurricane = len(W[np.where((W>=storm))]) / len_wind * 100

    NW_gentle_breeze = len(NW[np.where(NW<gentle_breeze)]) / len_wind * 100
    NW_strong_breeze = len(NW[np.where((NW>=gentle_breeze) & (NW<strong_breeze))]) / len_wind * 100
    NW_gale = len(NW[np.where((NW>=strong_breeze) & (NW<gale))]) / len_wind * 100
    NW_storm = len(NW[np.where((NW>=gale) & (NW<storm))]) / len_wind * 100
    NW_hurricane = len(NW[np.where((NW>=storm))]) / len_wind * 100

    #### can be removed after testing
    ####
    print([N_gentle_breeze, NE_gentle_breeze, E_gentle_breeze, SE_gentle_breeze, S_gentle_breeze, SW_gentle_breeze, W_gentle_breeze, NW_gentle_breeze])
    print([N_strong_breeze, NE_strong_breeze, E_strong_breeze, SE_strong_breeze, S_strong_breeze, SW_strong_breeze, W_strong_breeze, NW_strong_breeze])
    print([N_gale, NE_gale, E_gale, SE_gale, S_gale, SW_gale, W_gale, NW_gale])
    print([N_storm, NE_storm, E_storm, SE_storm, S_storm, SW_storm, W_storm, NW_storm])
    print([N_hurricane, NE_hurricane, E_hurricane, SE_hurricane, S_hurricane, SW_hurricane, W_hurricane, NW_hurricane])
    ####

    if js_str:
        str0 = "var light_winds = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_gentle_breeze, NE_gentle_breeze, E_gentle_breeze, SE_gentle_breeze, S_gentle_breeze, SW_gentle_breeze, W_gentle_breeze, NW_gentle_breeze)
        str1 = "var breeze = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_strong_breeze, NE_strong_breeze, E_strong_breeze, SE_strong_breeze, S_strong_breeze, SW_strong_breeze, W_strong_breeze, NW_strong_breeze)
        str2 = "var gale = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_gale, NE_gale, E_gale, SE_gale, S_gale, SW_gale, W_gale, NW_gale)
        str3 = "var storm = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_storm, NE_storm, E_storm, SE_storm, S_storm, SW_storm, W_storm, NW_storm)
        str4 = "var hurricane = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_hurricane, NE_hurricane, E_hurricane, SE_hurricane, S_hurricane, SW_hurricane, W_hurricane, NW_hurricane)

        json_str = "{0}\n{1}\n{2}\n{3}\n{4}".format(str0, str1, str2, str3, str4)

        return json_str

    else:
        wind_classes = {"gentle_breeze": [N_gentle_breeze, NE_gentle_breeze, E_gentle_breeze, SE_gentle_breeze, S_gentle_breeze, SW_gentle_breeze, W_gentle_breeze, NW_gentle_breeze],
                        "strong_breeze": [N_strong_breeze, NE_strong_breeze, E_strong_breeze, SE_strong_breeze, S_strong_breeze, SW_strong_breeze, W_strong_breeze, NW_strong_breeze],
                        "gale": [N_gale, NE_gale, E_gale, SE_gale, S_gale, SW_gale, W_gale, NW_gale],
                        "storm":[N_storm, NE_storm, E_storm, SE_storm, S_storm, SW_storm, W_storm, NW_storm],
                        "hurricane": [N_hurricane, NE_hurricane, E_hurricane, SE_hurricane, S_hurricane, SW_hurricane, W_hurricane, NW_hurricane]}

        return wind_classes

In [3]:
def classify_wind_transport(wind_speed_f, wind_dir_f, js_str=True):
    """
    Classes with regard to transport threshold.
    """
    len_wind = len(wind_speed_f)

    # Seperate by wind direction
    N = wind_speed_f[np.where((wind_dir_f>-22.5) & (wind_dir_f<=22.5))]

    NE = wind_speed_f[np.where((wind_dir_f>22.5) & (wind_dir_f<=67.5))]

    E = wind_speed_f[np.where((wind_dir_f>67.5) & (wind_dir_f<=112.5))]

    SE = wind_speed_f[np.where((wind_dir_f>112.5) & (wind_dir_f<=167.5))]

    S = wind_speed_f[np.where((wind_dir_f>167.5) & (wind_dir_f<=180.0) | (wind_dir_f>-167.5) & (wind_dir_f<=-180.0))]

    SW = wind_speed_f[np.where((wind_dir_f>-167.5) & (wind_dir_f<=-112.5))]

    W = wind_speed_f[np.where((wind_dir_f>-112.5) & (wind_dir_f<=-67.5))]

    NW = wind_speed_f[np.where((wind_dir_f>-67.5) & (wind_dir_f<=-22.5))]


    # Seperate by wind speed
    no_transport = 3.3 # less than light breeze, <2
    snowfall = 3.3 # more than light breeze, 3
    dry_snow = 5.5 # more than gentle breeze, 4
    wet_snow = 7.9 # more than moderate breeze, 5
    all_snow = 10.7 # more than fresh breeze, >5

    N_no_transport = len(N[np.where(N<no_transport)]) / len_wind * 100
    N_snowfall = len(N[np.where((N>=snowfall) & (N<dry_snow))]) / len_wind * 100
    N_dry_snow = len(N[np.where((N>=dry_snow) & (N<wet_snow))]) / len_wind * 100
    N_wet_snow = len(N[np.where((N>=wet_snow) & (N<all_snow))]) / len_wind * 100
    N_all_snow = len(N[np.where((N>=all_snow))]) / len_wind * 100

    NE_no_transport = len(NE[np.where(NE<no_transport)]) / len_wind * 100
    NE_snowfall = len(NE[np.where((NE>=snowfall) & (NE<dry_snow))]) / len_wind * 100
    NE_dry_snow = len(NE[np.where((NE>=dry_snow) & (NE<wet_snow))]) / len_wind * 100
    NE_wet_snow = len(NE[np.where((NE>=wet_snow) & (NE<all_snow))]) / len_wind * 100
    NE_all_snow = len(NE[np.where((NE>=all_snow))]) / len_wind * 100

    E_no_transport = len(E[np.where(E<no_transport)]) / len_wind * 100
    E_snowfall = len(E[np.where((E>=snowfall) & (E<dry_snow))]) / len_wind * 100
    E_dry_snow = len(E[np.where((E>=dry_snow) & (E<wet_snow))]) / len_wind * 100
    E_wet_snow = len(E[np.where((E>=wet_snow) & (E<all_snow))]) / len_wind * 100
    E_all_snow = len(E[np.where((E>=all_snow))]) / len_wind * 100

    SE_no_transport = len(SE[np.where(SE<no_transport)]) / len_wind * 100
    SE_snowfall = len(SE[np.where((SE>=snowfall) & (SE<dry_snow))]) / len_wind * 100
    SE_dry_snow = len(SE[np.where((SE>=dry_snow) & (SE<wet_snow))]) / len_wind * 100
    SE_wet_snow = len(SE[np.where((SE>=wet_snow) & (SE<all_snow))]) / len_wind * 100
    SE_all_snow = len(SE[np.where((SE>=all_snow))]) / len_wind * 100

    S_no_transport = len(S[np.where(S<no_transport)]) / len_wind * 100
    S_snowfall = len(S[np.where((S>=snowfall) & (S<dry_snow))]) / len_wind * 100
    S_dry_snow = len(S[np.where((S>=dry_snow) & (S<wet_snow))]) / len_wind * 100
    S_wet_snow = len(S[np.where((S>=wet_snow) & (S<all_snow))]) / len_wind * 100
    S_all_snow = len(S[np.where((S>=all_snow))]) / len_wind * 100

    SW_no_transport = len(SW[np.where(SW<no_transport)]) / len_wind * 100
    SW_snowfall = len(SW[np.where((SW>=snowfall) & (SW<dry_snow))]) / len_wind * 100
    SW_dry_snow = len(SW[np.where((SW>=dry_snow) & (SW<wet_snow))]) / len_wind * 100
    SW_wet_snow = len(SW[np.where((SW>=wet_snow) & (SW<all_snow))]) / len_wind * 100
    SW_all_snow = len(SW[np.where((SW>=all_snow))]) / len_wind * 100

    W_no_transport = len(W[np.where(W<no_transport)]) / len_wind * 100
    W_snowfall = len(W[np.where((W>=snowfall) & (W<dry_snow))]) / len_wind * 100
    W_dry_snow = len(W[np.where((W>=dry_snow) & (W<wet_snow))]) / len_wind * 100
    W_wet_snow = len(W[np.where((W>=wet_snow) & (W<all_snow))]) / len_wind * 100
    W_all_snow = len(W[np.where((W>=all_snow))]) / len_wind * 100

    NW_no_transport = len(NW[np.where(NW<no_transport)]) / len_wind * 100
    NW_snowfall = len(NW[np.where((NW>=snowfall) & (NW<dry_snow))]) / len_wind * 100
    NW_dry_snow = len(NW[np.where((NW>=dry_snow) & (NW<wet_snow))]) / len_wind * 100
    NW_wet_snow = len(NW[np.where((NW>=wet_snow) & (NW<all_snow))]) / len_wind * 100
    NW_all_snow = len(NW[np.where((NW>=all_snow))]) / len_wind * 100

    print([N_no_transport, NE_no_transport, E_no_transport, SE_no_transport, S_no_transport, SW_no_transport, W_no_transport, NW_no_transport])
    print([N_snowfall, NE_snowfall, E_snowfall, SE_snowfall, S_snowfall, SW_snowfall, W_snowfall, NW_snowfall])
    print([N_dry_snow, NE_dry_snow, E_dry_snow, SE_dry_snow, S_dry_snow, SW_dry_snow, W_dry_snow, NW_dry_snow])
    print([N_wet_snow, NE_wet_snow, E_wet_snow, SE_wet_snow, S_wet_snow, SW_wet_snow, W_wet_snow, NW_wet_snow])
    print([N_all_snow, NE_all_snow, E_all_snow, SE_all_snow, S_all_snow, SW_all_snow, W_all_snow, NW_all_snow])

    if js_str:
        str0 = "var no_transport = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_no_transport, NE_no_transport, E_no_transport, SE_no_transport, S_no_transport, SW_no_transport, W_no_transport, NW_no_transport)
        str1 = "var snowfall = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_snowfall, NE_snowfall, E_snowfall, SE_snowfall, S_snowfall, SW_snowfall, W_snowfall, NW_snowfall)
        str2 = "var dry_snow = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_dry_snow, NE_dry_snow, E_dry_snow, SE_dry_snow, S_dry_snow, SW_dry_snow, W_dry_snow, NW_dry_snow)
        str3 = "var wet_snow = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_wet_snow, NE_wet_snow, E_wet_snow, SE_wet_snow, S_wet_snow, SW_wet_snow, W_wet_snow, NW_wet_snow)
        str4 = "var all_snow = [{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}];".format(N_all_snow, NE_all_snow, E_all_snow, SE_all_snow, S_all_snow, SW_all_snow, W_all_snow, NW_all_snow)

        json_str = "{0}\n{1}\n{2}\n{3}\n{4}".format(str0, str1, str2, str3, str4)

        return json_str

    else:
        wind_classes = {"no_transport": [N_no_transport, NE_no_transport, E_no_transport, SE_no_transport, S_no_transport, SW_no_transport, W_no_transport, NW_no_transport],
                        "snowfall": [N_snowfall, NE_snowfall, E_snowfall, SE_snowfall, S_snowfall, SW_snowfall, W_snowfall, NW_snowfall],
                        "dry_snow": [N_dry_snow, NE_dry_snow, E_dry_snow, SE_dry_snow, S_dry_snow, SW_dry_snow, W_dry_snow, NW_dry_snow],
                        "wet_snow":[N_wet_snow, NE_wet_snow, E_wet_snow, SE_wet_snow, S_wet_snow, SW_wet_snow, W_wet_snow, NW_wet_snow],
                        "all_snow": [N_all_snow, NE_all_snow, E_all_snow, SE_all_snow, S_all_snow, SW_all_snow, W_all_snow, NW_all_snow]}

        return wind_classes

In [4]:
# Define plotting functions
def plt_wind_dir(wind_dir, ax=None):
    if ax == None:
        f, (ax) = plt.subplots(1, 1)
    pwd = ax.imshow(np.flipud(wind_dir), cmap=plt.cm.hsv, vmin=-180, vmax=180)
    cbar = plt.colorbar(mappable=pwd, ax=ax)
    cbar.set_ticks([-180, -135, -90, -45, 0, 45, 90, 135, 180])
    cbar.set_ticklabels(['S', 'SV', 'V', 'NV', 'N', 'NØ', 'Ø', 'SØ', 'S'])
    cbar.set_label("Vindretning")

def plt_wind_speed(wind_speed, ax=None):
    if ax == None:
        f, (ax) = plt.subplots(1, 1)
    pws = ax.imshow(np.flipud(wind_speed), cmap=plt.cm.jet, vmin=0, vmax=32.6)
    cbar = plt.colorbar(mappable=pws, ax=ax)
    cbar.set_ticks([0, 1.5, 3.3, 5.5, 7.9, 10.7, 13.8, 17.1, 20.7, 24.4, 28.4, 32.6])
    cbar.set_label("Vindhastighet (m/s)")

def plt_windrose(wind_dir_f, wind_speed_f, title=""):
    # Convert wind direction from -180 to 180 to 0 to 360 degree.
    wind_dir_f[np.where((wind_dir_f<0.0))] = wind_dir_f[np.where((wind_dir_f<0.0))] + 360.0

    ax = WindroseAxes.from_ax()
    ax.bar(wind_dir_f, wind_speed_f, normed=True, opening=0.8, edgecolor='white', nsector=8, bins=[0,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.6])
    ax.set_legend()
    ax.set_title(title)

    return ax

def plt_windrose_transport(wind_dir_f, wind_speed_f, title=""):
    # Convert wind direction from -180 to 180 to 0 to 360 degree.
    wind_dir_f[np.where((wind_dir_f<0.0))] = wind_dir_f[np.where((wind_dir_f<0.0))] + 360.0

    ax = WindroseAxes.from_ax()
    ax.bar(wind_dir_f, wind_speed_f, normed=True, opening=0.8, edgecolor='white', nsector=8, bins=[0,2,4.5,6.5,10.7,13.6])
    #ax.legend(labels=["ingen transport", "ved snøfall", "ved ubunden snø", "ved bunden snø", "hvis ikke skare/avblåst"])
    ax.set_legend()
    ax.set_title(title)

    return ax

def plt_snow_transport(wind_dir_f, wind_speed_f, title=""):
    # Convert wind direction from -180 to 180 to 0 to 360 degree.
    #wind_dir_f = -wind_dir_f
    wind_dir_f[np.where((wind_dir_f<0.0))] = wind_dir_f[np.where((wind_dir_f<0.0))] + 360.0

    ax = WindroseAxes.from_ax()
    ax.contourf(wind_dir_f, wind_speed_f, normed=True, bins=[0,2,4.5,6.5,10.7,13.6])
    ax.set_legend()
    ax.set_title(title)

    return ax

Short test


In [5]:
wind_dir = np.degrees(np.arctan2(-np.array([[0, 20, 10], [-5, -18, -1], [1, -20, 3]], dtype="float"), -np.array([[10, 10, 0], [-5, 8, -10], [-11, 1, 3]], dtype="float")))
print(wind_dir)
plt_wind_dir(wind_dir)


[[-180.         -116.56505118  -90.        ]
 [  45.          113.96248897    5.71059314]
 [  -5.19442891   92.86240523 -135.        ]]

Using MEPS-grid data


In [9]:
#nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_default2_5km_latest.nc")
#nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25files/meps_det_pp_2_5km_latest.nc")
#nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25epsarchive/2017/08/13/meps_mbr0_pp_2_5km_20170813T00Z.nc")
nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25epsarchive/2017/11/17/meps_mbr0_pp_2_5km_20171117T00Z.nc")


---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-9-fbaa7ccf3070> in <module>
      2 #nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25files/meps_det_pp_2_5km_latest.nc")
      3 #nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25epsarchive/2017/08/13/meps_mbr0_pp_2_5km_20170813T00Z.nc")
----> 4 nc = netCDF4.Dataset("http://thredds.met.no/thredds/dodsC/meps25epsarchive/2017/11/17/meps_mbr0_pp_2_5km_20171117T00Z.nc")
      5 

netCDF4\_netCDF4.pyx in netCDF4._netCDF4.Dataset.__init__()

netCDF4\_netCDF4.pyx in netCDF4._netCDF4._ensure_nc_success()

OSError: [Errno -77] NetCDF: Access failure: b'http://thredds.met.no/thredds/dodsC/meps25epsarchive/2017/11/17/meps_mbr0_pp_2_5km_20171117T00Z.nc'

In [10]:
time_v = nc.variables['time']

# Choose a time-step
t_index = 6
# Choose a pressure level (if applicable)
p_index = 12 # 12=1000hPa, 11=925hPa, 10=850hPa, ..., 7=500hPa, ..., 0=50hPa in arome_metcoop_test

ts = netCDF4.num2date(time_v[t_index], time_v.units)
print(ts)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-b4b604e44164> in <module>
----> 1 time_v = nc.variables['time']
      2 
      3 # Choose a time-step
      4 t_index = 6
      5 # Choose a pressure level (if applicable)

NameError: name 'nc' is not defined

Wind gusts


In [11]:
wind_gust_v = nc.variables['wind_speed_of_gust']
plt_wind_speed(wind_gust_v[t_index, :, :])


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-11-6ccd0c71d567> in <module>
----> 1 wind_gust_v = nc.variables['wind_speed_of_gust']
      2 plt_wind_speed(wind_gust_v[t_index, :, :])
      3 

NameError: name 'nc' is not defined

Wind speed x and y components


In [12]:
wind_x_v = nc.variables['x_wind_10m']
wind_y_v = nc.variables['y_wind_10m']


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-12-3a665767a3b4> in <module>
----> 1 wind_x_v = nc.variables['x_wind_10m']
      2 wind_y_v = nc.variables['y_wind_10m']
      3 

NameError: name 'nc' is not defined

In [13]:
f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1.imshow(wind_x_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)
ax2.imshow(wind_y_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-13-db2eab3da71d> in <module>
      1 f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
----> 2 ax1.imshow(wind_x_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)
      3 ax2.imshow(wind_y_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)
      4 

NameError: name 'wind_x_v' is not defined

In [13]:


In [13]:

Wind speed


In [14]:
wind_speed = np.sqrt(wind_x_v[t_index, :, :]**2 + wind_y_v[t_index, :, :]**2)
plt_wind_speed(wind_speed)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-14-a39e0611213c> in <module>
----> 1 wind_speed = np.sqrt(wind_x_v[t_index, :, :]**2 + wind_y_v[t_index, :, :]**2)
      2 plt_wind_speed(wind_speed)
      3 

NameError: name 'wind_x_v' is not defined

Wind direction

The calculated vector indicates the direction to where the wind is blowing to, while we want to indicate the direction it is coming from in a wind map. Therefore we need to invert the x and y components of the vector before calculating the angle.


In [15]:
wind_dir = np.degrees(np.arctan2(-wind_x_v[t_index, :, :], -wind_y_v[t_index, :, :]))
plt_wind_dir(wind_dir)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-7332e73a7228> in <module>
----> 1 wind_dir = np.degrees(np.arctan2(-wind_x_v[t_index, :, :], -wind_y_v[t_index, :, :]))
      2 plt_wind_dir(wind_dir)
      3 

NameError: name 'wind_x_v' is not defined

In [15]:

Analysis over a 24h period

Retrieve data for a defined rectangle and period


In [16]:
### Lofoten
#x_range = np.arange(340, 430)
#y_range = np.arange(650,730)

### Langfjella
#x_range = np.arange(160, 260)
#y_range = np.arange(270,320)

### Hordalandskysten
x_range = np.arange(180, 220)
y_range = np.arange(290,370)

t_range = np.arange(18,42)

t1 = netCDF4.num2date(time_v[t_range[0]], time_v.units)
t2 = netCDF4.num2date(time_v[t_range[-1]], time_v.units)
t_info = "Period: {0} - {1}".format(t1, t2)
print(t_info)

plt.imshow((nc.variables["altitude"][:]))

rect = patches.Rectangle((x_range[0], y_range[0]), x_range[-1]-x_range[0], y_range[-1]-y_range[0], linewidth=1,edgecolor='r',facecolor='none')
plt.gca().add_patch(rect)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-16-25b7adcabaf6> in <module>
     13 t_range = np.arange(18,42)
     14 
---> 15 t1 = netCDF4.num2date(time_v[t_range[0]], time_v.units)
     16 t2 = netCDF4.num2date(time_v[t_range[-1]], time_v.units)
     17 t_info = "Period: {0} - {1}".format(t1, t2)

NameError: name 'time_v' is not defined

In [17]:
wind_speed = np.sqrt(wind_x_v[t_range, y_range, x_range]**2 + wind_y_v[t_range, y_range, x_range]**2)

wind_dir = np.degrees(np.arctan2(-wind_x_v[t_range, y_range, x_range], -wind_y_v[t_range, y_range, x_range]))

snow_dep = np.degrees(np.arctan2(wind_x_v[t_range, y_range, x_range], wind_y_v[t_range, y_range, x_range]))


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-17-e5e8cd6525de> in <module>
----> 1 wind_speed = np.sqrt(wind_x_v[t_range, y_range, x_range]**2 + wind_y_v[t_range, y_range, x_range]**2)
      2 
      3 wind_dir = np.degrees(np.arctan2(-wind_x_v[t_range, y_range, x_range], -wind_y_v[t_range, y_range, x_range]))
      4 
      5 snow_dep = np.degrees(np.arctan2(wind_x_v[t_range, y_range, x_range], wind_y_v[t_range, y_range, x_range]))

NameError: name 'wind_x_v' is not defined

In [18]:
laf = nc.variables["land_area_fraction"][y_range, x_range]
alt = nc.variables["altitude"][y_range, x_range]

f, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)#, sharex=True, sharey=True)
ax1.imshow(np.flipud(laf))
ax2.imshow(np.flipud(alt))
plt_wind_speed(wind_speed[5,:,:], ax=ax3)
plt_wind_dir(wind_dir[5,:,:], ax=ax4)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-18-93ceadcafbf2> in <module>
----> 1 laf = nc.variables["land_area_fraction"][y_range, x_range]
      2 alt = nc.variables["altitude"][y_range, x_range]
      3 
      4 f, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)#, sharex=True, sharey=True)
      5 ax1.imshow(np.flipud(laf))

NameError: name 'nc' is not defined

In [19]:
print(wind_x_v[18, 300, 200], wind_y_v[18, 300, 200])


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-19-e1fc58d5b45d> in <module>
----> 1 print(wind_x_v[18, 300, 200], wind_y_v[18, 300, 200])
      2 

NameError: name 'wind_x_v' is not defined

In [ ]:


In [19]:


In [20]:
f, (ax1, ax2, ax3) = plt.subplots(1, 3, sharex=True, sharey=True)
ax1.imshow(np.flipud(wind_dir[5,:,:]), cmap=plt.cm.hsv,vmin=-180, vmax=180)
ax2.imshow(np.flipud(wind_dir[10,:,:]), cmap=plt.cm.hsv,vmin=-180, vmax=180)
ax3.imshow(np.flipud(wind_dir[15,:,:]), cmap=plt.cm.hsv,vmin=-180, vmax=180)


Out[20]:
<matplotlib.image.AxesImage at 0x2007a0f1eb8>

In [21]:
wind_dir_f = wind_dir.flatten()
wind_speed_f = wind_speed.flatten()
snow_dep_f = snow_dep.flatten()
print(wind_dir_f.shape, wind_speed_f.shape)
len_wind = len(wind_speed_f)


(76800,) (76800,)

In [22]:
classify_wind(wind_speed_f, wind_dir_f)


[2.4205729166666665, 1.02734375, 0.8763020833333333, 2.96484375, 0.9088541666666666, 9.259114583333334, 10.796875, 6.606770833333334]
[7.138020833333333, 0.7330729166666666, 0.026041666666666668, 0.19010416666666669, 0.13541666666666669, 5.815104166666667, 23.263020833333332, 20.157552083333332]
[0.8333333333333334, 0.018229166666666668, 0.0, 0.0, 0.0, 0.046875, 2.134114583333333, 3.145833333333333]
[0.00390625, 0.0, 0.0, 0.0, 0.0, 0.0, 0.03515625, 0.15234375]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
Out[22]:
'var light_winds = [2.4205729166666665, 1.02734375, 0.8763020833333333, 2.96484375, 0.9088541666666666, 9.259114583333334, 10.796875, 6.606770833333334];\nvar breeze = [7.138020833333333, 0.7330729166666666, 0.026041666666666668, 0.19010416666666669, 0.13541666666666669, 5.815104166666667, 23.263020833333332, 20.157552083333332];\nvar gale = [0.8333333333333334, 0.018229166666666668, 0.0, 0.0, 0.0, 0.046875, 2.134114583333333, 3.145833333333333];\nvar storm = [0.00390625, 0.0, 0.0, 0.0, 0.0, 0.0, 0.03515625, 0.15234375];\nvar hurricane = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];'

In [23]:
plt_windrose(wind_dir_f, wind_speed_f, t_info)


Out[23]:
<windrose.windrose.WindroseAxes at 0x2007a5c4d68>

In [24]:
#plt_windrose_transport(wind_dir_f, wind_speed_f, t_info)

In [25]:
#plt_snow_transport(snow_dep_f, wind_speed_f)

In [26]:
snow_classes = classify_wind_transport(wind_speed_f, snow_dep_f, js_str=True)
#print(snow_classes)


[2.5104166666666665, 3.727864583333333, 3.65625, 2.684895833333333, 0.3138020833333333, 0.83203125, 0.7369791666666667, 1.6731770833333333]
[1.3528645833333333, 4.471354166666667, 7.140625, 4.725260416666666, 0.45703125, 0.515625, 0.13932291666666669, 0.5169270833333333]
[0.5208333333333333, 3.3111979166666665, 9.76171875, 7.653645833333334, 0.8528645833333333, 0.5455729166666667, 0.0234375, 0.10026041666666666]
[0.14583333333333334, 1.6809895833333335, 8.404947916666666, 9.369791666666668, 1.1028645833333333, 0.6106770833333333, 0.002604166666666667, 0.00390625]
[0.013020833333333334, 0.6028645833333333, 7.265625000000001, 9.16796875, 1.0481770833333333, 0.3138020833333333, 0.0, 0.0]

Using wind data on xgeo-grid

Possible issues:

  • I do not have to use the flipud function for the xgeo-gridded data. Does that influence the wind direction, i.e. is the y-vector in the opposite direction between the two data sets???

In [23]:
# Load region mask
vr = netCDF4.Dataset(r"../data/terrain_parameters/VarslingsOmr_2017.nc", "r")

regions = (vr.variables["VarslingsOmr_2017"][:]) #np.flipud - needs to be flipped up/down when using wind from netCDF files.

ID = 3007 # Vest-Finnmark
# ID = 3014 # Lofoten & Vesterålen
#ID = 3029 # Indre Sogn
#ID = 3033 # Hordalandskysten
region_mask = np.where(regions==ID)
# get the lower left and upper right corner of a rectangle around the region
y_min, y_max, x_min, x_max = min(region_mask[0].flatten()), max(region_mask[0].flatten()), min(region_mask[1].flatten()), max(region_mask[1].flatten())

plt.imshow(regions, vmin=3007, vmax=3040)


Out[23]:
<matplotlib.image.AxesImage at 0x1da0af89c50>

In [24]:
#nc = netCDF4.Dataset(r"Y:\metdata\prognosis\arome\wind\netcdf\2017\arome2_5_wind_850_NVE_00_2017_04_27.nc", "r")
# nc = netCDF4.Dataset(r"Y:\metdata\prognosis\meps\det\archive\2017\mepsDet00_PTW_1km_20171117.nc", "r")
# nc = netCDF4.Dataset(r"Y:\metdata\prognosis\meps\det\archive\2020\meps_det_1km_20200319T03Z.nc", "r")
nc = netCDF4.Dataset(r"Y:\metdata\prognosis\meps\det\archive\2020\meps_det_1km_20200401T06Z.nc", "r")
time_v = nc.variables['time']

wind_x_v = nc.variables['x_wind_10m']
wind_y_v = nc.variables['y_wind_10m']

In [25]:
# Choose a time-step
t_index = 42
# Choose a pressure level (if applicable)
p_index = 12 # 12=1000hPa, 11=925hPa, 10=850hPa, ..., 7=500hPa, ..., 0=50hPa in arome_metcoop_test

print(netCDF4.num2date(time_v[t_index], time_v.units))


2020-04-03 00:00:00

In [26]:
f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1.imshow(wind_x_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)
ax2.imshow(wind_y_v[t_index, :, :], cmap=plt.cm.seismic, vmin=-20, vmax=20)


Out[26]:
<matplotlib.image.AxesImage at 0x1da0af89fd0>

In [27]:
wind_speed = np.sqrt(wind_x_v[t_index, :, :]**2 + wind_y_v[t_index, :, :]**2)
plt_wind_speed(wind_speed)



In [28]:
wind_dir = np.degrees(np.arctan2(-wind_x_v[t_index, :, :], -wind_y_v[t_index, :, :]))
plt_wind_dir(wind_dir)



In [29]:
x1, x2 = x_min, x_max # possible to add a buffer of step_x
y1, y2 = y_min, y_max # possible to add a buffer of step_y

print("Time period: {0} - {1}".format(netCDF4.num2date(time_v[t_index], time_v.units), netCDF4.num2date(time_v[t_index+24], time_v.units)))

# wind_x = wind_x_v[6:7, y1:y2, x1:x2]
# wind_y = wind_y_v[6:7, y1:y2, x1:x2]
# print(wind_x.shape)


wind_x = wind_x_v[t_index:t_index+24, y1:y2, x1:x2]
wind_y = wind_y_v[t_index:t_index+24, y1:y2, x1:x2]
print(wind_x.shape)

region_mask = regions[y1:y2, x1:x2] # redefine region_mask, now clipped to area of interest

wind_x_ma = np.ma.asarray(wind_x)
wind_y_ma = np.ma.asarray(wind_y)
for i in range(wind_x.shape[0]):
    wind_x_ma[i, :, :] = np.ma.masked_where(region_mask!=ID, wind_x[i, :, :], copy=False)
    #print(type(wind_x[i, :, :]))
    wind_y_ma[i, :, :] = np.ma.masked_where(region_mask!=ID, wind_y[i, :, :], copy=False)


Time period: 2020-04-03 00:00:00 - 2020-04-04 00:00:00
(24, 171, 141)

ToDo: split data in gridcells that are above and below treeline - use an fixed treeline elvation or the vegetation mask for each cell.


In [30]:
wind_speed_24h = np.sqrt(wind_x_ma**2 + wind_y_ma**2)
wind_dir_24h = np.degrees(np.arctan2(-wind_x_ma, -wind_y_ma)) # check if the minus is still applicable when using the xgeo-gridded data.
snow_dep_24h = np.degrees(np.arctan2(wind_x_ma, wind_y_ma)) # indicates the aspect where snow is deposited
print(type(wind_speed_24h))
wind_dir_f = wind_dir_24h.flatten()
wind_speed_f = wind_speed_24h.flatten()
snow_dep_f = snow_dep_24h.flatten()
print(wind_dir_f.shape, wind_speed_f.shape)


<class 'numpy.ma.core.MaskedArray'>
(578664,) (578664,)

In [31]:
# Choose a time-step
t_index_24h = 1
ts = netCDF4.num2date(time_v[t_index+t_index_24h], time_v.units)

f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
plt_wind_speed(wind_speed_24h[t_index_24h,:,:], ax=ax1)
plt_wind_dir(wind_dir_24h[t_index_24h,:,:], ax=ax2)

plt.title(ts)
plt.show()



In [32]:
plt_windrose(wind_dir_f, wind_speed_f)


Out[32]:
<windrose.windrose.WindroseAxes at 0x1da073eeef0>

In [33]:
plt_windrose_transport(wind_dir_f, wind_speed_f)


Out[33]:
<windrose.windrose.WindroseAxes at 0x1da0de96208>

ToDo: Compare wind speeds for 10m and 850hpa - 850hpa might be too high to use as a basis!

NEXT

Define criteria for which wind speed and direction to choose for the regional weather.

  • Lower threshold for wind speeds of concern
  • Threshold in % when to consider only one wind direction
  • Which directions to include if several wind directions could be relevant?

CHECK Looks like there is a bug. Percentages do not add up to 100% and values are generally too low...


In [47]:
wind_classes = classify_wind_transport(wind_speed_f, wind_dir_f, js_str=True)
print(wind_classes)


[0.0, 0.0, 0.0, 0.0, 0.0, 1.6268557398866477, 41.67182946696955, 28.824487735481057]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
var no_transport = [0.0, 0.0, 0.0, 0.0, 0.0, 1.6268557398866477, 41.67182946696955, 28.824487735481057];
var snowfall = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
var dry_snow = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
var wet_snow = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
var all_snow = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];

In [48]:
dominant = wind_dir_f[np.where(wind_speed_f>7.0)]
plt.hist(dominant)


Out[48]:
(array([ 75., 168., 136., 177., 198., 156.,  89.,  58.,  44.,  27.]),
 array([289.09796, 291.08255, 293.06717, 295.05176, 297.03638, 299.02097,
        301.00555, 302.99017, 304.97476, 306.95938, 308.94397],
       dtype=float32),
 <a list of 10 Patch objects>)

In [49]:
snow_classes = classify_wind_transport(wind_speed_f, snow_dep_f, js_str=True)
print(snow_classes)


[0.032124090773502215, 1.6084991165875036, 43.9549344898006, 28.980519033523784, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 18.714577453477432, 1.8884376218994514, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.8489938275854156, 2.3221128473417316, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.16750418760469013, 0.9729010348546384, 0.0, 0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 0.5093962965512494, 0.0, 0.0, 0.0, 0.0]
var no_transport = [0.032124090773502215, 1.6084991165875036, 43.9549344898006, 28.980519033523784, 0.0, 0.0, 0.0, 0.0];
var snowfall = [0.0, 0.0, 18.714577453477432, 1.8884376218994514, 0.0, 0.0, 0.0, 0.0];
var dry_snow = [0.0, 0.0, 0.8489938275854156, 2.3221128473417316, 0.0, 0.0, 0.0, 0.0];
var wet_snow = [0.0, 0.0, 0.16750418760469013, 0.9729010348546384, 0.0, 0.0, 0.0, 0.0];
var all_snow = [0.0, 0.0, 0.0, 0.5093962965512494, 0.0, 0.0, 0.0, 0.0];

Comparing different pressure levels from AROME-MetCoOp


In [22]:
nc_url = "http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_test2_5km_latest.nc"
#nc_url = "http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_test2_5km_20170423_06.nc"
nc = netCDF4.Dataset(nc_url, 'r')


---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-22-69e31ab0ec17> in <module>
      1 nc_url = "http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_test2_5km_latest.nc"
      2 #nc_url = "http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_test2_5km_20170423_06.nc"
----> 3 nc = netCDF4.Dataset(nc_url, 'r')
      4 

netCDF4\_netCDF4.pyx in netCDF4._netCDF4.Dataset.__init__()

netCDF4\_netCDF4.pyx in netCDF4._netCDF4._ensure_nc_success()

OSError: [Errno -77] NetCDF: Access failure: b'http://thredds.met.no/thredds/dodsC/arome25/arome_metcoop_test2_5km_latest.nc'

In [35]:
time_v = nc.variables['time']
pressure_v = nc.variables['pressure']
wind_x_v = nc.variables['x_wind_pl']
wind_y_v = nc.variables['y_wind_pl']

# Choose a time-period and spatial extent
x_range = np.arange(300, 400)
y_range = np.arange(600,750)
t_range = np.arange(6,30)
# Choose a pressure level (if applicable)
p_index = [12,11,10,7] # 12=1000hPa, 11=925hPa, 10=850hPa, ..., 7=500hPa, ..., 0=50hPa in arome_metcoop_test

In [36]:
t1 = netCDF4.num2date(time_v[t_range[0]], time_v.units)
t2 = netCDF4.num2date(time_v[t_range[-1]], time_v.units)

wind_speed = np.sqrt(wind_x_v[t_range, p_index, y_range, x_range]**2 + wind_y_v[t_range, p_index, y_range, x_range]**2)
wind_dir = np.degrees(np.arctan2(-wind_x_v[t_range, p_index, y_range, x_range], -wind_y_v[t_range, p_index, y_range, x_range]))

#f, axarr = plt.subplots(2, 2)
f = plt.figure(figsize=(12, 12))
i = 0

for pl in p_index: #p_index must be of length 4 at max

    # Flatten arrays
    wind_dir_f = wind_dir[:, i, :, :].flatten()
    wind_speed_f = wind_speed[:, i, :, :].flatten()
    print(wind_dir_f.shape, wind_speed_f.shape)

    t_info = "Period: {0} - {1}\nPressure level: {2} hPa".format(t1, t2, pressure_v[pl])

    ax = plt_windrose_transport(wind_dir_f, wind_speed_f, t_info)

    #f.add_axes(ax)
    #plt.savefig("windrose_pl_{0}.png".format(pl), dpi=90)

    i+=1


(360000,) (360000,)
(360000,) (360000,)
(360000,) (360000,)
(360000,) (360000,)
<matplotlib.figure.Figure at 0x23c3be39fd0>

TODO: Would be nice to get the plots equal in size.

Visualising snow deposition


In [42]:
plt_snow_transport(wind_dir_f, wind_speed_f)


Out[42]:
<windrose.windrose.WindroseAxes at 0x23c3ca24940>

In [ ]:


In [ ]:


In [ ]:

Testing influence of matrix convention on vector direction


In [136]:
def vec(x, y):
    vec_size = np.sqrt(x**2 + y**2)
    vec_dir = np.degrees(np.arctan2(x, y))

    return vec_size, vec_dir

In [158]:
x1 = np.array([[1, 2, -1],[-2, -1, 1],[2, -1, 1]])

y1 = np.array([[1, 2, -1],[-2, -1, 1],[2, -1, 1]])

f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1.imshow(x1)
ax2.imshow(y1)


Out[158]:
<matplotlib.image.AxesImage at 0x20002dc9080>

In [159]:
f, (ax1, ax2) = plt.subplots(1, 2, sharex=True, sharey=True)
ax1.imshow(np.flipud(x1))
ax2.imshow(np.flipud(y1))


Out[159]:
<matplotlib.image.AxesImage at 0x20002f18b70>

In [146]:
vec_size, vec_dir = vec(x1, y1)
plt_wind_dir(vec_dir)



In [144]:
vec_size, vec_dir = vec(np.flipud(x1), np.flipud(y1))
plt_wind_dir(vec_dir)



In [ ]: