iqplot 0.3.7__tar.gz → 0.3.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {iqplot-0.3.7 → iqplot-0.3.8}/.gitignore +3 -0
  2. iqplot-0.3.8/PKG-INFO +41 -0
  3. {iqplot-0.3.7 → iqplot-0.3.8}/iqplot/__init__.py +2 -2
  4. {iqplot-0.3.7 → iqplot-0.3.8}/iqplot/cat.py +125 -95
  5. {iqplot-0.3.7 → iqplot-0.3.8}/iqplot/dist.py +350 -192
  6. {iqplot-0.3.7 → iqplot-0.3.8}/iqplot/utils.py +76 -43
  7. iqplot-0.3.8/pyproject.toml +122 -0
  8. iqplot-0.3.8/test/test_plots.ipynb +2098 -0
  9. iqplot-0.3.7/PKG-INFO +0 -20
  10. iqplot-0.3.7/doc/.gitignore +0 -2
  11. iqplot-0.3.7/doc/Makefile +0 -20
  12. iqplot-0.3.7/doc/_static/custom.css +0 -44
  13. iqplot-0.3.7/doc/_static/logo.png +0 -0
  14. iqplot-0.3.7/doc/_templates/breadcrumbs.html +0 -42
  15. iqplot-0.3.7/doc/_templates/footer.html +0 -11
  16. iqplot-0.3.7/doc/_templates/layout.html +0 -8
  17. iqplot-0.3.7/doc/conf.py +0 -173
  18. iqplot-0.3.7/doc/credits_and_citation.rst +0 -28
  19. iqplot-0.3.7/doc/getting_started/installation.rst +0 -30
  20. iqplot-0.3.7/doc/getting_started/purpose.rst +0 -35
  21. iqplot-0.3.7/doc/index.rst +0 -29
  22. iqplot-0.3.7/doc/make.bat +0 -35
  23. iqplot-0.3.7/doc/user_guide/.gitignore +0 -2
  24. iqplot-0.3.7/doc/user_guide/api.rst +0 -18
  25. iqplot-0.3.7/doc/user_guide/holoviews.ipynb +0 -2988
  26. iqplot-0.3.7/doc/user_guide/omissions.ipynb +0 -1853
  27. iqplot-0.3.7/doc/user_guide/user_guide.ipynb +0 -2395
  28. iqplot-0.3.7/iqplot/.gitignore +0 -2
  29. iqplot-0.3.7/iqplot.egg-info/PKG-INFO +0 -20
  30. iqplot-0.3.7/iqplot.egg-info/SOURCES.txt +0 -34
  31. iqplot-0.3.7/iqplot.egg-info/dependency_links.txt +0 -1
  32. iqplot-0.3.7/iqplot.egg-info/requires.txt +0 -5
  33. iqplot-0.3.7/iqplot.egg-info/top_level.txt +0 -1
  34. iqplot-0.3.7/requirements.txt +0 -5
  35. iqplot-0.3.7/setup.cfg +0 -10
  36. iqplot-0.3.7/setup.py +0 -36
  37. {iqplot-0.3.7 → iqplot-0.3.8}/LICENSE +0 -0
  38. {iqplot-0.3.7 → iqplot-0.3.8}/README.md +0 -0
@@ -3,3 +3,6 @@ dist/
3
3
  iqplot.egg-info/
4
4
  sandbox/
5
5
  .DS_Store
