phoebe-project / phoebe2

PHOEBE - Eclipsing Binary Star Modeling Software
http://phoebe-project.org
GNU General Public License v3.0
79 stars 30 forks source link

When passing an existing matplotlib figure to PHOEBE's plot(), previous figure contents are cleared #836

Closed abhimat closed 6 months ago

abhimat commented 6 months ago

When passing an existing matplotlib figure to PHOEBE's plot() command using the fig= keyword, the contents of the figure are cleared. After a little bit of investigating, this appears to be due to the following portion of the figure.py code in autofig (lines 589–592) being called by PHOEBE.

        if calls is None:
            # then we need to reset the backend figure.  This is especially
            # important when passing draw(i=something)
            fig.clf()

My use case is wanting to plot mesh plots from several phases of a binary model as separate axes in a single matplotlib figure. I wasn't successfully able to pass in existing axis objects to PHOEBE's plot() function. I was hoping to instead use autofig's subplot commands and draw in the same figure for each call to PHOEBE's plot() function, but the contents of any figure objects passed to plot() in PHOEBE are wiped out each time, and at the end I'm only left with a figure object with a single axis object containing the most recent mesh plot drawn.

kecnry commented 6 months ago

This is (somewhat) by design - the idea was to support passing figures with specific sizes, etc, setup, but not designed to allow plotting on top of existing plots (since phoebe wouldn't know what axes to plot to or what it should vs should not overwrite). You can, however, modify the figure after getting it back from phoebe, but I don't think that will do the trick for you want either (since, if I understand correctly, you want to make multiple calls to phoebe's plotting). If matplotlib's subplot grid is flexible enough for you - would something like this do the trick?

import phoebe

b = phoebe.default_binary()
b.add_dataset('mesh', compute_times=[0, 0.1, 0.2, 0.3])
b.run_compute()

for time, axpos in ((0, 221), (0.1, 222), (0.2, 223), (0.3, 224)):
    b.plot(time=time, axpos=axpos)
b.show()
image
abhimat commented 6 months ago

Aaah I see. I was using the axpos keyword, but in each call to plot() I was also sending the save keyword! It seems this is what was leading to the clearing of the figure. If I omit the save keyword until the very end, I do obtain a subplot arrangement like your example.

Thank you for your quick and helpful response!