Commit 
							
							·
						
						1a93ec0
	
0
								Parent(s):
							
							
Initial commit for Safe Withdrawal Rate Calculator Gradio app
Browse files- README.md +29 -0
- app.py +222 -0
- requirements.txt +3 -0
    	
        README.md
    ADDED
    
    | @@ -0,0 +1,29 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            # Safe Withdrawal Rate Calculator
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This Hugging Face Space hosts an interactive application that performs Monte Carlo simulations to determine a safe withdrawal rate from a retirement portfolio. Users can adjust various financial parameters and instantly see the impact on portfolio success rates and projected portfolio paths.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## How to Use
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            1.  **Adjust Parameters**: On the left side of the interface, you will find several sections with sliders and number inputs:
         | 
| 8 | 
            +
                *   **Investment Details**: Set your initial investment, the number of years for the simulation, your target success rate, and the number of Monte Carlo simulations to run.
         | 
| 9 | 
            +
                *   **Market Assumptions**: Define the expected mean returns and standard deviations for stocks and bonds, their correlation, and your portfolio's stock allocation.
         | 
| 10 | 
            +
                *   **Inflation Assumptions**: Input the mean inflation rate and its standard deviation.
         | 
| 11 | 
            +
                *   **SWR Test Range**: Specify the range and step for the Safe Withdrawal Rates you want to test.
         | 
| 12 | 
            +
            2.  **Run Simulation**: Click the "Run Simulation" button.
         | 
| 13 | 
            +
            3.  **View Results**: The right side of the interface will display:
         | 
| 14 | 
            +
                *   **Calculated Safe Withdrawal Rate**: Text output showing the highest SWR that meets your target success rate and the corresponding initial annual withdrawal amount.
         | 
| 15 | 
            +
                *   **SWR Success Rates Plot**: A graph showing the probability of portfolio success for various withdrawal rates.
         | 
| 16 | 
            +
                *   **Sample Portfolio Paths Plot**: A visualization of how a sample of portfolios might perform over the simulation period.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ## Technical Details
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            This application is built using:
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            *   **Python**: For the core simulation logic.
         | 
| 23 | 
            +
            *   **NumPy**: For numerical operations and statistical calculations.
         | 
| 24 | 
            +
            *   **Matplotlib**: For generating the simulation plots.
         | 
| 25 | 
            +
            *   **Gradio**: For creating the interactive web interface, allowing easy deployment to Hugging Face Spaces.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## Deployment
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            This application is designed to be deployed on Hugging Face Spaces. The `app.py` file contains the Gradio application, and `requirements.txt` lists all necessary Python dependencies.
         | 
    	
        app.py
    ADDED
    
    | @@ -0,0 +1,222 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import numpy as np
         | 
| 2 | 
            +
            import matplotlib.pyplot as plt
         | 
| 3 | 
            +
            import gradio as gr
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def run_simulation(
         | 
| 6 | 
            +
                initial_investment: float,
         | 
| 7 | 
            +
                num_years: int,
         | 
| 8 | 
            +
                num_simulations: int,
         | 
| 9 | 
            +
                target_success_rate: float,
         | 
| 10 | 
            +
                stock_mean_return: float,
         | 
| 11 | 
            +
                stock_std_dev: float,
         | 
| 12 | 
            +
                bond_mean_return: float,
         | 
| 13 | 
            +
                bond_std_dev: float,
         | 
| 14 | 
            +
                stock_allocation: float,
         | 
| 15 | 
            +
                correlation_stock_bond: float,
         | 
| 16 | 
            +
                mean_inflation: float,
         | 
| 17 | 
            +
                std_dev_inflation: float,
         | 
| 18 | 
            +
                min_swr_test: float,
         | 
| 19 | 
            +
                max_swr_test: float,
         | 
| 20 | 
            +
                swr_test_step: float
         | 
| 21 | 
            +
            ):
         | 
| 22 | 
            +
                # --- Core Parameters ---
         | 
| 23 | 
            +
                initial_investment = float(initial_investment)
         | 
| 24 | 
            +
                num_years = int(num_years)
         | 
| 25 | 
            +
                num_simulations = int(num_simulations)
         | 
| 26 | 
            +
                target_success_rate = float(target_success_rate) / 100.0 # Convert percentage to decimal
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # --- Financial Assumptions (NOMINAL) ---
         | 
| 29 | 
            +
                stock_mean_return = float(stock_mean_return) / 100.0
         | 
| 30 | 
            +
                stock_std_dev = float(stock_std_dev) / 100.0
         | 
| 31 | 
            +
                bond_mean_return = float(bond_mean_return) / 100.0
         | 
| 32 | 
            +
                bond_std_dev = float(bond_std_dev) / 100.0
         | 
| 33 | 
            +
                stock_allocation = float(stock_allocation) / 100.0
         | 
| 34 | 
            +
                bond_allocation = 1.0 - stock_allocation
         | 
| 35 | 
            +
                correlation_stock_bond = float(correlation_stock_bond)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                mean_inflation = float(mean_inflation) / 100.0
         | 
| 38 | 
            +
                std_dev_inflation = float(std_dev_inflation) / 100.0
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                # --- Covariance Matrix for generating correlated asset returns ---
         | 
| 41 | 
            +
                mean_asset_returns = np.array([stock_mean_return, bond_mean_return])
         | 
| 42 | 
            +
                cov_matrix = np.array([
         | 
| 43 | 
            +
                    [stock_std_dev**2, correlation_stock_bond * stock_std_dev * bond_std_dev],
         | 
| 44 | 
            +
                    [correlation_stock_bond * stock_std_dev * bond_std_dev, bond_std_dev**2]
         | 
| 45 | 
            +
                ])
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # --- SWRs to Test ---
         | 
| 48 | 
            +
                withdrawal_rates_to_test = np.arange(min_swr_test / 100.0, (max_swr_test + swr_test_step) / 100.0, swr_test_step / 100.0)
         | 
| 49 | 
            +
                all_results = []
         | 
| 50 | 
            +
                portfolio_paths_for_plotting = {}
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                for swr in withdrawal_rates_to_test:
         | 
| 53 | 
            +
                    success_count = 0
         | 
| 54 | 
            +
                    current_swr_paths = []
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    for i in range(num_simulations):
         | 
| 57 | 
            +
                        portfolio_value = float(initial_investment)
         | 
| 58 | 
            +
                        current_annual_withdrawal_nominal = initial_investment * swr
         | 
| 59 | 
            +
                        
         | 
| 60 | 
            +
                        simulation_failed_this_run = False
         | 
| 61 | 
            +
                        path = [portfolio_value]
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                        for year in range(num_years):
         | 
| 64 | 
            +
                            if year > 0:
         | 
| 65 | 
            +
                                yearly_inflation = np.random.normal(mean_inflation, std_dev_inflation)
         | 
| 66 | 
            +
                                yearly_inflation = max(yearly_inflation, -0.05)
         | 
| 67 | 
            +
                                current_annual_withdrawal_nominal *= (1 + yearly_inflation)
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                            portfolio_value -= current_annual_withdrawal_nominal
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                            if portfolio_value <= 0:
         | 
| 72 | 
            +
                                simulation_failed_this_run = True
         | 
| 73 | 
            +
                                portfolio_value = 0
         | 
| 74 | 
            +
                                path.append(portfolio_value)
         | 
| 75 | 
            +
                                break
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                            asset_returns_this_year = np.random.multivariate_normal(mean_asset_returns, cov_matrix)
         | 
| 78 | 
            +
                            portfolio_return_this_year = (stock_allocation * asset_returns_this_year[0] +
         | 
| 79 | 
            +
                                                          bond_allocation * asset_returns_this_year[1])
         | 
| 80 | 
            +
                            portfolio_return_this_year = max(portfolio_return_this_year, -0.99)
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                            portfolio_value *= (1 + portfolio_return_this_year)
         | 
| 83 | 
            +
                            path.append(portfolio_value)
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                        if not simulation_failed_this_run:
         | 
| 86 | 
            +
                            success_count += 1
         | 
