Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 92d13cb

Browse filesBrowse files
px raises error when horizontal or vertical spacing is impossible
describes that facet_{row,col}_spacing should be adjusted.
1 parent 85fa3af commit 92d13cb
Copy full SHA for 92d13cb

File tree

Expand file treeCollapse file tree

4 files changed

+112
-34
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+112
-34
lines changed

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

Copy file name to clipboardExpand all lines: packages/python/plotly/plotly/express/_core.py
+34-15Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,22 +2120,41 @@ def init_figure(args, subplot_type, frame_list, nrows, ncols, col_labels, row_la
21202120
for j in range(ncols):
21212121
subplot_labels[i * ncols + j] = col_labels[(nrows - 1 - i) * ncols + j]
21222122

2123+
def _spacing_error_translator(e, direction, facet_arg):
2124+
"""
2125+
Translates the spacing errors thrown by the underlying make_subplots
2126+
routine into one that describes an argument adjustable through px.
2127+
"""
2128+
if ("%s spacing" % (direction,)) in e.args[0]:
2129+
e.args = (
2130+
e.args[0]
2131+
+ """
2132+
Use the {facet_arg} argument to adjust this spacing.""".format(
2133+
facet_arg=facet_arg
2134+
),
2135+
)
2136+
raise e
2137+
21232138
# Create figure with subplots
2124-
fig = make_subplots(
2125-
rows=nrows,
2126-
cols=ncols,
2127-
specs=specs,
2128-
shared_xaxes="all",
2129-
shared_yaxes="all",
2130-
row_titles=[] if facet_col_wrap else list(reversed(row_labels)),
2131-
column_titles=[] if facet_col_wrap else col_labels,
2132-
subplot_titles=subplot_labels if facet_col_wrap else [],
2133-
horizontal_spacing=horizontal_spacing,
2134-
vertical_spacing=vertical_spacing,
2135-
row_heights=row_heights,
2136-
column_widths=column_widths,
2137-
start_cell="bottom-left",
2138-
)
2139+
try:
2140+
fig = make_subplots(
2141+
rows=nrows,
2142+
cols=ncols,
2143+
specs=specs,
2144+
shared_xaxes="all",
2145+
shared_yaxes="all",
2146+
row_titles=[] if facet_col_wrap else list(reversed(row_labels)),
2147+
column_titles=[] if facet_col_wrap else col_labels,
2148+
subplot_titles=subplot_labels if facet_col_wrap else [],
2149+
horizontal_spacing=horizontal_spacing,
2150+
vertical_spacing=vertical_spacing,
2151+
row_heights=row_heights,
2152+
column_widths=column_widths,
2153+
start_cell="bottom-left",
2154+
)
2155+
except ValueError as e:
2156+
_spacing_error_translator(e, "Horizontal", "facet_col_spacing")
2157+
_spacing_error_translator(e, "Vertical", "facet_row_spacing")
21392158

21402159
# Remove explicit font size of row/col titles so template can take over
21412160
for annot in fig.layout.annotations:

‎packages/python/plotly/plotly/subplots.py

Copy file name to clipboardExpand all lines: packages/python/plotly/plotly/subplots.py
+11-5Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -530,16 +530,22 @@ def _checks(item, defaults):
530530
)
531531
)
532532

533-
def _check_hv_spacing(dimsize, spacing, name, dimname):
533+
def _check_hv_spacing(dimsize, spacing, name, dimvarname, dimname):
534534
if spacing < 0 or spacing > 1:
535535
raise ValueError("%s spacing must be between 0 and 1." % (name,))
536536
if dimsize <= 1:
537537
return
538538
max_spacing = 1.0 / float(dimsize - 1)
539539
if spacing > max_spacing:
540540
raise ValueError(
541-
"%s spacing cannot be greater than (1 / (%s - 1)) = %f."
542-
% (name, dimname, max_spacing)
541+
"""{name} spacing cannot be greater than (1 / ({dimvarname} - 1)) = {max_spacing:f}.
542+
The resulting plot would have {dimsize} {dimname} ({dimvarname}={dimsize}).""".format(
543+
dimvarname=dimvarname,
544+
name=name,
545+
dimname=dimname,
546+
max_spacing=max_spacing,
547+
dimsize=dimsize,
548+
)
543549
)
544550

545551
# ### horizontal_spacing ###
@@ -549,7 +555,7 @@ def _check_hv_spacing(dimsize, spacing, name, dimname):
549555
else:
550556
horizontal_spacing = 0.2 / cols
551557
# check horizontal_spacing can be satisfied:
552-
_check_hv_spacing(cols, horizontal_spacing, "Horizontal", "cols")
558+
_check_hv_spacing(cols, horizontal_spacing, "Horizontal", "cols", "columns")
553559

554560
# ### vertical_spacing ###
555561
if vertical_spacing is None:
@@ -558,7 +564,7 @@ def _check_hv_spacing(dimsize, spacing, name, dimname):
558564
else:
559565
vertical_spacing = 0.3 / rows
560566
# check vertical_spacing can be satisfied:
561-
_check_hv_spacing(rows, vertical_spacing, "Vertical", "rows")
567+
_check_hv_spacing(rows, vertical_spacing, "Vertical", "rows", "rows")
562568

563569
# ### subplot titles ###
564570
if subplot_titles is None:

‎packages/python/plotly/plotly/tests/test_core/test_px/test_facets.py

Copy file name to clipboardExpand all lines: packages/python/plotly/plotly/tests/test_core/test_px/test_facets.py
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import plotly
2+
import pandas as pd
13
import plotly.express as px
24
from pytest import approx
5+
import pytest
6+
import random
37

48

59
def test_facets():
@@ -41,3 +45,45 @@ def test_facets():
4145
)
4246
assert fig.layout.xaxis4.domain[0] - fig.layout.xaxis.domain[1] == approx(0.09)
4347
assert fig.layout.yaxis4.domain[0] - fig.layout.yaxis.domain[1] == approx(0.08)
48+
49+
50+
@pytest.fixture
51+
def bad_facet_spacing_df():
52+
NROWS = 101
53+
NDATA = 1000
54+
categories = [n % NROWS for n in range(NDATA)]
55+
df = pd.DataFrame(
56+
{
57+
"x": [random.random() for _ in range(NDATA)],
58+
"y": [random.random() for _ in range(NDATA)],
59+
"category": categories,
60+
}
61+
)
62+
return df
63+
64+
65+
def test_bad_facet_spacing_eror(bad_facet_spacing_df):
66+
df = bad_facet_spacing_df
67+
with pytest.raises(
68+
ValueError, match="Use the facet_row_spacing argument to adjust this spacing\."
69+
):
70+
fig = px.scatter(
71+
df, x="x", y="y", facet_row="category", facet_row_spacing=0.01001
72+
)
73+
with pytest.raises(
74+
ValueError, match="Use the facet_col_spacing argument to adjust this spacing\."
75+
):
76+
fig = px.scatter(
77+
df, x="x", y="y", facet_col="category", facet_col_spacing=0.01001
78+
)
79+
# Check error is not raised when the spacing is OK
80+
try:
81+
fig = px.scatter(df, x="x", y="y", facet_row="category", facet_row_spacing=0.01)
82+
except ValueError:
83+
# Error shouldn't be raised, so fail if it is
84+
assert False
85+
try:
86+
fig = px.scatter(df, x="x", y="y", facet_col="category", facet_col_spacing=0.01)
87+
except ValueError:
88+
# Error shouldn't be raised, so fail if it is
89+
assert False

‎packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py

Copy file name to clipboardExpand all lines: packages/python/plotly/plotly/tests/test_core/test_subplots/test_make_subplots.py
+21-14Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,22 +1940,29 @@ def test_if_passed_figure(self):
19401940
def test_make_subplots_spacing_error():
19411941
# check exception describing maximum value for horizontal_spacing or
19421942
# vertical_spacing is raised when spacing exceeds that value
1943-
with pytest.raises(
1944-
ValueError,
1945-
match=(
1946-
"^%s spacing cannot be greater than \(1 / \(%s - 1\)\) = %f.$"
1947-
% ("Vertical", "rows", 0.02)
1943+
for match in [
1944+
(
1945+
"^%s spacing cannot be greater than \(1 / \(%s - 1\)\) = %f."
1946+
% ("Vertical", "rows", 1.0 / 50.0)
19481947
).replace(".", "\."),
1949-
):
1950-
fig = subplots.make_subplots(51, 1, vertical_spacing=0.0201)
1951-
with pytest.raises(
1952-
ValueError,
1953-
match=(
1954-
"^%s spacing cannot be greater than \(1 / \(%s - 1\)\) = %f.$"
1955-
% ("Horizontal", "cols", 0.02)
1948+
"The resulting plot would have 51 rows \(rows=51\)\.$",
1949+
]:
1950+
with pytest.raises(
1951+
ValueError, match=match,
1952+
):
1953+
fig = subplots.make_subplots(51, 1, vertical_spacing=0.0201)
1954+
for match in [
1955+
(
1956+
"^%s spacing cannot be greater than \(1 / \(%s - 1\)\) = %f."
1957+
% ("Horizontal", "cols", 1.0 / 50.0)
19561958
).replace(".", "\."),
1957-
):
1958-
fig = subplots.make_subplots(1, 51, horizontal_spacing=0.0201)
1959+
"The resulting plot would have 51 columns \(cols=51\)\.$",
1960+
]:
1961+
with pytest.raises(
1962+
ValueError, match=match,
1963+
):
1964+
fig = subplots.make_subplots(1, 51, horizontal_spacing=0.0201)
1965+
# Check it's not raised when it's not beyond the maximum
19591966
try:
19601967
fig = subplots.make_subplots(51, 1, vertical_spacing=0.0200)
19611968
except ValueError:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.