Seaborn: ValueError: Axes instance argument was not found in a figure.

Created on 9 May 2014  Â·  13Comments  Â·  Source: mwaskom/seaborn

I'm trying to plot this basic DataFrame with a FacitGrid and running into this value error. Windows 7 x64, Python 2.7

print sns.__version__ 0.3.1
print pd.__version__ 0.13.1
print np.__version__ 1.7.1
print matplotlib.__version__ 1.3.0
import numpy as np
import pandas as pd
import seaborn as sns
from scipy import stats
import matplotlib as mpl
import matplotlib.pyplot as plt

In [2]:

sns.set(style="white")

np.random.seed(sum(map(ord, "axis_grids")))

In [3]:

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],

                 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],

                 'C' : randn(8), 'D' : randn(8)})

In [4]:

df

Out[4]:
    A   B   C   D
0   foo     one     0.805998    1.520340
1   bar     one     -1.519987   -1.845697
2   foo     two     -1.209843   -0.110755
3   bar     three   0.033920    0.569092
4   foo     two     0.138512    -0.341390
5   bar     two     -1.945447   -0.505211
6   foo     one     -0.933446   -0.161730
7   foo     three   0.815080    -0.755682

8 rows × 4 columns
In [5]:

g = sns.FacetGrid(df, col='A', row='B')

In [6]:

g.map(plt.scatter, 'C', 'D')

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-b16344b8ad2e> in <module>()
----> 1 g.map(plt.scatter, 'C', 'D')

D:\Python27\lib\site-packages\seaborn-0.3.1-py2.7.egg\seaborn\axisgrid.pyc in map(self, func, *args, **kwargs)
    291 
    292             # Get the current axis
--> 293             ax = self.facet_axis(row_i, col_j)
    294 
    295             # Decide what color to plot with

D:\Python27\lib\site-packages\seaborn-0.3.1-py2.7.egg\seaborn\axisgrid.pyc in facet_axis(self, row_i, col_j)
    415 
    416         # Get a reference to the axes object we want, and make it active
--> 417         plt.sca(ax)
    418         return ax
    419 

D:\Python27\lib\site-packages\matplotlib\pyplot.pyc in sca(ax)
    780             m.canvas.figure.sca(ax)
    781             return
--> 782     raise ValueError("Axes instance argument was not found in a figure.")
    783 
    784 

ValueError: Axes instance argument was not found in a figure.

Most helpful comment

It sounds like for the backend you're using you'll need to keep the call to the FacetGrid constructor and the call to g.map() in the same In cell/line.

All 13 comments

Hm, I'm unable to reproduce on OSX plotting with the inline backend in a notebook or with the qt backend in the qtconsole. Maybe try playing around with different backends? Also try calling plt.show() after cell 5 and see what the figure looks like?

plt.show() returns None. :frowning:

But the FacitGrid axes pops up when I run g = sns.FacetGrid(df, col='A', row='B')

calling plt.show() after the FacitGrid call also returns None.

This might have something to do with it: :sunglasses:

g.facet_axis(0,0)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-0d17d7463ac9> in <module>()
----> 1 g.facet_axis(0,0)

D:\Python27\lib\site-packages\seaborn-0.3.1-py2.7.egg\seaborn\axisgrid.pyc in facet_axis(self, row_i, col_j)
    415 
    416         # Get a reference to the axes object we want, and make it active
--> 417         plt.sca(ax)
    418         return ax
    419 

D:\Python27\lib\site-packages\matplotlib\pyplot.pyc in sca(ax)
    780             m.canvas.figure.sca(ax)
    781             return
--> 782     raise ValueError("Axes instance argument was not found in a figure.")
    783 
    784 

ValueError: Axes instance argument was not found in a figure.

It sounds like for the backend you're using you'll need to keep the call to the FacetGrid constructor and the call to g.map() in the same In cell/line.

Hey that worked! I'm just running it through the IPython web notebook but maybe I need to upgrade my IPython version. Thanks :+1:

BTW, do you have extranal links for the example data sources you use in your examples? I'm stuck behind firewalls for most of the day. :smile:

They should all be collected here: https://github.com/mwaskom/seaborn-data

Hi Michael,

I'm using FacitGrid to avoid using MPL subplots explicitly. So far I really
like it! :)

I have a need to facit custom plots that may make multiple calls on various
MPL plotting functions and overlap different symbols on *subsets *of the
grouped data. I considered wrapping the plotting functions and passing that
to FacitGrid.map() but then realized I actually need to use *subsets *of
the data for the different plotting functions.

Looking at the FacitGrid object it appears that you expose all the subplots
which would make it easy to add anything to any facit. This is great! I
would like to use this but I cannot see how to explicitly pass a group name
to return the facit axis.

I was thinking it would be cool to have an iterator protocol like
pd.groupby()

something like :

for axis, group, data in FacitGrid():
# data filtering & sampling
# various plotting code on axis

Any advice is appreciated,
-Gagi

On Fri, May 9, 2014 at 8:01 PM, Michael Waskom [email protected]
wrote:

Closed #194 https://github.com/mwaskom/seaborn/issues/194.

—
Reply to this email directly or view it on GitHub
https://github.com/mwaskom/seaborn/issues/194#event-119772860.

Awesome! Thanks!

-Gagi

On Wed, Jul 23, 2014 at 10:37 AM, Michael Waskom [email protected]
wrote:

Take a look at FacetGrid.facet_data:
https://github.com/mwaskom/seaborn/blob/master/seaborn/axisgrid.py#L219

—
Reply to this email directly or view it on GitHub
https://github.com/mwaskom/seaborn/issues/194#issuecomment-49908133.

I played around with facet_data() a bit and I think I got what I need, however, it does seems a bit cumbersome so maybe I'm missing a shortcut.

Given a simple data frame faceted across rows and columns and hue, I want to add markers to all points that are positive in the x-axis. (Or any other Boolean filter of rows)

Working Example:

import numpy as np
import pandas as pd
import seaborn as sns

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
                 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                 'C' : randn(8), 'D' : randn(8), 'E' : randint(0,3, size=(8,))})

# Plot the data with one facet missing and mark each facet with an integer.
g = sns.FacetGrid(df[:7], row='A', col='B', hue='E', palette='jet').map(plt.scatter, 'C', 'D');
[ax.scatter(0,0, marker=r'$ {} $'.format(i), s=100) for i, ax in enumerate(g.axes.flat)]
g.set(xlim=(-3, 3), ylim=(-3, 3));

# Loop through data facets, get axes, circle positive points where column D is positive.
for xyc, data in g.facet_data():
    if not data.empty:
        nd = data[data.D>0]
        g.axes[xyc[0], xyc[1]].scatter(nd.C, nd.D, marker='o', s=100, linewidth='1', edgecolor='r', facecolors='None')
g.fig

First Facet Plot:
1

Updated Facet Plot With Circled Points where D is positive:
2

Some Feedback/Ideas:

  1. I like the iterator protocol for going through subsets of facets! :+1:
  2. I think its cumbersome to explicitly have to index into FacetGrid.axes[row, col] to get back the facet axis.
  3. Empty Facet (row, col, hue) groups require checking for empty DataFrame as a workaround.

Ideally:

  1. The facet_data() (or another iterator method) would yield the (axes, data) for easy custom plotting.
  2. Is it possible to set the current axes when yielding so the MPL state machine can directly plot without explicit axes? :smile: I'm not sure this is even possible. :question:
  3. Can we have an option to yield only the non-empty facets by default with an option to yield them all?

I'm envisioning something like this, If I just want to draw an X through all points where D is positive:

for data in g.facet_data():
     nd = data[data.D>0]
     scatter(nd.C, nd.D, marker='x', s=100)

Just some ideas! I really like where seaborn is going!

I'd read through the FacetGrid.map function to see how it's used in context. In particular, check out the facet_axis method, it will do most of what you're looking for.

You might also find it easier to write your own function that is a light wrapper on plt.scatter and pass it to the FacetGrid.map_dataframe method.

I know this is closed, but I've been having the same original error message ("axes instance argument was not found..."). As with the original poster, keeping the call to the FacetGrid constructor and the call to g.map in the same line fixes the problem, but the problem with this is that it makes it very cumbersome to do repeated operations. For instance, if I want to add a bunch of vertical lines to every plot in a facet plot, it makes it impossible to do this via a for loop. Is there a more fundamental fix to this problem besides the workaround of keeping everything on one line?

@mwaskom ,
Thanks, this helped in 2018! @mwaskom

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JanHomann picture JanHomann  Â·  3Comments

chanshing picture chanshing  Â·  3Comments

stonebig picture stonebig  Â·  4Comments

vinay-jayaram picture vinay-jayaram  Â·  3Comments

alexpetralia picture alexpetralia  Â·  3Comments