Completed
Pull Request — master (#318)
by
unknown
01:36
created

parse_date()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
c 2
b 0
f 0
dl 0
loc 2
rs 10
1
2
import numpy as np
3
import matplotlib.pyplot as plt
4
import datetime as dt
5
import matplotlib as mpl
6
7
from metpy.cbook import get_test_data
8
from metpy.units import units
9
from metpy.calc import dewpoint_rh
10
11
def calc_mslp(T,P,h):
12
    return P*(1-(0.0065*h)/(T+0.0065*h+273.15))**(-5.257)
13
14
# Make meteogram plot
15
class Meteogram(object):
16
    """ Plot a time series of meteorological data from a particular station as a meteogram with standard variables 
17
    to visualize, including thermodynamic, kinematic, and pressure. The functions below control the plotting
18
    of each variable. 
19
    
20
    TO DO: Make the subplot creation dynamic so the number of rows is not static as it is currently. """
21
    def __init__(self,fig,dates,probeid,time=dt.datetime.utcnow(),axis=0):
22
        """ 
23
        Required input:
24
            fig: figure object
25
            dates: array of dates corresponding to the data
26
            probeid: ID of the station
27
        Optional Input:
28
            time: Time the data is to be plotted
29
            axis: number that controls the new axis to be plotted (FOR FUTURE)
30
        """
31
        self.start = dates[0]
32
        self.fig = fig
33
        self.end = dates[-1]
34
        self.axis_num = 0
35
        self.dates = mpl.dates.date2num(dates)
36
        self.time = time.strftime("%Y-%m-%d %H:%M UTC")
37
        self.title = 'Latest Ob Time: {0}\nProbe ID: {1}'.format(self.time,probeid)
38
39
    def plot_winds(self,WS,WD,WSMAX,plot_range=[0,20,1]):
40
        """ 
41
        Required input:
42
            WS: Wind speeds (knots)
43
            WD: Wind direction (degrees)
44
            WSMAX: Wind gust (knots)
45
        Optional Input:
46
            plot_range: Data range for making figure
47
        """        
48
        # PLOT WIND SPEED AND WIND DIRECTION
49
        self.ax1 = fig.add_subplot(4, 1, 1)
50
        ln1 = self.ax1.plot(self.dates, 
51
                   WS, 
52
                   label='Wind Speed'
53
                   )
54
        plt.fill_between(self.dates,WS,0)
55
        self.ax1.set_xlim(self.start,self.end)
56
        #self.ax1.get_xaxis().set_ticks([(self.starttime+dt.timedelta(hours=i*4)) for i in np.arange(0,7)])
57
        plt.ylabel('Wind Speed (knots)', multialignment='center')
58
        plt.grid(b=True,which='major',axis='y',color='k',linestyle='--',linewidth=0.5)
59
        ln2 = self.ax1.plot(self.dates,
60
            WSMAX,
61
            '.r',
62
            label='3-sec Wind Speed Max')
63
        plt.setp(self.ax1.get_xticklabels(), visible=True)
64
        ax7 = self.ax1.twinx()
65
        ln3 = ax7.plot(self.dates, 
66
                   WD, 
67
                   '.k', linewidth=0.5, label='Wind Direction')
68
        plt.ylabel('Wind\nDirection\n(degrees)', multialignment='center')
69
        plt.ylim(0,360)
70
        plt.yticks(np.arange(45,405,90),['NE','SE','SW','NW'])
71
        lns = ln1+ln2+ln3
72
        labs = [l.get_label() for l in lns]
73
        plt.gca().xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))
74
        ax7.legend(lns, labs, loc='upper center', bbox_to_anchor=(0.5,1.2),ncol=3,prop={'size':12})
75
76
        
77
    def plot_thermo(self,T,TD,plot_range=[10,90,2]): 
78
        """ 
79
        Required input:
80
            T: Temperature (deg F)
81
            TD: Dewpoint (deg F)
82
        Optional Input:
83
            plot_range: Data range for making figure
84
        """        
85
        # PLOT TEMPERATURE AND DEWPOINT       
86
        self.ax2 = fig.add_subplot(4, 1, 2,sharex=self.ax1)
87
        ln4 = self.ax2.plot(self.dates,
88
                   T,
89
                   'r-',
90
                   label='Temperature')
91
        plt.fill_between(self.dates,
92
                     T,
93
                     TD,
94
                     color='r')
95
        plt.setp(self.ax2.get_xticklabels(), visible=True)
96
        plt.ylabel('Temperature\n(F)', multialignment='center')
97
        plt.grid(b=True,which='major',axis='y',color='k',linestyle='--',linewidth=0.5)
98
        self.ax2.set_ylim(plot_range[0],plot_range[1],plot_range[2])
99
        ln5 = self.ax2.plot(self.dates,
100
                  TD,
101
                  'g-',
102
                   label='Dewpoint')
103
        plt.fill_between(self.dates,
104
                     TD,
105
                     plt.ylim()[0],
106
                     color='g')
107
        ax_twin = self.ax2.twinx()
108
        #    ax_twin.set_ylim(20,90,2)
109
        ax_twin.set_ylim(plot_range[0],plot_range[1],plot_range[2])
110
        lns = ln4+ln5
111
        labs = [l.get_label() for l in lns]
112
        plt.gca().xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))
