santosjorge / cufflinks

Productivity Tools for Plotly + Pandas
MIT License
3.02k stars 675 forks source link

Not able to set secondary_y for cufflinks version 0.14.4 ,throw attribute error __delitem__ #146

Open ghost opened 5 years ago

ghost commented 5 years ago

I noticed that some of my code using the older version of cufflinks(0.12.1) and plotly(2.5.1) no longer works. So I try to rerun the code as in the example to see if I can reproduce the problem. For this code here:

from plotly.offline import iplot
import cufflinks as cf
cf.set_config_file(offline=True)
%matplotlib inline

df=cf.datagen.lines(4,mode='abc')
df[['c','d']]=df[['c','d']]*100

#df.iplot(secondary_y=['c', 'd'])
fig1 = df.iplot(columns=['a', 'b'], asFigure=True)
fig2 = df.iplot(columns=['c', 'd'], kind='bar', secondary_y=['c', 'd'], asFigure=True)
fig2['data'].extend(fig1['data'])
iplot(fig2)

The code will give me AttributeError delitem screenshot from 2018-10-24 16-08-27

pjandrews commented 5 years ago

I'm also seeing this issue. This worked with plotly 2.

import cufflinks as cf cf.version '0.14.5'

import plotly plotly.version '3.4.2'

from plotly.offline import plot, iplot

df = pd.DataFrame([[1, 2,3,4,5,6], [1, 3,4,5,6,7], [4, 6,6,9,10,11]], columns=['A', 'B','C','D','E','F'])

fig1 = df.iplot(kind='scatter', mode='lines+markers', x=['A', 'B'], y=['C', 'D',], asFigure=True) fig2 = df.iplot(kind='bar', x=['A', 'B'], y=['C', 'D', ], secondary_y=['E','F'],asFigure=True) fig2['data'].extend(fig1['data'])

Error returned:


TypeError Traceback (most recent call last)

in () 4 fig2 = df.iplot(kind='bar', x=['A', 'B'], 5 y=['C', 'D', ], ----> 6 secondary_y=['E','F'],asFigure=True) 7 fig2['data'].extend(fig1['data']) C:\ProgramData\Anaconda3\lib\site-packages\cufflinks\plotlytools.py in _iplot(self, kind, data, layout, filename, sharing, title, xTitle, yTitle, zTitle, theme, colors, colorscale, fill, width, dash, mode, interpolation, symbol, size, barmode, sortbars, bargap, bargroupgap, bins, histnorm, histfunc, orientation, boxpoints, annotations, keys, bestfit, bestfit_colors, mean, mean_colors, categories, x, y, z, text, gridcolor, zerolinecolor, margin, labels, values, secondary_y, secondary_y_title, subplots, shape, error_x, error_y, error_type, locations, lon, lat, asFrame, asDates, asFigure, asImage, dimensions, asPlot, asUrl, online, **kwargs) 817 df=df[[y, secondary_y]] 818 else: --> 819 df=df[[y] + secondary_y] 820 elif y: 821 df=df[y] C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py in __getitem__(self, key) 2680 if isinstance(key, (Series, np.ndarray, Index, list)): 2681 # either boolean or fancy integer index -> 2682 return self._getitem_array(key) 2683 elif isinstance(key, DataFrame): 2684 return self._getitem_frame(key) C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\frame.py in _getitem_array(self, key) 2724 return self._take(indexer, axis=0) 2725 else: -> 2726 indexer = self.loc._convert_to_indexer(key, axis=1) 2727 return self._take(indexer, axis=1) 2728 C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\indexing.py in _convert_to_indexer(self, obj, axis, is_setter) 1312 # unique index 1313 if labels.is_unique: -> 1314 indexer = check = labels.get_indexer(objarr) 1315 1316 # non-unique (dups) C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in get_indexer(self, target, method, limit, tolerance) 3257 'backfill or nearest reindexing') 3258 -> 3259 indexer = self._engine.get_indexer(target._ndarray_values) 3260 3261 return _ensure_platform_int(indexer) pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_indexer() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.lookup() TypeError: unhashable type: 'list'
timkpaine commented 5 years ago

I have a fix for this, but the code will be slightly different:

from plotly.offline import iplot
import cufflinks as cf
cf.set_config_file(offline=True)
%matplotlib inline

df=cf.datagen.lines(4,mode='abc')
df[['c','d']]=df[['c','d']]*100

#df.iplot(secondary_y=['c', 'd'])
fig1 = df.iplot(columns=['a', 'b'], asFigure=True).to_plotly_json()
fig2 = df.iplot(columns=['c', 'd'], kind='bar', secondary_y=['c', 'd'], asFigure=True).to_plotly_json()
fig2['data'].extend(fig1['data'])
iplot(fig2)
screen shot 2018-12-18 at 7 55 00 pm
timkpaine commented 5 years ago

@MecShLmmm @pjandrews can you guys test https://github.com/santosjorge/cufflinks/pull/156

rightx2 commented 4 years ago

@timkpaine your code raise errors on plotly==4.8.1, cufflinks==0.17.3, Python 3.7.x:

AttributeError                            Traceback (most recent call last)
<ipython-input-11-336100cdb536> in <module>
      9 #df.iplot(secondary_y=['c', 'd'])
     10 fig1 = df.iplot(columns=['a', 'b'], asFigure=True).to_plotly_json()
---> 11 fig2 = df.iplot(columns=['c', 'd'], kind='bar', secondary_y=['c', 'd'], asFigure=True).to_plotly_json()
     12 fig2['data'].extend(fig1['data'])
     13 iplot(fig2)

/home/lib/python3.7/site-packages/cufflinks/plotlytools.py in _iplot(self, kind, data, layout, filename, sharing, title, xTitle, yTitle, zTitle, theme, colors, colorscale, fill, width, dash, mode, interpolation, symbol, size, barmode, sortbars, bargap, bargroupgap, bins, histnorm, histfunc, orientation, boxpoints, annotations, keys, bestfit, bestfit_colors, mean, mean_colors, categories, x, y, z, text, gridcolor, zerolinecolor, margin, labels, values, secondary_y, secondary_y_title, subplots, shape, error_x, error_y, error_type, locations, lon, lat, asFrame, asDates, asFigure, asImage, dimensions, asPlot, asUrl, online, **kwargs)
   1174 ## Check secondary axis
   1175         if secondary_y:
-> 1176                 figure=tools._set_axis(figure,secondary_y,side='right')
   1177                 if secondary_y_title:
   1178                         figure.layout.yaxis2.title=secondary_y_title

/home/lib/python3.7/site-packages/cufflinks/tools.py in _set_axis(self, traces, on, side, title)
   1178                 if k not in fig.axis['ref_axis']:
   1179                         try:
-> 1180                                 del fig['layout'][id]
   1181                         except KeyError:
   1182                                 pass

AttributeError: __delitem__

How can I solve this?