Skip to content

Commit 832b46c

Browse files
authored
Merge branch 'main' into matplotlib-import-fix
2 parents 2c5e2b6 + b258862 commit 832b46c

File tree

2 files changed

+149
-111
lines changed

2 files changed

+149
-111
lines changed

plotly/_subplots.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,19 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname):
746746
)
747747
grid_ref[r][c] = subplot_refs
748748

749-
_configure_shared_axes(layout, grid_ref, specs, "x", shared_xaxes, row_dir)
750-
_configure_shared_axes(layout, grid_ref, specs, "y", shared_yaxes, row_dir)
749+
_configure_shared_axes(layout, grid_ref, specs, "x", shared_xaxes, row_dir, False)
750+
_configure_shared_axes(layout, grid_ref, specs, "y", shared_yaxes, row_dir, False)
751+
752+
any_secondary_y = any(
753+
spec["secondary_y"]
754+
for spec_row in specs
755+
for spec in spec_row
756+
if spec is not None
757+
)
758+
if any_secondary_y:
759+
_configure_shared_axes(
760+
layout, grid_ref, specs, "y", shared_yaxes, row_dir, True
761+
)
751762

752763
# Build inset reference
753764
# ---------------------
@@ -879,7 +890,9 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname):
879890
return figure
880891

881892

882-
def _configure_shared_axes(layout, grid_ref, specs, x_or_y, shared, row_dir):
893+
def _configure_shared_axes(
894+
layout, grid_ref, specs, x_or_y, shared, row_dir, secondary_y
895+
):
883896
rows = len(grid_ref)
884897
cols = len(grid_ref[0])
885898

@@ -890,6 +903,13 @@ def _configure_shared_axes(layout, grid_ref, specs, x_or_y, shared, row_dir):
890903
else:
891904
rows_iter = range(rows)
892905

906+
if secondary_y:
907+
cols_iter = range(cols - 1, -1, -1)
908+
axis_index = 1
909+
else:
910+
cols_iter = range(cols)
911+
axis_index = 0
912+
893913
def update_axis_matches(first_axis_id, subplot_ref, spec, remove_label):
894914
if subplot_ref is None:
895915
return first_axis_id
@@ -913,13 +933,15 @@ def update_axis_matches(first_axis_id, subplot_ref, spec, remove_label):
913933
return first_axis_id
914934

