Skip to content

Matplotlib renderer crashes on Matplotlib 3.11: Line3D gets lists where it needs arrays #89

Description

@thc1006

What happens

With Matplotlib 3.11, the default matplotlib renderer crashes on the first frame:

File "mpl_toolkits/mplot3d/art3d.py", line 363, in draw
    (len(self._verts3d), *self._verts3d[0].shape)
AttributeError: 'list' object has no attribute 'shape'

The whole run dies, so a competitor loses the evaluation. README describes matplotlib as the renderer that needs no extra, and example_eval_cfg.yaml ships with render_mode: "matplotlib", so this is the default path.

Reproduced by running the shipped config with Matplotlib 3.11.1 on Python 3.14. It does not reproduce on 3.10.9, which is why local runs are fine and CI is not.

Root cause

Two conditions have to hold together, and balloon_world.py produces both.

The rocket line's _verts3d holds lists rather than arrays. _render_frame updates it with:

self.render_rocket[0].set_data(
    [self._rocket_states[0]], [self._rocket_states[1]]
)
self.render_rocket[0].set_3d_properties([self._rocket_states[2]])

A coordinate is invalid for the current axis scale. _rocket_states is np.full(13, np.nan) until the launch action builds the flight, and frames are drawn before that. In Line3D.draw the .shape access sits inside if np.any(scale_mask):, so a finite coordinate never reaches it. That is why passing lists went unnoticed for so long: it only breaks while the rocket has no state yet.

Isolated on 3.11.1:

coordinates _verts3d contents result
finite lists draws
NaN lists AttributeError: 'list' object has no attribute 'shape'
NaN arrays draws

Fix

Pass arrays. set_data_3d(np.array([x]), np.array([y]), np.array([z])) covers both calls and draws cleanly with NaN on 3.11.1.

Initialising the line with plot(scalar, scalar, scalar) at line 472 is worth tidying at the same time, though it is not what breaks: plot([x], [y], [z]) is the documented form.

Test note

A test that renders a NaN frame passes on Matplotlib 3.10 whether or not the fix is applied, since the crashing branch is only reachable on 3.11. Asserting that _verts3d entries are ndarray pins the fix on every version, which is what the fix actually guarantees.

Scope

Found while making the logging test in #88 hermetic; that test was driving the real CLI, which is how it surfaced. #88 no longer renders anything, so it is not blocked on this. #86 covers the vpython renderer and does not touch this branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions