Skip to content

Refactor GraphicsArray, fixing various issues #27865

@egourgoulhon

Description

@egourgoulhon

This ticket makes GraphicsArray derive from a new class, MultiGraphics, which is more generic (arbitrary positions of graphics objects on a canvas) and paves the way towards graphics insets in #27866.

GraphicsArray is now endowed with a matplotlib() function (inheritated from MultiGraphics). This fixes the issues reported in #10466, #10657, #11160 and #12591 (see :comment:3 and comment:5 below for a summary).
Moreover, this simplifies sphinx_plot() (defined in src/doc/common/conf.py), avoiding code duplication.

Beside introducing matplotlib() at the graphics array level, two bugs had to be corrected in Graphics.matplotlib():

  • _set_scale was called on the whole figure, while it should be called on the current subplot
  • tick_params was called on figure.get_axes()[0], i.e. the first subplot of the figure, while it should be called on the current subplot.

The documentation of Graphics.matplotlib() is also improved in this ticket.

Another bug has been corrected in Graphics.save(): contrary to what was claimed in the documentation g.save("filename") with "filename" having no extension did not save in a sobj file but yielded to an error.

Another modification is the introduction of the helper function _parse_figsize() in src/sage/plot/graphics.py to avoid code duplication: it is used in Graphics.matplotlib(), MultiGraphics.matplotlib() and sphinx_plot().

Since the file src/sage/plot/graphics.py was already quite long (3736 lines!), the class GraphicsArray was moved to the new file src/sage/plot/multigraphics.py, which contains the definition of the base class MultiGraphics. This makes things more consistent:

  • src/sage/plot/graphics.py: only Graphics objects
  • src/sage/plot/multigraphics.py: only MultiGraphics objects

Besides the bugs reported in the tickets #10466, #10657, #11160 and #12591, this ticket fixes two other bugs:

  • if any plot in the array had a log scale, the latter was erroneously applied to the first plot of the array

  • the computation of nrows and ncols in the function graphics_array() (defined in src/sage/plot/plot.py) yielded unnecessary large numbers in certain cases. For instance we have in Sage 8.7:

sage: graphics_array([plot(sin)]*4, ncols=4)
Graphics Array of size 2 x 4

with the second raw that is entirely blank. With the code in this ticket the output is

Graphics Array of size 1 x 4

This fix explains the change of doctest outputs in src/sage/categories/finite_posets.py and src/sage/repl/rich_output/pretty_print.py

A preview (including the functionalities introduced in #27866) is available here.

CC: @kcrisman @fchapoton @dkrenn @jdemeyer @embray

Component: graphics

Keywords: graphics_array, matplotlib

Author: Eric Gourgoulhon

Branch/Commit: 36c0f17

Reviewer: Frédéric Chapoton

Issue created by migration from https://trac.sagemath.org/ticket/27865

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions