Say I create a figure that will hold multiple plots, one of which I want to be a JointGrid
f = plt.figure(figsize=(12,6))
gs = gridspec.GridSpec(4,1 , height_ratios=[1.5,1.5,1.5, 1.5])
subplots = list(gs)
first_axis = f.add_subplot(subplots[0])
I would like to create a JointGrid plot on this axis. Is there any way to do that?
JointGrid does not seem to accept an ax parameter, I guess because it creates several axes (multiple of them, presumably), i.e. this doesn't work:
sns.JointGrid(xcol, ycol, df, size=12, ax=first_axis)
How can I use sns.JointGrid with subplot?
Because of the way matplotlib is structured, sns.JointGrid creates a whole separate figure composed of three different ax objects, and to my knowledge can't be inserted as a subplot as part of a larger figure.
See this StackOverflow question and answer for more details.
Thanks @mwaskom That answer is great. I guess there isn't an easy way of combining multiple figures into one for now (and either way that would be a matplotlib question). I am all set.
Actually there is a way to "insert a figure into an ax", if this is all done within gridspecs and subplotspecs: http://matplotlib.org/users/gridspec.html#gridspec-using-subplotspec.
If a plotting interface accepts a SubplotSpec and uses that to create GridSpec via GridSpecFromSubplotSpec for the subplots:
def plot_something(..., subplotspec=None, fig=None):
if fig is None:
fig = plt.gcf()
if subplotspec is None:
# create a new subplotspec, by creating a 1x1 GridSpec and taking the only
# element in there, which will then be the whole plotting area
subplotspec = gridspec.GridSpec(1, 1)[0]
# create a three times three subplot area on the available subplotspec
rows, columns = 3,3
gs = mpl.gridspec.GridSpecFromSubplotSpec(rows, columns, subplot_spec=subplotspec)
for row in rows:
for col in columns:
ax = fig.add_subplot(gs[row, col])
# plot something on this ax
# ...
gs.tight_layout(fig)
A caller, who wants to combine two plots would then have to do this:
import matplotlib as mpl
gs_outside = mpl.gridspec.GridSpec(1, 2)
ax_left = plt.subplot(gs_outside[0,0])
# use ax_left to plot something there, completely unrelated ... :-)
sub_right = gs_outside[0,0] # don't convert this to an ax!
plot_something(..., subplotspec=sub_right)
One could even use that for all plotting function, if the plotting function would guard against receiving ax as a SubplotSpec:
def plot_whatever(..., ax=None):
if ax is None:
# create figure + ax
else:
if isinstance(ax, mpl.gridspec.SubplotSpec):
ax = plt.subplot(ax)
# now plot something on the ax...
Can you provide a concrete example. I am trying to render two different plots and not able to get the above solution working.
I have implemented this!
fig = plt.figure(figsize=(16,8))
gs = gridspec.GridSpec(1,2, wspace=.2)
fig.add_subplot(gs[0])
iris = sns.load_dataset("iris")
g = sns.PairGrid(iris, subplot_spec=gs[1])
g = g.map(plt.scatter)
````

