|
| 1 | +import wx |
| 2 | +import wx.xrc |
| 3 | +import pandas as pd |
| 4 | +import matplotlib |
| 5 | +from matplotlib.figure import Figure |
| 6 | +from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas |
| 7 | + |
| 8 | +import datetime |
| 9 | + |
| 10 | +from sys import version |
| 11 | +if version > '3': |
| 12 | + from urllib.request import urlopen |
| 13 | + |
| 14 | +else: |
| 15 | + from urllib2 import urlopen |
| 16 | + |
| 17 | + |
| 18 | +def read_usgs_rdb(filepath_or_link): |
| 19 | + return pd.read_csv(filepath_or_link, comment='#', header=0, sep='\t')[1:].apply(lambda x: pd.to_numeric(x, errors='ignore') if x.name.endswith('_va') else x, axis=0) |
| 20 | + |
| 21 | + |
| 22 | +def create_streamflow_url(gauge_list, begin_date='1900-01-01', end_date='2019-12-31', step='D'): |
| 23 | + if type(gauge_list) is not list: |
| 24 | + raise TypeError('The gagelist must be a list type.') |
| 25 | + |
| 26 | + if gauge_list == []: |
| 27 | + raise ValueError('The gagelist must not be an empty list.') |
| 28 | + |
| 29 | + if step == 'D': |
| 30 | + gages = ('&site_no={}' * len(gauge_list)).format(*gauge_list) |
| 31 | + period = '&period=&begin_date={}&end_date={}'.format(begin_date, end_date) |
| 32 | + url = 'https://waterdata.usgs.gov/nwis/dv?&cb_00060=on&format=rdb{}&referred_module=sw{}'.format(gages, period) |
| 33 | + elif step == 'M': |
| 34 | + gages = ''.join(['&site_no={0}&por_{0}_93535=594467,00060,93535,{1:.7},{2:.7}'.format(g, begin_date, end_date) for g in gauge_list]) |
| 35 | + url = 'https://waterdata.usgs.gov/nwis/monthly?referred_module=sw&format=rdb{}'.format(gages) |
| 36 | + return url |
| 37 | + |
| 38 | + |
| 39 | +def read_usgs_flow(gauge_list, begin_date='1900-01-01', end_date='2019-12-31', step='D'): |
| 40 | + |
| 41 | + print('Requested gauges: ', gauge_list) |
| 42 | + print('Requested period: ', begin_date, end_date) |
| 43 | + |
| 44 | + try: |
| 45 | + bdate = datetime.datetime.strptime(begin_date, '%Y-%m-%d') |
| 46 | + edate = datetime.datetime.strptime(end_date, '%Y-%m-%d') |
| 47 | + except: |
| 48 | + raise ValueError ("The input formats for the begin_date:{} and end_date:{} must be YYYY-MM-DD".format(begin_date, end_date)) |
| 49 | + |
| 50 | + url = create_streamflow_url(gauge_list, begin_date, end_date, step) |
| 51 | + |
| 52 | + print('\nDownloading USGS observed streamflow data:') |
| 53 | + print(url, '\n') |
| 54 | + |
| 55 | + |
| 56 | + df = read_usgs_rdb(url).drop('agency_cd', axis=1) |
| 57 | + if step != 'D': |
| 58 | + df['datetime'] = df.apply(lambda x: datetime.datetime(int(x.year_nu), int(x.month_nu), 1), axis=1) |
| 59 | + df.drop(['year_nu', 'month_nu', 'parameter_cd', 'ts_id'], axis=1, inplace=True) |
| 60 | + df.set_index('datetime', inplace=True) |
| 61 | + |
| 62 | + f_url = urlopen(url) |
| 63 | + lines = [f_url.readline() for i in range(1000 + len(gauge_list))] |
| 64 | + f_url.close() |
| 65 | + gauge_names = dict() |
| 66 | + |
| 67 | + # read name of the gauge |
| 68 | + def find_site_name(gauge_no): |
| 69 | + for l in lines: |
| 70 | + if gauge_no.encode() in l: |
| 71 | + return l |
| 72 | + |
| 73 | + for g in gauge_list: |
| 74 | + l = find_site_name(g) |
| 75 | + gauge_names[g] = l.strip().lstrip(b'#').strip().decode() |
| 76 | + |
| 77 | + return df, gauge_names |
| 78 | + |
| 79 | + |
| 80 | +class MyFrame1 ( wx.Frame ): |
| 81 | + |
| 82 | + def __init__( self, parent ): |
| 83 | + wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 672,423 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) |
| 84 | + |
| 85 | + self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) |
| 86 | + |
| 87 | + bSizer1 = wx.BoxSizer( wx.VERTICAL ) |
| 88 | + |
| 89 | + bSizer2 = wx.BoxSizer( wx.HORIZONTAL ) |
| 90 | + |
| 91 | + self.m_textCtrl1 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) |
| 92 | + bSizer2.Add( self.m_textCtrl1, 1, wx.ALL, 5 ) |
| 93 | + |
| 94 | + self.m_button1 = wx.Button( self, wx.ID_ANY, u"Download&Plot", wx.DefaultPosition, wx.DefaultSize, 0 ) |
| 95 | + bSizer2.Add( self.m_button1, 0, wx.ALL, 5 ) |
| 96 | + |
| 97 | + |
| 98 | + bSizer1.Add( bSizer2, 0, wx.EXPAND, 5 ) |
| 99 | + |
| 100 | + self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) |
| 101 | + bSizer1.Add( self.m_panel1, 1, wx.EXPAND |wx.ALL, 5 ) |
| 102 | + |
| 103 | + self.m_panel1.figure = matplotlib.figure.Figure() |
| 104 | + self.axes = self.m_panel1.figure.add_subplot(111) |
| 105 | + |
| 106 | + |
| 107 | + |
| 108 | + self.SetSizer( bSizer1 ) |
| 109 | + self.Layout() |
| 110 | + |
| 111 | + self.Centre( wx.BOTH ) |
| 112 | + |
| 113 | + self.Bind(wx.EVT_BUTTON, self.download_usgs, self.m_button1) |
| 114 | + |
| 115 | + def download_usgs(self, event): |
| 116 | + station_id = self.m_textCtrl1.GetValue() |
| 117 | + df, names = read_usgs_flow([station_id]) |
| 118 | + pd.to_numeric(df.iloc[:, 1]).plot(ax=self.axes) |
| 119 | + print(df.head()) |
| 120 | + self.canvas = FigureCanvas(self.m_panel1,-1,self.m_panel1.figure) |
| 121 | + def __del__( self ): |
| 122 | + pass |
| 123 | + |
| 124 | +if __name__ == '__main__': |
| 125 | + app = wx.App(redirect=True) |
| 126 | + frm = MyFrame1(None) |
| 127 | + frm.Show() |
| 128 | + app.MainLoop() |
| 129 | + |
0 commit comments