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.
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.
Take a look at FacetGrid.facet_data: https://github.com/mwaskom/seaborn/blob/master/seaborn/axisgrid.py#L219
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:

Updated Facet Plot With Circled Points where D is positive:

Some Feedback/Ideas:
Ideally:
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
Most helpful comment
It sounds like for the backend you're using you'll need to keep the call to the
FacetGridconstructor and the call tog.map()in the sameIncell/line.