News 〉Releases

Helipad 1.6 has Scatterplots, Geospatial Models, and New Agents Container

Helipad 1.6 is out now, with a number of new visualization capabilities and model types.

Geospatial Models

Helipad now supports spatial models with arbitrary polygonal patches, using geometry='geo' when initializing a spatial model. Geospatial models are common in a variety of fields where actual geographic borders matter.

The model.patches container will be instantiated as the new PatchesGeo class, which stores patches as a list and allows new patches to be added one by one. Patch shapes can be imported from a GeoJSON or other GIS format using GeoPandas. As with the rectangular and polar geometries, patches are connected by a 'spatial' network to their bordering neighbors and (optionally) to patches they are connected to only by a corner. Agents can optionally be confined to patches, or wander into non-patch areas, with the offmap argument.

Geospatial models require Shapely, which can be installed with pip install shapely.

Scatterplot Visualizer

The visualizer formerly known as NetworkPlot – which was merged with the spatial visualizer in Helipad 1.3 – has been renamed to AgentsPlot to reflect its variety of layouts, all of which plot individual agents in one way or another.

In addition to spatial layout and a variety of network layouts, AgentsPlot now also features a scatterplot layout. A scatterplot can be initialized by passing a scatter=('prop1','prop2') argument to Charts.addPlot(), which will plot agent.prop1 and agent.prop2 on a scatterplot with an optional regression line. The usual network and spatial layouts can also be rotated through as usual by pressing L, if applicable (though network layouts will now be skipped if there is no network specified). Agent holdings of a good can also be plotted by passing 'good:goodname' as the property name.

New Agents Container

A number of model-level functions have been moved to model.agents, which now not only stores agents by primitive as a dict of lists, but also provides an interface to interact with and control agents. This comes with a number of improvements:

  • More logical function organization. A number of top-level methods and properties pertaining to agents – for example model.order or model.createNetwork() – have been moved to the Agents container: model.agents.order and model.agents.createNetwork(). Old code will continue to work per the deprecation policy, but aliases to the original functions will be removed in Helipad 1.8.
  • Merged Primitives container. The Primitive data object now resides in model.agents and contains the agents of that primitive as a subclass of list. The dedicated model.primitives container is now deprecated, and primitives can be added with model.agents.addPrimitive(). Because Agents subclasses dict and Primitive subclasses list, the Agents container stores agents in the exact same way as a dict of lists organized by primitive.
  • More flexible agent access. A list of agents of a primitive can be gotten as usual by model.agents['primitive'], but agents can also be retrieved individually by ID with a numeric index, e.g. model.agents[123], replacing the model.agent() function. A list of all agents can be retrieved with model.agents.all. Agents can be retrieved by breed with a double index, e.g. model.agents['primitive']['breedname'].

Other Improvements

  • Patches can now die. This removes the patch from the map and optionally prevents agents from moving to the corresponding area with the offmap argument. Since they are a fixed primitive, patches can also be revived.
  • Patches have center, area, and vertices properties.
  • Helipad modules and methods now have docstrings with links to full documentation, which will be helpful for users working with IDEs like Pylance or Visual Studio Code.
  • New Edges container. Network edges can be added and retrieved with agent.edges.add(), agent.edges['networkname'], agent.edges.inbound(), agent.edges.all, etc.

API Changes in Version 1.6

  • ⚠️ networkMoved from Model.network().
  • ⚠️ refreshRenamed from update() to avoid a collision with dict methods.
  • ⚠️ MPLVisualizationRenamed the keys property to keyListeners and the update() method to refresh to avoid collisions with dict methods.
    sendEvent() is no longer a bound method due to a Matplotlib bug.
    Deprecated the plots property. Plots can now be retrieved directly from the visualization object, like model.visual['plotName'].
  • ⚠️ baseAgentMoved Agent.alledges to Agent.edges.all.
  • ⚠️ createNetworkMoved from Model.createNetwork().
  • ⚠️ addBreedMoved from Model.addBreed().
  • ⚠️ AgentsMerged the Primitives container object into the Agents dict and took on a number of agent-relevant properties and methods from the main model object.
    Allow retrieval of individual agents with an int dict key.
  • ⚠️ addPrimitiveMoved from Primitives.add() with the merging of the Primitives and Agents objects.
  • ⚠️ removePrimitiveMoved from Primitives.remove() with the merging of the Primitives and Agents objects.
  • ⚠️ HelipadMerged model.primitives into model.agents.
    Deprecated model.allagents in favor of model.agents.all.
    Moved model.addBreed() to Agents.addBreed().
    Moved model.order to Agents.order.
    Moved network methods and properties model.network(), model.createNetwork(), and model.allEdges to the Agents object.
    Deprecated model.agent(id) in favor of model.agents[id] and model.agent(breed, prim) in favor of model.agents[prim][breed].
  • ⚠️ AgentsPlotRenamed from NetworkPlot to AgentsPlot in order to encompass the variety of layouts now supported.
    Now supports scatterplot layouts and geospatial models.
    Renamed the kind argument and property to network.
  • configAdded the mapBg and regression parameters.
  • basePatchesChanged to an abstract base class.
    Added the offmap property.
  • initializeMoved from Model.nUpdater().
  • PrimitiveNow stores Agent objects as a list.
    Agents can be retrieved by breed using Primitive[breed].
  • atIntroduced.
  • MultiDictIntroduced.
  • EdgesIntroduced.
  • neighborsChanged from a per-patch function to establishing patch edges all at once.
  • PatchesGeoIntroduced.
  • rotateLayoutSkips the NetworkX layouts if no network exists.
  • PatchIntroduced the center, area, and vertices properties.
    Patches can die now.
  • spatialAdded the offmap argument.