Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pmartiner opened this issue Apr 28, 2021 · 8 comments

Comments

@pmartiner
Copy link

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
Copy link
Contributor

rht commented Apr 30, 2021

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

@pmartiner
Copy link
Author

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

@rht
Copy link
Contributor

rht commented May 1, 2021

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

@pmartiner
Copy link
Author

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
Copy link
Contributor

rht commented May 1, 2021

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
Copy link
Author

pmartiner commented May 1, 2021

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!

@pmartiner pmartiner reopened this May 1, 2021
@jackiekazil
Copy link
Member

jackiekazil commented May 1, 2021 via email

@rht
Copy link
Contributor

rht commented May 9, 2021

Heads up. PR incoming from me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants