-
Notifications
You must be signed in to change notification settings - Fork 1
Creating and updating figures section #26
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
Conversation
|
||
```python | ||
import plotly.graph_objects as go | ||
fig = go.Figure({ |
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.
basically I would use this example as the first one :)
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 I would use the go.Scatter
constructor in the first example. We want the first example to look like a typical doc page.
```python | ||
import plotly.graph_objects as go | ||
fig = go.Figure(data=go.Bar(x=[1, 2, 3], y=[1, 3, 2])) | ||
fig.update_layout(title={"text": "A Bar Chart", |
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 would use magic underscores here :)
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.
👍
import plotly.express as px | ||
iris = px.data.iris() | ||
(px.scatter(iris, x="sepal_width", y="sepal_length", color="species", facet_col="species", trendline='ols') | ||
.update_layout(title_text='Iris Dataset') |
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.
so there's a px
kwarg for title... I like showing how to turn the legend horizontal with update_layout
as something that's not doable with existing kwargs :)
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 tried the horizontal legend, but it didn't look so great by default in this case (is gets squashed pretty close to the x-axis labels). So I set the title with px and used update_layout
to increase the title font size.
fig.data[0].marker.line.width = 4 | ||
fig.data[0].marker.line.color = 'black' | ||
fig.show() | ||
``` |
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.
Here I would consider a little example that shows the N ways of updating the same pair of attributes (one nested, one not) with an explanation saying "the following are equivalent": dict (in dict(x=
and in literal {"x":
forms plus in nested and magic-flat forms) and go
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 added an example of 6 equivalent update_layout
operations at the end of the update layout section. How's that?
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.
love this example
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.
if we moved property-assignment back up, we could add that kind of example here too.
This is really great: just what's needed IMO. @emmanuelle I would love your thoughts |
This is great. It's exactly what I would have needed when I started using the library :-). A few remarks:
|
2. Graph objects contain descriptions of each property as Python docstrings. You can use these docstrings to learn about the available properties as an alternative to consulting the *Full Reference*. | ||
3. Graph objects support higher-level convenience functions for making updates to already constructed figures. | ||
|
||
Graph objects are stored in a hierarchy of modules under the `plotly.graph_objects` package. Here is an example of one way that the figure above could be constructed using graph objects. |
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.
is it important for users (as opposed to devs) to mention the "hierarchy of modules"? How about "stored under the ... package"?
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.
Only insofar as it's important that people look for go.layout.title.Font()
and don't expect to find go.Font()
.
|
||
```python | ||
import plotly.graph_objects as go | ||
fig = go.Figure({ |
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 I would use the go.Scatter
constructor in the first example. We want the first example to look like a typical doc page.
``` | ||
|
||
### Plotly express | ||
Plotly express (included in plotly.py as the `plotly.express` module) is a high-level data exploration API that produces graph object figures. |
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.
"included as the plotly.express
module", I think most users only know "plotly" and mentioning "plotly.py" can be confusing.
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.
Also mention that px only works with tidy Pandas dataframes.
v1 = np.sin(x1)*y1 | ||
|
||
fig = ff.create_quiver(x1, y1, u1, v1) | ||
fig.show() |
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.
Here I tried to explore the fig object to know what was specific in the figure factory so that the resulting trace looks like a quiver but it was quite difficult (I finally found out that it's thanks to None and not connecting gaps, but it was not straightforward). Would it be possible to add something about properties introspection? Like, how can you use tab completion?
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.
Tab completion with getattr
access? I don't really want to get into the process of reverse engineering what the figure factories and plotly express do in this section. We could change which figure factory is demonstrated here if another example seems better.
|
||
### Magic underscore notation | ||
To make it easier to work with nested properties graph object constructors, and many graph object methods, support magic underscore notation. This allows you to reference nested properties by joining together multiple nested property names with underscores. For example, specifying the figure title in the figure constructor *without* magic underscore notation requires setting the `layout` argument to `{"title": {"text": "A Chart"}}`. | ||
|
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.
"As a rule of thumb most names with underscores denote a magic underscore syntax." (Is it true? Not all names with underscores, since there is "error_x" etc., but ideally it should be the case since it would be clearer).
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, it's a little messy.
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 there are only 3 or 4 properties that break this rule, so we could just call it out here. like:
By “most” we mean all properties except error_x, error_y, paper_bg, ... Those properties were added back in the early days of the library (2012 & 2013!) before we standardized on “no underscores in property names.”
i like using the markdown blocquotes (>) for little sidenotes like these.
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 added a block quote explanation in 9d14e21
|
||
Magic underscore notation is supported throughout the graph objects API, and it can often significantly simplify operations involving deeply nested properties. | ||
|
||
### Property assignment |
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 would put update_traces
and update_layout
before property assignment, because this is what we use in the docs. Or have them mentioned in the first "excutive summary" example.
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.
Good point, moving this to the end
Thanks for the quick feedback @nicolaskruchten and @emmanuelle. I've made all of the updates for the suggestions that I immediately agreed with. For what's left, it's probably better if one of you take a stab at the restructuring you have in mind. I definitely don't mind more changes being made, but the structure/order I have still makes sense to me, so I'm finding it difficult make the changes myself. I'm going to move on to the other new pages now (templates and renderers). |
Thanks Jon! I have an idea of how to preserve the structure and meet my goals as well, let me propose something in a bit when the kids are down |
fig.show() | ||
``` | ||
|
||
Once you have a figure as a graph object, you can retrieve the dictionary representation using the `fig.to_dict()` method. You can also retrieve the JSON string representation using the `fig.to_json()` method. |
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 would point out that you can also read attributes directly with fig.layout.title.text
as this is a big advantage over dicts
!
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 added another item to the advantages list above in c0f6c8c
|
||
The value of the top-level `"data"` key is a list of trace specifications. Each trace specification has a special `"type"` key that indicates the trace type that is being defined (e.g. a `"bar"`, `"scatter"`, `"contour"`, etc.). The rest of the keys in the trace specification are used to configure the properties of the trace of this type. | ||
|
||
The value of the top-level `"layout"` key is a dictionary that specifies the properties of the figure's layout. In contrast to trace configuration options that apply to individual traces, the layout configuration options apply to the figure as a whole. |
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.
“like the axes, annotations, shapes, legend, and more.”
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.
👍 28f1d8f
|
||
The [*Full Reference*](https://plot.ly/python/reference/) page contains descriptions of all of the supported trace and layout options. | ||
|
||
If working from the *Full Reference* to build figures as Python dictionaries suites your needs, go for it! This is a perfectly valid way to use use plotly.py to build figures. On the other hand, if you would like an API that offers a bit more assistance, read on to learn about graph objects. |
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.
“and lists”
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.
also maybe “as you become more comfortable with the graph reference, you may find yourself using this “shorthand” instead of the objects below.”?
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.
"and lists"
👍 in ff64f59
also maybe “as you become more comfortable with the graph reference, you may find yourself using this “shorthand” instead of the objects below.”?
This didn't quite fit the flow I was going for, so I didn't put it in yet. Does it feel like an important clarification to you?
```python | ||
import plotly.express as px | ||
iris = px.data.iris() | ||
fig = px.scatter(iris, x="sepal_width", y="sepal_length", color="species") |
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.
what if we added like a # print(fig.to_dict()). # if you inspect the fig, you’ll see it’s just a regular figure with data and layout
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.
👍 cacbc37
``` | ||
|
||
### Figure factories | ||
Figure factories (included in plotly.py in the `plotly.figure_factory` module) are functions that produce graph object figures, often to satisfy the needs of specialized domains. Here's an example of using the `create_quiver` figure factory to construct a graph object figure that displays a 2D quiver plot. |
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.
should we add a “Note - some of these functions are better served by px now, like ff.dist_plot and ff.facet_plot (or w/e)?
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 definitely think this info belongs somewhere, but in my mind it's a level below what this section is trying to communicate. At this level, I think we just want people to understand that the things produced by plotly express and the figure factories are just normal figures.
```python | ||
import plotly.graph_objects as go | ||
fig = go.Figure( | ||
data=[go.Bar(x=[1, 2, 3], y=[1, 3, 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.
what about having two bar traces, one that uses go.bar.Marker and one that uses just marker={colour: ...} to demonstrate the two ways then nested objects can be defined? could even have go.marker.Line too
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.
The first example in the "Constructor" section below calls out the fact that you can mix graph objects and dict
s in the constructor. Is that sufficient? I think I'd rather add another example to that section if we want to be more explicit about it.
We certainly could add more traces here, but I would want to add them to he prior dict
-only example above so that we're working with the same underlying figure. And that would make the first dict
-only figure a bit more complicated.
showlegend=False) | ||
fig.add_trace(reference_line, row=1, col=1) | ||
fig.add_trace(reference_line, row=1, col=2) | ||
fig.add_trace(reference_line, row=1, col=3) |
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.
nice example!
|
||
### Magic underscore notation | ||
To make it easier to work with nested properties graph object constructors, and many graph object methods, support magic underscore notation. This allows you to reference nested properties by joining together multiple nested property names with underscores. For example, specifying the figure title in the figure constructor *without* magic underscore notation requires setting the `layout` argument to `{"title": {"text": "A Chart"}}`. | ||
|
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 there are only 3 or 4 properties that break this rule, so we could just call it out here. like:
By “most” we mean all properties except error_x, error_y, paper_bg, ... Those properties were added back in the early days of the library (2012 & 2013!) before we standardized on “no underscores in property names.”
i like using the markdown blocquotes (>) for little sidenotes like these.
|
||
```python | ||
import plotly.graph_objects as go | ||
fig = go.Figure(layout=dict(title=dict(text="A Chart"))) |
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.
could we just add a simple trace here too to really enforce the point? with eg marker_color
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.
👍 d7d6a51
fig.data[0].marker.line.width = 4 | ||
fig.data[0].marker.line.color = 'black' | ||
fig.show() | ||
``` |
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.
love this example
Alright, I made another round of updates. Thanks for the feedback @nicolaskruchten @emmanuelle and @chriddyp . I'm really excited about having this page in our docs soon! |
I could keep workshopping this but it's certainly good to go as is from where I sit :) 💃 |
# Conflicts: # notebooks/user-guide.md
Let's merge this one in! |
The new section on representing, creating, and updating figures. Closes https://github.com/plotly/plotly.py-docs/issues/6.
Let me know what you think @nicolaskruchten @emmanuelle
Doc upgrade checklist:
graph_objs
has been renamed tograph_objects
fig = <something>
call is high up in each exampletrace
objectsadd_trace
andupdate_layout
fig.show()
at the end of each examplev4upgrade: true
metadata added