New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

df.plot(ax=ax) AttributeError: 'Axes' object has no attribute 'is_first_col' #11520

Closed
dragoljub opened this Issue Nov 4, 2015 · 11 comments

Comments

Projects
None yet
5 participants
@dragoljub

dragoljub commented Nov 4, 2015

When attempting to use the Pandas 0.17.0 plot method to target plotting on an external axes: AttributeError: 'Axes' object has no attribute 'is_first_col'.

Pandas: 0.17.0
Numpy: 1.9.2
Matplotlib: 1.5.0

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar', 'foo', 'foo'],
                    'B' : ['one', 'one', 'two', 'three',
                          'two', 'two', 'one', 'three'],
                    'C' : np.random.randn(8),
                    'D' : np.random.randn(8)})

fig = plt.figure()
ax = fig.add_axes((0,0,1,1))

df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0, colormap='hsv')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-b38f872a3fc3> in <module>()
----> 1 df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0)

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in __call__(self, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   3665                           fontsize=fontsize, colormap=colormap, table=table,
   3666                           yerr=yerr, xerr=xerr, secondary_y=secondary_y,
-> 3667                           sort_columns=sort_columns, **kwds)
   3668     __call__.__doc__ = plot_frame.__doc__
   3669 

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in plot_frame(data, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   2550                  yerr=yerr, xerr=xerr,
   2551                  secondary_y=secondary_y, sort_columns=sort_columns,
-> 2552                  **kwds)
   2553 
   2554 

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in _plot(data, x, y, subplots, ax, kind, **kwds)
   2378         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
   2379 
-> 2380     plot_obj.generate()
   2381     plot_obj.draw()
   2382     return plot_obj.result

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in generate(self)
    990             self._post_plot_logic_common(ax, self.data)
    991             self._post_plot_logic(ax, self.data)
--> 992         self._adorn_subplots()
    993 
    994     def _args_adjust(self):

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in _adorn_subplots(self)
   1141                                 naxes=nrows * ncols, nrows=nrows,
   1142                                 ncols=ncols, sharex=self.sharex,
-> 1143                                 sharey=self.sharey)
   1144 
   1145         for ax in self.axes:

D:\Python27\lib\site-packages\pandas\tools\plotting.pyc in _handle_shared_axes(axarr, nplots, naxes, nrows, ncols, sharex, sharey)
   3403                 # as we only have labels in teh first column and we always have a subplot there,
   3404                 # we can skip the layout test
-> 3405                 if ax.is_first_col():
   3406                     continue
   3407                 if sharey or len(ax.get_shared_y_axes().get_siblings(ax)) > 1:

AttributeError: 'Axes' object has no attribute 'is_first_col'
@jorisvandenbossche

This comment has been minimized.

Show comment
Hide comment
@jorisvandenbossche

jorisvandenbossche Nov 5, 2015

Member

@dragoljub Is there a specific reason that you use add_axes instead of add_subplot?
Because pandas seems to assume that the ax argument is an AxesSubplot and not a plain axes (the is_first_col method is only available on the former)

However, I can't reproduce this issue (using pandas master and matplotlib 1.5). Are you sure the above is a reproducible example? As the place where it fails should only be reached if you have multiple axes (and your example has only one)

Member

jorisvandenbossche commented Nov 5, 2015

@dragoljub Is there a specific reason that you use add_axes instead of add_subplot?
Because pandas seems to assume that the ax argument is an AxesSubplot and not a plain axes (the is_first_col method is only available on the former)

However, I can't reproduce this issue (using pandas master and matplotlib 1.5). Are you sure the above is a reproducible example? As the place where it fails should only be reached if you have multiple axes (and your example has only one)

@jorisvandenbossche

This comment has been minimized.

Show comment
Hide comment
@jorisvandenbossche

jorisvandenbossche Nov 5, 2015

Member

But that said, we maybe shouldn't rely on the assumption it is a Subplot ?

@TomAugspurger @sinhrks

Member

jorisvandenbossche commented Nov 5, 2015

But that said, we maybe shouldn't rely on the assumption it is a Subplot ?

@TomAugspurger @sinhrks

@TomAugspurger

This comment has been minimized.

Show comment
Hide comment
@TomAugspurger

TomAugspurger Nov 5, 2015

Contributor

Couldn't reproduce it either. (pandas master, matplotlib 1.5, OS X).

Contributor

TomAugspurger commented Nov 5, 2015

Couldn't reproduce it either. (pandas master, matplotlib 1.5, OS X).

@dragoljub

This comment has been minimized.

Show comment
Hide comment
@dragoljub

dragoljub Nov 5, 2015

@jorisvandenbossche I'm specifically using ax = fig.add_axes((0,0,1,1)) because I'm creating 1000's of plots that must completely fill the plotting area (edge to edge) when png images are generated.

I am able to reproduction it Jupiter Notebook 4.0 (all Windows X64, builds from Christoph Gohlke's UCI repository). I'll do some more digging to confirm this on other machines.

dragoljub commented Nov 5, 2015

@jorisvandenbossche I'm specifically using ax = fig.add_axes((0,0,1,1)) because I'm creating 1000's of plots that must completely fill the plotting area (edge to edge) when png images are generated.

I am able to reproduction it Jupiter Notebook 4.0 (all Windows X64, builds from Christoph Gohlke's UCI repository). I'll do some more digging to confirm this on other machines.

@dragoljub

This comment has been minimized.

Show comment
Hide comment
@dragoljub

dragoljub Nov 5, 2015

@jorisvandenbossche @TomAugspurger I just reproduced it on OSX, Pandas 0.17.0, Matplotlib 1.4.3

Looks like you have to add the cmap= or colormap= argument to see the issue:

df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0, colormap='hsv')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-76da9d6c62ce> in <module>()
----> 1 df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0, colormap='hsv')

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in __call__(self, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   3665                           fontsize=fontsize, colormap=colormap, table=table,
   3666                           yerr=yerr, xerr=xerr, secondary_y=secondary_y,
-> 3667                           sort_columns=sort_columns, **kwds)
   3668     __call__.__doc__ = plot_frame.__doc__
   3669 

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in plot_frame(data, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   2550                  yerr=yerr, xerr=xerr,
   2551                  secondary_y=secondary_y, sort_columns=sort_columns,
-> 2552                  **kwds)
   2553 
   2554 

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _plot(data, x, y, subplots, ax, kind, **kwds)
   2378         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
   2379 
-> 2380     plot_obj.generate()
   2381     plot_obj.draw()
   2382     return plot_obj.result

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in generate(self)
    990             self._post_plot_logic_common(ax, self.data)
    991             self._post_plot_logic(ax, self.data)
--> 992         self._adorn_subplots()
    993 
    994     def _args_adjust(self):

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _adorn_subplots(self)
   1141                                 naxes=nrows * ncols, nrows=nrows,
   1142                                 ncols=ncols, sharex=self.sharex,
-> 1143                                 sharey=self.sharey)
   1144 
   1145         for ax in self.axes:

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _handle_shared_axes(axarr, nplots, naxes, nrows, ncols, sharex, sharey)
   3403                 # as we only have labels in teh first column and we always have a subplot there,
   3404                 # we can skip the layout test
-> 3405                 if ax.is_first_col():
   3406                     continue
   3407                 if sharey or len(ax.get_shared_y_axes().get_siblings(ax)) > 1:

AttributeError: 'Axes' object has no attribute 'is_first_col'

dragoljub commented Nov 5, 2015

@jorisvandenbossche @TomAugspurger I just reproduced it on OSX, Pandas 0.17.0, Matplotlib 1.4.3

Looks like you have to add the cmap= or colormap= argument to see the issue:

df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0, colormap='hsv')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-76da9d6c62ce> in <module>()
----> 1 df.plot(kind='scatter', ax=ax, x='C', y='D', c=df.C, s=100, linewidth=0, colormap='hsv')

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in __call__(self, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   3665                           fontsize=fontsize, colormap=colormap, table=table,
   3666                           yerr=yerr, xerr=xerr, secondary_y=secondary_y,
-> 3667                           sort_columns=sort_columns, **kwds)
   3668     __call__.__doc__ = plot_frame.__doc__
   3669 

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in plot_frame(data, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)
   2550                  yerr=yerr, xerr=xerr,
   2551                  secondary_y=secondary_y, sort_columns=sort_columns,
-> 2552                  **kwds)
   2553 
   2554 

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _plot(data, x, y, subplots, ax, kind, **kwds)
   2378         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
   2379 
-> 2380     plot_obj.generate()
   2381     plot_obj.draw()
   2382     return plot_obj.result

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in generate(self)
    990             self._post_plot_logic_common(ax, self.data)
    991             self._post_plot_logic(ax, self.data)
--> 992         self._adorn_subplots()
    993 
    994     def _args_adjust(self):

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _adorn_subplots(self)
   1141                                 naxes=nrows * ncols, nrows=nrows,
   1142                                 ncols=ncols, sharex=self.sharex,
-> 1143                                 sharey=self.sharey)
   1144 
   1145         for ax in self.axes:

/Users/gagi/anaconda/lib/python2.7/site-packages/pandas/tools/plotting.pyc in _handle_shared_axes(axarr, nplots, naxes, nrows, ncols, sharex, sharey)
   3403                 # as we only have labels in teh first column and we always have a subplot there,
   3404                 # we can skip the layout test
-> 3405                 if ax.is_first_col():
   3406                     continue
   3407                 if sharey or len(ax.get_shared_y_axes().get_siblings(ax)) > 1:

AttributeError: 'Axes' object has no attribute 'is_first_col'
@TomAugspurger

This comment has been minimized.

Show comment
Hide comment
@TomAugspurger

TomAugspurger Nov 5, 2015

Contributor

Ok that one failed fails for me, thanks.

Needing colormap is suggestive. I suspect that we think we're only dealing with one axes since that's what is passed in. Then we add a secondary axes to draw the colormap on, so we reach that codepath which assumes there's multiple axes.

Contributor

TomAugspurger commented Nov 5, 2015

Ok that one failed fails for me, thanks.

Needing colormap is suggestive. I suspect that we think we're only dealing with one axes since that's what is passed in. Then we add a secondary axes to draw the colormap on, so we reach that codepath which assumes there's multiple axes.

@jorisvandenbossche

This comment has been minimized.

Show comment
Hide comment
@jorisvandenbossche

jorisvandenbossche Nov 5, 2015

Member

Yes, now I can also reproduce it. @dragoljub To get around the bug for now, you can always specify colorbar=False

Member

jorisvandenbossche commented Nov 5, 2015

Yes, now I can also reproduce it. @dragoljub To get around the bug for now, you can always specify colorbar=False

@dragoljub

This comment has been minimized.

Show comment
Hide comment
@dragoljub

dragoljub Nov 5, 2015

@TomAugspurger @jorisvandenbossche Yes, I just noticed by default Pandas adds the colorbar to the plot even though the argument is optional. In my case I do not want the colorbar but would like to customize the colormap. In that case colorbar=False works.

Thanks!

dragoljub commented Nov 5, 2015

@TomAugspurger @jorisvandenbossche Yes, I just noticed by default Pandas adds the colorbar to the plot even though the argument is optional. In my case I do not want the colorbar but would like to customize the colormap. In that case colorbar=False works.

Thanks!

@sinhrks

This comment has been minimized.

Show comment
Hide comment
@sinhrks

sinhrks Nov 7, 2015

Member

There seems to be some cases which ax doesn't have is_first_col and is_last_col (tested in 1.4.3). Nice to add test cases for them.

import matplotlib.pyplot

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
hasattr(ax, 'is_first_col')
# True

# divider
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
hasattr(cax, 'is_first_col')
# False

# insert_ax
from mpl_toolkits.axes_grid.inset_locator import inset_axes
iax = inset_axes(ax, width="30%", height=1., loc=3)
hasattr(iax, 'is_first_col')
# False

# add_axes
aax = fig.add_axes()
hasattr(aax, 'is_first_col')
# False
Member

sinhrks commented Nov 7, 2015

There seems to be some cases which ax doesn't have is_first_col and is_last_col (tested in 1.4.3). Nice to add test cases for them.

import matplotlib.pyplot

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
hasattr(ax, 'is_first_col')
# True

# divider
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
hasattr(cax, 'is_first_col')
# False

# insert_ax
from mpl_toolkits.axes_grid.inset_locator import inset_axes
iax = inset_axes(ax, width="30%", height=1., loc=3)
hasattr(iax, 'is_first_col')
# False

# add_axes
aax = fig.add_axes()
hasattr(aax, 'is_first_col')
# False
@jreback

This comment has been minimized.

Show comment
Hide comment
@jreback

jreback Nov 15, 2015

Contributor

closed by #11561

Contributor

jreback commented Nov 15, 2015

closed by #11561

@jreback jreback closed this Nov 15, 2015

@dragoljub

This comment has been minimized.

Show comment
Hide comment
@dragoljub

dragoljub commented Nov 15, 2015

@jreback
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment