Repository navigation
plotly express scatter with more than ~34 facet rows breaks #2026
Copy link
Copy link
Closed
Milestone
Description
I am trying to create subplots for a number of categories. I have approximately 250 categories in my actual data. I have found that this error occurs all the way down to 35 categories, and disappears around 34.
import numpy as np
import pandas as pd
import plotly.express as px
import plotly
# Versions I'm running with
np.__version__ # 1.17.4
pd.__version__ # 0.25.3
plotly.__version__ # 4.4.1
df = pd.DataFrame({
'x':np.random.rand(10_000),
'y':np.random.rand(10_000),
'category':np.random.choice(range(35), 10_000)
})
# The following breaks
fig = px.scatter(df, x = 'x', y = 'y', facet_row = 'category')
# Specifying a height seems to change nothing
fig = px.scatter(df, x = 'x', y = 'y', facet_row = 'category', height = 20_000)I get the following error in both cases
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-40-f3e17e288c8e> in <module>
----> 1 fig = px.scatter(df, x = 'x', y = 'y', facet_row = 'category', height = 20_000)
~/miniconda3/lib/python3.7/site-packages/plotly/express/_chart_types.py in scatter(data_frame, x, y, color, symbol, size, hover_name, hover_data, custom_data, text, facet_row, facet_col, facet_col_wrap, error_x, error_x_minus, error_y, error_y_minus, animation_frame, animation_group, category_orders, labels, color_discrete_sequence, color_discrete_map, color_continuous_scale, range_color, color_continuous_midpoint, symbol_sequence, symbol_map, opacity, size_max, marginal_x, marginal_y, trendline, trendline_color_override, log_x, log_y, range_x, range_y, render_mode, title, template, width, height)
53 mark in 2D space.
54 """
---> 55 return make_figure(args=locals(), constructor=go.Scatter)
56
57
~/miniconda3/lib/python3.7/site-packages/plotly/express/_core.py in make_figure(args, constructor, trace_patch, layout_patch)
1358
1359 fig = init_figure(
-> 1360 args, subplot_type, frame_list, nrows, ncols, col_labels, row_labels
1361 )
1362
~/miniconda3/lib/python3.7/site-packages/plotly/express/_core.py in init_figure(args, subplot_type, frame_list, nrows, ncols, col_labels, row_labels)
1464 row_heights=row_heights,
1465 column_widths=column_widths,
-> 1466 start_cell="bottom-left",
1467 )
1468
~/miniconda3/lib/python3.7/site-packages/plotly/subplots.py in make_subplots(rows, cols, shared_xaxes, shared_yaxes, start_cell, print_grid, horizontal_spacing, vertical_spacing, subplot_titles, column_widths, row_heights, specs, insets, column_titles, row_titles, x_title, y_title, **kwargs)
683 secondary_y = spec["secondary_y"]
684 subplot_refs = _init_subplot(
--> 685 layout, subplot_type, secondary_y, x_domain, y_domain, max_subplot_ids
686 )
687 grid_ref[r][c] = subplot_refs
~/miniconda3/lib/python3.7/site-packages/plotly/subplots.py in _init_subplot(layout, subplot_type, secondary_y, x_domain, y_domain, max_subplot_ids)
1055 if subplot_type == "xy":
1056 subplot_refs = _init_subplot_xy(
-> 1057 layout, secondary_y, x_domain, y_domain, max_subplot_ids
1058 )
1059 elif subplot_type in _single_subplot_types:
~/miniconda3/lib/python3.7/site-packages/plotly/subplots.py in _init_subplot_xy(layout, secondary_y, x_domain, y_domain, max_subplot_ids)
919
920 layout[xaxis_name] = x_axis
--> 921 layout[yaxis_name] = y_axis
922
923 subplot_refs = [
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in __setitem__(self, prop, value)
4435 if match is None:
4436 # Set as ordinary property
-> 4437 super(BaseLayoutHierarchyType, self).__setitem__(prop, value)
4438 else:
4439 # Set as subplotid property
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in __setitem__(self, prop, value)
3480 # ### Handle compound property ###
3481 if isinstance(validator, CompoundValidator):
-> 3482 self._set_compound_prop(prop, value)
3483
3484 # ### Handle compound array property ###
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in _set_compound_prop(self, prop, val)
3834 # ------------
3835 validator = self._validators.get(prop)
-> 3836 val = validator.validate_coerce(val, skip_invalid=self._skip_invalid)
3837
3838 # Save deep copies of current and new states
~/miniconda3/lib/python3.7/site-packages/_plotly_utils/basevalidators.py in validate_coerce(self, v, skip_invalid)
2442
2443 elif isinstance(v, dict):
-> 2444 v = self.data_class(v, skip_invalid=skip_invalid)
2445
2446 elif isinstance(v, self.data_class):
~/miniconda3/lib/python3.7/site-packages/plotly/graph_objs/layout/__init__.py in __init__(self, arg, anchor, automargin, autorange, calendar, categoryarray, categoryarraysrc, categoryorder, color, constrain, constraintoward, dividercolor, dividerwidth, domain, dtick, exponentformat, fixedrange, gridcolor, gridwidth, hoverformat, layer, linecolor, linewidth, matches, mirror, nticks, overlaying, position, range, rangemode, scaleanchor, scaleratio, separatethousands, showdividers, showexponent, showgrid, showline, showspikes, showticklabels, showtickprefix, showticksuffix, side, spikecolor, spikedash, spikemode, spikesnap, spikethickness, tick0, tickangle, tickcolor, tickfont, tickformat, tickformatstops, tickformatstopdefaults, ticklen, tickmode, tickprefix, ticks, tickson, ticksuffix, ticktext, ticktextsrc, tickvals, tickvalssrc, tickwidth, title, titlefont, type, uirevision, visible, zeroline, zerolinecolor, zerolinewidth, **kwargs)
3053 self["dividerwidth"] = dividerwidth if dividerwidth is not None else _v
3054 _v = arg.pop("domain", None)
-> 3055 self["domain"] = domain if domain is not None else _v
3056 _v = arg.pop("dtick", None)
3057 self["dtick"] = dtick if dtick is not None else _v
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in __setitem__(self, prop, value)
3488 # ### Handle simple property ###
3489 else:
-> 3490 self._set_prop(prop, value)
3491
3492 # Handle non-scalar case
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in _set_prop(self, prop, val)
3775 return
3776 else:
-> 3777 raise err
3778
3779 # val is None
~/miniconda3/lib/python3.7/site-packages/plotly/basedatatypes.py in _set_prop(self, prop, val)
3770 validator = self._validators.get(prop)
3771 try:
-> 3772 val = validator.validate_coerce(val)
3773 except ValueError as err:
3774 if self._skip_invalid:
~/miniconda3/lib/python3.7/site-packages/_plotly_utils/basevalidators.py in validate_coerce(self, v)
2170 for i, (el, validator) in enumerate(zip(v, self.item_validators)):
2171 # Validate coerce elements
-> 2172 v[i] = validator.validate_coerce(el)
2173
2174 return v
~/miniconda3/lib/python3.7/site-packages/_plotly_utils/basevalidators.py in validate_coerce(self, v)
785 if self.has_min_max:
786 if not (self.min_val <= v <= self.max_val):
--> 787 self.raise_invalid_val(v)
788 return v
789
~/miniconda3/lib/python3.7/site-packages/_plotly_utils/basevalidators.py in raise_invalid_val(self, v, inds)
281 typ=type_str(v),
282 v=repr(v),
--> 283 valid_clr_desc=self.description(),
284 )
285 )
ValueError:
Invalid value of type 'builtins.float' received for the 'domain[1]' property of layout.yaxis
Received value: -0.0005714285714285719
The 'domain[1]' property is a number and may be specified as:
- An int or float in the interval [0, 1]Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
wookayin commentedon Jan 12, 2020
Related to #1031, #1216. This bug still does present as of now (I am using plotly 4.4.1).
hamzahiqb commentedon Feb 4, 2020
I get the same error (plotly 4.5.0). Were you able to find a workaround?
albertsugi-tallridge commentedon Feb 24, 2020
Hi @jonmmease , I am using plotly 4.5.1 and am getting this error too as i tried creating a subplot with 63 rows. it gives an error if the row is bigger than 58 rows.
Here is the code:
fig = make_subplots(rows=63, cols=1, shared_xaxes=True, vertical_spacing=0.02) size = len(asinhourlydict) xvalues = ["12am", "1am", "2am","3am","4am","5am","6am","7am","8am","9am","10am","11am","12pm","1pm", "2pm","3pm","4pm","5pm","6pm","7pm","8pm","9pm","10pm","11pm" ] for key,value in asinhourlydict.items(): fig.add_trace(go.Bar(x=xvalues,y=value),row=size,col= 1) fig.update_yaxes(title_text=key, row=size, col=1) size = size -1 fig.write_html('violationbarchart.html', config={ "displayModeBar" : False} )and here is the error:
ValueError: Invalid value of type 'builtins.float' received for the 'domain[0]' property of layout.yaxis Received value: 1.0038095238095237 The 'domain[0]' property is a number and may be specified as: - An int or float in the interval [0, 1]Is there a way to fix this? Or is it my code that have bugs? Thanks in advance!
nicolaskruchten commentedon Jun 9, 2020
@albertsugi-tallridge you're encountering bug #2556 and you can get around it by reducing your
vertical_spacingnicolaskruchten commentedon Jun 9, 2020
The reason this is breaking down is because Plotly Express' defaults are running afoul of the problem described in #2556... We'll have to solve it within Plotly Express, as we don't expose
vertical_spacingin the PX API, so PX needs to be smarter about how it sets things.nicolaskruchten commentedon Jul 16, 2020
In Plotly Express you can now (as of version 4.9) avoid this problem by using
facet_row_spacingandfacet_col_spacinghttps://plotly.com/python/facet-plots/#controlling-facet-spacingnicolaskruchten commentedon Jul 16, 2020
I'll close this issue when I finish #2556 and the error message will be clearer :)
albertsugi-tallridge commentedon Jul 16, 2020