113
114
        self.ax2.legend(lns,labs,loc='upper center', bbox_to_anchor=(0.5,1.2),ncol=2,prop={'size':12})
115
        
116 View Code Duplication
    def plot_rh(self,RH,plot_range=[0,100,4]):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
117
        """ 
118
        Required input:
119
            RH: Relative humidity (%)
120
        Optional Input:
121
            plot_range: Data range for making figure
122
        """        
123
        # PLOT RELATIVE HUMIDITY
124
        self.ax3 = fig.add_subplot(4, 1, 3,sharex=self.ax1)
125
        self.ax3.plot(self.dates,
126
             RH,
127
             'g-',
128
             label='Relative Humidity')
129
        self.ax3.legend(loc='upper center',bbox_to_anchor=(0.5,1.22),prop={'size':12})
130
        plt.setp(self.ax3.get_xticklabels(),visible=True)
131
        plt.grid(b=True,which='major',axis='y',color='k',linestyle='--',linewidth=0.5)
132
        self.ax3.set_ylim(plot_range[0],plot_range[1],plot_range[2])
133
        plt.fill_between(self.dates,RH,plt.ylim()[0],color='g')
134
        plt.ylabel('Relative Humidity\n(%)',multialignment='center')
135
        plt.gca().xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))
136
        axtwin = self.ax3.twinx()
137
        axtwin.set_ylim(plot_range[0],plot_range[1],plot_range[2])
138
        
139 View Code Duplication
    def plot_pressure(self,P,plot_range=[970,1030,2]):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
140
        """ 
141
        Required input:
142
            P: Mean Sea Level Pressure (hPa)
143
        Optional Input:
144
            plot_range: Data range for making figure
145
        """        
146
        # PLOT PRESSURE
147
        self.ax4 = fig.add_subplot(4, 1, 4,sharex=self.ax1)
148
        self.ax4.plot(self.dates,
149
             P,'m',label='Mean Sea Level Pressure')
150
        plt.ylabel('Mean Sea\nLevel Pressure\n(mb)', multialignment='center')
151
        plt.ylim(plot_range[0],plot_range[1],plot_range[2])
152
        #    plt.ylim(920,970)
153
        axtwin = self.ax4.twinx()
154
        axtwin.set_ylim(plot_range[0],plot_range[1],plot_range[2])
155
        #    axtwin.set_ylim(920,970)
156
        plt.fill_between(self.dates,P,plt.ylim()[0],color='m')
157
        plt.gca().xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))
158
159
        self.ax4.legend(loc='upper center',bbox_to_anchor=(0.5,1.2),prop={'size':12})
160
        plt.grid(b=True,which='major',axis='y',color='k',linestyle='--',linewidth=0.5)        
161
        plt.setp(self.ax4.get_xticklabels(), visible=True)
162
        
163
        # OTHER OPTIONAL AXES TO PLOT
164
        # plot_irradiance
165
        # plot_precipitation
166
        
167
    
168
169
# set the starttime and endtime for plotting, 24 hour range
170
endtime      = dt.datetime(2016,3,31,22,0,0,0)
171
starttime    = endtime - dt.timedelta(hours=24)
172
173
# Height of the station to calculate MSLP
174
hgt_example = 292.
175
176
177
# Parse dates from .csv file, knowing their format as a string and convert to datetime
178
def parse_date(date):
179
    return dt.datetime.strptime(date,"%Y-%m-%d %H:%M:%S")
180
181
testdata = np.genfromtxt(get_test_data('timeseries.csv', False), names=True, dtype=None,
182
                         usecols=list(range(1,8)),
183
                         converters={'DATE': parse_date}, delimiter=',')
184
185
# Temporary variables for ease
186
temp = testdata['T']
187
pres = testdata['P']
188
rh = testdata['RH']
189
ws = testdata['WS']
190
wsmax = testdata['WSMAX']
191
wd = testdata['WD']
192
date = testdata['DATE']    
193
194
# ID For Plotting on Meteogram
195
probe_id = '0102A'
196
197
data = dict()
198
data['wind_speed'] = (np.array(ws)*units('m/s')).to(units('knots'))
199
data['wind_speed_max'] = (np.array(wsmax)*units('m/s')).to(units('knots'))
200
data['wind_direction'] = np.array(wd)*units('degrees')
201
data['dewpoint'] = dewpoint_rh((np.array(temp)*units('degC')).to(units('K')),np.array(rh)/100.).to(units('degF'))
202
data['air_temperature'] = (np.array(temp)* units('degC')).to(units('degF')) 
203
data['mean_slp'] = calc_mslp(np.array(temp),np.array(pres),hgt_example) * units('hPa')
204
data['relative_humidity'] = np.array(rh)
205
data['times'] = np.array(date)    
206
207
fig = plt.figure(figsize=(20, 16))
208
meteogram = Meteogram(fig,data['times'],probe_id)
209
meteogram.plot_winds(data['wind_speed'],data['wind_direction'],data['wind_speed_max'])        
210
meteogram.plot_thermo(data['air_temperature'],data['dewpoint']) 
211
meteogram.plot_rh(data['relative_humidity']) 
212
meteogram.plot_pressure(data['mean_slp'])
213
fig.subplots_adjust(hspace=0.5)
214
plt.show()
215
#plt.text(1,1.02,meteogram.title,horizontalalignment='right',verticalalignment='bottom')        
216
217
218
219