Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Pass figure through go.Figure for validation? #257

Closed
chriddyp opened this issue Aug 7, 2018 · 5 comments
Closed

Pass figure through go.Figure for validation? #257

chriddyp opened this issue Aug 7, 2018 · 5 comments
Assignees

Comments

@chriddyp
Copy link
Member

chriddyp commented Aug 7, 2018

If a user supplies their data with dictionaries and lists, they won't get validation. Perhaps we should pass the figure through plotly.graph_objs.Figure to give them validation.

This will require us to write some intermediate code between the auto-generated code and the serialization, which we haven't done before. It might be a good use case to try out these types of abstractions.

@rmarren1
Copy link
Contributor

Will happen in plotly/dash#340

@rmarren1
Copy link
Contributor

This worked pretty generally, but it seems there are some instances where go.Figure breaks on inputs that would have otherwise worked fine. One example (from the dash docs):

ComponentInitializationValidationError:
A Dash Component was initialized with invalid properties!

Dash tried to create a `Graph` component with the
following arguments, which caused a validation failure:

***************************************************************
{'figure': {'data': [{'name': 'SF',
                      'type': 'bar',
                      'x': [1, 2, 3],
                      'y': [4, 1, 2]},
                     {'name': u'Montr\xe9al',
                      'type': 'bar',
                      'x': [1, 2, 3],
                      'y': [2, 4, 5]}],
            'layout': {'title': 'Dash Data Visualization'}},
 'id': 'example-graph'}
***************************************************************

The expected schema for the `Graph` component is:

***************************************************************
{'animate': {'nullable': False, 'required': False, 'type': 'boolean'},
 'animation_options': {'nullable': False, 'required': False, 'type': 'dict'},
 'className': {'nullable': False, 'required': False, 'type': 'string'},
 'clear_on_unhover': {'nullable': False, 'required': False, 'type': 'boolean'},
 'clickAnnotationData': {'nullable': False, 'required': False, 'type': 'dict'},
 'clickData': {'nullable': False, 'required': False, 'type': 'dict'},
 'config': {'allow_unknown': False,
            'nullable': False,
            'required': False,
            'schema': {'autosizable': {'type': 'boolean'},
                       'displayModeBar': {'allowed': [True, False, 'hover'],
                                          'type': ('string', 'number')},
                       'displaylogo': {'type': 'boolean'},
                       'doubleClick': {'allowed': [False,
                                                   'reset',
                                                   'autosize',
                                                   'reset+autosize'],
                                       'type': ('string', 'number')},
                       'editable': {'type': 'boolean'},
                       'edits': {'allow_unknown': False,
                                 'nullable': False,
                                 'schema': {'annotationPosition': {'type': 'boolean'},
                                            'annotationTail': {'type': 'boolean'},
                                            'annotationText': {'type': 'boolean'},
                                            'axisTitleText': {'type': 'boolean'},
                                            'colorbarPosition': {'type': 'boolean'},
                                            'colorbarTitleText': {'type': 'boolean'},
                                            'legendPosition': {'type': 'boolean'},
                                            'legendText': {'type': 'boolean'},
                                            'shapePosition': {'type': 'boolean'},
                                            'titleText': {'type': 'boolean'}},
                                 'type': 'dict'},
                       'fillFrame': {'type': 'boolean'},
                       'frameMargins': {'type': 'number'},
                       'linkText': {'type': 'string'},
                       'mapboxAccessToken': {},
                       'modeBarButtons': {},
                       'modeBarButtonsToAdd': {'type': 'list'},
                       'modeBarButtonsToRemove': {'type': 'list'},
                       'plotGlPixelRatio': {'type': 'number'},
                       'queueLength': {'type': 'number'},
                       'scrollZoom': {'type': 'boolean'},
                       'sendData': {'type': 'boolean'},
                       'showAxisDragHandles': {'type': 'boolean'},
                       'showAxisRangeEntryBoxes': {'type': 'boolean'},
                       'showLink': {'type': 'boolean'},
                       'showTips': {'type': 'boolean'},
                       'staticPlot': {'type': 'boolean'},
                       'topojsonURL': {'type': 'string'}},
            'type': 'dict'},
 'dashEvents': {'allowed': ['click',
                            'clickannotation',
                            'hover',
                            'selected',
                            'relayout',
                            'unhover'],
                'nullable': False,
                'required': False,
                'type': ('string', 'number')},
 'figure': {'nullable': False,
            'required': False,
            'type': 'dict',
            'validator': 'plotly_figure'},
 'fireEvent': {'nullable': False, 'required': False},
 'hoverData': {'nullable': False, 'required': False, 'type': 'dict'},
 'id': {'nullable': False, 'required': False, 'type': 'string'},
 'relayoutData': {'nullable': False, 'required': False, 'type': 'dict'},
 'selectedData': {'nullable': False, 'required': False, 'type': 'dict'},
 'setProps': {'nullable': False, 'required': False},
 'style': {'nullable': False, 'required': False, 'type': 'dict'}}
***************************************************************

The errors in validation are as follows:


* figure        <- Invalid Plotly Figure:

'ascii' codec can't encode character u'\xe9' in position 5: ordinal not in range(128)

You can turn off these validation exceptions by setting
`app.config.suppress_validation_exceptions=True`


e.g., go.Figure errors because of u'Montr\xe9al'

@rmarren1
Copy link
Contributor

rmarren1 commented Dec 1, 2018

^ Looks like this is an issue in plotly.py
plotly/plotly.py#1289

@ghost
Copy link

ghost commented Oct 1, 2019

Is figure validation already implemented? I am looking for ways to boost performance and would prefer to turn this off if it's on by default.

@alexcjohnson
Copy link
Collaborator

No, if you construct your figure as a plain dict it will not be validated. @chriddyp my gut reaction is we should leave it that way, if people do want validation (with its associated overhead) they have plenty of options to get that already. Feel free to reopen though if you disagree.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants