From 6d994b9e7478164837873f23560a88b7d625a14e Mon Sep 17 00:00:00 2001 From: Ethan Gray Date: Sat, 18 Nov 2023 14:33:58 -0800 Subject: [PATCH] Documentation & README update --- .gitignore | 3 +++ GUI.py | 22 ++++++++++------ README.md | 59 ++++++++++++++++++++++++++++++++++++++++-- README_data/plot.png | Bin 0 -> 70726 bytes graph.py | 60 ++++++++++++++++++++++++++++++++++--------- main.py | 4 ++- 6 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 README_data/plot.png diff --git a/.gitignore b/.gitignore index 496f46d..f6e7371 100644 --- a/.gitignore +++ b/.gitignore @@ -150,3 +150,6 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + + +data/parquets/* \ No newline at end of file diff --git a/GUI.py b/GUI.py index 7b52a73..151d058 100644 --- a/GUI.py +++ b/GUI.py @@ -9,11 +9,12 @@ from graph import HydroGraph def create_gui(): + # Create a HydroGraph class to use all of its functions graph_backend = HydroGraph() # Create the main window root = tk.Tk() - root.title("River Flow Predictions") + root.title("FlowForecast") root.iconbitmap("data/eef-g.ico") # Create a Figure and a Canvas to draw the graph @@ -34,8 +35,12 @@ def validate_input(input): # Add a date selector date_selector = DateEntry(root) date_selector.pack() - + + # Add a button def collect_info(): + if not os.path.exists("data/parquets"): + os.makedirs("data/parquets") + selcted_date = date_selector.get_date().strftime("%Y-%m-%d") # selected_date = selected_date.strftime("%Y-%m-%d") selected_sensor = textbox.get() @@ -50,6 +55,11 @@ def collect_info(): canvas.figure = fig canvas.draw() + + button = ttk.Button(root, text="Get Data", command=collect_info) + button.pack() + + # Add a second button that clears the cached data def clear_cache(): cache_folder = "data" parquet_subfolder = f"{cache_folder}/parquets" @@ -57,14 +67,10 @@ def clear_cache(): for file in os.listdir(parquet_subfolder): file_path = os.path.join(parquet_subfolder, file) os.remove(file_path) - - # Add a button - button = ttk.Button(root, text="Get Data", command=collect_info) - button.pack() + - # Add a second button that clears the cached data cache_button = ttk.Button(root, text="Clear Cache", command=clear_cache) cache_button.pack() - # Start the main loop + # Start the application loop tk.mainloop() \ No newline at end of file diff --git a/README.md b/README.md index 143f015..6a4b8de 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,57 @@ -# Streamflow-Predictions - A python application that allows the user to predict waterflow in a given area + +

FlowForecast

+

A python application to predict river flow

+
+ + +

Libraries used:

+ +

+ CHydrofunctions + Pandas + Numpy + Matplotlib +

+
+
+
+
+
+
+ +

Features:

+ +
+
+
+ +

Example Graph:

+

+ Example graph +

+
+
+
+
+

Planned Features:

+ \ No newline at end of file diff --git a/README_data/plot.png b/README_data/plot.png new file mode 100644 index 0000000000000000000000000000000000000000..e470c2cc1c8af4eedd7629cc00528c0378ae4476 GIT binary patch literal 70726 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

wbWm7gHmV<@faZhZgS6J!Zx& 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 H%f{aUsp9_q literal 0 HcmV?d00001 diff --git a/graph.py b/graph.py index 8f1c1b5..9557a32 100644 --- a/graph.py +++ b/graph.py @@ -10,10 +10,16 @@ from datetime import datetime, timedelta class HydroGraph: + """ + This is the custom class that collects, parses, and plots data from a hydro sensor + """ def __init__(self): self.ResetVariables() def ResetVariables(self): + """ + Reset all class variables to allow for different sites and anchor dates to be passed through + """ # Self string variables self.sensor_id = '' self.anchor_date = '' @@ -43,20 +49,27 @@ def ResetVariables(self): self.graph_finished = False def SetFullInfo(self, date, id): + """ + Sets all of the information needed for the class at the same time + """ self.ResetVariables() self.SetSensorId(id) self.SetAnchorDate(date) def SetSensorId(self, id): + """ Set the class's sensor_id variable to the given id""" self.sensor_id = id def SetAnchorDate(self, date): + """ Set the class's anchor_date to the given date""" self.anchor_date = date self.current_year = date[:4] self.GetSensorName() self.CreatePlot() def CreatePlot(self): + """Plot all of the data stored in the class and assign it to the Figure in the class + [DOES NOT DISPLAY THE PLOT]""" # Collect all the needed data self.sensor_df = self.GetSensorDf(self.anchor_date, True) # Get the modern data self.GetHistoricDfs() # Get the historic data dfs @@ -68,11 +81,7 @@ def CreatePlot(self): self.ConvertDfs() # Converts all the dfs to arrays and stores them in the class # Split modern x and y vals for later - modern_x = [] - modern_y = [] - for point in self.modern_data: - modern_x.append(point[0]) - modern_y.append(point[1]) + modern_x, modern_y = zip(*self.modern_data) # Calculate the volume & flow volume = self.CalculateVolume(modern_y) @@ -117,7 +126,6 @@ def CreatePlot(self): self.ax.fill_between( avg_x, avg_high_y, avg_low_y, color='Gray', alpha=0.5) # Plot the anchor date - # today_obj = datetime.strptime(modern_x[-1], '%m-%d') self.ax.axvline(modern_x[-1], color='r', linestyle='--', label=f'{datetime.strftime(modern_x[-1], "%b %m %H:%M")}') # Add vertical line # Plot the linear regression line @@ -131,12 +139,13 @@ def CreatePlot(self): self.fig.autofmt_xdate() self.ax.legend() - # self.fig.show() + # Save the figure to disk & change the graph_finished flag for the GUI self.fig.savefig('plot.png') self.graph_finished = True def GetPlot(self): + """Returns the matplotlib Figure object""" return self.fig @@ -145,14 +154,18 @@ def GetHistoricDfs(self): overall_data = [] for i in range(int(self.current_year) - 9, int(self.current_year)): today_past = str(i) + self.anchor_date[4:] + # Request the data from year i and add it to the array overall_data.append(self.GetSensorDf(today_past, False)) - self.historic_dfs = overall_data + self.historic_dfs = overall_data # Set class variable to the array of historic dataframes def GetSensorDf(self, anchor, today_max=False): + """Grabs data from the class's sensor_id variable and gets data over a 3 week period""" # Calculate the start date as 2 weeks in the past from today past_date = self.GetPastDate(anchor) future_date = self.GetFutureDate(anchor) + + # Check if the given anchor date is the current date if not today_max: request = hf.NWIS(self.sensor_id, 'iv', past_date, future_date, file=f'data/parquets/{self.sensor_id}-{anchor}.parquet', verbose=False) else: @@ -164,33 +177,43 @@ def GetSensorDf(self, anchor, today_max=False): def GetSensorName(self): + """Uses the class's sensor_id variable to get the name of where the sensor is""" past_date = self.GetPastDate(self.anchor_date) request = hf.NWIS(self.sensor_id, 'iv', past_date, self.anchor_date, file=f'data/parquets/{self.sensor_id}-{self.anchor_date}.parquet', verbose=False) + # From the request, parse the header and get the name of the sensor sensor_caps = str(request)[str(request).index(' '):str(request).index('\n')] sensor_title = sensor_caps.title() + # Set the sensor name to the formatted string slices self.sensor_name = sensor_title[:-2] + sensor_caps[-2:] def GetPastDate(self, date_str): + """Returns a string two weeks in the past from the given date""" date_obj = datetime.strptime(date_str, '%Y-%m-%d') past_date = date_obj - timedelta(weeks=2) return past_date.strftime('%Y-%m-%d') def GetFutureDate(self, date_str): + """Returns a string one week in the future from the given date""" date_obj = datetime.strptime(date_str, '%Y-%m-%d') future_date = date_obj + timedelta(weeks=1) return future_date.strftime('%Y-%m-%d') def GetLowestDf(self): + """Finds the DataFrame that contains the lowest point from the historical data""" + # Set lowest to the current year's lowest point lowest = min(self.sensor_df.loc[:, list(self.sensor_df)[0]]) lowest_index = -1 + # Go thru each historic dataframe and look for a lower point for i in range(len(self.historic_dfs)): historic_lowest = min(self.historic_dfs[i].loc[:, list(self.historic_dfs[i])[0]]) + # If year i has a lower point than what is stored, update the stored lowest point if historic_lowest < lowest: lowest = historic_lowest lowest_index = i + # Check if there was a lower point than current year's lowest & update values accordingly if lowest_index != -1: self.lowest_df = self.historic_dfs[lowest_index] self.lowest_year = str(int(self.current_year) - lowest_index + 1) @@ -200,13 +223,18 @@ def GetLowestDf(self): def GetHighestDf(self): + """Finds the DataFrame that contains the highest point from the historical data""" + # Set highest to the current year's highest point highest = max(self.sensor_df.loc[:, list(self.sensor_df)[0]]) highest_index = -1 + # Go thru each historic dataframe and look for a higher point for i in range(len(self.historic_dfs)): historic_highest = max(self.historic_dfs[i].loc[:, list(self.historic_dfs[i])[0]]) + # If year i has a higher point than what is stored, update the stored highest point if historic_highest > highest: highest = historic_highest highest_index = i + # Check if there was a higher point than the current year's highest & update values accordingly if highest_index != -1: self.highest_df = self.historic_dfs[highest_index] self.highest_year = str(int(self.current_year) - highest_index + 1) @@ -216,12 +244,18 @@ def GetHighestDf(self): def GetAverageFromData(self): + """Creates a dataframe that contains the average for each timestamp from all historic data""" + # Set aside a list for where we will store the y-values disc_values = [] + # Go through each row of the historic dataframes for i in range(len(self.historic_dfs[0])): + # Set aside list to store the current row at each historic year curr_time_data = [] + # Go thru each year and add the year j's value at row i for j in range(len(self.historic_dfs)): data_lump = self.historic_dfs[j].loc[:, list(self.historic_dfs[j])[0]] curr_time_data.append(data_lump[i]) + # Calculate the average of the row and add it to the overall average y-values avg = sum(curr_time_data) / len(curr_time_data) disc_values.append(avg) @@ -232,6 +266,7 @@ def GetAverageFromData(self): def ConvertDfs(self): + """Converts each class dataframe into a zipped list for graphing""" self.modern_data = self.DfToArray(self.sensor_df) self.lowest_data = self.DfToArray(self.lowest_df) self.highest_data = self.DfToArray(self.highest_df) @@ -239,6 +274,7 @@ def ConvertDfs(self): def DfToArray(self, df): + """Converts the given dataframe, df, into a zipped list""" columns = list(df) y_vals = df.loc[:, columns[0]] raw_dates = [str(date) for date in df.index] @@ -247,6 +283,7 @@ def DfToArray(self, df): def CalculateVolume(self, y_vals): + """Calculates the river's total volume from the given y_values. Assumes that data is taken in CFS every 15 minutes.""" # Time interval in seconds (15 minutes = 900 seconds) delta_t = 15 * 60 # Calculate total volume in cubic feet @@ -257,6 +294,7 @@ def CalculateVolume(self, y_vals): def CalculateFlow(self, y_vals): + """Calculates the river's flow from the given y_values. Assumes that data is taken in CFS every 15 minutes.""" if len(y_vals) < 2: return None last_val = y_vals[-1] @@ -270,7 +308,5 @@ def CalculateFlow(self, y_vals): if __name__ == "__main__": trinity_id = '11527000' today = '2023-06-05' - # graph = HydroGraph() - # graph.SetFullInfo(today, trinity_id) - nwis_dict = hf.extract_nwis_df() - print(nwis_dict) \ No newline at end of file + graph = HydroGraph() + graph.SetFullInfo(today, trinity_id) \ No newline at end of file diff --git a/main.py b/main.py index db49ba3..a813620 100644 --- a/main.py +++ b/main.py @@ -3,15 +3,17 @@ REQUIRED_PACKAGES = ['hydrofunctions', 'tkcalendar','matplotlib', 'pandas', 'numpy'] +# Check and make sure all of the required packages are installed on the computer & install any uninstalled packages for package in REQUIRED_PACKAGES: try: dist = distribution(package) except: subprocess.call(['pip', 'install', package]) +# Now import the files that are used in the project to avoid any missing dependencies import GUI import warnings if __name__ == "__main__": - warnings.simplefilter(action='ignore', category=FutureWarning) + warnings.simplefilter(action='ignore', category=FutureWarning) # Mute the warning about sorting by keys GUI.create_gui() \ No newline at end of file