镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

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

Closed

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]

Activity

  1. wookayin commented on Jan 12, 2020

    @wookayin

    Related to #1031, #1216. This bug still does present as of now (I am using plotly 4.4.1).

  2. hamzahiqb commented on Feb 4, 2020

    @hamzahiqb

    I get the same error (plotly 4.5.0). Were you able to find a workaround?

  3. albertsugi-tallridge commented on Feb 24, 2020

    @albertsugi-tallridge

    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!

  4. nicolaskruchten commented on Jun 9, 2020

    @nicolaskruchten
    Contributor

    @albertsugi-tallridge you're encountering bug #2556 and you can get around it by reducing your vertical_spacing

  5. nicolaskruchten commented on Jun 9, 2020

    @nicolaskruchten
    Contributor

    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_spacing in the PX API, so PX needs to be smarter about how it sets things.

  6. nicolaskruchten commented on Jul 16, 2020

    @nicolaskruchten
    Contributor

    In Plotly Express you can now (as of version 4.9) avoid this problem by using facet_row_spacing and facet_col_spacing https://plotly.com/python/facet-plots/#controlling-facet-spacing

  7. nicolaskruchten commented on Jul 16, 2020

    @nicolaskruchten
    Contributor

    I'll close this issue when I finish #2556 and the error message will be clearer :)

  8. added this to the 4.10 milestone on Jul 16, 2020
  9. albertsugi-tallridge commented on Jul 16, 2020

    @albertsugi-tallridge
  10. modified the milestones: 4.10, v4.x on Sep 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions