Skip to content
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

layout subplots has implicit magic, needs a better API #1436

Closed
jthornbrue opened this issue Feb 14, 2019 · 2 comments
Closed

layout subplots has implicit magic, needs a better API #1436

jthornbrue opened this issue Feb 14, 2019 · 2 comments

Comments

@jthornbrue
Copy link

jthornbrue commented Feb 14, 2019

This issue refers to the example "Stacked Subplots with a Shared X-Axis".

import plotly.plotly as py
import plotly.graph_objs as go

trace1 = go.Scatter(
    x=[0, 1, 2],
    y=[10, 11, 12]
)
trace2 = go.Scatter(
    x=[2, 3, 4],
    y=[100, 110, 120],
    yaxis='y2'
)
trace3 = go.Scatter(
    x=[3, 4, 5],
    y=[1000, 1100, 1200],
    yaxis='y3'
)
data = [trace1, trace2, trace3]
layout = go.Layout(
    yaxis=dict(
        domain=[0, 0.33]
    ),
    legend=dict(
        traceorder='reversed'
    ),
    yaxis2=dict(
        domain=[0.33, 0.66]
    ),
    yaxis3=dict(
        domain=[0.66, 1]
    )
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='stacked-subplots-shared-x-axis')

First of all, I know that make_subplots abstracts a lot of this magic away, but the second I want finer control of my plot (e.g., more than just a grid or some shared axes), I need to use the layout object.

The implicit mapping of a trace from yaxis='y2' to the axis yaxis2 is a bit too magical for me. The name of the axis that you give a trace doesn't match the name of the axis in the layout (x vs xaxis, y2 vs yaxis2, etc.). Also, the name of the first axis doesn't have a number, e.g., x, x2, ... and xaxis, xaxis2, ... . As far as I can tell, this is only documented by example. I had to reverse engineer it from the example and by examining the layout object after much trial and error.

Ideally, an axis would be a first-class object with a unique identifier. A default name like xaxis1, yaxis3 is fine (as long as the naming convention is consistent for all), but it would also be nice to allow custom names that are even more meaningful.

The top-level separation between a list of traces and a layout that define a figure is confusing once subplots are involved. There is a natural relationship between a trace, axes, and axis. An axes should have x and y (or z) axis. An axes should have one or more trace children.

I'd like to see the API look more like this:

fig = go.Figure(...)
ax = fig.add_axes(...) . # create a custom subplot
ax.add_trace(go.Trace(...))  # add a trace to an axes

There could be some convenience functions:

ax = fig.axes  # default axes
fig.add_trace(go.Trace(...))  # equivalent to fig.axes.add_trace()

ax00, ax01, ax10, ax11 = fig.make_subplots(rows=2, cols=2)

Once the API is more object-oriented, you can do cool things like add a trace to more than one axes, and share axis objects between axes. In the JSON representation, these would be defined once and referenced elsewhere by unique name.

These are just suggestions. Obviously there are many corner cases and backward compatibility that would have to be addressed.

The bottom line is that the current API is not intuitive and not well documented, therefore hard to use.

@jonmmease
Copy link
Contributor

Hi @jthornbrue,

Thanks for taking the time to share your thoughts here and to propose an API alternative. Improving subplot support is something I'm hoping we'll be able to tackle for plotly.py version 4, where we'll have a bit more flexibility with the API and backward compatibility.

In the last year or so Plotly.js added a built-in subplot API based on the concept of grids. This isn't something we've really done examples with for plotly.py yet, but I would like to reimplement the make_subplots API on top of this abstraction for plotly.py v4. See plotly/plotly.js#3507.

Another interesting development is that ploltly.js is adding matching axis support: plotly/plotly.js#3506. So I would like any new API to make it easy to express these matching relationships.

I'll try to remember to follow up here when we're getting ready to start working on the API design a bit more. It would be great to have your input at that stage!

@gvwilson
Copy link
Contributor

Hi - we are currently trying to tidy up Plotly's public repositories to help us focus our efforts on things that will help users most. Since this issue has been sitting for several years, I'm going to close it. If it's still a concern, we'd be grateful if you could open a new issue (with a short reproducible example if appropriate) so that we can add it to our backlog. Thanks for your help - @gvwilson

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

No branches or pull requests

3 participants