Skip to content

Commit 29b2c8b

Browse files
px_combine with secondary-y
Argument and logic is there, but not yet tested. It doesn't break the case where px_combine was called with fig1_secondary_y=False.
1 parent fe86651 commit 29b2c8b

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

packages/python/plotly/plotly/basedatatypes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ class is a subclass of both BaseFigure and widgets.DOMWidget.
391391
self._animation_duration_validator = animation.DurationValidator()
392392
self._animation_easing_validator = animation.EasingValidator()
393393

394+
# Space for auxiliary data
395+
self._aux = dict()
396+
394397
# Template
395398
# --------
396399
# ### Check for default template ###

packages/python/plotly/plotly/express/_core.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,8 @@ def make_figure(args, constructor, trace_patch=None, layout_patch=None):
20572057

20582058
configure_axes(args, constructor, fig, orders)
20592059
configure_animation_controls(args, constructor, fig)
2060+
# store args in figure metadata
2061+
fig._aux["px"] = dict(args=args)
20602062
return fig
20612063

20622064

proto/px_combine/px_combine.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,38 +49,51 @@ def extract_axis_titles(fig):
4949
return (r_titles, c_titles)
5050

5151

52-
def px_simple_combine(fig0, fig1):
52+
def px_simple_combine(fig0, fig1, fig1_secondary_y=False):
5353
"""
5454
Combines two figures by just using the layout of the first figure and
5555
appending the data of the second figure.
5656
"""
57+
if fig1_secondary_y and (
58+
("px" not in fig0._aux.keys()) or ("px" not in fig0._aux.keys())
59+
):
60+
raise ValueError(
61+
"To place fig1's traces on secondary y-axes, both figures must have "
62+
"been made with Plotly Express."
63+
)
5764
grid_ref_shape = fig_grid_ref_shape(fig0)
5865
if grid_ref_shape != fig_grid_ref_shape(fig1):
5966
raise ValueError(
6067
"Only two figures with the same subplot geometry can be combined."
6168
)
6269
# reflow the colors
6370
colorway = fig0.layout.template.layout.colorway
64-
fig = make_subplots(*fig_grid_ref_shape(fig0))
71+
specs = None
72+
if fig1_secondary_y:
73+
specs = [
74+
[dict(secondary_y=True) for __ in range(grid_ref_shape[1])]
75+
for _ in range(grid_ref_shape[0])
76+
]
77+
fig = make_subplots(*fig_grid_ref_shape(fig0), specs=specs)
6578
for r, c in multi_index(*fig_grid_ref_shape(fig)):
66-
for (tr, title), color in zip(
79+
for (tr, f), color in zip(
6780
chain(
6881
*[
69-
zip(
70-
f.select_traces(row=r + 1, col=c + 1),
71-
cycle([f.layout.title.text]),
72-
)
82+
zip(f.select_traces(row=r + 1, col=c + 1), cycle([f]),)
7383
for f in [fig0, fig1]
7484
]
7585
),
7686
cycle(colorway),
7787
):
88+
title = f.layout.title.text
7889
set_main_trace_color(tr, color)
7990
# use figure title to differentiate the legend items
8091
tr["name"] = "%s %s" % (title, tr["name"])
8192
# TODO: argument to group legend items?
8293
tr["legendgroup"] = None
83-
fig.add_trace(tr, row=r + 1, col=c + 1)
94+
fig.add_trace(
95+
tr, row=r + 1, col=c + 1, secondary_y=(fig1_secondary_y and (f == fig1))
96+
)
8497
fig.update_layout(fig0.layout)
8598
# title will be wrong
8699
fig.layout.title = None

0 commit comments

Comments
 (0)