sub-sub-plots, sub-sub-sub-plots, etc.

I need to generate a fairly complex chart, for which I need the ability to specify not only subplots, but also sub-subplots, and even sub-sub-sub-plots. (Our group has found such charts useful in the past, but they were generated using horrific MATLAB code.)

I’ll try to describe what I want to do in a bit more detail (it’s messy).

First imagine a simple plot (just a simple X-Y line graph connecting 3-4 datapoints). I’ll call this a level-0 plot. Now, join ~10 of these level-0 plots side-by-side (with no space between the plots). This new aggregate is a level-1 plot. Next stack ~10 level-1 plots vertically, again, with no space between them. The resulting aggregate is a level-2 plot. Finally arrange ~10 of these level-2 plots side-by-side, with some spacing between them. The desired final product is this level-3 plot.

Without knowing much about the internals of matplotlib, it seems to me that the best way to do this would be to define a container class that can have itself as one of the contained elements. In this way, a containment hierarchy of arbitrary depth could be defined. But it is my understanding that there is no immediate way to do this in matplotlib now, so I’d have to implement it myself.

I could use some guidance to the source code.

What I need to clarify is the following. First consider some simple plot A: it has axes, data points, tick marks, labels, etc., and for all these elements there are associated absolute x-y coordinates on the canvas. If now we make this plot A one of the subplots in a collection of, say, 12 subplots, arranged as 3 rows of 4 subplots each, all the x-y coordinates associated with the original plot A will have to be translated and scaled, so that the subplot lands in the right place on the canvas, and has the appropriate size. This process of translation and scaling is what I want to pinpoint: What exactly is the connection between running the add_subplot method and the translation+scaling that it entails?

What would be a good entry point for me to answer the questions above by reading the source code?

TIA!

~kj

Looks like you are talking about an arbitrarily deep hierarchical subplotting feature. I am not exactly sure how feasible/unfeasible this is, but a good place to start might be to take a look at the axes_grid toolkit that does a lot of very advanced axes organizational tricks.

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/index.html

I hope this proves useful, or at least inspires you for ideas on how to accomplish what you are looking for cleanly. And, as always, patches are always welcome!

Ben Root

···

On Fri, Oct 22, 2010 at 5:09 PM, Kynn Jones <kynnjo@…149…> wrote:

I need to generate a fairly complex chart, for which I need the ability to specify not only subplots, but also sub-subplots, and even sub-sub-sub-plots. (Our group has found such charts useful in the past, but they were generated using horrific MATLAB code.)

I’ll try to describe what I want to do in a bit more detail (it’s messy).

First imagine a simple plot (just a simple X-Y line graph connecting 3-4 datapoints). I’ll call this a level-0 plot. Now, join ~10 of these level-0 plots side-by-side (with no space between the plots). This new aggregate is a level-1 plot. Next stack ~10 level-1 plots vertically, again, with no space between them. The resulting aggregate is a level-2 plot. Finally arrange ~10 of these level-2 plots side-by-side, with some spacing between them. The desired final product is this level-3 plot.

Without knowing much about the internals of matplotlib, it seems to me that the best way to do this would be to define a container class that can have itself as one of the contained elements. In this way, a containment hierarchy of arbitrary depth could be defined. But it is my understanding that there is no immediate way to do this in matplotlib now, so I’d have to implement it myself.

I could use some guidance to the source code.

What I need to clarify is the following. First consider some simple plot A: it has axes, data points, tick marks, labels, etc., and for all these elements there are associated absolute x-y coordinates on the canvas. If now we make this plot A one of the subplots in a collection of, say, 12 subplots, arranged as 3 rows of 4 subplots each, all the x-y coordinates associated with the original plot A will have to be translated and scaled, so that the subplot lands in the right place on the canvas, and has the appropriate size. This process of translation and scaling is what I want to pinpoint: What exactly is the connection between running the add_subplot method and the translation+scaling that it entails?

What would be a good entry point for me to answer the questions above by reading the source code?

TIA!

~kj

Matplotlib has a simple hierachy of Figure-Axes-Artists (this is not
100% correct description as a matter of fact, see
http://matplotlib.sourceforge.net/users/artists.html for more
details).

All Axes instances have associated positions within a figure instance.
If you want to have a hierarchy of multiple axes, what you can do
basically is to make those positions in hierarchical manner.

This can be very trivial depending on what exactly you want (e.g., how
you want the axes sizes (and the gaps inbetween) specified). However,
there are a few ways to ease this process.

http://github.com/astraw/mplsizer

mpl v1.0 has gridspec.

http://matplotlib.sourceforge.net/users/gridspec.html#gridspec-using-subplotspec

For example, you may do something like

import matplotlib.gridspec as gridspec
fig = gcf()
gs0 = gridspec.GridSpec(2, 2)
ax = fig.add_subplot(gs0[0, 0])

gs00 = gridspec.GridSpecFromSubplotSpec(2, 2, subplot_spec=gs0[1])
ax2 = fig.add_subplot(gs00[0])

gs000 = gridspec.GridSpecFromSubplotSpec(2, 2, subplot_spec=gs00[1])
ax3 = fig.add_subplot(gs000[0])

Or, you can use axes_grid toolkit as mentioned above.

Regards,

-JJ

···

On Sat, Oct 23, 2010 at 7:09 AM, Kynn Jones <kynnjo@...149...> wrote:

Without knowing much about the internals of matplotlib, it seems to me that
the best way to do this would be to define a container class that can have
itself as one of the contained elements. In this way, a containment
hierarchy of arbitrary depth could be defined. But it is my understanding
that there is no immediate way to do this in matplotlib now, so I'd have to
implement it myself.

Ben, JJ, thanks for your suggestions. I’ll look into what you proposed.

~kj