-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
[WIP] Plotly 3.0.0 - Deep Jupyter Integration, Validation, Performance, and More #942
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember Pep-8: 79 char limits :)
Not a thorough review of all your code, but I hope this helps
@@ -0,0 +1,909 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at least a portion of these examples in the overview .ipynb should be in the README file. I prefer a README that has examples right there to get started
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed (Added to the checklist above). Also, I didn't plan for these notebooks to stay here in the long run. I just wanted to share some examples for the team to use as part of the discussion.
"outputs": [], | ||
"source": [ | ||
"# Set marker styles / colorbars to match between figures\n", | ||
"scatt2.marker = scatt1.marker" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a big deal, but running this cell more than once raises a ValueError
:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
I suggest changing the code so that an error doesn't get raised or writing a little blurb about the reason why this happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
"outputs": [], | ||
"source": [ | ||
"# Save figure 1 to a pdf in the exports directory (requires cairosvg be installed)\n", | ||
"# f1.save_image('exports/f1.pdf')" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After installing cariosvg I get an error running this cell:
OSError: dlopen() failed to load a library: cairo / cairo-2
Looks like there's a thread open here: Kozea/CairoSVG#84
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you install through pip or conda? I've had better luck through conda as conda will also pull down the cairo binary without needing to build it. It might be that you have cairosvg installed but not cairo, in this case you might be able to install just cairo using conda.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's important that the install works w/ pip (as well as conda)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very possible.
and yes I was using pip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cldougl Agreed. The trouble is that cairsosvg requires the non-python cairo executable be installed and pip can't (or at least doesn't) do that.
If cairo(svg) proves to be too much of a hassle to be even an optional dependency then one option is to allow users to register custom file type output filters. This way a user can register cairosvg.svg2png
to be the function to be called when a plot is to be saved to a png
file.
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall very good work here! The convenience bar for using Plotly in Jupyter has been greatly raised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
plotly/basedatatypes.py
Outdated
if invalid_uids: | ||
raise ValueError(('The trace property of a figure may only be assigned to ' | ||
'a permutation of a subset of itself\n' | ||
' Invalid trace(s) with uid(s): {invalid_uids}').format(invalid_uids=invalid_uids)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple things:
- Your line has more than 79 characters. https://www.python.org/dev/peps/pep-0008/#id19
- Write the ValueError message something like this:
raise ValueError(
'The trace property of a figure may only be assigned to '
'a permutation of a subset of itself \n Invalid trace(s) with uid(s): '
'{invalid_uids}'.format(invalid_uids=invalid_uids)
)
it addresses 1) and it's more clean IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I started this as an independent project originally and chose to use a 119 character line width at the time. We can do a mass reformatting commit at some point (probably just run everything through yapf
like I do in the codegen logic)
hey @jmmease - I'm having some trouble running
Am I missing something? |
Looks like a circular dependency issue, not sure why I wasn't hitting it. Try commenting out graph_objs.py while running the codegen logic, then uncommenting. |
Any luck with that @chriddyp? |
@jmmease that worked, thanks! |
📣 I have published a pre-release version of this branch on PyPI. Try it out (python 3 only) with:
|
@jmmease This is not a bug, but a suggestion to improve an error message:
returns:
I don't think it's a very user friendly error message for someone who is trying to select input an Perhaps a message that enumerates all of the scatter params or something that says:
|
@Kully - I don't think that will actually happen it a lot, since all of our documentation will show Alternatively, perhaps the keyword arguments |
Thanks a lot for this Jon. I'm going to be hitting through these this week so it's nice to have them all written out cleanly. |
Sounds good @Kully |
- plotly/datatypes package is gone - codegen object hierarchy directly into plotly/graph_objs. - Refactor codegen output hierarchy to be compatible with legacy Figure/Layout/Trace types. e.g. go.Figure, go.Layout, go.Scatter. - Codegen deprecated classes as dict/list subclasses with deprecation warnings that point users to which classes to use instead. - The entire legacy graph_objs directory is gone (PlotlyDict/PlotlyList/etc.) - _plotly_utils package introduced as a package to hold code that should be available during both code generation and runtime. Moved base validators to this package so we can reuse their descriptions in docstrings. All of the order-dependency of code generation is now gone, and the plotly/ package is not imported. This makes code generation much less fragile to future extension.
@chriddyp @Kully
Give it a try and see what you think. I'm going to go back through and review/cleanup the entire |
(e.g. xaxis1 is now accepted and converted into xaxis)
…tly.py into ipyplotly_integration
…ct stable component.
Circle has been timeing out on this command sporadically
This was another source of flaky test failures
… failures at 30s)
Here's a summary of what I've done to (hopefully 🤞) get the tests running more reliably on circleci:
@cldougl @chriddyp Please take a quick look when you can, and let me know if you're uncomfortable with any of these changes. |
The changes look awesome! Do you have an ETA for Plotly 3.0.0? 😃 |
@Juanlu001 Thanks! We don't have a date, but "very soon" 🙂 Unless something pops up 3.0.0rc11 may well become 3.0.0 final, so give it a spin if you can! (Install instructions at the top of the thread) |
Update: June 27, 2018
This branch will mark a major release of the plotly.py branch, Version 3.0.0
There are many new and great features in this branch including deeper Jupyter integration, deeper figure validation, improved performance, and more.
You can try this out with a prerelease version, see https://pypi.org/project/plotly/#history for the latest.
To install and enable with Jupyter, run:
If you're using older versions of
notebook
oripywidgets
you may need to manually activate the widget extensions (this should not be needed fornotebook>=5.3
andipywidgets>=7.2
)In addition, to add JupyterLab support run the following commands:
The original message from February 19, 2018 is below:
Alright, here we go! @chriddyp @jackparmer
Overview
This is a first cut at integrating the work I started in the ipyplotly project into plotly.py.
Integration Approach
I moved the new object hierarchy to plotly/datatypes. I modified the
graph_objs.py
code generation logic to remapFigure
,Layout
, and all of the trace objects (Bar
,Scatter
, etc.) to the corresponding objects in the newdatatypes
hierarchy. All of the other classes ingraph_objs
were converted intolist
ordict
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.Widget notes
The backend ipywidget logic is implemented in the new
datatypes.Figure
anddatatypes.FigureWidget
classes. The front-end logic is implemented in thejs/
directory.Examples
See the notebooks in
specs/ipyplotly_integration
for an overview of the new functionality.TODO
dict
-style.update
method on all datatypesFailing test modes
Summary of reasons for current test failures
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.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.Annotations
don't have an equivalent because sequences are now represented as tuples of compound types. For instance, theannotations
property ofLayout
accepts tuples ofdatatypes.layout.Annotation
objects and there is noAnnotations
type.Marker
,ColorBar
,ErrorX
,Font
,Line
,Frames
, etc. are replaced by more precise types. For example, there is now atrace.scatter.Marker
class and atrace.bar.Marker
class and they each contain only the properties that are valid for their trace type.validate()
methodSubplot properties may only be suffixed by an integer > 1
. See [wip] - ipyplotly fixes #956 (comment) for some comments. The documentation and schema of Plotly.js seem to disallowsubplotid
properties ending in 1. (x
,x2
,x3
, but notx1
).get_data
method on datatype objects. This had aflatten
option to return a dict with keys likefoo.bar.baz
. I think this could be implemented on the new objects if there's a need for.test_graph_objs.py
because the collection of classes in graph_objs.py has changed.dict
subclasses so tests likeassert Scatter() == dict(type='scatter')
fail.ValueError
andKeyError
exceptions. Many of the tests expect aPlotlyError
.strip_style
method on datatypes. The new logic doesn't maintain thestyle
meta-data after code generation, but it would be possible to add this if this method needs to be preserved.to_string
method, but again this could be added.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
propertiesdata_array
types (e.g.scatter.x
). This breaks some of the streaming tests which have things likemy_stream.write(Scatter(x=1, y=10), ...)
layout.width/height
properties are numbers (according to the schema), but the dendrogram figure_factory sets height to the string'100%'
.data_array
typed properties are converted to read-only numpy arrays internally. So comparisons that expect lists fail (seeTestStreamline/test_simple_streamline
)TestTrisurf/test_trisurf_all_args
becausehoverinfo
is set to'None'
rather than'none'
'Figure' object has no attribute 'to_dataframe'
: I'm not really clear on what this method is supposed to do in general.'dot'
is in invalid marker type (according to the schema). Used intest_optional/test_matplotlylib/data/scatter.py/SIMPLE_SCATTER
AttributeError: module 'plotly.graph_objs.graph_objs' has no attribute 'Histogram2dcontour'
: It's Histogram2dContour. We could support both versions if we need to.Summary
Missing methods on datatypes
Next steps
strict
flag in string validator (see Add number type toannotations.text
chart schema plotly.js#2523).data_array
s as lists internally, but convert to tuples on property access.add_traces
. Deprecateappend_traces
and remap toadd_traces
with row/col args.FigureWidget
constructor is called.figure_factory
,matplotlylib
, etc.