Radial plots for exploratory analysis of climate data with Python and Matplotlib - Tutorial

On the development of hydrological evaluations, there is a need to assess which weather stations will be used for the numerical modeling stage. The main acceptance criteria would be the amount of climate variables and records available however huge areas could have docens or hundreds of stations delivered in one text file. This tutorial shows the procedure to plot climate variable records from a single text file on a polar plot with aperture angle related to value statistics. The tutorial is done with standar Python packages as Matplotlib, Numpy and Pandas.

Interactive visualization

Tutorial

Code

This is the Python code:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#open the csv
climateData = pd.read_csv('../Data/2805958.csv',parse_dates=True,index_col=1)
#description of variables
climateData.describe()
C:\Users\saulm\miniconda3\lib\site-packages\IPython\core\interactiveshell.py:3441: DtypeWarning: Columns (15) have mixed types.Specify dtype option on import or set low_memory=False.
  exec(code_obj, self.user_global_ns, self.user_ns)
LATITUDE LONGITUDE ELEVATION AWND PRCP TMAX TMIN TSUN
count 53094.000000 53094.000000 53094.000000 7198.000000 52218.000000 24791.000000 24757.000000 889.0
mean 26.157937 -81.729122 9.599311 3.318394 4.121282 29.018071 19.001474 0.0
std 0.104336 0.041891 34.862054 1.188413 11.728384 4.190826 5.239559 0.0
min 25.949100 -81.816683 1.200000 0.600000 0.000000 5.000000 -2.200000 0.0
25% 26.128961 -81.763369 2.700000 2.500000 0.000000 26.700000 15.600000 0.0
50% 26.165300 -81.722053 4.300000 3.100000 0.000000 30.000000 20.600000 0.0
75% 26.235972 -81.689149 12.200000 4.000000 1.500000 32.200000 23.300000 0.0
max 26.375011 -81.624320 388.900000 15.200000 245.900000 36.700000 34.400000 0.0

Main climate variables

AWND = Average daily wind speed (meters per second or miles per hour as per user preference)
PRCP = Precipitation (mm or inches as per user preference, inches to hundredths on Daily Form pdf file)
TMAX = Maximum temperature (Fahrenheit or Celsius as per user preference, Fahrenheit to tenths on Daily Form pdf file
TMIN = Minimum temperature (Fahrenheit or Celsius as per user preference, Fahrenheit to tenths on Daily Form pdf file
TSUN = Daily total sunshine (minutes).

#show stations
weatherStations = pd.unique(climateData.index)
print(weatherStations)
['NAPLES 5.7 SE, FL US' 'NAPLES 1.3 NW, FL US' 'NAPLES 1.3 SE, FL US'
 'NAPLES 8.7 SE, FL US' 'NORTH NAPLES 5.1 NE, FL US'
 'NAPLES 7.4 NNE, FL US' 'NAPLES 11.8 ENE, FL US'
 'BONITA SPRINGS 3.1 NW, FL US' 'NAPLES PARK 3.7 ENE, FL US'
 'COLLIER 14.1 NE, FL US' 'NAPLES, FL US'
 'NAPLES MUNICIPAL AIRPORT, FL US' 'NAPLES 9.0 NE, FL US'
 'MARCO ISLAND 6.6 NNE, FL US' 'GOLDEN GATE 2.2 SW, FL US'
 'NAPLES 3.6 N, FL US' 'NORTH NAPLES 7.3 E, FL US'
 'NAPLES 12.5 N NUMBER 9 NORTH, FL US'
 'NAPLES 11.7 N NUMBER 17 NORTH, FL US' 'EAST NAPLES 0.9 NE, FL US'
 'NAPLES 11.0 N CLUBHOUSE, FL US' 'NAPLES 11.9 SSE, FL US'
 'NAPLES MANOR 2.3 E, FL US' 'NORTH NAPLES 4.8 NNE, FL US'
 'NAPLES 6.7 NE, FL US' 'NAPLES 1.4 NNW, FL US'
 'NAPLES 12.0 N NUMBER 2 SOUTH, FL US' 'PALM RIVER 3.9 E, FL US'
 'NAPLES 11.5 N NUMBER 17 SOUTH, FL US' 'NAPLES 0.7 SSW, FL US'
 'MARCO ISLAND, FL US']
#list of parameters to plot
paramValues = ['AWND','PRCP','TMAX','TMIN','TSUN']
N = len(paramValues)
#analysis of record distribution for one station
stationName = 'MARCO ISLAND, FL US'
stationDf = climateData.loc[stationName]

#get number of windspeed, precipitation, tmax, tmin, tsun
paramArray = stationDf[paramValues].count().values
#get the standard deviation
stdArray = stationDf[paramValues].std().values
#replace nan by 0
stdArray = np.nan_to_num(stdArray)
print(paramArray)
print(stdArray)
[   0 7118 7106 7106    0]
[ 0.         12.15939423  4.38560156  5.36778437  0.        ]
#example of polar plot
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = paramArray

ax = plt.subplot(projection='polar')
ax.bar(theta, radii)
plt.show()
# Improved plot for record amounts
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = paramArray
width = stdArray * np.pi / 180
colors = plt.cm.viridis(radii / 10.)

ax = plt.subplot(projection='polar')

for index, value in enumerate(paramValues):
    ax.bar(theta[index], radii[index], width=width[index], label=value)
ax.legend(loc='lower left', bbox_to_anchor=(1.0, 0))
ax.set_title(stationName)
ax.set_ylim(0,climateData.count()[0])
plt.gcf().set_size_inches(15, 8)
plt.show()
#create plot function
def plotRecords(stationName,yMax):
    stationDf = climateData.loc[stationName]

    #get number of windspeed, precipitation, tmax, tmin, tsun
    paramArray = stationDf[paramValues].count().values
    #get the standard deviation
    stdArray = stationDf[paramValues].std().values
    #replace nan by 0
    stdArray = np.nan_to_num(stdArray)

    theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
    radii = paramArray
    width = stdArray * np.pi / 180
    colors = plt.cm.viridis(radii / 10.)

    ax = plt.subplot(projection='polar')

    for index, value in enumerate(paramValues):
        ax.bar(theta[index], radii[index], width=width[index], label=value)
    ax.legend(loc='lower left', bbox_to_anchor=(1.0, 0))
    ax.set_title(stationName)
    ax.set_ylim(0,yMax)
    plt.gcf().set_size_inches(15, 8)
    plt.show()
plotRecords('MARCO ISLAND, FL US',10000)
import ipywidgets as widgets
from ipywidgets import interact

def interactivePlot(index, yMax):
    plotRecords(weatherStations[index], yMax)

interact(interactivePlot, index=(0,weatherStations.shape[0]-1), yMax=(0,5000,200))
interactive(children=(IntSlider(value=15, description='index', max=30), IntSlider(value=2400, description='yMa…





<function __main__.interactivePlot(index, yMax)>

Input data

You can download the input data from this link.

Comment

Saul Montoya

Saul Montoya es Ingeniero Civil graduado de la Pontificia Universidad Católica del Perú en Lima con estudios de postgrado en Manejo e Ingeniería de Recursos Hídricos (Programa WAREM) de la Universidad de Stuttgart con mención en Ingeniería de Aguas Subterráneas y Hidroinformática.

 

Suscribe to our online newsletter

Subscribe for free newsletter, receive news, interesting facts and dates of our courses in water resources.