915935
if shared == "columns" or (x_or_y == "x" and shared is True):
916-
for c in range(cols):
936+
for c in cols_iter:
917937
first_axis_id = None
918938
ok_to_remove_label = x_or_y == "x"
919939
for r in rows_iter:
920940
if not grid_ref[r][c]:
921941
continue
922-
subplot_ref = grid_ref[r][c][0]
942+
if axis_index >= len(grid_ref[r][c]):
943+
continue
944+
subplot_ref = grid_ref[r][c][axis_index]
923945
spec = specs[r][c]
924946
first_axis_id = update_axis_matches(
925947
first_axis_id, subplot_ref, spec, ok_to_remove_label
@@ -929,26 +951,30 @@ def update_axis_matches(first_axis_id, subplot_ref, spec, remove_label):
929951
for r in rows_iter:
930952
first_axis_id = None
931953
ok_to_remove_label = x_or_y == "y"
932-
for c in range(cols):
954+
for c in cols_iter:
933955
if not grid_ref[r][c]:
934956
continue
935-
subplot_ref = grid_ref[r][c][0]
957+
if axis_index >= len(grid_ref[r][c]):
958+
continue
959+
subplot_ref = grid_ref[r][c][axis_index]
936960
spec = specs[r][c]
937961
first_axis_id = update_axis_matches(
938962
first_axis_id, subplot_ref, spec, ok_to_remove_label
939963
)
940964

941965
elif shared == "all":
942966
first_axis_id = None
943-
for c in range(cols):
944-
for ri, r in enumerate(rows_iter):
967+
for ri, r in enumerate(rows_iter):
968+
for c in cols_iter:
945969
if not grid_ref[r][c]:
946970
continue
947-
subplot_ref = grid_ref[r][c][0]
971+
if axis_index >= len(grid_ref[r][c]):
972+
continue
973+
subplot_ref = grid_ref[r][c][axis_index]
948974
spec = specs[r][c]
949975

950976
if x_or_y == "y":
951-
ok_to_remove_label = c > 0
977+
ok_to_remove_label = c < cols - 1 if secondary_y else c > 0
952978
else:
953979
ok_to_remove_label = ri > 0 if row_dir > 0 else r < rows - 1
954980

tests/test_core/test_subplots/test_make_subplots.py

Lines changed: 112 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,115 +1828,127 @@ def test_secondary_y_traces(self):
18281828
self.assertEqual(fig.to_plotly_json(), expected.to_plotly_json())
18291829

18301830
def test_secondary_y_subplots(self):
1831-
fig = subplots.make_subplots(
1832-
rows=2,
1833-
cols=2,
1834-
specs=[
1835-
[{"secondary_y": True}, {"secondary_y": True}],
1836-
[{"secondary_y": True}, {"secondary_y": True}],
1837-
],
1838-
)
1831+
for shared_y_axes in [False, True]:
1832+
fig = subplots.make_subplots(
1833+
rows=2,
1834+
cols=2,
1835+
shared_yaxes=shared_y_axes,
1836+
specs=[
1837+
[{"secondary_y": True}, {"secondary_y": True}],
1838+
[{"secondary_y": True}, {"secondary_y": True}],
1839+
],
1840+
)
18391841

1840-
fig.add_scatter(y=[1, 3, 2], name="First", row=1, col=1)
1841-
fig.add_scatter(y=[2, 1, 3], name="Second", row=1, col=1, secondary_y=True)
1842+
fig.add_scatter(y=[1, 3, 2], name="First", row=1, col=1)
1843+
fig.add_scatter(y=[2, 1, 3], name="Second", row=1, col=1, secondary_y=True)
18421844

1843-
fig.add_scatter(y=[4, 3, 2], name="Third", row=1, col=2)
1844-
fig.add_scatter(y=[8, 1, 3], name="Forth", row=1, col=2, secondary_y=True)
1845+
fig.add_scatter(y=[4, 3, 2], name="Third", row=1, col=2)
1846+
fig.add_scatter(y=[8, 1, 3], name="Forth", row=1, col=2, secondary_y=True)
18451847

1846-
fig.add_scatter(y=[0, 2, 4], name="Fifth", row=2, col=1)
1847-
fig.add_scatter(y=[2, 1, 3], name="Sixth", row=2, col=1, secondary_y=True)
1848+
fig.add_scatter(y=[0, 2, 4], name="Fifth", row=2, col=1)
1849+
fig.add_scatter(y=[2, 1, 3], name="Sixth", row=2, col=1, secondary_y=True)
18481850

1849-
fig.add_scatter(y=[2, 4, 0], name="Fifth", row=2, col=2)
1850-
fig.add_scatter(y=[2, 3, 6], name="Sixth", row=2, col=2, secondary_y=True)
1851+
fig.add_scatter(y=[2, 4, 0], name="Fifth", row=2, col=2)
1852+
fig.add_scatter(y=[2, 3, 6], name="Sixth", row=2, col=2, secondary_y=True)
18511853

1852-
fig.update_traces(uid=None)
1854+
fig.update_traces(uid=None)
18531855

1854-
expected = Figure(
1855-
{
1856-
"data": [
1857-
{
1858-
"name": "First",
1859-
"type": "scatter",
1860-
"xaxis": "x",
1861-
"y": [1, 3, 2],
1862-
"yaxis": "y",
1863-
},
1864-
{
1865-
"name": "Second",
1866-
"type": "scatter",
1867-
"xaxis": "x",
1868-
"y": [2, 1, 3],
1869-
"yaxis": "y2",
1870-
},
1871-
{
1872-
"name": "Third",
1873-
"type": "scatter",
1874-
"xaxis": "x2",
1875-
"y": [4, 3, 2],
1876-
"yaxis": "y3",
1877-
},
1878-
{
1879-
"name": "Forth",
1880-
"type": "scatter",
1881-
"xaxis": "x2",
1882-
"y": [8, 1, 3],
1883-
"yaxis": "y4",
1884-
},
1885-
{
1886-
"name": "Fifth",
1887-
"type": "scatter",
1888-
"xaxis": "x3",
1889-
"y": [0, 2, 4],
1890-
"yaxis": "y5",
1891-
},
1892-
{
1893-
"name": "Sixth",
1894-
"type": "scatter",
1895-
"xaxis": "x3",
1896-
"y": [2, 1, 3],
1897-
"yaxis": "y6",
1898-
},
1899-
{
1900-
"name": "Fifth",
1901-
"type": "scatter",
1902-
"xaxis": "x4",
1903-
"y": [2, 4, 0],
1904-
"yaxis": "y7",
1905-
},
1906-
{
1907-
"name": "Sixth",
1908-
"type": "scatter",
1909-
"xaxis": "x4",
1910-
"y": [2, 3, 6],
1911-
"yaxis": "y8",
1912-
},
1913-
],
1914-
"layout": {
1915-
"xaxis": {"anchor": "y", "domain": [0.0, 0.37]},
1916-
"xaxis2": {
1917-
"anchor": "y3",
1918-
"domain": [0.5700000000000001, 0.9400000000000001],
1919-
},
1920-
"xaxis3": {"anchor": "y5", "domain": [0.0, 0.37]},
1921-
"xaxis4": {
1922-
"anchor": "y7",
1923-
"domain": [0.5700000000000001, 0.9400000000000001],
1856+
expected = Figure(
1857+
{
1858+
"data": [
1859+
{
1860+
"name": "First",
1861+
"type": "scatter",
1862+
"xaxis": "x",
1863+
"y": [1, 3, 2],
1864+
"yaxis": "y",
1865+
},
1866+
{
1867+
"name": "Second",
1868+
"type": "scatter",
1869+
"xaxis": "x",
1870+
"y": [2, 1, 3],
1871+
"yaxis": "y2",
1872+
},
1873+
{
1874+
"name": "Third",
1875+
"type": "scatter",
1876+
"xaxis": "x2",
1877+
"y": [4, 3, 2],
1878+
"yaxis": "y3",
1879+
},
1880+
{
1881+
"name": "Forth",
1882+
"type": "scatter",
1883+
"xaxis": "x2",
1884+
"y": [8, 1, 3],
1885+
"yaxis": "y4",
1886+
},
1887+
{
1888+
"name": "Fifth",
1889+
"type": "scatter",
1890+
"xaxis": "x3",
1891+
"y": [0, 2, 4],
1892+
"yaxis": "y5",
1893+
},
1894+
{
1895+
"name": "Sixth",
1896+
"type": "scatter",
1897+
"xaxis": "x3",
1898+
"y": [2, 1, 3],
1899+
"yaxis": "y6",
1900+
},
1901+
{
1902+
"name": "Fifth",
1903+
"type": "scatter",
1904+
"xaxis": "x4",
1905+
"y": [2, 4, 0],
1906+
"yaxis": "y7",
1907+
},
1908+
{
1909+
"name": "Sixth",
1910+
"type": "scatter",
1911+
"xaxis": "x4",
1912+
"y": [2, 3, 6],
1913+
"yaxis": "y8",
1914+
},
1915+
],
1916+
"layout": {
1917+
"xaxis": {"anchor": "y", "domain": [0.0, 0.37]},
1918+
"xaxis2": {
1919+
"anchor": "y3",
1920+
"domain": [0.5700000000000001, 0.9400000000000001],
1921+
},
1922+
"xaxis3": {"anchor": "y5", "domain": [0.0, 0.37]},
1923+
"xaxis4": {
1924+
"anchor": "y7",
1925+
"domain": [0.5700000000000001, 0.9400000000000001],
1926+
},
1927+
"yaxis": {"anchor": "x", "domain": [0.575, 1.0]},
1928+
"yaxis2": {"anchor": "x", "overlaying": "y", "side": "right"},
1929+
"yaxis3": {"anchor": "x2", "domain": [0.575, 1.0]},
1930+
"yaxis4": {"anchor": "x2", "overlaying": "y3", "side": "right"},
1931+
"yaxis5": {"anchor": "x3", "domain": [0.0, 0.425]},
1932+
"yaxis6": {"anchor": "x3", "overlaying": "y5", "side": "right"},
1933+
"yaxis7": {"anchor": "x4", "domain": [0.0, 0.425]},
1934+
"yaxis8": {"anchor": "x4", "overlaying": "y7", "side": "right"},
19241935
},
1925-
"yaxis": {"anchor": "x", "domain": [0.575, 1.0]},
1926-
"yaxis2": {"anchor": "x", "overlaying": "y", "side": "right"},
1927-
"yaxis3": {"anchor": "x2", "domain": [0.575, 1.0]},
1928-
"yaxis4": {"anchor": "x2", "overlaying": "y3", "side": "right"},
1929-
"yaxis5": {"anchor": "x3", "domain": [0.0, 0.425]},
1930-
"yaxis6": {"anchor": "x3", "overlaying": "y5", "side": "right"},
1931-
"yaxis7": {"anchor": "x4", "domain": [0.0, 0.425]},
1932-
"yaxis8": {"anchor": "x4", "overlaying": "y7", "side": "right"},
1933-
},
1934-
}
1935-
)
1936+
}
1937+
)
19361938

1937-
expected.update_traces(uid=None)
1939+
if shared_y_axes:
1940+
expected["layout"]["yaxis2"]["matches"] = "y4"
1941+
expected["layout"]["yaxis2"]["showticklabels"] = False
1942+
expected["layout"]["yaxis3"]["matches"] = "y"
1943+
expected["layout"]["yaxis3"]["showticklabels"] = False
1944+
expected["layout"]["yaxis6"]["matches"] = "y8"
1945+
expected["layout"]["yaxis6"]["showticklabels"] = False
1946+
expected["layout"]["yaxis7"]["matches"] = "y5"
1947+
expected["layout"]["yaxis7"]["showticklabels"] = False
19381948

1939-
self.assertEqual(fig.to_plotly_json(), expected.to_plotly_json())
1949+
expected.update_traces(uid=None)
1950+
1951+
self.assertEqual(fig.to_plotly_json(), expected.to_plotly_json())
19401952

19411953
def test_if_passed_figure(self):
19421954
# assert it returns the same figure it was passed

0 commit comments

Comments
 (0)