`sns.pairplot(iris, grid_kws={'subplot_spec':gs[1]})` also works.
I also implemented it for JointGrid:
fig = plt.figure(figsize=(8,4))
gs = gridspec.GridSpec(1,2, wspace=.2)
fig.add_subplot(gs[0])
g = sns.JointGrid(x="total_bill", y="tip", data=tips, size=5, ratio=2,
subplot_spec=gs[1])
g = g.plot_joint(sns.kdeplot, cmap="Reds_d")
g = g.plot_marginals(sns.kdeplot, color="r", shade=True)
```

(similar results for g = sns.jointplot(x="total_bill", y="tip", kind='kde',data=tips, size=5, ratio=2,
subplot_spec=gs[1]))
The JointPlot/jointplot implementation was pretty straightforward, however, PairGrid/pairplot depends on a change to matplotlib that is in the master branch but has not yet been released. The implementation of plt.subplots() was recently moved to fig.subplots(). That change allowed me to implement this without a giant overhaul to seaborn, because it allowed me to call subplots and use the sharex and sharey optional arguments on a pre-existing figure. To do it with the current release, one would have to implement sharex and sharey themselves. Then we'd probably want to change it to this implementation once the mpl update occurs anyway so I feel like that would be a waste.
I'm new to contributing, so I don't know what the standard protocol is for features that rely on not-yet-released dependencies. Please advise.
What's the timeframe for this? I see last post on this was in April, but it hasn't been implemented in an official release yet, as far as I can tell. Simply closed...
Let me take a look at this and see if MPL has made the necessary release for this to be smooth
I looked back into this. MPL did push that update, so you can use this feature if you want to install my fork and branch: https://github.com/bendichter/seaborn/tree/PairGrid_as_subplot but there have been some organizational changes to seaborn since I implemented this and I'm not sure how easy it will be to incorporate into the latest master branch. I'll take a look, but no promises.
I merged and issued a PR
I wrote a small class in this Stackoverflow anser that would allow to transfer a plot from one of the figure type seaborn graphs to a position of a gridspec in a different matplotlib figure. There are some minor issues still, so such solution needs a bit tweaking, but is in principle usable.
The output might then look something like this:

@bendichter I think to merge your PR into seaborn you need to make sure that it doesn't break for versions of matplotlib which do not have fig.subplots() available. Also, does it cover pairplot and lmplot?
It will surely break with older versions of matplotlib :-(
On Dec 4, 2017 6:21 PM, "Importance of Being Ernest" <
[email protected]> wrote:
@bendichter https://github.com/bendichter I think to merge your PR
https://github.com/mwaskom/seaborn/pull/1338 into seaborn you need to
make sure that it doesn't break for versions of matplotlib which do not
have fig.subplots() available. Also, does it cover pairplot and lmplot?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mwaskom/seaborn/issues/399#issuecomment-348933893,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAziErqIkjHGEpeAo8ei6hhNxMtackuMks5s89WwgaJpZM4DHU5y
.
It works for pairplot, but I haven't tried with lmplot.
On Dec 4, 2017 6:21 PM, "Importance of Being Ernest" <
[email protected]> wrote:
@bendichter https://github.com/bendichter I think to merge your PR
https://github.com/mwaskom/seaborn/pull/1338 into seaborn you need to
make sure that it doesn't break for versions of matplotlib which do not
have fig.subplots() available. Also, does it cover pairplot and lmplot?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mwaskom/seaborn/issues/399#issuecomment-348933893,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAziErqIkjHGEpeAo8ei6hhNxMtackuMks5s89WwgaJpZM4DHU5y
.
@bendichter What I mean is that when it is used with older versions it should fall back to create its own figure and issue a warning or similar, not throw an error.
Ah, well that's doable
On Dec 4, 2017 6:28 PM, "Importance of Being Ernest" <
[email protected]> wrote:
@bendichter https://github.com/bendichter What I mean is that when it
is used with older versions it should fall back to create its own figure
and issue a warning or similar, not throw an error.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mwaskom/seaborn/issues/399#issuecomment-348935518,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAziEoGWN99DVtzx3NvHKz20V863MutCks5s89dqgaJpZM4DHU5y
.
@ImportanceOfBeingErnest
not work for multi-dimension gridspec like gs[:2, :3] with customized dpi.
@yech1990 I suppose with "not work" you are refering to the stackoverflow answer of mine? Note that this is merely a proof of priniciple, or a quick hack. It's not meant to be used for production purposes. Or in other words: If it works, feel free to use it, if it doesn't, don't use it, or try to improve it.
The problem is that the solution does not replicate the transform chain in the new figure, but relies on the transforms of the original figure. If you have problems with the dpi, try to use the same dpi in both, the seaborn figure(s) and the matplotlib figure.
I got this warning while using subplot_spec and only the second figure shows.
UserWarning: The following kwargs were not used by contour: 'subplot_spec'
Here's the version of packages:
# Name Version Build Channel
seaborn 0.9.0 py36_0 defaults
matplotlib 3.0.3 py36h5429711_0 defaults
Most helpful comment
I wrote a small class in this Stackoverflow anser that would allow to transfer a plot from one of the figure type seaborn graphs to a position of a gridspec in a different matplotlib figure. There are some minor issues still, so such solution needs a bit tweaking, but is in principle usable.
The output might then look something like this:
