Description
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.