{"action":"created","issue":{"url":"https://api.github.com/repos/plotly/plotly.py/issues/942","repository_url":"https://api.github.com/repos/plotly/plotly.py","labels_url":"https://api.github.com/repos/plotly/plotly.py/issues/942/labels{/name}","comments_url":"https://api.github.com/repos/plotly/plotly.py/issues/942/comments","events_url":"https://api.github.com/repos/plotly/plotly.py/issues/942/events","html_url":"https://github.com/plotly/plotly.py/pull/942","id":298432043,"node_id":"MDExOlB1bGxSZXF1ZXN0MTcwMDc0NjY1","number":942,"title":"[WIP] ipyplotly integration","user":{"login":"jmmease","id":15064365,"node_id":"MDQ6VXNlcjE1MDY0MzY1","avatar_url":"https://avatars1.githubusercontent.com/u/15064365?v=4","gravatar_id":"","url":"https://api.github.com/users/jmmease","html_url":"https://github.com/jmmease","followers_url":"https://api.github.com/users/jmmease/followers","following_url":"https://api.github.com/users/jmmease/following{/other_user}","gists_url":"https://api.github.com/users/jmmease/gists{/gist_id}","starred_url":"https://api.github.com/users/jmmease/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmmease/subscriptions","organizations_url":"https://api.github.com/users/jmmease/orgs","repos_url":"https://api.github.com/users/jmmease/repos","events_url":"https://api.github.com/users/jmmease/events{/privacy}","received_events_url":"https://api.github.com/users/jmmease/received_events","type":"User","site_admin":false},"labels":[{"id":857139852,"node_id":"MDU6TGFiZWw4NTcxMzk4NTI=","url":"https://api.github.com/repos/plotly/plotly.py/labels/breaking%20change","name":"breaking change","color":"ff91a5","default":false},{"id":66960566,"node_id":"MDU6TGFiZWw2Njk2MDU2Ng==","url":"https://api.github.com/repos/plotly/plotly.py/labels/enhancement","name":"enhancement","color":"84b6eb","default":true},{"id":857140278,"node_id":"MDU6TGFiZWw4NTcxNDAyNzg=","url":"https://api.github.com/repos/plotly/plotly.py/labels/jupyter","name":"jupyter","color":"26d3b6","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":111,"created_at":"2018-02-19T23:58:30Z","updated_at":"2018-06-11T21:45:25Z","closed_at":null,"author_association":"COLLABORATOR","pull_request":{"url":"https://api.github.com/repos/plotly/plotly.py/pulls/942","html_url":"https://github.com/plotly/plotly.py/pull/942","diff_url":"https://github.com/plotly/plotly.py/pull/942.diff","patch_url":"https://github.com/plotly/plotly.py/pull/942.patch"},"body":"Alright, here we go! @chriddyp @jackparmer \r\n\r\n# Overview\r\nThis is a first cut at integrating the work I started in the [ipyplotly](https://github.com/jmmease/ipyplotly) project into plotly.py.\r\n\r\n# Integration Approach\r\nI moved the new object hierarchy to plotly/datatypes.  I modified the `graph_objs.py` code generation logic to remap `Figure`, `Layout`, and all of the trace objects (`Bar`, `Scatter`, etc.) to the corresponding objects in the new `datatypes` hierarchy.  All of the other classes in `graph_objs` were converted into `list` or `dict` subclasses. This is simply for backwards compatibility for the time being, I'm not sure what we want to do with these in the long run.\r\n\r\n# Widget notes\r\nThe backend ipywidget logic is implemented in the new `datatypes.Figure` and `datatypes.FigureWidget` classes. The front-end logic is implemented in the `js/` directory.\r\n\r\n# Installation instructions\r\n```\r\n$ pip install -e .\r\n$ pip install yapf\r\n$ python setup.py codegen\r\n$ jupyter nbextension enable --py widgetsnbextension\r\n$ jupyter nbextension install --py --symlink --sys-prefix plotlywidget\r\n$ jupyter nbextension enable --py --sys-prefix plotlywidget\r\n```\r\n\r\n# Examples\r\nSee the notebooks in `specs/ipyplotly_integration` for an overview of the new functionality.\r\n\r\n# TODO\r\n- [x] Support `dict`-style `.update` method on all datatypes\r\n- [x] Assess existing tests and catalog breakage\r\n- [x] Python 2.7 support\r\n- [x] JupyterLab support\r\n- [ ] Update README with some examples from Overview.ipynb\r\n- [ ] Reformat for 79 character width (plus PEP8 in general)\r\n- [ ] Pickle support for Figure/FigureWidget (See #579, #786, )\r\n\r\n# Failing test modes\r\nSummary of reasons for current test failures\r\n - `unexpected keyword argument '_raise'` (`test_get_figure`). Looks like old graph objects had a `_raise` constructor parameter to control whether validation was performed. I'm not sure why this was needed, but validation isn't optional for the new objects.\r\n - Validation exceptions not raised on compatibility classes.  Some of the current `graph_objs.py` classes don't directly map to objects in the new hierarchy, and they are currently included as dict/list subclasses for source compatibility. e.g.\r\n    - Sequence types like `Annotations` don't have an equivalent because sequences are now represented as tuples of compound types. For instance, the `annotations` property of `Layout` accepts tuples of `datatypes.layout.Annotation` objects and there is no `Annotations` type.\r\n    - Types like `Marker`, `ColorBar`, `ErrorX`, `Font`, `Line`, `Frames`, etc. are replaced by more precise types. For example, there is now a `trace.scatter.Marker` class and a `trace.bar.Marker` class and they each contain only the properties that are valid for their trace type.\r\n - New datatype objects don't have a `validate()` method\r\n - `Subplot properties may only be suffixed by an integer > 1`.  See https://github.com/plotly/plotly.py/pull/956#issuecomment-371340640 for some comments. The documentation and schema of Plotly.js seem to disallow `subplotid` properties ending in 1. (`x`, `x2`, `x3`, but not `x1`).\r\n - There is no `get_data` method on datatype objects. This had a `flatten` option to return a dict with keys like `foo.bar.baz`. I think this could be implemented on the new objects if there's a need for.\r\n - Errors in `test_graph_objs.py` because the collection of classes in graph_objs.py has changed.\r\n - Datatypes are no longer `dict` subclasses so tests like `assert Scatter() == dict(type='scatter')` fail.\r\n - Exception types don't always match: The current datatype/validator logic mostly raises `ValueError` and `KeyError` exceptions. Many of the tests expect a `PlotlyError`.\r\n - There is no `strip_style` method on datatypes. The new logic doesn't maintain the `style` meta-data after code generation, but it would be possible to add this if this method needs to be preserved.\r\n - Datatypes have no `to_string` method, but again this could be added.\r\n - `Invalid value of type 'plotly.grid_objs.grid_objs.Column' received for the 'xsrc' property of trace.scatter`: grid_objs aren't accepted as `*src` properties\r\n - Scalar values aren't currently accepted as `data_array` types (e.g. `scatter.x`). This breaks some of the streaming tests which have things like `my_stream.write(Scatter(x=1, y=10), ...)`\r\n - It's not valid to pass a dictionary of object properties to the constructor of a data type without kwarg expansion. Scatter({'x': ..., 'y': ...}) is invalid, need to do Scatter(**{'x': ..., 'y': ...}). This breaks the tools.py/validate function.\r\n - The `layout.width/height` properties are numbers (according to the schema), but the dendrogram figure_factory sets height to the string `'100%'`.\r\n - All `data_array` typed properties are converted to read-only numpy arrays internally. So comparisons that expect lists fail (see `TestStreamline/test_simple_streamline`)\r\n - flaglist/enumeration types are case sensitive. Causes failure in `TestTrisurf/test_trisurf_all_args` because `hoverinfo` is set to `'None'` rather than `'none'`\r\n - `'Figure' object has no attribute 'to_dataframe'`: I'm not really clear on what this method is supposed to do in general.\r\n - `'dot'` is in invalid marker type (according to the schema). Used in `test_optional/test_matplotlylib/data/scatter.py/SIMPLE_SCATTER`\r\n - `AttributeError: module 'plotly.graph_objs.graph_objs' has no attribute 'Histogram2dcontour'`: It's Histogram2dContour. We could support both versions if we need to.\r\n - There are a buch of JSON encoding failure that seem to relate to date encoding.\r\n\r\n## Summary\r\n### Missing methods on datatypes\r\n - to_string [removing]\r\n - strip_style [removing]\r\n - get_data [removing]\r\n - validate [removing]\r\n - to_dataframe [removing]\r\n\r\n## Next steps\r\n- [x] Support `strict` flag in string validator (see plotly/plotly.js#2523).\r\n- [x] Remove hard numpy dependency. Support storing `data_array`s as lists internally, but convert to tuples on property access.\r\n- [x] Investigate improving import performance and reenabling recursive submodule imports.\r\n- [x] add optional row/col support to `add_traces`. Deprecate `append_traces` and remap to `add_traces` with row/col args.\r\n- [x] Make ipywidgets an optional dependency, only loaded when `FigureWidget` constructor is called.\r\n- [x] Remove all use of deprecated classes in `figure_factory`, `matplotlylib`, etc.\r\n  - [x] tests\r\n  - [x] the actual modules users call"},"comment":{"url":"https://api.github.com/repos/plotly/plotly.py/issues/comments/396397454","html_url":"https://github.com/plotly/plotly.py/pull/942#issuecomment-396397454","issue_url":"https://api.github.com/repos/plotly/plotly.py/issues/942","id":396397454,"node_id":"MDEyOklzc3VlQ29tbWVudDM5NjM5NzQ1NA==","user":{"login":"chriddyp","id":1280389,"node_id":"MDQ6VXNlcjEyODAzODk=","avatar_url":"https://avatars3.githubusercontent.com/u/1280389?v=4","gravatar_id":"","url":"https://api.github.com/users/chriddyp","html_url":"https://github.com/chriddyp","followers_url":"https://api.github.com/users/chriddyp/followers","following_url":"https://api.github.com/users/chriddyp/following{/other_user}","gists_url":"https://api.github.com/users/chriddyp/gists{/gist_id}","starred_url":"https://api.github.com/users/chriddyp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chriddyp/subscriptions","organizations_url":"https://api.github.com/users/chriddyp/orgs","repos_url":"https://api.github.com/users/chriddyp/repos","events_url":"https://api.github.com/users/chriddyp/events{/privacy}","received_events_url":"https://api.github.com/users/chriddyp/received_events","type":"User","site_admin":false},"created_at":"2018-06-11T21:45:24Z","updated_at":"2018-06-11T21:45:24Z","author_association":"MEMBER","body":"@cldougl and I will work on these this week\r\n- [ ] npm release\r\n- [ ] test release in jupyter lab\r\n- [ ] test in various versions of jupyter and create setup/installation instructions for each version\r\n- [ ] upload a prelease version to pypi\r\n- [ ] draft prerelease announcement post\r\n- [ ] draft migration guide\r\n- [ ] help @Kully go through _all_ python docs \r\n- [ ] identify which docs need to change, and start working on new versions\r\n- [ ] test it with `dash`"}}
{"actor":{"display_login":"chriddyp"}}