Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
natemcintosh opened this issue Jan 2, 2020 · 8 comments · Fixed by #2897
Closed

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

natemcintosh opened this issue Jan 2, 2020 · 8 comments · Fixed by #2897
Assignees
Milestone

Comments

@natemcintosh
Copy link

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]
@wookayin
Copy link

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

@hamzahiqb
Copy link

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

@albertsugi-tallridge
Copy link

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
Copy link
Contributor

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

@nicolaskruchten
Copy link
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.

@nicolaskruchten
Copy link
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

@nicolaskruchten
Copy link
Contributor

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

@nicolaskruchten nicolaskruchten added this to the 4.10 milestone Jul 16, 2020
@albertsugi-tallridge
Copy link

albertsugi-tallridge commented Jul 16, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants