factoriax.analysis.utils#
Helpers that every plot in the analysis package shares.
resolve_ax() settles who owns the figure. resolve_player_actions()
settles which player a plot reads. Both exist so that each plot
function can accept the same two arguments and behave the same way.
- factoriax.analysis.utils.distinct_colors(n: int) list[str]#
Return
ncolors that a reader can tell apart.Use this to give every member of an enum its own color. A list shorter than the enum is worse than it looks. Matplotlib gives every index past the end of a colormap the same last color. Unrelated members then render alike, and nothing reports it.
Hues advance by
_HUE_STEPand wrap. Lightness and saturation cycle over a few values as well, which separates two entries that land on near hues.These colors carry no meaning. Neighboring entries are not related, and one entry has no fixed color across two runs with different
n. Pass an explicit list where a color has to mean something.- Parameters:
n – How many colors to return.
- Returns:
ndistinct#rrggbbstrings. Annof 0 or less gives an empty list.- Return type:
- factoriax.analysis.utils.resolve_ax(ax: Axes | None, figsize: tuple[float, float]) tuple[Figure, Axes]#
Return the axes to draw on, and the figure that owns it.
A plot function calls this first. With
axofNoneit makes its own figure, and the caller must close that figure. With anaxfrom the caller it draws into the caller’s layout, and the caller keeps ownership.- Parameters:
ax – The axes to draw on, or
Noneto make a new figure.figsize – The width and height of the new figure, in inches. A caller that supplies
axowns the layout, so this value is then ignored. A resize moves every other subplot on that figure.
- Returns:
(figure, axes). WithaxofNone, both are new. With anaxfrom the caller, the figure isax.figureand the axes isaxitself.- Return type:
- factoriax.analysis.utils.resolve_player_actions(traj: Trajectory, player: int | None) ndarray#
Reduce a trajectory’s actions to one array per episode and step.
Recordings arrive in three shapes. A single-agent scenario gives
(B, T). A multi-agent scenario gives(B, T, P). A single agent recorded by multi-agent code gives(B, T, 1). This last shape reportsis_multi_playerasFalseand still carries the player axis. All three return as(B, T).- Parameters:
traj – The recording to read. The function changes nothing. Where the shape allows it, the result is a view into
traj.actions.player – The player to keep.
Nonemeans player 0. A recording with no player axis ignores this value, because it holds the actions of one player only.
- Returns:
Shape
(B, T), holding action ids.- Return type:
- Raises:
IndexError – When
playernames a slot the player axis does not have.