@@ -660,6 +660,12 @@ def configure_cartesian_axes(args, fig, orders):
660
660
if "is_timeline" in args :
661
661
fig .update_xaxes (type = "date" )
662
662
663
+ if "ecdfmode" in args :
664
+ if args ["orientation" ] == "v" :
665
+ fig .update_yaxes (rangemode = "tozero" )
666
+ else :
667
+ fig .update_xaxes (rangemode = "tozero" )
668
+
663
669
664
670
def configure_ternary_axes (args , fig , orders ):
665
671
fig .update_ternaries (
@@ -1313,7 +1319,7 @@ def build_dataframe(args, constructor):
1313
1319
value_name = None # will likely be "value" in wide_mode
1314
1320
hist2d_types = [go .Histogram2d , go .Histogram2dContour ]
1315
1321
hist1d_orientation = (
1316
- constructor == go .Histogram or "complementary " in args or "kernel" in args
1322
+ constructor == go .Histogram or "ecdfmode " in args or "kernel" in args
1317
1323
)
1318
1324
if constructor in cartesians :
1319
1325
if wide_x and wide_y :
@@ -1802,11 +1808,15 @@ def infer_config(args, constructor, trace_patch, layout_patch):
1802
1808
if (
1803
1809
"line_group" in args or "line_dash" in args
1804
1810
): # px.line, px.line_*, px.area, px.ecdf, px, kde
1805
- modes = set (["lines" ])
1811
+ modes = set ()
1812
+ if args .get ("lines" , True ):
1813
+ modes .add ("lines" )
1806
1814
if args .get ("text" ) or args .get ("symbol" ) or args .get ("markers" ):
1807
1815
modes .add ("markers" )
1808
1816
if args .get ("text" ):
1809
1817
modes .add ("text" )
1818
+ if len (modes ) == 0 :
1819
+ modes .add ("lines" )
1810
1820
trace_patch ["mode" ] = "+" .join (modes )
1811
1821
elif constructor != go .Splom and (
1812
1822
"symbol" in args or constructor == go .Scattermapbox
@@ -1856,13 +1866,13 @@ def infer_config(args, constructor, trace_patch, layout_patch):
1856
1866
if "trendline_options" in args and args ["trendline_options" ] is None :
1857
1867
args ["trendline_options" ] = dict ()
1858
1868
1859
- if "norm " in args :
1860
- if args .get ("norm " , None ) not in [None , "percent" , "probability" ]:
1869
+ if "ecdfnorm " in args :
1870
+ if args .get ("ecdfnorm " , None ) not in [None , "percent" , "probability" ]:
1861
1871
raise ValueError (
1862
- "`norm ` must be one of None, 'percent' or 'probability'. "
1863
- + "'%s' was provided." % args ["norm " ]
1872
+ "`ecdfnorm ` must be one of None, 'percent' or 'probability'. "
1873
+ + "'%s' was provided." % args ["ecdfnorm " ]
1864
1874
)
1865
- args ["histnorm" ] = args ["norm " ]
1875
+ args ["histnorm" ] = args ["ecdfnorm " ]
1866
1876
1867
1877
# Compute applicable grouping attributes
1868
1878
for k in group_attrables :
@@ -2078,18 +2088,22 @@ def make_figure(args, constructor, trace_patch=None, layout_patch=None):
2078
2088
):
2079
2089
trace .update (marker = dict (color = trace .line .color ))
2080
2090
2081
- if "complementary " in args : # ECDF
2091
+ if "ecdfmode " in args :
2082
2092
base = args ["x" ] if args ["orientation" ] == "v" else args ["y" ]
2083
2093
var = args ["x" ] if args ["orientation" ] == "h" else args ["y" ]
2084
- group = group .sort_values (by = base )
2085
- group_sum = group [var ].sum ()
2094
+ ascending = args .get ("ecdfmode" , "standard" ) != "reversed"
2095
+ group = group .sort_values (by = base , ascending = ascending )
2096
+ group_sum = group [var ].sum () # compute here before next line mutates
2086
2097
group [var ] = group [var ].cumsum ()
2087
- if args ["complementary" ]:
2098
+ if not ascending :
2099
+ group = group .sort_values (by = base , ascending = True )
2100
+
2101
+ if args .get ("ecdfmode" , "standard" ) == "complementary" :
2088
2102
group [var ] = group_sum - group [var ]
2089
2103
2090
- if args ["norm " ] == "probability" :
2104
+ if args ["ecdfnorm " ] == "probability" :
2091
2105
group [var ] = group [var ] / group_sum
2092
- elif args ["norm " ] == "percent" :
2106
+ elif args ["ecdfnorm " ] == "percent" :
2093
2107
group [var ] = 100.0 * group [var ] / group_sum
2094
2108
2095
2109
patch , fit_results = make_trace_kwargs (
0 commit comments