diff --git a/README.md b/README.md index 8471ea1..ec3d8a0 100644 --- a/README.md +++ b/README.md @@ -30,4 +30,6 @@ solara run app.py - For some weird reason, after adding interactivity, the solara app only runs after being reloaded after initial build. This can be triggered by saving any file within the repo, and things seem to work fine after that - you can even make source edits and re-run, which is a nice workflow. Weird! -- Sliders don't seem to change model inits whatsoever - and docs don't show any explicit way to access them, seems to just 'happen' when registering model params? \ No newline at end of file +- Sliders don't seem to change model inits whatsoever - and docs don't show any explicit way to access them, seems to just 'happen' when registering model params? + +- Occasionally Solara appears to never render (stuck on "Loading App"). Simply rebuilding (not from cache) seems to fix it, and it seems to happen after changes are made to the `SolaraViz` class from mesa-geo - could have something to do with autoreload, but not sure. \ No newline at end of file diff --git a/vegetation/app.py b/vegetation/app.py index 20ac5cd..5b947f9 100644 --- a/vegetation/app.py +++ b/vegetation/app.py @@ -7,7 +7,8 @@ from mesa_geo.visualization import make_geospace_component from vegetation.patch.model import Vegetation, JoshuaTreeAgent from vegetation.patch.space import VegCell -from vegetation.viz.simple_raster_map import make_raster_only_geospace_component +from vegetation.viz.simple_raster_map import make_simple_raster_geospace_component +from vegetation.viz.log_window import make_log_window_component # from patch.management import init_tree_management_control from vegetation.config.stages import LIFE_STAGE_RGB_VIZ_MAP @@ -87,19 +88,16 @@ def cell_portrayal(agent): model = Vegetation(bounds=TST_JOTR_BOUNDS) -tree_management = GeomanDrawControl( - drag=False, cut=False, rotate=False, polyline={}, circlemarker={} -) +tree_management = GeomanDrawControl(drag=False, cut=False, rotate=False, polyline={}) tree_management.on_draw(model.add_agents_from_management_draw) page = SolaraViz( model, name="Veg Model", components=[ - make_raster_only_geospace_component( + make_simple_raster_geospace_component( cell_portrayal, zoom=14, controls=[tree_management] ), - # make_geospace_component(cell_portrayal, zoom=14, controls=[tree_management]), make_plot_component( [ "Mean Age", @@ -114,6 +112,7 @@ def cell_portrayal(agent): make_plot_component( ["% Refugia Cells Occupied"], ), + make_log_window_component(), ], model_params=model_params, ) diff --git a/vegetation/viz/log_window.py b/vegetation/viz/log_window.py new file mode 100644 index 0000000..abe9d3d --- /dev/null +++ b/vegetation/viz/log_window.py @@ -0,0 +1,38 @@ +import sys +import io +import solara + + +class StdoutCapture: + def __init__(self): + self.output = io.StringIO() + self.old_stdout = None + + def __enter__(self): + self.old_stdout = sys.stdout + sys.stdout = self.output + return self.output + + def __exit__(self, exc_type, exc_val, exc_tb): + sys.stdout = self.old_stdout + + +def make_log_window_component(): + @solara.component + def StdoutDisplay(): + # Create a state to store captured output + output, set_output = solara.use_state("") + + # Capture stdout when model runs + def capture_output(): + with StdoutCapture() as stdout: + # Your model operations here + model.step() + set_output(stdout.getvalue()) + + return solara.Column( + solara.Button("Capture Output", on_click=capture_output), + solara.Textarea(value=output, read_only=True), + ) + + return StdoutDisplay diff --git a/vegetation/viz/simple_raster_map.py b/vegetation/viz/simple_raster_map.py index 9c54e2c..5ba4c7f 100644 --- a/vegetation/viz/simple_raster_map.py +++ b/vegetation/viz/simple_raster_map.py @@ -5,7 +5,7 @@ from mesa_geo.visualization.components.geospace_component import MapModule -def make_raster_only_geospace_component( +def make_simple_raster_geospace_component( agent_portrayal, view=None, tiles=xyzservices.providers.OpenStreetMap.Mapnik,