| 87 | 
            +
                        
         | 
| 88 | 
            +
                        if swr == 0.035 and i < 100:
         | 
| 89 | 
            +
                             current_swr_paths.append(path)
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    success_probability = success_count / num_simulations
         | 
| 92 | 
            +
                    all_results.append({'swr': swr, 'success_rate': success_probability})
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                    if swr == 0.035:
         | 
| 95 | 
            +
                        portfolio_paths_for_plotting[swr] = current_swr_paths
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                final_swr = 0.0
         | 
| 98 | 
            +
                initial_annual_withdrawal_amount = 0.0
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                eligible_rates = [r for r in all_results if r['success_rate'] >= target_success_rate]
         | 
| 101 | 
            +
                if eligible_rates:
         | 
| 102 | 
            +
                    final_swr = max(r['swr'] for r in eligible_rates)
         | 
| 103 | 
            +
                    initial_annual_withdrawal_amount = initial_investment * final_swr
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                results_text = ""
         | 
| 106 | 
            +
                if final_swr > 0:
         | 
| 107 | 
            +
                    results_text += f"The highest Safe Withdrawal Rate for {target_success_rate*100:.0f}% success over {num_years} years is approximately: {final_swr*100:.2f}%\n"
         | 
| 108 | 
            +
                    results_text += f"This corresponds to an initial annual withdrawal of: ${initial_annual_withdrawal_amount:,.2f}\n"
         | 
| 109 | 
            +
                else:
         | 
| 110 | 
            +
                    results_text += f"No tested SWR achieved the {target_success_rate*100:.0f}% success rate with the given assumptions.\n"
         | 
| 111 | 
            +
                    lowest_tested_swr = min(r['swr'] for r in all_results)
         | 
| 112 | 
            +
                    highest_success_at_lowest_swr = [r['success_rate'] for r in all_results if r['swr'] == lowest_tested_swr][0]
         | 
| 113 | 
            +
                    results_text += f"The lowest tested SWR ({lowest_tested_swr*100:.1f}%) had a success rate of {highest_success_at_lowest_swr*100:.2f}%.\n"
         | 
| 114 | 
            +
                    results_text += "Consider revising assumptions (e.g., higher returns, lower volatility/inflation, shorter horizon) or target success rate.\n"
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                # --- Plotting Results ---
         | 
| 117 | 
            +
                swrs_plot = [r['swr'] * 100 for r in all_results]
         | 
| 118 | 
            +
                success_rates_plot = [r['success_rate'] * 100 for r in all_results]
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                fig1, ax1 = plt.subplots(figsize=(10, 6))
         | 
| 121 | 
            +
                ax1.plot(swrs_plot, success_rates_plot, marker='o', linestyle='-')
         | 
| 122 | 
            +
                ax1.axhline(y=target_success_rate * 100, color='r', linestyle='--', label=f'{target_success_rate*100:.0f}% Target Success')
         | 
| 123 | 
            +
                if final_swr > 0:
         | 
| 124 | 
            +
                    ax1.axvline(x=final_swr * 100, color='g', linestyle=':', label=f'Calculated SWR: {final_swr*100:.2f}%')
         | 
| 125 | 
            +
                ax1.set_title(f'Monte Carlo SWR Success Rates ({num_simulations:,} simulations)')
         | 
| 126 | 
            +
                ax1.set_xlabel('Initial Withdrawal Rate (%)')
         | 
| 127 | 
            +
                ax1.set_ylabel('Probability of Portfolio Lasting 30 Years (%)')
         | 
| 128 | 
            +
                ax1.grid(True)
         | 
| 129 | 
            +
                ax1.legend()
         | 
| 130 | 
            +
                ax1.set_ylim(0, 105)
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                fig2, ax2 = plt.subplots(figsize=(12, 7))
         | 
| 133 | 
            +
                chosen_swr_for_path_plot = final_swr if final_swr > 0 else 0.035
         | 
| 134 | 
            +
                if chosen_swr_for_path_plot in portfolio_paths_for_plotting and portfolio_paths_for_plotting[chosen_swr_for_path_plot]:
         | 
| 135 | 
            +
                    paths_to_plot_sample = portfolio_paths_for_plotting[chosen_swr_for_path_plot]
         | 
| 136 | 
            +
                    for i, path_data in enumerate(paths_to_plot_sample):
         | 
| 137 | 
            +
                        if len(path_data) == num_years + 1:
         | 
| 138 | 
            +
                             ax2.plot(range(num_years + 1), path_data, alpha=0.1, color='blue' if path_data[-1] > 0 else 'red')
         | 
| 139 | 
            +
                    
         | 
| 140 | 
            +
                    ax2.set_title(f'Sample Portfolio Paths for {chosen_swr_for_path_plot*100:.2f}% SWR (100 simulations shown)')
         | 
| 141 | 
            +
                    ax2.set_xlabel('Year')
         | 
| 142 | 
            +
                    ax2.set_ylabel('Portfolio Value ($)')
         | 
| 143 | 
            +
                    ax2.set_yscale('log')
         | 
| 144 | 
            +
                    ax2.grid(True, which="both", ls="-", alpha=0.5)
         | 
| 145 | 
            +
                    ax2.axhline(y=initial_investment, color='k', linestyle='--', label=f'Initial: ${initial_investment:,.0f}')
         | 
| 146 | 
            +
                    ax2.axhline(y=1, color='grey', linestyle=':', label='$1 (for log scale visibility near zero)')
         | 
| 147 | 
            +
                    ax2.legend()
         | 
| 148 | 
            +
                else:
         | 
| 149 | 
            +
                    ax2.text(0.5, 0.5, f"No portfolio paths were stored for SWR {chosen_swr_for_path_plot*100:.2f}% to plot individual simulations.",
         | 
| 150 | 
            +
                             horizontalalignment='center', verticalalignment='center', transform=ax2.transAxes, fontsize=12)
         | 
| 151 | 
            +
                    ax2.set_title("Sample Portfolio Paths")
         | 
| 152 | 
            +
                    ax2.set_xlabel("Year")
         | 
| 153 | 
            +
                    ax2.set_ylabel("Portfolio Value ($)")
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                return results_text, fig1, fig2
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            # Gradio Interface
         | 
| 158 | 
            +
            with gr.Blocks() as demo:
         | 
| 159 | 
            +
                gr.Markdown(
         | 
| 160 | 
            +
                    """
         | 
| 161 | 
            +
                    # Safe Withdrawal Rate Calculator
         | 
| 162 | 
            +
                    This application performs Monte Carlo simulations to determine a safe withdrawal rate from a retirement portfolio.
         | 
| 163 | 
            +
                    Adjust the parameters below and click "Run Simulation" to see the results and portfolio projections.
         | 
| 164 | 
            +
                    """
         | 
| 165 | 
            +
                )
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                with gr.Row():
         | 
| 168 | 
            +
                    with gr.Column():
         | 
| 169 | 
            +
                        gr.Markdown("### Investment Details")
         | 
| 170 | 
            +
                        initial_investment = gr.Number(label="Initial Investment ($)", value=2_500_000.0, interactive=True)
         | 
| 171 | 
            +
                        num_years = gr.Slider(minimum=10, maximum=60, value=30, step=1, label="Number of Years", interactive=True)
         | 
| 172 | 
            +
                        target_success_rate = gr.Slider(minimum=70, maximum=100, value=95, step=1, label="Target Success Rate (%)", interactive=True)
         | 
| 173 | 
            +
                        num_simulations = gr.Slider(minimum=1000, maximum=50000, value=10000, step=1000, label="Number of Simulations", interactive=True)
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                        gr.Markdown("### Market Assumptions (Annualized Nominal Returns)")
         | 
| 176 | 
            +
                        stock_mean_return = gr.Slider(minimum=0, maximum=20, value=9.0, step=0.1, label="Stock Mean Return (%)", interactive=True)
         | 
| 177 | 
            +
                        stock_std_dev = gr.Slider(minimum=5, maximum=30, value=15.0, step=0.1, label="Stock Standard Deviation (%)", interactive=True)
         | 
| 178 | 
            +
                        bond_mean_return = gr.Slider(minimum=0, maximum=10, value=4.0, step=0.1, label="Bond Mean Return (%)", interactive=True)
         | 
| 179 | 
            +
                        bond_std_dev = gr.Slider(minimum=1, maximum=15, value=5.0, step=0.1, label="Bond Standard Deviation (%)", interactive=True)
         | 
| 180 | 
            +
                        correlation_stock_bond = gr.Slider(minimum=-1.0, maximum=1.0, value=-0.2, step=0.01, label="Correlation (Stocks vs. Bonds)", interactive=True)
         | 
| 181 | 
            +
                        stock_allocation = gr.Slider(minimum=0, maximum=100, value=60, step=1, label="Stock Allocation (%)", interactive=True)
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                        gr.Markdown("### Inflation Assumptions (Annualized)")
         | 
| 184 | 
            +
                        mean_inflation = gr.Slider(minimum=0, maximum=10, value=2.5, step=0.1, label="Mean Inflation (%)", interactive=True)
         | 
| 185 | 
            +
                        std_dev_inflation = gr.Slider(minimum=0, maximum=5, value=1.5, step=0.1, label="Inflation Standard Deviation (%)", interactive=True)
         | 
| 186 | 
            +
                        
         | 
| 187 | 
            +
                        gr.Markdown("### SWR Test Range")
         | 
| 188 | 
            +
                        min_swr_test = gr.Slider(minimum=0.5, maximum=10.0, value=2.5, step=0.1, label="Min SWR to Test (%)", interactive=True)
         | 
| 189 | 
            +
                        max_swr_test = gr.Slider(minimum=0.5, maximum=10.0, value=5.0, step=0.1, label="Max SWR to Test (%)", interactive=True)
         | 
| 190 | 
            +
                        swr_test_step = gr.Slider(minimum=0.01, maximum=0.5, value=0.1, step=0.01, label="SWR Test Step (%)", interactive=True)
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                        run_button = gr.Button("Run Simulation")
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                    with gr.Column():
         | 
| 195 | 
            +
                        gr.Markdown("### Simulation Results")
         | 
| 196 | 
            +
                        results_output = gr.Textbox(label="Calculated Safe Withdrawal Rate", lines=5)
         | 
| 197 | 
            +
                        swr_plot_output = gr.Plot(label="SWR Success Rates")
         | 
| 198 | 
            +
                        paths_plot_output = gr.Plot(label="Sample Portfolio Paths")
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                run_button.click(
         | 
| 201 | 
            +
                    fn=run_simulation,
         | 
| 202 | 
            +
                    inputs=[
         | 
| 203 | 
            +
                        initial_investment,
         | 
| 204 | 
            +
                        num_years,
         | 
| 205 | 
            +
                        num_simulations,
         | 
| 206 | 
            +
                        target_success_rate,
         | 
| 207 | 
            +
                        stock_mean_return,
         | 
| 208 | 
            +
                        stock_std_dev,
         | 
| 209 | 
            +
                        bond_mean_return,
         | 
| 210 | 
            +
                        bond_std_dev,
         | 
| 211 | 
            +
                        stock_allocation,
         | 
| 212 | 
            +
                        correlation_stock_bond,
         | 
| 213 | 
            +
                        mean_inflation,
         | 
| 214 | 
            +
                        std_dev_inflation,
         | 
| 215 | 
            +
                        min_swr_test,
         | 
| 216 | 
            +
                        max_swr_test,
         | 
| 217 | 
            +
                        swr_test_step
         | 
| 218 | 
            +
                    ],
         | 
| 219 | 
            +
                    outputs=[results_output, swr_plot_output, paths_plot_output]
         | 
| 220 | 
            +
                )
         | 
| 221 | 
            +
             | 
| 222 | 
            +
            demo.launch()
         | 
    	
        requirements.txt
    ADDED
    
    | @@ -0,0 +1,3 @@ | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            numpy
         | 
| 2 | 
            +
            matplotlib
         | 
| 3 | 
            +
            gradio
         |