lets-plot 4.7.2rc1__cp39-cp39-win_amd64.whl → 4.8.0rc1__cp39-cp39-win_amd64.whl

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.

Potentially problematic release.


This version of lets-plot might be problematic. Click here for more details.

Files changed (29) hide show
  1. lets_plot/__init__.py +1 -1
  2. lets_plot/_version.py +1 -1
  3. lets_plot/bistro/_plot2d_common.py +6 -0
  4. lets_plot/bistro/joint.py +4 -4
  5. lets_plot/bistro/residual.py +1 -1
  6. lets_plot/export/ggsave_.py +35 -18
  7. lets_plot/package_data/lets-plot.min.js +1 -1
  8. lets_plot/plot/core.py +38 -7
  9. lets_plot/plot/facet.py +3 -3
  10. lets_plot/plot/geom.py +295 -16
  11. lets_plot/plot/geom_livemap_.py +8 -0
  12. lets_plot/plot/gggrid_.py +20 -7
  13. lets_plot/plot/ggtb_.py +28 -2
  14. lets_plot/plot/label.py +1 -1
  15. lets_plot/plot/pos.py +32 -8
  16. lets_plot/plot/scale_identity_.py +20 -16
  17. lets_plot/plot/theme_.py +18 -10
  18. lets_plot/plot/theme_set.py +39 -15
  19. lets_plot/plot/tooltip.py +1 -1
  20. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/METADATA +10 -6
  21. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/RECORD +29 -29
  22. lets_plot_kotlin_bridge.cp39-win_amd64.pyd +0 -0
  23. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/WHEEL +0 -0
  24. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/licenses/LICENSE +0 -0
  25. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/licenses/licenses/LICENSE.FreeType +0 -0
  26. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/licenses/licenses/LICENSE.ImageMagick +0 -0
  27. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/licenses/licenses/LICENSE.expat +0 -0
  28. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/licenses/licenses/LICENSE.fontconfig +0 -0
  29. {lets_plot-4.7.2rc1.dist-info → lets_plot-4.8.0rc1.dist-info}/top_level.txt +0 -0
lets_plot/plot/core.py CHANGED
@@ -19,8 +19,12 @@ def aes(x=None, y=None, **kwargs):
19
19
  Parameters
20
20
  ----------
21
21
  x, y, ... :
22
- List of name value pairs giving aesthetics to map to variables.
22
+ Aesthetic mappings. Name-value pairs specifying which data variables to use for each aesthetic.
23
23
  The names for x and y aesthetics are typically omitted because they are so common; all other aesthetics must be named.
24
+ The specific list of supported aesthetics differs by geometry type.
25
+ group : str or list, optional
26
+ Data grouping control (not a true aesthetic). Use a variable name to group by that variable,
27
+ a list of variables to group by their interaction, or an empty list to disable all grouping.
24
28
 
25
29
  Returns
26
30
  -------
@@ -33,11 +37,25 @@ def aes(x=None, y=None, **kwargs):
33
37
  (aesthetics) of geometries. This function also standardizes aesthetic names by, for example, converting
34
38
  colour to color.
35
39
 
36
- Aesthetic mappings are not to be confused with aesthetic settings; the latter are used to set aesthetics to
37
- some constant values, e.g. make all points red in the plot. If one wants to make the color of a point
40
+ Aesthetic mappings are not to be confused with aesthetic settings; the latter is used to set aesthetics to
41
+ some constant values, e.g., make all points red in the plot. If one wants to make the color of a point
38
42
  depend on the value of a variable, he/she should project this variable to the color aesthetic via
39
43
  aesthetic mapping.
40
44
 
45
+ **Data Grouping**
46
+
47
+ The ``group`` parameter is not a true aesthetic but controls how data is grouped for visualization:
48
+
49
+ Default Grouping Behavior:
50
+ Lets-Plot automatically groups data by discrete variables mapped to aesthetics like ``color``, ``shape``,
51
+ ``linetype``, etc. This creates separate visual elements (lines, paths, polygons) for each unique
52
+ combination of these variables.
53
+
54
+ Explicit Group Control:
55
+ - Use ``group='variable_name'`` to group only by that specific variable, overriding default grouping
56
+ - Use ``group=['var1', 'var2', ...]`` to group by the interaction of multiple variables
57
+ - Use ``group=[]`` to disable all the grouping completely
58
+
41
59
  Examples
42
60
  --------
43
61
  .. jupyter-execute::
@@ -477,6 +495,8 @@ class PlotSpec(FeatureSpec):
477
495
  """
478
496
  Export the plot in SVG format.
479
497
 
498
+ Plots containing ``geom_livemap()`` are not supported.
499
+
480
500
  Parameters
481
501
  ----------
482
502
  self : ``PlotSpec``
@@ -503,18 +523,20 @@ class PlotSpec(FeatureSpec):
503
523
  --------
504
524
  .. jupyter-execute::
505
525
  :linenos:
506
- :emphasize-lines: 9
526
+ :emphasize-lines: 10
507
527
 
508
528
  import numpy as np
509
529
  import io
510
530
  from lets_plot import *
511
531
  from IPython import display
512
532
  LetsPlot.setup_html()
533
+ np.random.seed(42)
513
534
  x = np.random.randint(10, size=100)
514
535
  p = ggplot({'x': x}, aes(x='x')) + geom_bar()
515
536
  file_like = io.BytesIO()
516
537
  p.to_svg(file_like)
517
538
  display.SVG(file_like.getvalue())
539
+
518
540
  """
519
541
  return _to_svg(self, path, w=w, h=h, unit=unit)
520
542
 
@@ -544,16 +566,20 @@ class PlotSpec(FeatureSpec):
544
566
  --------
545
567
  .. jupyter-execute::
546
568
  :linenos:
547
- :emphasize-lines: 8
569
+ :emphasize-lines: 10
548
570
 
549
- import numpy as np
550
571
  import io
572
+ from IPython.display import HTML
573
+ import numpy as np
551
574
  from lets_plot import *
552
575
  LetsPlot.setup_html()
576
+ np.random.seed(42)
553
577
  x = np.random.randint(10, size=100)
554
578
  p = ggplot({'x': x}, aes(x='x')) + geom_bar()
555
579
  file_like = io.BytesIO()
556
580
  p.to_html(file_like)
581
+ HTML(file_like.getvalue().decode('utf-8'))
582
+
557
583
  """
558
584
  return _to_html(self, path, iframe)
559
585
 
@@ -561,6 +587,8 @@ class PlotSpec(FeatureSpec):
561
587
  """
562
588
  Export a plot to a file or to a file-like object in PNG format.
563
589
 
590
+ Plots containing ``geom_livemap()`` are not supported.
591
+
564
592
  Parameters
565
593
  ----------
566
594
  self : ``PlotSpec``
@@ -622,13 +650,14 @@ class PlotSpec(FeatureSpec):
622
650
  --------
623
651
  .. jupyter-execute::
624
652
  :linenos:
625
- :emphasize-lines: 9
653
+ :emphasize-lines: 10
626
654
 
627
655
  import numpy as np
628
656
  import io
629
657
  from lets_plot import *
630
658
  from IPython import display
631
659
  LetsPlot.setup_html()
660
+ np.random.seed(42)
632
661
  x = np.random.randint(10, size=100)
633
662
  p = ggplot({'x': x}, aes(x='x')) + geom_bar()
634
663
  file_like = io.BytesIO()
@@ -642,6 +671,8 @@ class PlotSpec(FeatureSpec):
642
671
  """
643
672
  Export a plot to a file or to a file-like object in PDF format.
644
673
 
674
+ Plots containing ``geom_livemap()`` are not supported.
675
+
645
676
  Parameters
646
677
  ----------
647
678
  self : ``PlotSpec``
lets_plot/plot/facet.py CHANGED
@@ -38,11 +38,11 @@ def facet_grid(x=None, y=None, *, scales=None, x_order=1, y_order=1,
38
38
  Specify the format pattern for displaying faceting values in rows.
39
39
  x_labwidth : int, default=None
40
40
  The maximum label length (in characters) before a line breaking is applied.
41
- If the original facet label already contains ``\\\\n`` as a text separator, it splits at those points first,
41
+ If the original facet label already contains ``\\n`` as a text separator, it splits at those points first,
42
42
  then wraps each part according to ``x_labwidth``.
43
43
  y_labwidth : int, default=None
44
44
  The maximum label length (in characters) before a line breaking is applied.
45
- If the original facet label already contains ``\\\\n`` as a text separator, it splits at those points first,
45
+ If the original facet label already contains ``\\n`` as a text separator, it splits at those points first,
46
46
  then wraps each part according to ``y_labwidth``.
47
47
 
48
48
  Returns
@@ -138,7 +138,7 @@ def facet_wrap(facets, ncol=None, nrow=None, *, scales=None, order=1, format=Non
138
138
  Direction: either 'h' for horizontal or 'v' for vertical.
139
139
  labwidth : int or list
140
140
  The maximum label length (in characters) before a line breaking is applied.
141
- If the original facet label already contains ``\\\\n`` as a text separator, it splits at those points first,
141
+ If the original facet label already contains ``\\n`` as a text separator, it splits at those points first,
142
142
  then wraps each part according to ``labwidth``.
143
143
 
144
144
 
lets_plot/plot/geom.py CHANGED
@@ -22,7 +22,7 @@ __all__ = ['geom_point', 'geom_path', 'geom_line',
22
22
  'geom_boxplot', 'geom_violin', 'geom_sina', 'geom_ydotplot',
23
23
  'geom_area_ridges',
24
24
  'geom_ribbon', 'geom_area', 'geom_density',
25
- 'geom_density2d', 'geom_density2df', 'geom_jitter',
25
+ 'geom_density2d', 'geom_density2df', 'geom_pointdensity', 'geom_jitter',
26
26
  'geom_qq', 'geom_qq2', 'geom_qq_line', 'geom_qq2_line',
27
27
  'geom_freqpoly', 'geom_step', 'geom_rect',
28
28
  'geom_segment', 'geom_curve', 'geom_spoke',
@@ -510,21 +510,48 @@ def geom_line(mapping=None, *, data=None, stat=None, position=None, show_legend=
510
510
 
511
511
  .. jupyter-execute::
512
512
  :linenos:
513
- :emphasize-lines: 12-13
513
+ :emphasize-lines: 11-12
514
514
 
515
515
  import numpy as np
516
516
  import pandas as pd
517
517
  from lets_plot import *
518
518
  LetsPlot.setup_html()
519
+ n = 100
519
520
  np.random.seed(42)
520
- t = np.arange(100)
521
+ x = np.random.uniform(0, 2, size=n)
522
+ y = x**2 + np.random.normal(scale=.5, size=n)
523
+ ggplot({'x': x, 'y': y}, aes('x', 'y')) + \\
524
+ geom_point() + \\
525
+ geom_line(stat='smooth', method='loess',
526
+ color='red', linetype='longdash')
527
+
528
+ |
529
+
530
+ .. jupyter-execute::
531
+ :linenos:
532
+ :emphasize-lines: 13-16,19
533
+
534
+ import numpy as np
535
+ import pandas as pd
536
+ from lets_plot import *
537
+ LetsPlot.setup_html()
538
+ np.random.seed(42)
539
+ t = np.linspace(0, 1, 100)
521
540
  x1 = np.cumsum(np.random.normal(size=t.size))
522
541
  x2 = np.cumsum(np.random.normal(size=t.size))
523
542
  df = pd.DataFrame({'t': t, 'x1': x1, 'x2': x2})
524
- df = pd.melt(df, id_vars=['t'], value_vars=['x1', 'x2'])
525
- ggplot(df, aes(x='t', y='value', group='variable')) + \\
526
- geom_line(aes(color='variable'), size=1, alpha=0.5) + \\
527
- geom_line(stat='smooth', color='red', linetype='longdash')
543
+ melted_df = pd.melt(df, id_vars=['t'], value_vars=['x1', 'x2'])
544
+ gggrid([
545
+ ggplot(df) + \\
546
+ geom_line(aes(x='t', y='x1'), size=1, alpha=0.5,
547
+ color="red", manual_key="x1") + \\
548
+ geom_line(aes(x='t', y='x2'), size=1, alpha=0.5,
549
+ color="blue", manual_key="x2") + \\
550
+ ggtitle('Two geom_line() layers'),
551
+ ggplot(melted_df, aes(x='t', y='value', group='variable')) + \\
552
+ geom_line(aes(color='variable'), size=1, alpha=0.5) + \\
553
+ ggtitle('One geom_line() layer')
554
+ ])
528
555
 
529
556
  """
530
557
  return _geom('line',
@@ -804,8 +831,10 @@ def geom_bar(mapping=None, *, data=None, stat=None, position=None, show_legend=N
804
831
  -----
805
832
  ``geom_bar()`` makes the height of the bar proportional to the number
806
833
  of observed variable values, mapped to x-axis. Is intended to use for discrete data.
807
- If used for continuous data with stat='bin' produces histogram for binned data.
808
- ``geom_bar()`` handles no group aesthetics.
834
+ If used for continuous data with ``stat='bin'`` produces histogram for binned data.
835
+
836
+ ``geom_bar()`` handles no group aesthetics. Stacking and dodging are controlled by the position adjustment.
837
+ With ``position='identity'``, groups are neither stacked nor dodged (bars overlap).
809
838
 
810
839
  Computed variables:
811
840
 
@@ -906,6 +935,7 @@ def geom_histogram(mapping=None, *, data=None, stat=None, position=None, show_le
906
935
  binwidth=None,
907
936
  center=None,
908
937
  boundary=None,
938
+ breaks=None,
909
939
  color_by=None, fill_by=None,
910
940
  **other_args):
911
941
  """
@@ -965,6 +995,9 @@ def geom_histogram(mapping=None, *, data=None, stat=None, position=None, show_le
965
995
  Specify x-value to align bin centers to.
966
996
  boundary : float
967
997
  Specify x-value to align bin boundary (i.e., point between bins) to.
998
+ breaks : list of float
999
+ Specify exact positions of bin boundaries.
1000
+ Overrides ``bins``, ``binwidth``, ``center`` and ``boundary``.
968
1001
  color_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='color'
969
1002
  Define the color aesthetic for the geometry.
970
1003
  fill_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='fill'
@@ -991,7 +1024,6 @@ def geom_histogram(mapping=None, *, data=None, stat=None, position=None, show_le
991
1024
  - ..density.. : normalized number of points so that plot area is 1.
992
1025
  - ..sumprop.. : normalized number of points so that sum of y-values is 1.
993
1026
  - ..sumpct.. : normalized number of points so that sum of y-values is 100.
994
- - ..binwidth.. : width of each bin.
995
1027
 
996
1028
  ``geom_histogram()`` understands the following aesthetics mappings:
997
1029
 
@@ -1037,6 +1069,21 @@ def geom_histogram(mapping=None, *, data=None, stat=None, position=None, show_le
1037
1069
 
1038
1070
  |
1039
1071
 
1072
+ .. jupyter-execute::
1073
+ :linenos:
1074
+ :emphasize-lines: 7-8
1075
+
1076
+ import numpy as np
1077
+ from lets_plot import *
1078
+ LetsPlot.setup_html()
1079
+ np.random.seed(42)
1080
+ data = {'age': np.random.gamma(4.0, size=1000, scale=10.0)}
1081
+ age_breaks = [0, 12, 17, 64, 100]
1082
+ ggplot(data) + geom_histogram(aes(x='age'), breaks=age_breaks,
1083
+ color="black", fill="gray80")
1084
+
1085
+ |
1086
+
1040
1087
  .. jupyter-execute::
1041
1088
  :linenos:
1042
1089
  :emphasize-lines: 8-10
@@ -1070,6 +1117,7 @@ def geom_histogram(mapping=None, *, data=None, stat=None, position=None, show_le
1070
1117
  binwidth=binwidth,
1071
1118
  center=center,
1072
1119
  boundary=boundary,
1120
+ breaks=breaks,
1073
1121
  color_by=color_by, fill_by=fill_by,
1074
1122
  **other_args)
1075
1123
 
@@ -5656,6 +5704,232 @@ def geom_density2df(mapping=None, *, data=None, stat=None, position=None, show_l
5656
5704
  **other_args)
5657
5705
 
5658
5706
 
5707
+ def geom_pointdensity(mapping=None, *, data=None, stat=None, position=None, show_legend=None, inherit_aes=None,
5708
+ manual_key=None, sampling=None,
5709
+ tooltips=None,
5710
+ method=None,
5711
+ kernel=None,
5712
+ adjust=None,
5713
+ bw=None,
5714
+ n=None,
5715
+ map=None, map_join=None, use_crs=None,
5716
+ color_by=None, fill_by=None,
5717
+ **other_args):
5718
+ """
5719
+ Plots data points and colors each point by the local density of nearby points.
5720
+
5721
+ Parameters
5722
+ ----------
5723
+ mapping : ``FeatureSpec``
5724
+ Set of aesthetic mappings created by `aes() <https://lets-plot.org/python/pages/api/lets_plot.aes.html>`__ function.
5725
+ Aesthetic mappings describe the way that variables in the data are
5726
+ mapped to plot "aesthetics".
5727
+ data : dict or Pandas or Polars ``DataFrame``
5728
+ The data to be displayed in this layer. If None, the default, the data
5729
+ is inherited from the plot data as specified in the call to ggplot.
5730
+ stat : str, default='pointdensity'
5731
+ The statistical transformation to use on the data for this layer, as a string.
5732
+ position : str or ``FeatureSpec``, default='identity'
5733
+ Position adjustment.
5734
+ Either a position adjustment name: 'dodge', 'jitter', 'nudge', 'jitterdodge', 'fill',
5735
+ 'stack' or 'identity', or the result of calling a position adjustment function (e.g., `position_dodge() <https://lets-plot.org/python/pages/api/lets_plot.position_dodge.html>`__ etc.).
5736
+ show_legend : bool, default=True
5737
+ False - do not show legend for this layer.
5738
+ inherit_aes : bool, default=True
5739
+ False - do not combine the layer aesthetic mappings with the plot shared mappings.
5740
+ manual_key : str or ``layer_key``
5741
+ The key to show in the manual legend.
5742
+ Specify text for the legend label or advanced settings using the `layer_key() <https://lets-plot.org/python/pages/api/lets_plot.layer_key.html>`__ function.
5743
+ sampling : ``FeatureSpec``
5744
+ Result of the call to the ``sampling_xxx()`` function.
5745
+ To prevent any sampling for this layer pass value "none" (string "none").
5746
+ tooltips : ``layer_tooltips``
5747
+ Result of the call to the `layer_tooltips() <https://lets-plot.org/python/pages/api/lets_plot.layer_tooltips.html>`__ function.
5748
+ Specify appearance, style and content.
5749
+ Set tooltips='none' to hide tooltips from the layer.
5750
+ method : {'auto', 'neighbours', 'kde2d'}, default='auto'
5751
+ The method to compute the density estimate.
5752
+
5753
+ - ``'neighbours'`` – estimates density from the number of nearby points.
5754
+ - ``'kde2d'`` – estimates density using a smoothed 2D kernel density.
5755
+ - ``'auto'`` – automatically selects an estimation method based on data size.
5756
+
5757
+ kernel : str, default='gaussian'
5758
+ The kernel we use to calculate the density function.
5759
+ Choose among 'gaussian', 'cosine', 'optcosine', 'rectangular' (or 'uniform'),
5760
+ 'triangular', 'biweight' (or 'quartic'), 'epanechikov' (or 'parabolic').
5761
+ Only used when ``method='kde2d'``.
5762
+ bw : str or list of float
5763
+ The method (or exact value) of bandwidth.
5764
+ Either a string (choose among 'nrd0' and 'nrd'), or a float array of length 2.
5765
+ Only used when ``method='kde2d'``.
5766
+ adjust : float
5767
+ If ``method='neighbours'``, adjust the radius in which to count neighbours.
5768
+ If ``method='kde2d'``, adjust the value of bandwidth by multiplying it.
5769
+ n : list of int
5770
+ The number of sampled points for plotting the function
5771
+ (on x and y direction correspondingly).
5772
+ Only used when ``method='kde2d'``.
5773
+ map : ``GeoDataFrame`` or ``Geocoder``
5774
+ Data containing coordinates of points.
5775
+ map_join : str or list
5776
+ Keys used to join map coordinates with data.
5777
+ First value in pair - column/columns in ``data``.
5778
+ Second value in pair - column/columns in ``map``.
5779
+ use_crs : str, optional, default="EPSG:4326" (aka WGS84)
5780
+ EPSG code of the coordinate reference system (CRS) or the keyword "provided".
5781
+ If an EPSG code is given, then all the coordinates in ``GeoDataFrame`` (see the ``map`` parameter)
5782
+ will be projected to this CRS.
5783
+ Specify "provided" to disable any further re-projection and to keep the ``GeoDataFrame``'s original CRS.
5784
+ color_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='color'
5785
+ Define the color aesthetic for the geometry.
5786
+ fill_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='fill'
5787
+ Define the fill aesthetic for the geometry.
5788
+ other_args
5789
+ Other arguments passed on to the layer.
5790
+ These are often aesthetics settings used to set an aesthetic to a fixed value,
5791
+ like color='red', fill='blue', size=3 or shape=21.
5792
+ They may also be parameters to the paired geom/stat.
5793
+
5794
+ Returns
5795
+ -------
5796
+ ``LayerSpec``
5797
+ Geom object specification.
5798
+
5799
+ Notes
5800
+ -----
5801
+ Computed variables:
5802
+
5803
+ - ..density.. : density estimate (mapped by default).
5804
+ - ..count.. : density * number of points (corresponds to number of nearby points for ``'neighbours'`` method).
5805
+ - ..scaled.. : density estimate, scaled to maximum of 1.
5806
+
5807
+ ``geom_pointdensity()`` understands the following aesthetics mappings:
5808
+
5809
+ - x : x-axis value.
5810
+ - y : y-axis value.
5811
+ - alpha : transparency level of the point. Accept values between 0 and 1.
5812
+ - color (colour) : color of the geometry. For more info see `Color and Fill <https://lets-plot.org/python/pages/aesthetics.html#color-and-fill>`__.
5813
+ - fill : fill color. Is applied only to the points of shapes having inner area. For more info see `Color and Fill <https://lets-plot.org/python/pages/aesthetics.html#color-and-fill>`__.
5814
+ - shape : shape of the point, an integer from 0 to 25. For more info see `Point Shapes <https://lets-plot.org/python/pages/aesthetics.html#point-shapes>`__.
5815
+ - angle : rotation angle of the point shape, in degrees.
5816
+ - size : size of the point.
5817
+ - stroke : width of the shape border. Applied only to the shapes having border.
5818
+ - weight : used by 'pointdensity' stat to compute weighted density.
5819
+
5820
+ ----
5821
+
5822
+ The ``data`` and ``map`` parameters of ``GeoDataFrame`` type support shapes ``Point`` and ``MultiPoint``.
5823
+
5824
+ The ``map`` parameter of ``Geocoder`` type implicitly invokes
5825
+ `get_centroids() <https://lets-plot.org/python/pages/api/lets_plot.geo_data.NamesGeocoder.html#lets_plot.geo_data.NamesGeocoder.get_centroids>`__ function.
5826
+
5827
+ ----
5828
+
5829
+ The conventions for the values of ``map_join`` parameter are as follows:
5830
+
5831
+ - Joining data and ``GeoDataFrame`` object
5832
+
5833
+ Data has a column named 'State_name' and ``GeoDataFrame`` has a matching column named 'state':
5834
+
5835
+ - map_join=['State_Name', 'state']
5836
+ - map_join=[['State_Name'], ['state']]
5837
+
5838
+ - Joining data and ``Geocoder`` object
5839
+
5840
+ Data has a column named 'State_name'. The matching key in ``Geocoder`` is always 'state' (providing it is a state-level geocoder) and can be omitted:
5841
+
5842
+ - map_join='State_Name'
5843
+ - map_join=['State_Name']
5844
+
5845
+ - Joining data by composite key
5846
+
5847
+ Joining by composite key works like in examples above, but instead of using a string for a simple key you need to use an array of strings for a composite key. The names in the composite key must be in the same order as in the US street addresses convention: 'city', 'county', 'state', 'country'. For example, the data has columns 'State_name' and 'County_name'. Joining with a 2-keys county level ``Geocoder`` object (the ``Geocoder`` keys 'county' and 'state' are omitted in this case):
5848
+
5849
+ - map_join=['County_name', 'State_Name']
5850
+
5851
+ ----
5852
+
5853
+ To hide axis tooltips, set 'blank' or the result of `element_blank() <https://lets-plot.org/python/pages/api/lets_plot.element_blank.html>`__
5854
+ to the ``axis_tooltip``, ``axis_tooltip_x`` or ``axis_tooltip_y`` parameter of the `theme() <https://lets-plot.org/python/pages/api/lets_plot.theme.html>`__.
5855
+
5856
+ Examples
5857
+ --------
5858
+ .. jupyter-execute::
5859
+ :linenos:
5860
+ :emphasize-lines: 9
5861
+
5862
+ import numpy as np
5863
+ from lets_plot import *
5864
+ LetsPlot.setup_html()
5865
+ n = 1000
5866
+ np.random.seed(42)
5867
+ x = np.random.normal(size=n)
5868
+ y = np.random.normal(size=n)
5869
+ ggplot({'x': x, 'y': y}, aes('x', 'y')) + \\
5870
+ geom_pointdensity()
5871
+
5872
+ |
5873
+
5874
+ .. jupyter-execute::
5875
+ :linenos:
5876
+ :emphasize-lines: 10-11
5877
+
5878
+ import numpy as np
5879
+ from lets_plot import *
5880
+ LetsPlot.setup_html()
5881
+ n = 5_000
5882
+ np.random.seed(42)
5883
+ x = np.random.poisson(size=n) + np.random.normal(scale=.1, size=n)
5884
+ y = np.random.normal(size=n)
5885
+ gggrid([
5886
+ ggplot({'x': x, 'y': y}, aes('x', 'y')) + \\
5887
+ geom_pointdensity(aes(color='..count..'),
5888
+ method=method) + \\
5889
+ ggtitle("method='{0}'".format(method))
5890
+ for method in ['neighbours', 'kde2d']
5891
+ ])
5892
+
5893
+ |
5894
+
5895
+ .. jupyter-execute::
5896
+ :linenos:
5897
+ :emphasize-lines: 10-12
5898
+
5899
+ import numpy as np
5900
+ from lets_plot import *
5901
+ LetsPlot.setup_html()
5902
+ n = 1000
5903
+ np.random.seed(42)
5904
+ data = {'x': 10 * np.random.normal(size=n) - 100, \\
5905
+ 'y': 3 * np.random.normal(size=n) + 40}
5906
+ ggplot(data, aes('x', 'y')) + \\
5907
+ geom_livemap(zoom=4) + \\
5908
+ geom_pointdensity(aes(fill='..density..'),
5909
+ color='black', shape=21,
5910
+ show_legend=False) + \\
5911
+ scale_fill_viridis()
5912
+
5913
+ """
5914
+ return _geom('pointdensity',
5915
+ mapping=mapping,
5916
+ data=data,
5917
+ stat=stat,
5918
+ position=position,
5919
+ show_legend=show_legend,
5920
+ inherit_aes=inherit_aes,
5921
+ manual_key=manual_key,
5922
+ sampling=sampling,
5923
+ tooltips=tooltips,
5924
+ method=method,
5925
+ kernel=kernel,
5926
+ adjust=adjust,
5927
+ bw=bw, n=n,
5928
+ map=map, map_join=map_join, use_crs=use_crs,
5929
+ color_by=color_by, fill_by=fill_by,
5930
+ **other_args)
5931
+
5932
+
5659
5933
  def geom_jitter(mapping=None, *, data=None, stat=None, position=None, show_legend=None, inherit_aes=None,
5660
5934
  manual_key=None, sampling=None,
5661
5935
  tooltips=None,
@@ -8368,19 +8642,24 @@ def geom_pie(mapping=None, *, data=None, stat=None, position=None, show_legend=N
8368
8642
 
8369
8643
  .. jupyter-execute::
8370
8644
  :linenos:
8371
- :emphasize-lines: 9-10
8645
+ :emphasize-lines: 9-15
8372
8646
 
8373
8647
  from lets_plot import *
8374
8648
  from lets_plot.geo_data import *
8375
8649
  LetsPlot.setup_html()
8376
- data = {"city": ["New York", "New York", "Philadelphia", "Philadelphia"], \\
8377
- "est_pop_2020": [4_381_593, 3_997_959, 832_685, 748_846], \\
8650
+ data = {"city": ["New York", "New York", "Philadelphia", "Philadelphia"],
8651
+ "est_pop_2020": [4_381_593, 3_997_959, 832_685, 748_846],
8378
8652
  "sex": ["female", "male", "female", "male"]}
8379
8653
  centroids = geocode_cities(data["city"]).get_centroids()
8380
8654
  ggplot() + geom_livemap() + \\
8381
- geom_pie(aes(slice="est_pop_2020", fill="sex", size="est_pop_2020"), \\
8382
- stat='identity', data=data, map=centroids, map_join="city") + \\
8383
- scale_size(guide='none')
8655
+ geom_pie(aes(fill="sex", weight="est_pop_2020", size="..sum..", group=["city", "sex"]),
8656
+ data=data, map=centroids, map_join="city",
8657
+ tooltips=layer_tooltips().title("@city")
8658
+ .format("@est_pop_2020", ".3~s")
8659
+ .line("population (@sex):\\n@est_pop_2020 (@..proppct..)")
8660
+ .format("@..sum..", ".3~s")
8661
+ .line("population (total):\\n@..sum..")) + \\
8662
+ scale_size(range=[4, 10], guide='none')
8384
8663
 
8385
8664
  """
8386
8665
  if 'stroke_color' in other_args:
@@ -63,17 +63,25 @@ def geom_livemap(*,
63
63
  data_size_zoomin : int, default=0
64
64
  Control how zooming-in of the map widget increases size of geometry objects (circles, lines etc.) on map
65
65
  when the size is set by means of mapping between the data and the ``size`` aesthetic.
66
+
66
67
  0 - size never increases;
68
+
67
69
  -1 - size will be increasing without limits;
70
+
68
71
  n - a number of zooming-in steps (counting from the initial state of the map widget)
69
72
  when size of objects will be increasing. Farther zooming will no longer affect the size.
73
+
70
74
  const_size_zoomin : int, default=-1
71
75
  Control how zooming-in of the map widget increases size of geometry objects (circles, lines etc.) on map
72
76
  when the size is not linked to a data (i.e. constant size).
77
+
73
78
  0 - size never increases;
79
+
74
80
  -1 - size will be increasing without limits;
81
+
75
82
  n - a number of zooming-in steps (counting from the initial state of the map widget)
76
83
  when size of objects will be increasing. Farther zooming will no longer affect the size.
84
+
77
85
  other_args
78
86
  Other arguments passed on to the layer.
79
87
 
lets_plot/plot/gggrid_.py CHANGED
@@ -19,7 +19,8 @@ def gggrid(plots: list, ncol: int = None, *,
19
19
  hspace: float = None,
20
20
  vspace: float = None,
21
21
  fit: bool = None,
22
- align: bool = None
22
+ align: bool = None,
23
+ guides: str = None
23
24
  ) -> SupPlotsSpec:
24
25
  """
25
26
  Combine several plots on one figure, organized in a regular grid.
@@ -27,10 +28,10 @@ def gggrid(plots: list, ncol: int = None, *,
27
28
  Parameters
28
29
  ----------
29
30
  plots : list
30
- A list where each element is a plot specification, a subplots specification, or None.
31
- Use value None to fill-in empty cells in grid.
31
+ A list where each element is a plot specification, a subplot specification, or None.
32
+ Use None to fill in empty cells in the grid.
32
33
  ncol : int
33
- Number of columns in grid.
34
+ Number of columns in the grid.
34
35
  If not specified, shows plots horizontally, in one row.
35
36
  sharex, sharey : bool or str, default=False
36
37
  Controls sharing of axis limits between subplots in the grid.
@@ -41,9 +42,9 @@ def gggrid(plots: list, ncol: int = None, *,
41
42
  - 'col' - share limits between subplots in the same column.
42
43
 
43
44
  widths : list of numbers
44
- Relative width of each column of grid, left to right.
45
+ Relative width of each column in the grid, left to right.
45
46
  heights : list of numbers
46
- Relative height of each row of grid, top-down.
47
+ Relative height of each row in the grid, top-down.
47
48
  hspace : float, default=4.0
48
49
  Cell horizontal spacing in px.
49
50
  vspace : float, default=4.0
@@ -54,6 +55,17 @@ def gggrid(plots: list, ncol: int = None, *,
54
55
  align : bool, default=False
55
56
  If True, align inner areas (i.e. "geom" bounds) of plots.
56
57
  However, cells containing other (sub)grids are not participating in the plot "inner areas" layouting.
58
+ guides : str, default='auto'
59
+ Specifies how guides (legends and colorbars) should be treated in the layout.
60
+
61
+ - 'collect' - collect guides from all subplots, removing duplicates.
62
+ - 'keep' - keep guides in their original subplots; do not collect at this level.
63
+ - 'auto' - allow guides to be collected if an upper-level layout uses ``guides='collect'``; otherwise, keep them in subplots.
64
+
65
+ Duplicates are identified by comparing visual properties:
66
+
67
+ - For legends: title, labels, and all aesthetic values (colors, shapes, sizes, etc.).
68
+ - For colorbars: title, domain limits, breaks, and color gradient.
57
69
 
58
70
  Returns
59
71
  -------
@@ -111,7 +123,8 @@ def gggrid(plots: list, ncol: int = None, *,
111
123
  hspace=hspace,
112
124
  vspace=vspace,
113
125
  fit=fit,
114
- align=align
126
+ align=align,
127
+ guides=guides
115
128
  )
116
129
 
117
130
  figures = [_strip_theme_if_global(fig) for fig in plots]