From dc6e7bb556331e1e9cf7b866d778d54f9cee7cf3 Mon Sep 17 00:00:00 2001 From: stephenpardy Date: Thu, 6 Apr 2023 14:28:09 -0500 Subject: [PATCH 1/6] Adding some rounding and error messaging --- packages/python/plotly/plotly/_subplots.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/python/plotly/plotly/_subplots.py b/packages/python/plotly/plotly/_subplots.py index 24ec630e01d..f35ec24e16a 100644 --- a/packages/python/plotly/plotly/_subplots.py +++ b/packages/python/plotly/plotly/_subplots.py @@ -702,6 +702,26 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): else: y_s = grid[r_spanned][c][1] + spec["b"] y_e = grid[r][c][1] + heights[-1 - r] - spec["t"] + + if y_s > 1.0: + # round for values very close to one + # handles some floating point errors + if y_s < 1.01: + y_s = 1.0 + else: + raise Exception( + "A combination of the 'b' values, heights, and " + "number of subplots too large for this subplot gird." + ) + if y_e > 1.0: + if y_e < 1.01: + y_e = 1.0 + else: + raise Exception( + "A combination of the 't' values, heights, and " + "number of subplots too large for this subplot gird." + ) + y_domain = [y_s, y_e] list_of_domains.append(x_domain) From d80f975695abefd234050666db0d786d954e54b1 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 5 May 2023 12:44:33 -0400 Subject: [PATCH 2/6] Update packages/python/plotly/plotly/_subplots.py --- packages/python/plotly/plotly/_subplots.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/python/plotly/plotly/_subplots.py b/packages/python/plotly/plotly/_subplots.py index f35ec24e16a..a2dba5fbf02 100644 --- a/packages/python/plotly/plotly/_subplots.py +++ b/packages/python/plotly/plotly/_subplots.py @@ -711,7 +711,7 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): else: raise Exception( "A combination of the 'b' values, heights, and " - "number of subplots too large for this subplot gird." + "number of subplots too large for this subplot grid." ) if y_e > 1.0: if y_e < 1.01: @@ -719,7 +719,7 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): else: raise Exception( "A combination of the 't' values, heights, and " - "number of subplots too large for this subplot gird." + "number of subplots too large for this subplot grid." ) y_domain = [y_s, y_e] From 2bc5258f81a464fa22822de7919bfa8cef96d7b9 Mon Sep 17 00:00:00 2001 From: stephenpardy Date: Fri, 5 May 2023 12:26:03 -0500 Subject: [PATCH 3/6] Add test for rounding --- .../test_subplots/test_make_subplots.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py index 7c7a1a9da8e..6489491091a 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py +++ b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py @@ -660,6 +660,22 @@ def test_specs_padding(self): ) self.assertEqual(fig.to_plotly_json(), expected.to_plotly_json()) + def test_specs_rounding_rounds_down(self): + n_subplots = 8 + padding_size = 0.2 + + specs = [] + for _ in range(n_subplots): + specs.append([{"b": padding_size / 2.0, "t": padding_size / 2.0}]) + + fig = tls.make_subplots(rows=n_subplots, specs=specs) + self.assertTrue( + all( + fig.layout[f"yaxis{i if i > 1 else ''}"]["domain"][0] <= 1.0 + for i in range(1, n_subplots+1) + ) + ) + def test_specs_padding_bottom_left(self): expected = Figure( data=Data(), @@ -1592,7 +1608,6 @@ def test_large_columns_no_errors(self): ) def test_row_width_and_column_width(self): - expected = Figure( { "data": [], @@ -1680,7 +1695,6 @@ def test_row_width_and_column_width(self): self.assertEqual(fig.to_plotly_json(), expected.to_plotly_json()) def test_row_width_and_shared_yaxes(self): - expected = Figure( { "data": [], From 6936fd340909ceb8270bb3c524eb903751576f84 Mon Sep 17 00:00:00 2001 From: stephenpardy Date: Fri, 5 May 2023 12:30:34 -0500 Subject: [PATCH 4/6] Add to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a9966375c..880774085a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed another compatibility issue with Pandas 2.0, just affecting `px.*(line_close=True)` [[#4190](https://github.com/plotly/plotly.py/pull/4190)] + - Added some rounding to the `make_subplots` function to handle situations where the user-input specs cause the domain to exceed 1 by small amounts https://github.com/plotly/plotly.py/pull/4153 ## [5.14.1] - 2023-04-05 From d5bce9ade10b2cd4d7a4172dfefd6627317cc8e3 Mon Sep 17 00:00:00 2001 From: stephenpardy Date: Fri, 5 May 2023 15:12:27 -0500 Subject: [PATCH 5/6] Update test and also round other values --- packages/python/plotly/plotly/_subplots.py | 27 ++++++++++++++----- .../test_subplots/test_make_subplots.py | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/python/plotly/plotly/_subplots.py b/packages/python/plotly/plotly/_subplots.py index a2dba5fbf02..f2606f49e45 100644 --- a/packages/python/plotly/plotly/_subplots.py +++ b/packages/python/plotly/plotly/_subplots.py @@ -671,7 +671,6 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): # Loop through specs -- (r, c) <-> (row, col) for r, spec_row in enumerate(specs): for c, spec in enumerate(spec_row): - if spec is None: # skip over None cells continue @@ -703,6 +702,16 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): y_s = grid[r_spanned][c][1] + spec["b"] y_e = grid[r][c][1] + heights[-1 - r] - spec["t"] + if y_s < 0.0: + # round for values very close to one + # handles some floating point errors + if y_s > -0.01: + y_s = 0.0 + else: + raise Exception( + "A combination of the 'b' values, heights, and " + "number of subplots too large for this subplot grid." + ) if y_s > 1.0: # round for values very close to one # handles some floating point errors @@ -713,6 +722,16 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): "A combination of the 'b' values, heights, and " "number of subplots too large for this subplot grid." ) + + if y_e < 0.0: + if y_e > -0.01: + y_e = 0.0 + else: + raise Exception( + "A combination of the 't' values, heights, and " + "number of subplots too large for this subplot grid." + ) + if y_e > 1.0: if y_e < 1.01: y_e = 1.0 @@ -746,7 +765,6 @@ def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname): insets_ref = [None for inset in range(len(insets))] if insets else None if insets: for i_inset, inset in enumerate(insets): - r = inset["cell"][0] - 1 c = inset["cell"][1] - 1 @@ -1072,7 +1090,6 @@ def _subplot_type_for_trace_type(trace_type): def _validate_coerce_subplot_type(subplot_type): - # Lowercase subplot_type orig_subplot_type = subplot_type subplot_type = subplot_type.lower() @@ -1220,7 +1237,6 @@ def _build_subplot_title_annotations( def _build_grid_str(specs, grid_ref, insets, insets_ref, row_seq): - # Compute rows and columns rows = len(specs) cols = len(specs[0]) @@ -1277,7 +1293,6 @@ def _pad(s, cell_len=cell_len): # Loop through specs, fill in _tmp for r, spec_row in enumerate(specs): for c, spec in enumerate(spec_row): - ref = grid_ref[r][c] if ref is None: if _tmp[r][c] == "": @@ -1359,7 +1374,6 @@ def _pad(s, cell_len=cell_len): def _set_trace_grid_reference(trace, layout, grid_ref, row, col, secondary_y=False): - if row <= 0: raise Exception( "Row value is out of range. " "Note: the starting cell is (1, 1)" @@ -1481,7 +1495,6 @@ def _get_grid_subplot(fig, row, col, secondary_y=False): def _get_subplot_ref_for_trace(trace): - if "domain" in trace: return SubplotRef( subplot_type="domain", diff --git a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py index 6489491091a..171b12df121 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py +++ b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py @@ -668,7 +668,7 @@ def test_specs_rounding_rounds_down(self): for _ in range(n_subplots): specs.append([{"b": padding_size / 2.0, "t": padding_size / 2.0}]) - fig = tls.make_subplots(rows=n_subplots, specs=specs) + fig = subplots.make_subplots(rows=n_subplots, specs=specs) self.assertTrue( all( fig.layout[f"yaxis{i if i > 1 else ''}"]["domain"][0] <= 1.0 From bf7f6de247aae37afe9f0db9a7e2d4d88abf01b8 Mon Sep 17 00:00:00 2001 From: stephenpardy Date: Fri, 5 May 2023 16:02:03 -0500 Subject: [PATCH 6/6] code formatting --- .../plotly/tests/test_core/test_subplots/test_make_subplots.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py index 171b12df121..28ad18f19a6 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py +++ b/packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py @@ -672,7 +672,7 @@ def test_specs_rounding_rounds_down(self): self.assertTrue( all( fig.layout[f"yaxis{i if i > 1 else ''}"]["domain"][0] <= 1.0 - for i in range(1, n_subplots+1) + for i in range(1, n_subplots + 1) ) )