9

I am writing a bunch of scripts and functions for processing astronomical data. I have a set of galaxies, for which I want to plot some different properties in a 3-panel plot. I have an example of the layout here:

enter image description here

Now, this is not a problem. But sometimes, I want to create this plot just for a single galaxy. In other cases, I want to make a larger plot consisting of subplots that each are made up of the three+pane structure, like this mockup:

enter image description here

For the sake of modularity and reusability of my code, I would like to do something to the effect of just letting my function return a matplotlib.figure.Figure object and then let the caller - function or interactive session - decide whether to show() or savefig the object or embed it in a larger figure. But I cannot seem to find any hints of this in the documentation or elsewhere, it doesn't seem to be something people do that often.

Any suggestions as to what would be the best road to take? I have speculated whether using axes_grid would be the solution, but it doesn't seem quite clean and caller-agnostic to me. Any suggestions?

Thriveth
  • 377
  • 1
  • 6
  • 18
  • http://stackoverflow.com/questions/16750333/how-do-i-include-a-matplotlib-figure-object-as-subplot/16754215#16754215 – tacaswell Sep 24 '13 at 12:54

1 Answers1

5

The best solution is to separate the figure layout logic from the plotting logic. Write your plotting code something like this:

 def three_panel_plot(data, ploting_args, ax1, ax2, ax3):
     # what you do to plot

So now the code that turns data -> images takes as arguments the data and where it should plot that data too.

If you want to do just one, it's easy, if you want to do a 3x3 grid, you just need to generate the layout and then loop over the axes sets + data.

The way you are suggesting (returning an object out of your plotting routine) would be very hard in matplotlib, the internals are too connected.

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • 2
    Thanks you, this is what I ended up doing. Even though it does frustrate me a bit, it would be nice to be able to build a figure from figures like they were axes... – Thriveth Oct 09 '13 at 16:55
  • 1
    To do so would (I think) require a major re-factoring of how the backends work. That said, I have convinced my self that this way is more modular than making 'super figures'. If you order your signatures as `def my_plot(ax, *args, **kwargs)` than they match the expected signature pattern for the built in plotting commands. This question has come up enough (I have answered variations on it 2 or 3 times) I should write up a canonical example someplace. – tacaswell Oct 09 '13 at 17:11