0

I have some code that generates a figure with a single Axes object.

import matplotlib.pyplot as plt

def myfunc():
    fig, ax = plt.subplots()
    ax.plot(range(5))
    return fig, ax

fig, ax = myfunc()

I want to wrap that code such that I can call it multiple times, extract the ax object and collect it into a new figure, essentially creating a composition. I already have some code to move the axes from a figure to another:

def move_axes(ax, original_fig, target_fig, position=None):
    """
    Move Axes object from original_fig to target_fig.
    Sacrifices original_fig.
    # MISSING A CLEVER WAY TO AUTOMATICALLY ESTIMATE THE NEW POSITION.
    """
    if position is None:
        position = ax.get_position()
    ax.remove()

    ax.figure = target_fig
    target_fig.axes.append(ax)
    target_fig.add_axes(ax)

    ax.set_position(position)
    plt.close(original_fig)
    return target_fig

So what I want to do is something like:

target_fig = plt.figure()
for i in range(3):
    fig, ax = myfunc()
    move_axes(ax, fig, target_fig)

But that doesn't work because I need to set the position of the Axes such that they don't overlap each other. Is there a clean way to do this, i.e., grab the size of the Axes, expand the target_fig so that every new ax would be stacked vertically below the previous one?

Daniel
  • 11,332
  • 9
  • 44
  • 72
  • Moving an axes from one figure to another is really not best practice. Are you sure this is not an [xyproblem](http://xyproblem.info)? What is the purpose of this? – ImportanceOfBeingErnest Jan 18 '18 at 14:20
  • It could well be an xyproblem. I have an experiment with multiple trials, and I wrote the `myfunc()` code some time ago to analyse data from a single trial. My goal here was to reuse that code to generate a figure for all trials without having to explicitly change `myfunc()`. My idea of a quick solution would be to stack all `ax` into a single figure and have the size of the figure adjust automatically. – Daniel Jan 18 '18 at 14:28
  • 2
    For how to move an axes to a new figure, see [this answer](https://stackoverflow.com/a/46906599/4124317). However, for the case in use it really seems not well suited. I would say the best solution is to modify (or copy) the original function and add an argument `ax`, which denotes the axes to plot to. Inside that function, plot to that axes (`ax.plot()` or whatever). Outside that function create a figure and as many axes as you like, which you can then supply to that function. – ImportanceOfBeingErnest Jan 18 '18 at 14:31
  • That sounds like a much better idea, I‘ll give it a try. Thanks – Daniel Jan 18 '18 at 17:45

0 Answers0