Interactive Animated Bar chart issue - 'Figure field is invalid'


#1

I am attempting to adapt the Python Plotly example on ‘Adding Sliders to Animations in Python’ to a barchart but am getting a ‘Figure field is invalid’ message.

I am trying to adapt the input data to reflect that of a bar chart rather than a scatter chart (used in the example). I have created a grid:

Capture

Which I am using with the following code:

years = ['2007','2008','2009']
items = ['Name_1','Name_2']

col_name_template = '{column}'
for year in years:
	frame = {'data': [], 'name': str(year)}
	x_list = []
	y_list = []
	
	for item in items:
		x_list.append(grid.get_column_reference(col_name_template.format(column='name')))
		y_list.append(grid.get_column_reference(col_name_template.format(column=year)))
	 
	frame['data'].append(go.Bar(
			x=x_list,
			y=y_list
	))

	figure['frames'].append(frame)
	slider_step = {'args': [
		[year],
		{'frame': {'duration': 300, 'redraw': False},
		 'mode': 'immediate',
	   'transition': {'duration': 300}}
	 ],
	 'label': year,
	 'method': 'animate'}
	sliders_dict['steps'].append(slider_step)

figure['layout']['sliders'] = [sliders_dict]

py.icreate_animations(figure, 'barchart example')

When trying to plot I get the following error:

Figure field is invalid. Reason: Raw data arrays are not allowed at this endpoint. Use grid references instead. Raw data found at the following paths in the figure…

How do I use only grid references but also ensure that a bar chart is plotted rather than a scatter chart?


#2

Hi @calum,

If you’re working offline you can display a figure that includes animations with plotly.offline.iplot. Also, in version 3.7.0 (released yesterday) there was an update to create_animations/icreate_animations to allow them to handle inline data arrays, so you don’t need to manually create Grids anymore.

That should at least get you past the “Raw data arrays are not allowed” error.

-Jon


#3

Thanks @jmmease - very helpful.

For anyone interested, I used the offline iplot to fix this. The only issue is that transitions don’t seem to be supported for bar charts.

Code:

from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML

init_notebook_mode(connected = True)

years = ['2010', '2011', '2012']
items = ['A', 'B', 'C', 'D']
count = [
  [1, 2, 3, 4],
  [2, 3, 4, 1],
  [3, 4, 1, 2]
]

figure = {
  'data': [{
    'type': 'bar',
    'x': items,
    'y': count[0]
  }],
  'layout': {
    'xaxis': {
      'title': 'X',
      'gridcolor': '#FFFFFF',
      'linecolor': '#000',
      'linewidth': 1,
      'zeroline': False,
      'autorange': False
    },
    'yaxis': {
      'title': 'Y',
      'gridcolor': '#FFFFFF',
      'linecolor': '#000',
      'linewidth': 1,
      'range': [0, 5],
      'autorange': False
    },
    'title': 'Example Title',
    'hovermode': 'closest',
    'updatemenus': [{
      'type': 'buttons',
      'buttons': [{
          'label': 'Play',
          'method': 'animate',
          'args': [None, {
            'frame': {
              'duration': 500,
              'redraw': True
            },
            'fromcurrent': True,
            'transition': {
              'duration': 300,
              'easing': 'quadratic-in-out'
            }
          }]
        },
        {
          'label': 'End',
          'method': 'animate',
          'args': [None, {
            'frame': {
              'duration': 0,
              'redraw': True
            },
            'fromcurrent': True,
            'mode': 'immediate',
            'transition': {
              'duration': 0
            }
          }]
        }
      ],
      'direction': 'left',
      'pad': {
        'r': 10,
        't': 87
      },
      'showactive': False,
      'type': 'buttons',
      'x': 0.1,
      'xanchor': 'right',
      'y': 0,
      'yanchor': 'top'
    }]
  },
  'frames': []
}

sliders_dict = {
  'active': 0,
  'yanchor': 'top',
  'xanchor': 'left',
  'currentvalue': {
    'font': {
      'size': 20
    },
    'prefix': 'Year:',
    'visible': True,
    'xanchor': 'right'
  },
  'transition': {
    'duration': 300,
    'easing': 'cubic-in-out'
  },
  'pad': {
    'b': 10,
    't': 50
  },
  'len': 0.9,
  'x': 0.1,
  'y': 0,
  'steps': []
}

for index, year in enumerate(years):
    frame = {
        'data': [{
          'type': 'bar',
          'x': items,
          'y': count[index]
        }],
        'name': str(year)
        }
    figure['frames'].append(frame)

    slider_step = {
      'args': [
        [year],
        {
          'frame': {
            'duration': 300,
            'redraw': True
          },
          'mode': 'immediate',
          'transition': {
            'duration': 300
          }
        }
      ],
      'label': year,
      'method': 'animate'
    }
    sliders_dict['steps'].append(slider_step)

figure['layout']['sliders'] = [sliders_dict]

iplot(figure)

#4

Yes, this is true unfortunately. There was some work on this a while back that just didn’t quite get finished: See https://github.com/plotly/plotly.js/pull/1143, https://github.com/plotly/plotly.js/pull/1647, and https://github.com/plotly/plotly.js/issues/1019 for background if you’re interested.

-Jon