projectmesa / mesa-viz-tornado

Apache License 2.0
3 stars 9 forks source link

IndexError: index -1 is out of bounds for axis 0 with size 0 with scope="agent" BarChartModule #25

Open pmartiner opened 3 years ago

pmartiner commented 3 years ago

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!

rht commented 3 years ago

Do you have a public repo containing your code that I can look at?

pmartiner commented 3 years ago

Sure thing! Here's the repo: https://github.com/pmartiner/cas-market-socialism

rht commented 3 years ago

Found the bug: you forgot to add self.datacollector.collect(self) at the end of the __init__ of EconomiaSocialista

pmartiner commented 3 years ago

It makes so much sense! I spent a lot of time checking what was wrong, yet I couldn't see it 😂. Thank you so much for taking your time to debug my bug. I really really appreciate it!

rht commented 3 years ago

Wait, can you reopen the issue? I think it should be possible to detect whether a user forgets to add that datacollector.collect thing. Maybe we should add a check in https://github.com/projectmesa/mesa/blob/bbf1b885ebe274e4b1eb269e30567a475e158aaf/mesa/visualization/ModularVisualization.py#L211. Any thoughts from others?

pmartiner commented 3 years ago

I thought it wasn't missing since I had it on my step method, and not on my __init__, so that improvement would be incredibly helpful!

jackiekazil commented 3 years ago

@rht I think that would be a good add.

On Fri, Apr 30, 2021 at 8:20 PM pmartiner @.***> wrote:

Reopened projectmesa/mesa-viz-tornado#25 https://github.com/projectmesa/mesa-viz-tornado/issues/25.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/projectmesa/mesa-viz-tornado/issues/25, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABIWTUXYLDH3LSW2AN4CTDTLNJPBANCNFSM43XY24QA .

-- Jacqueline Kazil | @jackiekazil

rht commented 3 years ago

Heads up. PR incoming from me.