From 149ea8d8cfe9ee1723b44739e23bef10ab68b430 Mon Sep 17 00:00:00 2001 From: Connor Ferster Date: Thu, 25 Jul 2024 09:37:41 -0700 Subject: [PATCH 1/2] consolidate maximum force plot clauses --- functions.py | 353 ++++++++++----------------------------------------- 1 file changed, 69 insertions(+), 284 deletions(-) diff --git a/functions.py b/functions.py index a1bea1d..e829f5c 100644 --- a/functions.py +++ b/functions.py @@ -193,290 +193,6 @@ def generate_plot(option, new_df, safe_pile_capacity=None, safe_pile_tensile_cap yaxis_title='Y Coordinate', ) - elif option == 'Maximum Fx': - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fx: {row["Max +Fx"]} kN
Combination +Fx: {row["Max +Fx Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -Fx: {row["Max -Fx"]} kN
Combination -Fx: {row["Max -Fx Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fx: {row["Max +Fx"]} kN
Max -Fx: {row["Max -Fx"]} kN
Combination +Fx: {row["Max +Fx Combination"]}
Combination -Fx: {row["Max -Fx Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] Fx", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum Fx and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - elif option == 'Maximum Fy': - - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fy: {row["Max +Fy"]} kN
Combination +Fy: {row["Max +Fy Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -Fy: {row["Max -Fy"]} kN
Combination -Fy: {row["Max -Fy Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fy: {row["Max +Fy"]} kN
Max -Fy: {row["Max -Fy"]} kN
Combination +Fy: {row["Max +Fy Combination"]}
Combination -Fy: {row["Max -Fy Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] Fy", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum Fy and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - elif option == 'Maximum Fz': - - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fz: {row["Max +Fz"]} kN
Combination +Fz: {row["Max +Fz Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -Fz: {row["Max -Fz"]} kN
Combination -Fz: {row["Max -Fz Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Fz: {row["Max +Fz"]} kN
Max -Fz: {row["Max -Fz"]} kN
Combination +Fz: {row["Max +Fz Combination"]}
Combination -Fz: {row["Max -Fz Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] Fz", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum Fz and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - - elif option == 'Maximum Mx': - - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Mx: {row["Max +Mx"]} kN
Combination +Mx: {row["Max +Mx Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -Mx: {row["Max -Mx"]} kN
Combination -Mx: {row["Max -Mx Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Mx: {row["Max +Mx"]} kN
Max -Mx: {row["Max -Mx"]} kN
Combination +Mx: {row["Max +Mx Combination"]}
Combination -Mx: {row["Max -Mx Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] Mx", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum Mx and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - elif option == 'Maximum My': - - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +My: {row["Max +My"]} kN
Combination +My: {row["Max +My Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -My: {row["Max -My"]} kN
Combination -My: {row["Max -My Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +My: {row["Max +My"]} kN
Max -My: {row["Max -My"]} kN
Combination +My: {row["Max +My Combination"]}
Combination -My: {row["Max -My Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] My", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum My and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - - elif option == 'Maximum Mz': - - max_primary = new_df[f'Max +{option.split()[-1]}'] - max_secondary = new_df[f'Max -{option.split()[-1]}'] - - fig = make_subplots(rows=2, cols=1) - - hovertext01 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Mz: {row["Max +Mz"]} kN
Combination +Mz: {row["Max +Mz Combination"]}', axis=1) - hovertext02 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max -Mz: {row["Max -Mz"]} kN
Combination -Mz: {row["Max -Mz Combination"]}', axis=1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_primary, - name=f'Maximum +{option.split()[-1]}', - text=hovertext01, - hoverinfo='text' - ), row= 1, col= 1) - fig.add_trace(go.Bar( - x=new_df['Support'], - y=max_secondary, - name=f'Maximum -{option.split()[-1]}', - text=hovertext02, - hoverinfo='text' - ), row=1, col=1) - - scatter_color = 'blue' # Adjust scatter color based on option - hovertext03 = new_df.apply(lambda row: f'Support: {row["Support"]}
Max +Mz: {row["Max +Mz"]} kN
Max -Mz: {row["Max -Mz"]} kN
Combination +Mz: {row["Max +Mz Combination"]}
Combination -Mz: {row["Max -Mz Combination"]}', axis=1) - - fig.add_trace(go.Scatter( - x=new_df['X Coordinate'], - y=new_df["Y Coordinate"], - mode='markers', - marker=dict(color=scatter_color), - name="Max [+/-] Mz", - text=hovertext03, - hoverinfo='text' - ), row=2, col=1) - - fig.update_layout( - title='Maximum Mz and Support Coordinates', - autosize=False, - width=1300, - height=900 - - ) - - fig.update_yaxes(automargin=True) - - elif option == 'Number of Piles': if safe_pile_capacity is None: raise ValueError("Safe pile capacity must be provided for 'Number of Piles' option") @@ -526,6 +242,75 @@ def generate_plot(option, new_df, safe_pile_capacity=None, safe_pile_tensile_cap ) + elif 'maximum' in option.lower(): + force_dir = option.split()[-1] + max_primary = new_df[f'Max +{force_dir}'] + max_secondary = new_df[f'Max -{force_dir}'] + + fig = make_subplots(rows=2, cols=1) + + hovertext01 = new_df.apply( + lambda row: ( + f'Support: {row["Support"]}
' + f'Max +{force_dir}: {row[f"Max +{force_dir}"]} kN
' + f'Combination +Fx: {row[f"Max +{force_dir} Combination"]}' + ), axis=1 + ) + hovertext02 = new_df.apply( + lambda row: ( + f'Support: {row["Support"]}
' + f'Max -{force_dir}: {row[f"Max -{force_dir}"]} kN
' + f'Combination -Fx: {row[f"Max -{force_dir} Combination"]}' + ), axis=1 + ) + + fig.add_trace(go.Bar( + x=new_df['Support'], + y=max_primary, + name=f'Maximum +{force_dir}', + text=hovertext01, + hoverinfo='text' + ), row= 1, col= 1) + fig.add_trace(go.Bar( + x=new_df['Support'], + y=max_secondary, + name=f'Maximum -{force_dir}', + text=hovertext02, + hoverinfo='text' + ), row=1, col=1) + + scatter_color = 'blue' # Adjust scatter color based on option + hovertext03 = new_df.apply( + lambda row: ( + f'Support: {row["Support"]}
' + f'Max +{force_dir}: {row[f"Max +{force_dir}"]} kN
' + f'Max -{force_dir}: {row[f"Max -{force_dir}"]} kN
' + f'Combination +{force_dir}: {row[f"Max +{force_dir} Combination"]}
' + f'Combination -{force_dir}: {row[f"Max -{force_dir} Combination"]}' + ) + ,axis=1 + ) + + fig.add_trace(go.Scatter( + x=new_df['X Coordinate'], + y=new_df["Y Coordinate"], + mode='markers', + marker=dict(color=scatter_color), + name=f"Max [+/-] {force_dir}", + text=hovertext03, + hoverinfo='text' + ), row=2, col=1) + + fig.update_layout( + title=f'Maximum {force_dir} and Support Coordinates', + autosize=False, + width=1300, + height=900 + + ) + + fig.update_yaxes(automargin=True) + else: raise ValueError(f"Invalid option {option}.") From 2c2a56432b7e8129869be5cac3afc65b36a92a91 Mon Sep 17 00:00:00 2001 From: Connor Ferster Date: Fri, 26 Jul 2024 10:00:11 -0700 Subject: [PATCH 2/2] refactored functions.generate_data_for_display - Kept all operations "in pandas" --- functions.py | 139 +++++++++++++-------------------------------------- 1 file changed, 34 insertions(+), 105 deletions(-) diff --git a/functions.py b/functions.py index e829f5c..436b36a 100644 --- a/functions.py +++ b/functions.py @@ -42,110 +42,38 @@ def find_extremes(series, combinations): return max_positive, max_positive_combination, max_negative, max_negative_combination def generate_data_for_display(df_data): - supports = [] - x_coordinates = [] - y_coordinates = [] - z_coordinates = [] - max_pos_fx = [] - max_pos_fx_comb = [] - max_neg_fx = [] - max_neg_fx_comb = [] - max_pos_fy = [] - max_pos_fy_comb = [] - max_neg_fy = [] - max_neg_fy_comb = [] - max_pos_fz = [] - max_pos_fz_comb = [] - max_neg_fz = [] - max_neg_fz_comb = [] - max_pos_Mx = [] - max_pos_Mx_comb = [] - max_neg_Mx = [] - max_neg_Mx_comb = [] - max_pos_My = [] - max_pos_My_comb = [] - max_neg_My = [] - max_neg_My_comb = [] - max_pos_Mz = [] - max_pos_Mz_comb = [] - max_neg_Mz = [] - max_neg_Mz_comb = [] - - unique_supports = df_data.index.get_level_values('Support').unique() - - for support in unique_supports: - x_coord = df_data.loc[support, 'X Coordinate'].unique()[0] - y_coord = df_data.loc[support, 'Y Coordinate'].unique()[0] - z_coord = df_data.loc[support, 'Z Coordinate'].unique()[0] - - max_positive_fx, max_positive_comb_fx, max_negative_fx, max_negative_comb_fx = find_extremes(df_data.loc[support]['Fx [kN]'], df_data.loc[support]['Combination']) - max_positive_fy, max_positive_comb_fy, max_negative_fy, max_negative_comb_fy = find_extremes(df_data.loc[support]['Fy [kN]'], df_data.loc[support]['Combination']) - max_positive_fz, max_positive_comb_fz, max_negative_fz, max_negative_comb_fz = find_extremes(df_data.loc[support]['Fz [kN]'], df_data.loc[support]['Combination']) - max_positive_Mx, max_positive_comb_Mx, max_negative_Mx, max_negative_comb_Mx = find_extremes(df_data.loc[support]['Mx [kNm]'], df_data.loc[support]['Combination']) - max_positive_My, max_positive_comb_My, max_negative_My, max_negative_comb_My = find_extremes(df_data.loc[support]['My [kNm]'], df_data.loc[support]['Combination']) - max_positive_Mz, max_positive_comb_Mz, max_negative_Mz, max_negative_comb_Mz = find_extremes(df_data.loc[support]['Mz [kNm]'], df_data.loc[support]['Combination']) - - supports.append(support) - x_coordinates.append(x_coord) - y_coordinates.append(y_coord) - z_coordinates.append(z_coord) - max_pos_fx.append(max_positive_fx) - max_pos_fx_comb.append(max_positive_comb_fx) - max_neg_fx.append(max_negative_fx) - max_neg_fx_comb.append(max_negative_comb_fx) - max_pos_fy.append(max_positive_fy) - max_pos_fy_comb.append(max_positive_comb_fy) - max_neg_fy.append(max_negative_fy) - max_neg_fy_comb.append(max_negative_comb_fy) - max_pos_fz.append(max_positive_fz) - max_pos_fz_comb.append(max_positive_comb_fz) - max_neg_fz.append(max_negative_fz) - max_neg_fz_comb.append(max_negative_comb_fz) - max_pos_Mx.append(max_positive_Mx) - max_pos_Mx_comb.append(max_positive_comb_Mx) - max_neg_Mx.append(max_negative_Mx) - max_neg_Mx_comb.append(max_negative_comb_Mx) - max_pos_My.append(max_positive_My) - max_pos_My_comb.append(max_positive_comb_My) - max_neg_My.append(max_negative_My) - max_neg_My_comb.append(max_negative_comb_My) - max_pos_Mz.append(max_positive_Mz) - max_pos_Mz_comb.append(max_positive_comb_Mz) - max_neg_Mz.append(max_negative_Mz) - max_neg_Mz_comb.append(max_negative_comb_Mz) - - new_data = { - 'Support': supports, - 'X Coordinate': x_coordinates, - 'Y Coordinate': y_coordinates, - 'Z Coordinate': z_coordinates, - 'Max +Fx': max_pos_fx, - 'Max +Fx Combination': max_pos_fx_comb, - 'Max -Fx': max_neg_fx, - 'Max -Fx Combination': max_neg_fx_comb, - 'Max +Fy': max_pos_fy, - 'Max +Fy Combination': max_pos_fy_comb, - 'Max -Fy': max_neg_fy, - 'Max -Fy Combination': max_neg_fy_comb, - 'Max +Fz': max_pos_fz, - 'Max +Fz Combination': max_pos_fz_comb, - 'Max -Fz': max_neg_fz, - 'Max -Fz Combination': max_neg_fz_comb, - 'Max +Mx': max_pos_Mx, - 'Max +Mx Combination': max_pos_Mx_comb, - 'Max -Mx': max_neg_Mx, - 'Max -Mx Combination': max_neg_Mx_comb, - 'Max +My': max_pos_My, - 'Max +My Combination': max_pos_My_comb, - 'Max -My': max_neg_My, - 'Max -My Combination': max_neg_My_comb, - 'Max +Mz': max_pos_Mz, - 'Max +Mz Combination': max_pos_Mz_comb, - 'Max -Mz': max_neg_Mz, - 'Max -Mz Combination': max_neg_Mz_comb, - } - - new_df = pd.DataFrame(new_data) + # I took a try at removing all of the accumulators and manual DataFrame building + # See below. Your 'find_extremes' function is what makes all of this work! + + df_acc = pd.DataFrame() + for force_col in ['Fx [kN]', 'Fy [kN]', 'Fz [kN]', 'Mx [kNm]', 'My [kNm]','Mz [kNm]']: + force_dir = force_col.split(" ")[0] + + # The next line creates a series with an index of "Support" but each cell contains a tuple of the four values + # So we need to split the values out of tuples and into their own separate columns + # This find_extremes function is great (well done!) Let's use it in .apply! + result_series = df_data.groupby(['Support']).apply(lambda x: find_extremes(x[force_col], x['Combination'])) + enveloped_column_names = ( + f"Max +{force_dir}", + f"Max +{force_dir} Combination", + f"Max -{force_dir}", + f"Max -{force_dir} Combination" + ) + + # If the result is a series of tuples (with an index), then if we convert the series to a list then we have + # a list of tuples which can be used to create a new df with however-many-rows x four-columns + enveloped_df = pd.DataFrame(data = result_series.to_list(), index=result_series.index, columns=enveloped_column_names) + df_acc = pd.concat([df_acc, enveloped_df], axis=1) + + # Last, we need to add the X, Y, Z coordinates. + # If our indexes match, then we can just add the columns onto our 'df_acc' + # without needing to do anything fancy. + + coords_df = df_data.reset_index().loc[:, ['Support', 'X Coordinate', 'Y Coordinate', 'Z Coordinate']].drop_duplicates() + coords_df = coords_df.set_index(['Support']) + + new_df = pd.concat([coords_df, df_acc], axis=1).reset_index() # Take "Support" out of the index and back in to the columns + return new_df def calculate_piles(safe_capacity, max_load): @@ -241,7 +169,8 @@ def generate_plot(option, new_df, safe_pile_capacity=None, safe_pile_tensile_cap hovermode='closest' ) - + # I also removed the repetitive plotting code. They all seemed to be exactly the same + # except for the hover labels so I parametrized the hover labels so you only need one elif 'maximum' in option.lower(): force_dir = option.split()[-1] max_primary = new_df[f'Max +{force_dir}']