projectmesa / mesa-viz-tornado Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
What's the problem this feature will solve?
The size of a canvas is set when a visualization is initialized and cannot be updated. Sometimes, the size of the grid can be an important part of the model and it would be nice to have a way to change it in the UI.
Describe the solution you'd like
I think that my suggestion is for the reset button to also reset the JS that draws the canvas, or maybe even to redraw the entire "elements" div. This would make it possible to make aspects of the display editable in the UI.
Additional context
A discussion about this was started on the mailing list at https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/projectmesa/5ln8Ip7oIFg/UWx2R3EhBwAJ with initial exploration done by Jared Norman.
Describe the bug
In the Schelling model, chart label is shown as "undefined" and colors are not rendered correctly:
Expected behavior
Chart label should be "happy" and color should be black, as specified in the code: https://github.com/projectmesa/mesa-examples/blob/6f3e077f2d3050e11852abfa29954eb06ef0a057/examples/schelling/server.py#L30
To Reproduce
Run the Schelling model from mesa-examples repo via mesa runserver
.
Additional context
Probably introduced in projectmesa/mesa#1685
The settings used in Mesa are "Color" and "Label" (with capital "C" and "L"). They were mapped to "borderColor" and "label" before the PR. With the PR they are used as-is.
What's the problem this feature will solve?
The current grid visualization uses HTML5 Canvas which rasterizes elements. This means that when using visualizations in publications or presentations there are image resolution and quality limits.
Describe the solution you'd like
A grid visualization based in SVG would permit the creation of vector-based visualizations of models.
Additional context
I have created two working files (SVGGridModule.js and SVGGridVisualization.py) that currently perform well on my system, but I would like additional testing and input/recommendations related to functionality. One feature of my work is a simple shift-click download that permits the user to easily access a complete .svg capture of a current state of the model visualization. This .svg file can be easily converted to PDF (using Inkscape or similar applications) for use in high-resolution publications, printing, and presentations without loss due to rasterizing.
The arrowHead seems to appear in CanvasGrid for (heading_x, heading_y) in (-1,0), (1,0), (0,-1) and (0,1), but it doesn't appear at all for any other combination I tried. I have tried options like (1,1), (sqrt(0.5),sqrt(0.5)), etc.
Are only those 4 values valid, or am I doing something wrong?
Describe the bug
When loading the JavaScript files in the html template, their order is nondeterministic because local_includes and package_includes are converted in a set() in ModularVisualization. When there are dependencies between these javascript files, the resulting html may not preserve the correct order and the scripts will not work.
Expected behavior
JavaScript files are loaded in the order given in the local_includes and package_includes variables inside the VisualizationElement subclass.
To Reproduce
Build a VisualizationElement that needs multiple JavaScript files, you will see that the generated html files at run time randomly shuffles the scripts loading order.
Additional context
I'm not sure if this is a bug. But I don't understand the reason for the set() inside ModularVisualization.py when collecting the local_includes and package_includes from the Visualization Elements.
Describe the bug
If the web socket gets closed, the simulation stops and doesn't reset without a manual refresh of the page.
Expected behavior
The web socket should attempt to reopen if it gets closed
To Reproduce
In my case when my Mac goes to sleep overnight and the sockets all time out in my virtual machine!
Additional context
May be worth switching the direct call to WebSocket to a ReconnectingWebSocket library like https://github.com/joewalnes/reconnecting-websocket
It would be nice to refactor both the front-end javascript and the back-end rendering code of a VisualizationElement
, so that they aren't coupled as tightly to the Tornado server setup and its template.
The motivation for this issue is to allow the front-end visualizations written in javascript to be used in situations where the webserver is not needed (or wanted). Examples would include the inside of a Jupyter notebook output cell, or a static HTML page where the data for a model run could be saved statically and replayed.
Currently the javascript visualization code makes assumptions about the template it is loaded into, injecting into the body tag. Some of the visualizations also send along canvas commands, rather than data which should be left to the javascript to make use of.
Each individual visualization also uses a js_code
property to specify initialization code, which must deal with specifying arguments itself.
js_code
with an initialization function name e.g. ChartModule
, and always pass a provided dictionary as the single argument containing any of the options. This will ensure new modules are written in a way which doesn't make assumptions about the type of front-end environment it will be run in and also allows the tornado webserver or notebook extension to change options as needed (possibly change dimensions?).I'd like a stacked area chart showing the numbers of each kind of agent.
Describe the bug
mesa runserver
results in 404 errors and the visualization is not running properly:
$ mesa runserver
Interface starting at http://127.0.0.1:8521
404 GET /static/external/bootstrap-slider-11.0.2/dist/css/bootstrap-slider.min.css (127.0.0.1) 4.28ms
404 GET /static/external/bootstrap-slider-11.0.2/dist/bootstrap-slider.min.js (127.0.0.1) 1.42ms
Expected behavior
$ mesa runserver
Interface starting at http://127.0.0.1:8521
Socket opened!
{"type":"reset"}
To Reproduce
Go to the Schelling example and install latest dependencies: python3 -m pip install -Ur requirements.txt
Additional context
It is likely introduced through #39. If mesa-viz-tornado
is installed at its previous commit, the issue disappears:
python3 -m pip install git+https://github.com/projectmesa/mesa-viz-tornado.git@b4e9cae550a6ef1580dd906a5f9a1b8c51726aa8#egg=mesa-viz-tornado
What's the problem this feature will solve?
Currently the changing model parameters with UserParams comes into effect when resetting the model. But for some usecases it would be interesting to change the model parameters while the model is in progress. I propose to change model parameters dynamically using UserParams.
Describe the solution you'd like
To ModularServer constructor add an is_dynamic argument.
If is_dynamic is on, when a submit_params message is received, while updating kwargs, also change the currently running model's parameters as well.
Additional context
I do quite a bit a policy modelling, and it's always useful to observe how agent behaviour changes when a policy change comes into effect. I believe this can be easily incorporated by making some simple changes to mesa-viz-tornado code.
I've overridden these for my personal use. If this is something the community would like, I can send through a pull request.
Add History file for releases
I would love to be precise, but honestly I am quite lost. Playing around with displaying graphs I could not manage to resize the graph properly. If I input a different canvas_height value it works just fine. But when I input a canvas_width, it modifies the height again. What is more, the result is reversed for me.
To Reproduce
chart = ChartModule(
series=[],
canvas_height=200,
canvas_width=200,
)
Will make a really tall graph, rather than a square one.
Is it a bug or I am just dumm? :)
Describe the bug
I am seeing freezes when letting a model run on it's own.
Expected behavior
The model would continue to run at any number of agents and any frame rate.
To Reproduce
It isn't yet clear how to reproduce this. I also can't figure out if it's frozen in the javascript or python interpreter. I've tried setting breakpoints in both and no success yet. So for now just posting in case others have observed this.
Model in question: https://github.com/patrickkidd/systems-models
To run: $ python run.py --models mythematical
Describe the bug
The steps label in a generated chart starts to display wrong labels when pausing. E.g. It might display steps 3+ when the model is still computing step 1 (as seen from the python console). It also often displays repeated labels such as below.
Expected behavior
The chart should display the correct labels.
To Reproduce
Set the fps to 0 and then pause the module after awhile. The issue can be consistently reproduced.
Additional context
Setting the fps to 0 is to let the module run as fast as possible. This trick was mentioned by one of the other members and appears to work with SimpleCanvas and BarChart as far as I can tell from my own testing. On a related note, is there a simple way to modify the FPS beyond 20 without directly editing the library files?
While working on the sprint at PyCon 2023, noticed an issue where the browser cache seems to be altering aspects the launched web pages's UI. Specifically, upon editing the FPS Slider, it will not update on the web page unless you clear your browser's cache.
This bug could be specific to my browser's settings as not everyone else encountered this issue but it is still worth documenting.
Perhaps something could be done to launch the page without caching anything.
Below I have included a screenshot where the same page displays different results in Edge and Firefox
Describe the bug
I'm running a mesa simulation on a remote machine. I'm programming on the remote with vscode server; The issue comes with the visualisation.
Running, for example mesa runserver examples/wolf_sheep
, vscode correctly detects the server being created on port 8521 and sets up a port forward from
remote:8521 to http://localhost:8080/proxy/8521/
The proxy/8521/
that appears in the URL seems to be causing trouble to mesa-viz-tornado.
Here is what I get :
Then, opening the developper console, I noticed a lot of messages complaining about the inability to get various files , for example
GET
http://localhost:8080/static/external/bootstrap-5.1.3-dist/css/bootstrap.min.css
[HTTP/1.1 404 Not Found 12ms]
I then edited your modular_template.html
, replacing all the /static/
and /local/
to respectively static/
and local/
removing the leading /
; Then , the visualization gets more elements but I'm not yet there;
As you can see, there are some remaining "Unexpected token" errors . It seems to me also that :
Do you have any idea of how to fix this ? On the vscode side, I did not find any way to change the forwarded port prefix, to remove the proxy/8521/
prefix; My hope is to adapt your html production code to prevent the ressource loading to go back to the root of the site;
When using CanvasGrid(portrayal_method, grid_width, grid_height, canvas_width=500, canvas_height=500), beyond a certain value of grid_width or grid_height, the visualisation does not show any agents. (Image attached)
I noticed it from the 'Advanced Tutorial'.
grid = CanvasGrid(agent_portrayal, 134, 134, 400, 400)
Here for a canvas size of 400x400, grid sizes from 134x134 does not work. If you increase the canvas size, it will support a higher grid size, until it stops working again. I increase the agent indicator size to see if the agents were just too small; that is not the case.
Complete File: (Money_Model_Viz.py as per the tutorial)
from MoneyModel import *
from mesa.visualization.modules import CanvasGrid
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.modules import ChartModule
import random
import numpy as np
main_grid = 133
display_grid = 400
from mesa.visualization.ModularVisualization import VisualizationElement
def agent_portrayal(agent):
portrayal = {"Shape": "circle",
"Filled": "true",
"r": 0.5}
if agent.wealth > 0:
portrayal["Color"] = "red"
portrayal["Layer"] = 0
else:
portrayal["Color"] = "grey"
portrayal["Layer"] = 1
portrayal["r"] = 0.2
return portrayal
grid = CanvasGrid(agent_portrayal, 134, 134, 400, 400)
chart = ChartModule([{"Label": "Gini",
"Color": "Black"}],
data_collector_name='datacollector')
class HistogramModule(VisualizationElement):
package_includes = ["Chart.min.js"]
local_includes = ["HistogramModule.js"]
def __init__(self, bins, canvas_height, canvas_width):
self.canvas_height = canvas_height
self.canvas_width = canvas_width
self.bins = bins
new_element = "new HistogramModule({}, {}, {})"
new_element = new_element.format(bins,
canvas_width,
canvas_height)
self.js_code = "elements.push(" + new_element + ");"
def render(self, model):
wealth_vals = [agent.wealth for agent in model.schedule.agents]
hist = np.histogram(wealth_vals, bins=self.bins)[0]
return [int(x) for x in hist]
histogram = HistogramModule(list(range(10)), 200, 500)
server = ModularServer(MoneyModel,
[grid, histogram, chart],
"Money Model",
{"N":1000, "width":134, "height":134})
server.port = 8521 # The default
server.launch()
The layer feature for agent portrayal is very handy. I would like to be able to turn the layers' visibility off/on in the browser window via a control, e.g. a list of layers with checkboxes/radio buttons to turn visibility off/on.
Thanks
Hello, I am developing a model and visualization project that involves vehicles moving arround a city. The GPS graph of my city is used, and vehicles can travel to point A to point B and interact with each other. Is a simple model of traffic in a city. Visualization is done with a leaflet map, and D3.
The issue is that I am doing test with 500 - 1000 agents, and after a few minutes I note that the visualization slows down. My guess is that the front end is asking for get_step request less frequently that it should. It starts at 20 FPS, and after a few minutes, it seems to go like 5 FPS or so. (judging visually the speed of get_step requests, and visualization)
So, how can I debug this ? Can I meassure FPS from server and from front end? What other things could be happening?
I am running the model and visualization in Ubuntu 16.04 , mesa installed with conda, in a I5 processor.
Any help is appreciated.
Nicolas.
Thanks.
What's the problem this feature will solve?
Only way to stop ModularServer
is when control is with the user in the terminal and pressing 'Control+c'. When running through IDE, control is no longer with user, there is no direct way to stop the server. Running visualization code throws error, RuntimeError: This event loop is already running
or OSError: [Errno 48] Address already in use
even after restarting the kernel and/or closing the browser.
Describe the solution you'd like
Add a stop()
method to ModularServer
class.
Additional context
N/A
What's the problem this feature will solve?
I'm a postgraduate student and new to mesa. I have developed an EV charging model in mesa.
It is working fine and visualise the chart element with step in x axis.
What i want is, the sysem is running in every five minutes as one step it should be represented in the chart module like 2.00,2.05....etc.
How can i do that?
Plwase help me. It will eeally helpfull to continue my modelling process.
What's the problem this feature will solve?
I need to visualize the time value that i have modeled in my model.py in x-axis of chart module instead of steps.
How to do that suggest me a solution
We recently did an adaptation of the Wolf Sheep example to try and build a disease model (susceptible, infected, recovered) in mesa. When we plotted the population sizes, as is done in the wolf sheep model, the chart plots correctly the first time. However, when we reset the parameters and try and run a new model, the chart that shows up in the server first displays the data from the previous model's execution, and then it shows the data from the next iteration.
An example is shown below:
The sharp discontinuity in the graph is where the new data for the model starts being displayed. We then thought that it may have been our model (a bug), but revisiting the wold sheep model we saw the same thing
Is there a known issue where the DataCollector does not reset between runs? Closing the kernel and restarting it fixes the issue.
Our code can be found here.
Hi, everyone!
I'm a newbie with mesa (and somewhat with Python as well) and I'm having difficulties trying to plot a Bar Chart of my agent reporter within my data collector. I thought this could be a good place to ask.
When running my server, I'm receiving the following error:
ERROR:tornado.application:Uncaught exception GET /ws (127.0.0.1)
HTTPServerRequest(protocol='http', host='127.0.0.1:8521', method='GET', uri='/ws', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
File "C:\Python39\lib\site-packages\tornado\websocket.py", line 647, in _run_callback
result = callback(*args, **kwargs)
File "C:\Python39\lib\site-packages\mesa\visualization\ModularVisualization.py", line 212, in on_message
self.write_message(self.viz_state_message)
File "C:\Python39\lib\site-packages\mesa\visualization\ModularVisualization.py", line 195, in viz_state_message
return {"type": "viz_state", "data": self.application.render_model()}
File "C:\Python39\lib\site-packages\mesa\visualization\ModularVisualization.py", line 323, in render_model
element_state = element.render(self.model)
File "C:\Python39\lib\site-packages\mesa\visualization\modules\BarChartVisualization.py", line 80, in render
latest_step = df.index.levels[0][-1]
File "C:\Python39\lib\site-packages\pandas\core\indexes\base.py", line 4297, in __getitem__
return getitem(key)
IndexError: index -1 is out of bounds for axis 0 with size 0
I thought this was a weird error, so I checked my DataFrame and I received the following:
Empty DataFrame
Columns: [Ingreso total]
Index: []
As you can see, my Index is empty, but I don't know why.
Here's a small fragment of my model's code:
class EconomiaSocialista(Model):
'''A model with some number of agents.'''
def __init__(self, I, J, impuesto_ingreso, costo_vida, ingreso_inicial):
...
self.datacollector = DataCollector(
model_reporters={
"Gini": compute_gini,
"S80/S20": compute_s80_s20
}, # `compute_gini` defined above
agent_reporters={"Ingreso total": lambda x: x.ingreso_total}
)
As you can see, my Index is empty, but I don't know why.
Here's a small fragment of my agent's code:
class Consumidore(Agent):
''' An agent with fixed initial wealth.'''
def __init__(self, unique_id, model, num_empresas, ingreso_inicial, impuesto_ingreso):
super().__init__(unique_id, model)
...
self.ingreso_inicial = ingreso_inicial
self.ingreso_total = self.ingreso_inicial
And here's my server's code:
import numpy as np
import inspect
from numpy.random import default_rng
from mesa.visualization.ModularVisualization import ModularServer
from mesa.visualization.modules import ChartModule, BarChartModule
from mesa.visualization.UserParam import UserSettableParameter
from model import EconomiaSocialista
rng = default_rng()
model_params = {
"I": UserSettableParameter(
"slider",
name="Número de consumidores",
value=100,
min_value=100,
max_value=1000,
step=100,
description="Número de consumidores en la economía",
),
"J": 0,
"impuesto_ingreso": UserSettableParameter(
"slider",
name="Impuesto al ingreso",
value=0.2,
min_value=0,
max_value=1,
step=0.05,
description="Impuesto al ingreso en la economía",
),
"costo_vida": UserSettableParameter(
"slider",
name="Costo de vivir en la economía",
value=10,
min_value=0,
max_value=100,
step=1,
description="Costo de vivir en la economía",
),
"ingreso_inicial": UserSettableParameter(
"slider",
name="Ingreso inicial en la economía",
value=0,
min_value=0,
max_value=1000,
step=50,
description="Ingreso inicial en la economía",
)
}
print(model_params)
chartGini = ChartModule([{"Label": "Gini",
"Color": "#18496D"},],
data_collector_name='datacollector')
chartGiniS80S20 = ChartModule([{"Label": "Gini",
"Color": "#18496D"},
{"Label": "S80/S20",
"Color": "#A43DC6"}],
data_collector_name='datacollector')
agent_bar = BarChartModule(
fields=[{"Label": "Ingreso total", "Color": "#4CCE59"}],
scope="agent",
)
server = ModularServer(EconomiaSocialista, [chartGini, chartGiniS80S20, agent_bar], "Economia Socialista", model_params)
server.port = 8521 # The default
server.launch()
The server works perfectly when I remove the BarChartModule.
I'm still trying to figure the error out, since, as far as I can see, my BarChartModule looks very similar to the one on the "charts" example. Does anyone know what's going on?
Thanks!
What's the problem this feature will solve?
Adding a title to Charts in order to make their purpose clear
Describe the solution you'd like
A way to pass the title text along with the chart data
I am trying the "MoneyModel" from the tutorial and it demonstrates how to add a "Histogram" to the visualization window. I followed the instructions and I get the following error:
module 'mesa.flat.visualization' has no attribute 'HistogramModule'
I made sure I saved the "HistogramModule.py" and "HistogramModule.js" in the same folder. It still gives me the same error.
I noticed that the tooltip
only displays for agents on the highest "Layer"
in the portrayal when using mesa.visualization.CanvasGrid
and mesa.visualization.ModularServer
. Is there a way to enable tooltips for agents on other layers as well?
Describe the bug
Tornado server loads cached javascript. Any changes to simple_continous_module.js require manual cache removal or to go incognito.
Expected behavior
javascript code should be loaded fresh on each run
To Reproduce
hardcode the color red, run the program and view on browser, then hard code color blue in:
https://github.com/projectmesa/mesa/blob/main/examples/boid_flockers/boid_flockers/simple_continuous_canvas.js
Additional context
Using Chrome on Mac OS.
This may be useful https://stackoverflow.com/questions/12031007/disable-static-file-caching-in-tornado and somewhere around here should be modified
https://github.com/projectmesa/mesa/blob/main/mesa/visualization/ModularVisualization.py#L243
So that projectmesa/mesa#1246 (comment) can be automated in the CI.
What's the problem this feature will solve?
For many applications displaying the counts of the different kinds of agents in a stacked area chart is extremely useful.
Describe the solution you'd like
See: https://python-graph-gallery.com/250-basic-stacked-area-chart/
Additional context
You can't do them all. I've also submitted a documentation request as a separate issue. So, folks can do their own.
Describe the bug
The HistogramModule.js advanced tutorial does not display the bars. The data does refresh the axes values but the bars themselves do not show so a blank canvas is displayed.
Expected behavior
A histogram presented at the end of the advanced tutorial.
To Reproduce
Tutorial used for reproducibility can be found here
What's the problem this feature will solve?
Using ModularServer - When I run my code it works, when I run it again I get a socket error.
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitt
Describe the solution you'd like
A function in the ModularServer that closes (if open
) any socket you intend to use.
server = ModularServer(...)
server.close()
server.launch()
Or
Maybe a relaunch option that closes then launches in one command
ModularServer(...).relaunch()
Or
A button on the website to close the socket.
Title | About| --- | Start | Step | Reset | **Exit**
Additional context
I attempted to understand how to close tornado web applications by reading the literature, but I'm not experienced and couldn't find a simple solution.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.