6
+ .pixi/
7
+ *.egg-info/
8
+ __pycache__/
iqplot-0.3.8/PKG-INFO ADDED
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.5
2
+ Name: iqplot
3
+ Version: 0.3.8
4
+ Summary: Generate Bokeh plots for data sets with one quantitative variable.
5
+ Project-URL: Homepage, https://github.com/justinbois/iqplot
6
+ Project-URL: Documentation, http://iqplot.github.io/
7
+ Project-URL: Repository, https://github.com/justinbois/iqplot
8
+ Project-URL: Issues, https://github.com/justinbois/iqplot/issues
9
+ Author-email: Justin Bois <bois@caltech.edu>
10
+ Maintainer-email: Justin Bois <bois@caltech.edu>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: bokeh,box plot,ecdf,histogram,plotting,visualization
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Visualization
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: bokeh>=3.0
25
+ Requires-Dist: colorcet
26
+ Requires-Dist: numpy
27
+ Requires-Dist: pandas
28
+ Provides-Extra: data
29
+ Requires-Dist: polars; extra == 'data'
30
+ Requires-Dist: xarray; extra == 'data'
31
+ Provides-Extra: speedups
32
+ Requires-Dist: numba; extra == 'speedups'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # iqplot
36
+
37
+ [![DOI](https://data.caltech.edu/badge/DOI/10.22002/D1.20286.svg)](https://doi.org/10.22002/D1.20286)
38
+
39
+ A utility to use Bokeh to generate plots for data sets containing one quantitative variable and an arbitrary many categorical variables. It generates strip plots, box plots, histograms, and ECDFs.
40
+
41
+ Read the [documentation](http://iqplot.github.io/) for details.
@@ -1,10 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  """Top-level package for iqplot."""
4
+
4
5
  from .cat import *
5
6
  from .dist import *
6
7
 
7
-
8
8
  __author__ = """Justin Bois"""
9
9
  __email__ = "bois@caltech.edu"
10
- __version__ = "0.3.7"
10
+ __version__ = "0.3.8"
@@ -96,16 +96,15 @@ def strip(
96
96
  tooltips : list of 2-tuples
97
97
  Specification for tooltips as per Bokeh specifications. For
98
98
  example, if we want `col1` and `col2` tooltips, we can use
99
- `tooltips=[('label 1': '@col1'), ('label 2': '@col2')]`.
99
+ `tooltips=[('label 1', '@col1'), ('label 2', '@col2')]`.
100
100
  marker : str, default 'circle'
101
- Name of marker to be used in the plot (ignored if `formal` is
102
- False). Must be one of['asterisk', 'circle', 'circle_cross',
103
- 'circle_x', 'cross', 'dash', 'diamond', 'diamond_cross', 'hex',
104
- 'inverted_triangle', 'square', 'square_cross', 'square_x',
105
- 'triangle', 'x']
101
+ Name of marker to be used in the plot. Must be one of
102
+ ['asterisk', 'circle', 'circle_cross', 'circle_x', 'cross',
103
+ 'dash', 'diamond', 'diamond_cross', 'hex', 'inverted_triangle',
104
+ 'square', 'square_cross', 'square_x', 'triangle', 'x'].
106
105
  spread : str or None, default None
107
106
  If 'jitter', spread points out using a jitter transform. If
108
- 'swarm', spread points in beeswarm style. In None or 'none', do
107
+ 'swarm', spread points in beeswarm style. If None or 'none', do
109
108
  not spread.
110
109
  cat_grid : bool, default False
111
110
  If True, show grid lines for categorical axis.
@@ -125,9 +124,9 @@ def strip(
125
124
 
126
125
  - 'corral': Either 'gutter' (default) or 'wrap'. This
127
126
  specifies how points that are moved too far out are dealt
128
- with. Using 'gutter', points are overlayed at the maximum
127
+ with. Using 'gutter', points are overlaid at the maximum
129
128
  allowed distance. Using 'wrap', points are reflected inwards
130
- form the maximal extent and possibly overlayed with other
129
+ from the maximal extent and possibly overlaid with other
131
130
  points.
132
131
 
133
132
  - 'priority': Either 'ascending' (default) or 'descending'.
@@ -138,7 +137,8 @@ def strip(
138
137
  default 0.
139
138
  parcoord_kwargs : dict
140
139
  Keyword arguments to be passed to `p.line()` when making lines
141
- for kwargs. Default is to have one-pixel gray lines.
140
+ for the parallel coordinate plot. Default is to have one-pixel
141
+ gray lines.
142
142
  jitter : bool, default False
143
143
  Deprecated, use `spread`.
144
144
  horizontal : bool or None, default None
@@ -188,12 +188,12 @@ def strip(
188
188
  # Check spread
189
189
  if spread is not None:
190
190
  spread = spread.lower()
191
- if spread == 'beeswarm':
191
+ if spread == "beeswarm":
192
192
  raise RuntimeError("Did you mean `spread='swarm'`?")
193
- if spread not in ('swarm', 'jitter', 'none', None):
193
+ if spread not in ("swarm", "jitter", "none", None):
194
194
  raise RuntimeError(
195
195
  "Invalid `spread`. Valid choices are 'swarm', 'jitter', and None."
196
- )
196
+ )
197
197
 
198
198
  if spread is not None and spread != "none" and parcoord_column is not None:
199
199
  raise NotImplementedError(
@@ -209,6 +209,10 @@ def strip(
209
209
  else:
210
210
  show_legend = not _color_column_hexcodes(data, color_column)
211
211
 
212
+ # The legend for a strip plot comes from `color_column`, not `cats`,
213
+ # so only `order` is checked here.
214
+ utils._check_cats_none(cats, order)
215
+
212
216
  data, q, cats, show_legend = utils._data_cats(data, q, cats, show_legend, None)
213
217
  order = utils._order_to_str(order)
214
218
 
@@ -223,9 +227,9 @@ def strip(
223
227
  data, grouped, q, order, color_column, q_axis, kwargs
224
228
  )
225
229
  else:
226
- if type(p.x_range) == bokeh.models.ranges.FactorRange and q_axis == "x":
230
+ if isinstance(p.x_range, bokeh.models.ranges.FactorRange) and q_axis == "x":
227
231
  raise RuntimeError("`q_axis` is 'x', but `p` has a categorical x-axis.")
228
- elif type(p.y_range) == bokeh.models.ranges.FactorRange and q_axis == "y":
232
+ elif isinstance(p.y_range, bokeh.models.ranges.FactorRange) and q_axis == "y":
229
233
  raise RuntimeError("`q_axis` is 'y', but `p` has a categorical y-axis.")
230
234
 
231
235
  _, factors, color_factors = _get_cat_range(
@@ -237,7 +241,7 @@ def strip(
237
241
 
238
242
  if jitter_kwargs is None:
239
243
  jitter_kwargs = dict(width=0.1, mean=0, distribution="normal")
240
- elif type(jitter_kwargs) != dict:
244
+ elif not isinstance(jitter_kwargs, dict):
241
245
  raise RuntimeError("`jitter_kwargs` must be a dict.")
242
246
  elif "width" not in jitter_kwargs:
243
247
  if (
@@ -250,7 +254,7 @@ def strip(
250
254
 
251
255
  if swarm_kwargs is None:
252
256
  swarm_kwargs = dict(corral="gutter", priority="ascending", marker_pad_px=0)
253
- elif type(swarm_kwargs) != dict:
257
+ elif not isinstance(swarm_kwargs, dict):
254
258
  raise RuntimeError("`swarm_kwargs` must be a dict.")
255
259
  if "corral" not in swarm_kwargs:
256
260
  swarm_kwargs["corral"] = "gutter"
@@ -318,7 +322,11 @@ def strip(
318
322
  if spread == "swarm":
319
323
  r = (marker_kwargs["size"] + marker_kwargs["line_width"]) / 2
320
324
 
321
- if (q_axis == 'x' and 'x_axis_type' in kwargs and kwargs['x_axis_type'] == 'log') or (q_axis == 'y' and 'y_axis_type' in kwargs and kwargs['y_axis_type'] == 'log'):
325
+ if (
326
+ q_axis == "x" and "x_axis_type" in kwargs and kwargs["x_axis_type"] == "log"
327
+ ) or (
328
+ q_axis == "y" and "y_axis_type" in kwargs and kwargs["y_axis_type"] == "log"
329
+ ):
322
330
  log_q = True
323
331
  else:
324
332
  log_q = False
@@ -347,12 +355,13 @@ def strip(
347
355
  data[q].max() + 0.05 * q_range_width,
348
356
  ]
349
357
 
350
-
351
358
  swarm_transform = (
352
- grouped[q].transform(_swarm, p, r, q_range, q_axis, log_q, **swarm_kwargs).values
359
+ grouped[q]
360
+ .transform(_swarm, p, r, q_range, q_axis, log_q, **swarm_kwargs)
361
+ .values
353
362
  )
354
363
  source_dict["__swarm"] = [
355
- (*cat, y_val) if type(cat) == tuple else (cat, y_val)
364
+ (*cat, y_val) if isinstance(cat, tuple) else (cat, y_val)
356
365
  for cat, y_val in zip(source_dict["cat"], swarm_transform)
357
366
  ]
358
367
 
@@ -385,7 +394,7 @@ def strip(
385
394
  if parcoord_kwargs is None:
386
395
  line_color = "gray"
387
396
  parcoord_kwargs = {}
388
- elif type(parcoord_kwargs) != dict:
397
+ elif not isinstance(parcoord_kwargs, dict):
389
398
  raise RuntimeError("`parcoord_kwargs` must be a dict.")
390
399
 
391
400
  if "color" in parcoord_kwargs and "line_color" not in parcoord_kwargs:
@@ -431,21 +440,17 @@ def strip(
431
440
  title=color_column,
432
441
  )
433
442
  p.add_layout(legend, legend_location)
434
- elif (
435
- legend_location
436
- in [
437
- "top_left",
438
- "top_center",
439
- "top_right",
440
- "center_right",
441
- "bottom_right",
442
- "bottom_center",
443
- "bottom_left",
444
- "center_left",
445
- "center",
446
- ]
447
- or type(legend_location) == tuple
448
- ):
443
+ elif legend_location in [
444
+ "top_left",
445
+ "top_center",
446
+ "top_right",
447
+ "center_right",
448
+ "bottom_right",
449
+ "bottom_center",
450
+ "bottom_left",
451
+ "center_left",
452
+ "center",
453
+ ] or isinstance(legend_location, tuple):
449
454
  legend = bokeh.models.Legend(
450
455
  items=items,
451
456
  location=legend_location,
@@ -523,11 +528,10 @@ def box(
523
528
  suppress them. This should only be False when using the boxes
524
529
  as annotation on another plot.
525
530
  outlier_marker : str, default 'circle'
526
- Name of marker to be used in the plot (ignored if `formal` is
527
- False). Must be one of['asterisk', 'circle', 'circle_cross',
528
- 'circle_x', 'cross', 'dash', 'diamond', 'diamond_cross', 'hex',
529
- 'inverted_triangle', 'square', 'square_cross', 'square_x',
530
- 'triangle', 'x']
531
+ Name of marker to be used in the plot. Must be one of
532
+ ['asterisk', 'circle', 'circle_cross', 'circle_x', 'cross',
533
+ 'dash', 'diamond', 'diamond_cross', 'hex', 'inverted_triangle',
534
+ 'square', 'square_cross', 'square_x', 'triangle', 'x'].
531
535
  min_data : int, default 5
532
536
  Minimum number of data points in a given category in order to
533
537
  make a box and whisker. Otherwise, individual data points are
@@ -546,12 +550,14 @@ def box(
546
550
  outlier_kwargs : dict, default None
547
551
  A dictionary of kwargs to be passed into `p.scatter()`
548
552
  when constructing the outliers for the box plot.
553
+ display_outliers : bool, default None
554
+ Deprecated. Use `display_points`.
549
555
  horizontal : bool or None, default None
550
556
  Deprecated. Use `q_axis`.
551
557
  val : hashable
552
558
  Deprecated, use `q`.
553
559
  kwargs
554
- Kwargs that are passed to bokeh.plotting.figure() in contructing
560
+ Kwargs that are passed to bokeh.plotting.figure() in constructing
555
561
  the figure.
556
562
 
557
563
  Returns
@@ -590,6 +596,9 @@ def box(
590
596
  if palette is None:
591
597
  palette = colorcet.b_glasbey_category10
592
598
 
599
+ # A box plot has no legend, so only `order` is checked here.
600
+ utils._check_cats_none(cats, order)
601
+
593
602
  data, q, cats, _ = utils._data_cats(data, q, cats, False, None)
594
603
  order = utils._order_to_str(order)
595
604
 
@@ -599,13 +608,13 @@ def box(
599
608
 
600
609
  if outlier_kwargs is None:
601
610
  outlier_kwargs = dict()
602
- elif type(outlier_kwargs) != dict:
611
+ elif not isinstance(outlier_kwargs, dict):
603
612
  raise RuntimeError("`outlier_kwargs` must be a dict.")
604
613
 
605
614
  if box_kwargs is None:
606
615
  box_kwargs = {"line_color": None}
607
616
  box_width = 0.4
608
- elif type(box_kwargs) != dict:
617
+ elif not isinstance(box_kwargs, dict):
609
618
  raise RuntimeError("`box_kwargs` must be a dict.")
610
619
  else:
611
620
  box_width = box_kwargs.pop("width", 0.4)
@@ -614,14 +623,16 @@ def box(
614
623
 
615
624
  if whisker_kwargs is None:
616
625
  whisker_kwargs = {"line_color": "black"}
617
- elif type(whisker_kwargs) != dict:
626
+ elif not isinstance(whisker_kwargs, dict):
618
627
  raise RuntimeError("`whisker_kwargs` must be a dict.")
628
+ elif "line_color" not in whisker_kwargs and "color" not in whisker_kwargs:
629
+ whisker_kwargs["line_color"] = "black"
619
630
 
620
631
  if median_kwargs is None:
621
632
  median_kwargs = {"line_color": "white"}
622
- elif type(median_kwargs) != dict:
633
+ elif not isinstance(median_kwargs, dict):
623
634
  raise RuntimeError("`median_kwargs` must be a dict.")
624
- elif "line_color" not in median_kwargs:
635
+ elif "color" not in median_kwargs and "line_color" not in median_kwargs:
625
636
  median_kwargs["line_color"] = "white"
626
637
 
627
638
  if q_axis == "x":
@@ -723,7 +734,9 @@ def box(
723
734
  **median_kwargs,
724
735
  )
725
736
  if display_points:
726
- p.scatter(source=source_outliers, y="cat", x=q, marker=marker, **outlier_kwargs)
737
+ p.scatter(
738
+ source=source_outliers, y="cat", x=q, marker=marker, **outlier_kwargs
739
+ )
727
740
  if not cat_grid:
728
741
  p.ygrid.grid_line_color = None
729
742
  else:
@@ -777,7 +790,9 @@ def box(
777
790
  **median_kwargs,
778
791
  )
779
792
  if display_points:
780
- p.scatter(source=source_outliers, x="cat", y=q, marker=marker, **outlier_kwargs)
793
+ p.scatter(
794
+ source=source_outliers, x="cat", y=q, marker=marker, **outlier_kwargs
795
+ )
781
796
  if not cat_grid:
782
797
  p.xgrid.grid_line_color = None
783
798
 
@@ -808,7 +823,6 @@ def stripbox(
808
823
  swarm_kwargs=None,
809
824
  parcoord_kwargs=None,
810
825
  whisker_caps=True,
811
- display_points=True,
812
826
  min_data=5,
813
827
  box_kwargs=None,
814
828
  median_kwargs=None,
@@ -880,16 +894,15 @@ def stripbox(
880
894
  tooltips : list of 2-tuples
881
895
  Specification for tooltips as per Bokeh specifications. For
882
896
  example, if we want `col1` and `col2` tooltips, we can use
883
- `tooltips=[('label 1': '@col1'), ('label 2': '@col2')]`.
897
+ `tooltips=[('label 1', '@col1'), ('label 2', '@col2')]`.
884
898
  marker : str, default 'circle'
885
- Name of marker to be used in the plot (ignored if `formal` is
886
- False). Must be one of['asterisk', 'circle', 'circle_cross',
887
- 'circle_x', 'cross', 'dash', 'diamond', 'diamond_cross', 'hex',
888
- 'inverted_triangle', 'square', 'square_cross', 'square_x',
889
- 'triangle', 'x']
899
+ Name of marker to be used in the plot. Must be one of
900
+ ['asterisk', 'circle', 'circle_cross', 'circle_x', 'cross',
901
+ 'dash', 'diamond', 'diamond_cross', 'hex', 'inverted_triangle',
902
+ 'square', 'square_cross', 'square_x', 'triangle', 'x'].
890
903
  spread : str or None, default None
891
904
  If 'jitter', spread points out using a jitter transform. If
892
- 'swarm', spread points in beeswarm style. In None or 'none', do
905
+ 'swarm', spread points in beeswarm style. If None or 'none', do
893
906
  not spread.
894
907
  cat_grid : bool, default False
895
908
  If True, display grid line for categorical axis.
@@ -909,9 +922,9 @@ def stripbox(
909
922
 
910
923
  - 'corral': Either 'gutter' (default) or 'wrap'. This
911
924
  specifies how points that are moved too far out are dealt
912
- with. Using 'gutter', points are overlayed at the maximum
925
+ with. Using 'gutter', points are overlaid at the maximum
913
926
  allowed distance. Using 'wrap', points are reflected inwards
914
- form the maximal extent and possibly overlayed with other
927
+ from the maximal extent and possibly overlaid with other
915
928
  points.
916
929
 
917
930
  - 'priority': Either 'ascending' (default) or 'descending'.
@@ -922,7 +935,8 @@ def stripbox(
922
935
  default 0.
923
936
  parcoord_kwargs : dict
924
937
  Keyword arguments to be passed to `p.line()` when making lines
925
- for kwargs. Default is to have one-pixel gray lines.
938
+ for the parallel coordinate plot. Default is to have one-pixel
939
+ gray lines.
926
940
  whisker_caps : bool, default True
927
941
  If True, put caps on whiskers. If False, omit caps.
928
942
  min_data : int, default 5
@@ -955,6 +969,10 @@ def stripbox(
955
969
  output : bokeh.plotting.Figure instance
956
970
  Plot populated with a strip-box plot.
957
971
  """
972
+ # display_points not allowed in kwargs
973
+ if "display_points" in kwargs:
974
+ raise ValueError("display_points not allowed as a kwarg for stripbox.")
975
+
958
976
  # Protect against mutability of dicts
959
977
  box_kwargs = copy.copy(box_kwargs)
960
978
  median_kwargs = copy.copy(median_kwargs)
@@ -976,12 +994,12 @@ def stripbox(
976
994
 
977
995
  if median_kwargs is None:
978
996
  median_kwargs = dict(line_color="gray")
979
- if "color" not in box_kwargs and "line_color" not in median_kwargs:
997
+ if "color" not in median_kwargs and "line_color" not in median_kwargs:
980
998
  median_kwargs["line_color"] = "gray"
981
999
 
982
1000
  if whisker_kwargs is None:
983
1001
  whisker_kwargs = dict(line_color="gray")
984
- if "color" not in box_kwargs and "line_color" not in whisker_kwargs:
1002
+ if "color" not in whisker_kwargs and "line_color" not in whisker_kwargs:
985
1003
  whisker_kwargs["line_color"] = "gray"
986
1004
 
987
1005
  if top_level == "box":
@@ -1157,7 +1175,7 @@ def striphistogram(
1157
1175
  If None, create a new figure. Otherwise, populate the existing
1158
1176
  figure `p`.
1159
1177
  top_level : str, default 'strip'
1160
- If 'histogram', the histogram is overlaid. If 'strip', the strip\
1178
+ If 'histogram', the histogram is overlaid. If 'strip', the strip
1161
1179
  plot is overlaid.
1162
1180
  show_legend : bool, default False
1163
1181
  If True, display legend.
@@ -1187,20 +1205,21 @@ def striphistogram(
1187
1205
  tooltips : list of 2-tuples
1188
1206
  Specification for tooltips as per Bokeh specifications. For
1189
1207
  example, if we want `col1` and `col2` tooltips, we can use
1190
- `tooltips=[('label 1': '@col1'), ('label 2': '@col2')]`.
1208
+ `tooltips=[('label 1', '@col1'), ('label 2', '@col2')]`.
1191
1209
  marker : str, default 'circle'
1192
- Name of marker to be used in the plot (ignored if `formal` is
1193
- False). Must be one of['asterisk', 'circle', 'circle_cross',
1194
- 'circle_x', 'cross', 'dash', 'diamond', 'diamond_cross', 'hex',
1195
- 'inverted_triangle', 'square', 'square_cross', 'square_x',
1196
- 'triangle', 'x']
1197
- jitter : bool, default False
1198
- If True, apply a jitter transform to the glyphs.
1210
+ Name of marker to be used in the plot. Must be one of
1211
+ ['asterisk', 'circle', 'circle_cross', 'circle_x', 'cross',
1212
+ 'dash', 'diamond', 'diamond_cross', 'hex', 'inverted_triangle',
1213
+ 'square', 'square_cross', 'square_x', 'triangle', 'x'].
1214
+ spread : str or None, default None
1215
+ If 'jitter', spread points out using a jitter transform. If
1216
+ 'swarm', spread points in beeswarm style. If None or 'none', do
1217
+ not spread.
1199
1218
  cat_grid : bool, default True
1200
1219
  If True, display grid line for categorical axis.
1201
1220
  marker_kwargs : dict
1202
1221
  Keyword arguments to pass when adding markers to the plot.
1203
- ["x", "y", "source", "marker", "cat", "legend"] are note allowed
1222
+ ["x", "y", "source", "marker", "cat", "legend"] are not allowed
1204
1223
  because they are determined by other inputs.
1205
1224
  jitter_kwargs : dict
1206
1225
  Keyword arguments to be passed to `bokeh.transform.jitter()`. If
@@ -1214,9 +1233,9 @@ def striphistogram(
1214
1233
 
1215
1234
  - 'corral': Either 'gutter' (default) or 'wrap'. This
1216
1235
  specifies how points that are moved too far out are dealt
1217
- with. Using 'gutter', points are overlayed at the maximum
1236
+ with. Using 'gutter', points are overlaid at the maximum
1218
1237
  allowed distance. Using 'wrap', points are reflected inwards
1219
- form the maximal extent and possibly overlayed with other
1238
+ from the maximal extent and possibly overlaid with other
1220
1239
  points.
1221
1240
 
1222
1241
  - 'priority': Either 'ascending' (default) or 'descending'.
@@ -1227,7 +1246,8 @@ def striphistogram(
1227
1246
  default 0.
1228
1247
  parcoord_kwargs : dict
1229
1248
  Keyword arguments to be passed to `p.line()` when making lines
1230
- for kwargs. Default is to have one-pixel gray lines.
1249
+ for the parallel coordinate plot. Default is to have one-pixel
1250
+ gray lines.
1231
1251
  bins : int, array_like, or str, default 'freedman-diaconis'
1232
1252
  If int or array_like, setting for `bins` kwarg to be passed to
1233
1253
  `np.histogram()`. If 'exact', then each unique value in the
@@ -1237,17 +1257,17 @@ def striphistogram(
1237
1257
  `freedman-diaconis`, uses the Freedman-Diaconis rule for number
1238
1258
  of bins.
1239
1259
  style : None or one of ['step', 'step_filled']
1240
- Default for overlayed histograms is 'step' and for stacked
1241
- histograms 'step_filled'. The exception is when `cont_int` is
1260
+ Default for overlaid histograms is 'step' and for stacked
1261
+ histograms 'step_filled'. The exception is when `conf_int` is
1242
1262
  True, in which case `style` must be 'step'.
1243
1263
  mirror : bool, default True
1244
1264
  If True, reflect the histogram through zero.
1245
1265
  hist_height : float, default 0.75
1246
- Maximal height of histogram of its confidence interval as a
1266
+ Maximal height of histogram or its confidence interval as a
1247
1267
  fraction of available height along categorical axis. Only active
1248
1268
  when `arrangement` is 'stack'.
1249
1269
  conf_int : bool, default False
1250
- If True, display confidence interval of ECDF.
1270
+ If True, display confidence interval of the histogram.
1251
1271
  ptiles : list, default (2.5, 97.5)
1252
1272
  The percentiles to use for the confidence interval of the
1253
1273
  histogram. Ignored if `conf_int` is False.
@@ -1262,6 +1282,8 @@ def striphistogram(
1262
1282
  for the step-filled histogram or confidence intervals. Ignored
1263
1283
  if `style = 'step'` and `conf_int` is False. By default
1264
1284
  {"fill_alpha": 0.3, "line_alpha": 0}.
1285
+ jitter : bool, default False
1286
+ Deprecated, use `spread`.
1265
1287
  horizontal : bool or None, default None
1266
1288
  Deprecated. Use `q_axis`.
1267
1289
  val : hashable
@@ -1434,7 +1456,7 @@ def _get_cat_range(df, grouped, order, color_column, q_axis):
1434
1456
  else:
1435
1457
  factors = tuple([str(key) for key in grouped.groups.keys()])
1436
1458
  else:
1437
- if type(order[0]) in [list, tuple]:
1459
+ if isinstance(order[0], (list, tuple)):
1438
1460
  factors = tuple([tuple([str(k) for k in key]) for key in order])
1439
1461
  else:
1440
1462
  factors = tuple([str(entry) for entry in order])
@@ -1455,7 +1477,7 @@ def _get_cat_range(df, grouped, order, color_column, q_axis):
1455
1477
 
1456
1478
 
1457
1479
  def _color_column_hexcodes(df, color_column):
1458
- """Return True of the color column consists of all hex codes"""
1480
+ """Return True if the color column consists of all hex codes."""
1459
1481
  try:
1460
1482
  return df[color_column].str.match(r"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$").all()
1461
1483
  except:
@@ -1494,7 +1516,7 @@ def _cat_figure(df, grouped, q, order, color_column, q_axis, kwargs):
1494
1516
  def _cat_source_dict(df, cats, cols, color_column):
1495
1517
  cat_source, labels = utils._source_and_labels_from_cats(df, cats)
1496
1518
 
1497
- if type(cols) in [list, tuple, pd.core.indexes.base.Index]:
1519
+ if isinstance(cols, (list, tuple, pd.Index)):
1498
1520
  source_dict = {col: list(df[col].values) for col in cols}
1499
1521
  else:
1500
1522
  source_dict = {cols: list(df[cols].values)}
@@ -1510,7 +1532,7 @@ def _cat_source_dict(df, cats, cols, color_column):
1510
1532
 
1511
1533
 
1512
1534
  def _parcoord_source(data, q, cats, q_axis, parcoord_column, factors):
1513
- if type(cats) not in [list, tuple]:
1535
+ if not isinstance(cats, (list, tuple)):
1514
1536
  cats = [cats]
1515
1537
  tuple_factors = False
1516
1538
  else:
@@ -1629,7 +1651,7 @@ def _box_source(df, cats, q, cols, min_data):
1629
1651
 
1630
1652
 
1631
1653
  def _out_every_interval(y, intervals, epsilon=1e-6):
1632
- """Check to see if a value `y` list outside every interval in a
1654
+ """Check to see if a value `y` lies outside every interval in a
1633
1655
  list of 2-tuples `intervals`."""
1634
1656
  for interval in intervals:
1635
1657
  if y > interval[0] + epsilon and y < interval[1] - epsilon:
@@ -1654,7 +1676,7 @@ def _swarm_px(
1654
1676
  Parameters
1655
1677
  ----------
1656
1678
  x : array_like
1657
- Array of values of quantitative varaible.
1679
+ Array of values of quantitative variable.
1658
1680
  frame_width : int or float
1659
1681
  Width of plot frame in pixels.
1660
1682
  r : float
@@ -1667,14 +1689,14 @@ def _swarm_px(
1667
1689
  the quantitative axis.
1668
1690
  max_y_px : float, default np.inf
1669
1691
  Maximum allowed displacement. Any points with computed y-values
1670
- beyond this will be corraled.
1692
+ beyond this will be corralled.
1671
1693
  corral : str, default 'gutter'
1672
1694
  Either 'gutter' or 'wrap'. How to corral points beyond the
1673
1695
  maximum displacement.
1674
- priority : str, either
1696
+ priority : str, default 'ascending'
1675
1697
  Sort order when determining which points get moved in the
1676
1698
  y-direction first. Either 'ascending' or 'descending'.
1677
- marker_pad_px : int of float
1699
+ marker_pad_px : int or float
1678
1700
  Gap between markers in units of pixels.
1679
1701
 
1680
1702
  Returns
@@ -1709,7 +1731,7 @@ def _swarm_px(
1709
1731
  else:
1710
1732
  continue
1711
1733
  if y_pixels[j] < np.inf:
1712
- offset = np.sqrt(4 * r ** 2 - dist ** 2) + marker_pad_px
1734
+ offset = np.sqrt(4 * r**2 - dist**2) + marker_pad_px
1713
1735
  intervals.append([y_pixels[j] - offset, y_pixels[j] + offset])
1714
1736
 
1715
1737
  # Scan points to the left
@@ -1721,11 +1743,11 @@ def _swarm_px(
1721
1743
  else:
1722
1744
  continue
1723
1745
  if y_pixels[j] < np.inf:
1724
- offset = np.sqrt(4 * r ** 2 - dist ** 2) + marker_pad_px
1746
+ offset = np.sqrt(4 * r**2 - dist**2) + marker_pad_px
1725
1747
  intervals.append([y_pixels[j] - offset, y_pixels[j] + offset])
1726
1748
 
1727
1749
  # Any y-position must be outside all intervals and should be at the edge of one of the intervals
1728
- # Need to find first candidate the satisfies this
1750
+ # Need to find the first candidate that satisfies this
1729
1751
  y_cand = 0
1730
1752
  if len(intervals) > 0:
1731
1753
  candidates = sorted(np.array(intervals).flatten(), key=abs)
@@ -1754,11 +1776,19 @@ def _swarm_px(
1754
1776
 
1755
1777
 
1756
1778
  def _swarm(
1757
- x, p, r, x_range, q_axis, log_q, corral="gutter", priority="ascending", marker_pad_px=0
1779
+ x,
1780
+ p,
1781
+ r,
1782
+ x_range,
1783
+ q_axis,
1784
+ log_q,
1785
+ corral="gutter",
1786
+ priority="ascending",
1787
+ marker_pad_px=0,
1758
1788
  ):
1759
1789
  if q_axis == "x":
1760
1790
  extra_padding = 0
1761
- if type(p.y_range.factors[0]) == tuple:
1791
+ if isinstance(p.y_range.factors[0], tuple):
1762
1792
  if len(p.y_range.factors[0]) >= 2:
1763
1793
  extra_padding += p.y_range.group_padding
1764
1794
  if len(p.y_range.factors[0]) > 2:
@@ -1770,7 +1800,7 @@ def _swarm(
1770
1800
  n_factors = len(p.y_range.factors) + extra_padding
1771
1801
  else:
1772
1802
  extra_padding = 0
1773
- if type(p.x_range.factors[0]) == tuple:
1803
+ if isinstance(p.x_range.factors[0], tuple):
1774
1804
  if len(p.x_range.factors[0]) >= 2:
1775
1805
  extra_padding += p.x_range.group_padding
1776
1806
  if len(p.x_range.factors[0]) > 2: