Skip to content

plotly express scatter with more than ~34 facet rows breaks #2026

Closed
@natemcintosh

Description

@natemcintosh

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]

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions