lets-plot 4.5.3a1__cp312-cp312-win_amd64.whl → 4.6.0a2__cp312-cp312-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.
- lets_plot/_kbridge.py +71 -0
- lets_plot/_version.py +1 -1
- lets_plot/bistro/_plot2d_common.py +7 -0
- lets_plot/bistro/im.py +38 -7
- lets_plot/bistro/joint.py +3 -3
- lets_plot/bistro/residual.py +3 -3
- lets_plot/package_data/lets-plot.min.js +2 -2
- lets_plot/plot/__init__.py +2 -0
- lets_plot/plot/core.py +1 -1
- lets_plot/plot/geom.py +248 -61
- lets_plot/plot/ggbunch_.py +96 -0
- lets_plot/plot/gggrid_.py +3 -18
- lets_plot/plot/plot.py +7 -0
- lets_plot/plot/scale.py +45 -20
- lets_plot/plot/subplots.py +1 -1
- lets_plot/plot/subplots_util.py +24 -0
- lets_plot/plot/theme_.py +12 -12
- {lets_plot-4.5.3a1.dist-info → lets_plot-4.6.0a2.dist-info}/METADATA +16 -3
- {lets_plot-4.5.3a1.dist-info → lets_plot-4.6.0a2.dist-info}/RECORD +23 -21
- {lets_plot-4.5.3a1.dist-info → lets_plot-4.6.0a2.dist-info}/WHEEL +1 -1
- lets_plot_kotlin_bridge.cp312-win_amd64.pyd +0 -0
- {lets_plot-4.5.3a1.dist-info → lets_plot-4.6.0a2.dist-info}/LICENSE +0 -0
- {lets_plot-4.5.3a1.dist-info → lets_plot-4.6.0a2.dist-info}/top_level.txt +0 -0
lets_plot/plot/__init__.py
CHANGED
|
@@ -13,6 +13,7 @@ from .geom_extras import *
|
|
|
13
13
|
from .geom_function_ import *
|
|
14
14
|
from .geom_imshow_ import *
|
|
15
15
|
from .geom_livemap_ import *
|
|
16
|
+
from .ggbunch_ import *
|
|
16
17
|
from .gggrid_ import *
|
|
17
18
|
from .ggtb_ import *
|
|
18
19
|
from .guide import *
|
|
@@ -56,6 +57,7 @@ __all__ = (coord.__all__ +
|
|
|
56
57
|
annotation.__all__ +
|
|
57
58
|
marginal_layer.__all__ +
|
|
58
59
|
font_features.__all__ +
|
|
60
|
+
ggbunch_.__all__ +
|
|
59
61
|
gggrid_.__all__ +
|
|
60
62
|
ggtb_.__all__ +
|
|
61
63
|
expand_limits_.__all__
|
lets_plot/plot/core.py
CHANGED
|
@@ -706,7 +706,7 @@ class LayerSpec(FeatureSpec):
|
|
|
706
706
|
map_data_meta = {'georeference': {}}
|
|
707
707
|
else:
|
|
708
708
|
# Fetch proper GeoDataFrame. Further processing is the same as if map was a GDF.
|
|
709
|
-
if name in ['point', 'pie', 'text', 'livemap']:
|
|
709
|
+
if name in ['point', 'pie', 'text', 'label', 'livemap']:
|
|
710
710
|
map = map.get_centroids()
|
|
711
711
|
elif name in ['map', 'polygon']:
|
|
712
712
|
map = map.get_boundaries()
|
lets_plot/plot/geom.py
CHANGED
|
@@ -12,7 +12,7 @@ from .util import as_annotated_data, is_geo_data_frame, geo_data_frame_to_crs, g
|
|
|
12
12
|
#
|
|
13
13
|
__all__ = ['geom_point', 'geom_path', 'geom_line',
|
|
14
14
|
'geom_smooth', 'geom_bar',
|
|
15
|
-
'geom_histogram', 'geom_dotplot', 'geom_bin2d',
|
|
15
|
+
'geom_histogram', 'geom_dotplot', 'geom_bin2d', 'geom_hex',
|
|
16
16
|
'geom_tile', 'geom_raster',
|
|
17
17
|
'geom_errorbar', 'geom_crossbar', 'geom_linerange', 'geom_pointrange',
|
|
18
18
|
'geom_contour',
|
|
@@ -128,7 +128,7 @@ def geom_point(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
128
128
|
|
|
129
129
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Point` and `MultiPoint`.
|
|
130
130
|
|
|
131
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
131
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_centroids()` function.
|
|
132
132
|
|
|
133
133
|
----
|
|
134
134
|
|
|
@@ -193,7 +193,7 @@ def geom_point(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
193
193
|
|
|
194
194
|
.. jupyter-execute::
|
|
195
195
|
:linenos:
|
|
196
|
-
:emphasize-lines: 8-
|
|
196
|
+
:emphasize-lines: 8-12
|
|
197
197
|
|
|
198
198
|
from lets_plot import *
|
|
199
199
|
from lets_plot.geo_data import *
|
|
@@ -205,7 +205,8 @@ def geom_point(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
205
205
|
geom_point(aes(size="est_pop_2019"), color="red", show_legend=False, \\
|
|
206
206
|
data=data, map=centroids, map_join="city", \\
|
|
207
207
|
tooltips=layer_tooltips().title("@city")
|
|
208
|
-
.line("population|@est_pop_2019")
|
|
208
|
+
.line("population|@est_pop_2019")
|
|
209
|
+
.format("@est_pop_2019", ".2~s"))
|
|
209
210
|
|
|
210
211
|
"""
|
|
211
212
|
return _geom('point',
|
|
@@ -1420,6 +1421,173 @@ def geom_bin2d(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
1420
1421
|
**other_args)
|
|
1421
1422
|
|
|
1422
1423
|
|
|
1424
|
+
def geom_hex(mapping=None, *, data=None, stat=None, position=None, show_legend=None, inherit_aes=None,
|
|
1425
|
+
manual_key=None, sampling=None,
|
|
1426
|
+
tooltips=None,
|
|
1427
|
+
bins=None,
|
|
1428
|
+
binwidth=None,
|
|
1429
|
+
drop=None,
|
|
1430
|
+
color_by=None, fill_by=None,
|
|
1431
|
+
**other_args):
|
|
1432
|
+
"""
|
|
1433
|
+
Apply a hexagonal grid to the plane, count observations in each cell (hexagonal bin) of the grid,
|
|
1434
|
+
and map the count to the fill color of the cell (hexagonal tile).
|
|
1435
|
+
|
|
1436
|
+
By default, this geom uses `coord_fixed()`.
|
|
1437
|
+
However, this may not be the best choice when the values on the X/Y axis have significantly different magnitudes.
|
|
1438
|
+
In such cases, try using `coord_cartesian()`.
|
|
1439
|
+
|
|
1440
|
+
Parameters
|
|
1441
|
+
----------
|
|
1442
|
+
mapping : `FeatureSpec`
|
|
1443
|
+
Set of aesthetic mappings created by `aes()` function.
|
|
1444
|
+
Aesthetic mappings describe the way that variables in the data are
|
|
1445
|
+
mapped to plot "aesthetics".
|
|
1446
|
+
data : dict or Pandas or Polars `DataFrame`
|
|
1447
|
+
The data to be displayed in this layer. If None, the default, the data
|
|
1448
|
+
is inherited from the plot data as specified in the call to ggplot.
|
|
1449
|
+
stat : str, default='binhex'
|
|
1450
|
+
The statistical transformation to use on the data for this layer, as a string.
|
|
1451
|
+
position : str or `FeatureSpec`, default='identity'
|
|
1452
|
+
Position adjustment.
|
|
1453
|
+
Either a position adjustment name: 'dodge', 'dodgev', 'jitter', 'nudge', 'jitterdodge', 'fill',
|
|
1454
|
+
'stack' or 'identity', or the result of calling a position adjustment function (e.g., `position_dodge()` etc.).
|
|
1455
|
+
show_legend : bool, default=True
|
|
1456
|
+
False - do not show legend for this layer.
|
|
1457
|
+
inherit_aes : bool, default=True
|
|
1458
|
+
False - do not combine the layer aesthetic mappings with the plot shared mappings.
|
|
1459
|
+
manual_key : str or `layer_key`
|
|
1460
|
+
The key to show in the manual legend.
|
|
1461
|
+
Specify text for the legend label or advanced settings using the `layer_key()` function.
|
|
1462
|
+
sampling : `FeatureSpec`
|
|
1463
|
+
Result of the call to the `sampling_xxx()` function.
|
|
1464
|
+
To prevent any sampling for this layer pass value "none" (string "none").
|
|
1465
|
+
tooltips : `layer_tooltips`
|
|
1466
|
+
Result of the call to the `layer_tooltips()` function.
|
|
1467
|
+
Specify appearance, style and content.
|
|
1468
|
+
Set tooltips='none' to hide tooltips from the layer.
|
|
1469
|
+
bins : list of int, default=[30, 30]
|
|
1470
|
+
Number of hexagonal bins in both directions, vertical and horizontal. Overridden by `binwidth`.
|
|
1471
|
+
binwidth : list of float
|
|
1472
|
+
The width of the hexagonal bins in both directions, vertical and horizontal.
|
|
1473
|
+
Override `bins`. The default is to use bin widths that cover the entire range of the data.
|
|
1474
|
+
drop : bool, default=True
|
|
1475
|
+
Specify whether to remove all hexagonal bins with 0 counts.
|
|
1476
|
+
color_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='color'
|
|
1477
|
+
Define the color aesthetic for the geometry.
|
|
1478
|
+
fill_by : {'fill', 'color', 'paint_a', 'paint_b', 'paint_c'}, default='fill'
|
|
1479
|
+
Define the fill aesthetic for the geometry.
|
|
1480
|
+
other_args
|
|
1481
|
+
Other arguments passed on to the layer.
|
|
1482
|
+
These are often aesthetics settings used to set an aesthetic to a fixed value,
|
|
1483
|
+
like color='red', fill='blue', size=3 or shape=21.
|
|
1484
|
+
They may also be parameters to the paired geom/stat.
|
|
1485
|
+
|
|
1486
|
+
Returns
|
|
1487
|
+
-------
|
|
1488
|
+
`LayerSpec`
|
|
1489
|
+
Geom object specification.
|
|
1490
|
+
|
|
1491
|
+
Notes
|
|
1492
|
+
-----
|
|
1493
|
+
|
|
1494
|
+
Computed variables:
|
|
1495
|
+
|
|
1496
|
+
- ..count.. : number of points with coordinates in the same hexagonal bin.
|
|
1497
|
+
|
|
1498
|
+
`geom_hex()` understands the following aesthetics mappings:
|
|
1499
|
+
|
|
1500
|
+
- x : x-axis value.
|
|
1501
|
+
- y : y-axis value.
|
|
1502
|
+
- alpha : transparency level of a layer. Accept values between 0 and 1.
|
|
1503
|
+
- color (colour) : color of the geometry lines. For more info see `Color and Fill <https://lets-plot.org/python/pages/aesthetics.html#color-and-fill>`__.
|
|
1504
|
+
- fill : fill color. For more info see `Color and Fill <https://lets-plot.org/python/pages/aesthetics.html#color-and-fill>`__.
|
|
1505
|
+
- size : line width, default=0 (i.e. tiles outline initially is not visible).
|
|
1506
|
+
- weight : used by 'binhex' stat to compute weighted sum instead of simple count.
|
|
1507
|
+
- width : width of the hexagon.
|
|
1508
|
+
- height : the real height of the hexagon will be 2/sqrt(3) times this value, so with width=height the hexagon will be the regular.
|
|
1509
|
+
|
|
1510
|
+
----
|
|
1511
|
+
|
|
1512
|
+
To hide axis tooltips, set 'blank' or the result of `element_blank()`
|
|
1513
|
+
to the `axis_tooltip`, `axis_tooltip_x` or `axis_tooltip_y` parameter of the `theme()`.
|
|
1514
|
+
|
|
1515
|
+
Examples
|
|
1516
|
+
--------
|
|
1517
|
+
.. jupyter-execute::
|
|
1518
|
+
:linenos:
|
|
1519
|
+
:emphasize-lines: 8
|
|
1520
|
+
|
|
1521
|
+
import numpy as np
|
|
1522
|
+
from lets_plot import *
|
|
1523
|
+
LetsPlot.setup_html()
|
|
1524
|
+
np.random.seed(42)
|
|
1525
|
+
mean = np.zeros(2)
|
|
1526
|
+
cov = np.eye(2)
|
|
1527
|
+
x, y = np.random.multivariate_normal(mean, cov, 1000).T
|
|
1528
|
+
ggplot({'x': x, 'y': y}, aes(x='x', y='y')) + geom_hex()
|
|
1529
|
+
|
|
1530
|
+
|
|
|
1531
|
+
|
|
1532
|
+
.. jupyter-execute::
|
|
1533
|
+
:linenos:
|
|
1534
|
+
:emphasize-lines: 9-14
|
|
1535
|
+
|
|
1536
|
+
import numpy as np
|
|
1537
|
+
from lets_plot import *
|
|
1538
|
+
LetsPlot.setup_html()
|
|
1539
|
+
np.random.seed(42)
|
|
1540
|
+
n = 5000
|
|
1541
|
+
x = np.random.uniform(-2, 2, size=n)
|
|
1542
|
+
y = np.random.normal(scale=.5, size=n)
|
|
1543
|
+
ggplot({'x': x, 'y': y}, aes(x='x', y='y')) + \\
|
|
1544
|
+
geom_hex(aes(fill='..density..'), binwidth=[.25, .24], \\
|
|
1545
|
+
tooltips=layer_tooltips().format('@x', '.2f')
|
|
1546
|
+
.format('@y', '.2f').line('(@x, @y)')
|
|
1547
|
+
.line('count|@..count..')
|
|
1548
|
+
.format('@..density..', '.3f')
|
|
1549
|
+
.line('density|@..density..')) + \\
|
|
1550
|
+
scale_fill_gradient(low='black', high='red')
|
|
1551
|
+
|
|
1552
|
+
|
|
|
1553
|
+
|
|
1554
|
+
.. jupyter-execute::
|
|
1555
|
+
:linenos:
|
|
1556
|
+
:emphasize-lines: 10-11
|
|
1557
|
+
|
|
1558
|
+
import numpy as np
|
|
1559
|
+
from lets_plot import *
|
|
1560
|
+
LetsPlot.setup_html()
|
|
1561
|
+
np.random.seed(42)
|
|
1562
|
+
mean = np.zeros(2)
|
|
1563
|
+
cov = [[1, .5],
|
|
1564
|
+
[.5, 1]]
|
|
1565
|
+
x, y = np.random.multivariate_normal(mean, cov, 500).T
|
|
1566
|
+
ggplot({'x': x, 'y': y}, aes(x='x', y='y')) + \\
|
|
1567
|
+
geom_hex(aes(alpha='..count..'), bins=[20, 20], \\
|
|
1568
|
+
fill='darkgreen') + \\
|
|
1569
|
+
geom_point(size=1.5, shape=21, color='white', \\
|
|
1570
|
+
fill='darkgreen') + \\
|
|
1571
|
+
ggsize(600, 450)
|
|
1572
|
+
|
|
1573
|
+
"""
|
|
1574
|
+
return _geom('hex',
|
|
1575
|
+
mapping=mapping,
|
|
1576
|
+
data=data,
|
|
1577
|
+
stat=stat,
|
|
1578
|
+
position=position,
|
|
1579
|
+
show_legend=show_legend,
|
|
1580
|
+
inherit_aes=inherit_aes,
|
|
1581
|
+
manual_key=manual_key,
|
|
1582
|
+
sampling=sampling,
|
|
1583
|
+
tooltips=tooltips,
|
|
1584
|
+
bins=bins,
|
|
1585
|
+
binwidth=binwidth,
|
|
1586
|
+
drop=drop,
|
|
1587
|
+
color_by=color_by, fill_by=fill_by,
|
|
1588
|
+
**other_args)
|
|
1589
|
+
|
|
1590
|
+
|
|
1423
1591
|
def geom_tile(mapping=None, *, data=None, stat=None, position=None, show_legend=None, inherit_aes=None,
|
|
1424
1592
|
manual_key=None, sampling=None,
|
|
1425
1593
|
tooltips=None,
|
|
@@ -2617,7 +2785,7 @@ def geom_polygon(mapping=None, *, data=None, stat=None, position=None, show_lege
|
|
|
2617
2785
|
|
|
2618
2786
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Polygon` and `MultiPolygon`.
|
|
2619
2787
|
|
|
2620
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
2788
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_boundaries()` function.
|
|
2621
2789
|
|
|
2622
2790
|
----
|
|
2623
2791
|
|
|
@@ -2807,7 +2975,7 @@ def geom_map(mapping=None, *, data=None, stat=None, position=None, show_legend=N
|
|
|
2807
2975
|
|
|
2808
2976
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Polygon` and `MultiPolygon`.
|
|
2809
2977
|
|
|
2810
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
2978
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_boundaries()` function.
|
|
2811
2979
|
|
|
2812
2980
|
----
|
|
2813
2981
|
|
|
@@ -4652,7 +4820,7 @@ def geom_density(mapping=None, *, data=None, stat=None, position=None, show_lege
|
|
|
4652
4820
|
|
|
4653
4821
|
.. jupyter-execute::
|
|
4654
4822
|
:linenos:
|
|
4655
|
-
:emphasize-lines:
|
|
4823
|
+
:emphasize-lines: 11
|
|
4656
4824
|
|
|
4657
4825
|
import numpy as np
|
|
4658
4826
|
from lets_plot import *
|
|
@@ -4660,13 +4828,17 @@ def geom_density(mapping=None, *, data=None, stat=None, position=None, show_lege
|
|
|
4660
4828
|
np.random.seed(42)
|
|
4661
4829
|
x = np.random.normal(size=1000)
|
|
4662
4830
|
p = ggplot({'x': x}, aes(x='x'))
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4831
|
+
bandwidths = [0.1, 0.2, 0.4]
|
|
4832
|
+
sample_sizes = [16, 64, 256]
|
|
4833
|
+
plots = [
|
|
4834
|
+
p + geom_density(
|
|
4835
|
+
kernel='epanechikov', bw=bw, n=n
|
|
4836
|
+
) + ggtitle(f'bw={bw}, n={n}')
|
|
4837
|
+
for bw in bandwidths
|
|
4838
|
+
for n in sample_sizes
|
|
4839
|
+
]
|
|
4840
|
+
|
|
4841
|
+
gggrid(plots, ncol=3) + ggsize(900, 600)
|
|
4670
4842
|
|
|
4671
4843
|
|
|
|
4672
4844
|
|
|
@@ -4681,13 +4853,15 @@ def geom_density(mapping=None, *, data=None, stat=None, position=None, show_lege
|
|
|
4681
4853
|
x = np.random.normal(size=1000)
|
|
4682
4854
|
y = np.sign(x)
|
|
4683
4855
|
p = ggplot({'x': x, 'y': y}, aes(x='x'))
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4856
|
+
adjustments = [0.5 * (1 + i) for i in range(3)]
|
|
4857
|
+
plots = [
|
|
4858
|
+
p + geom_density(aes(weight='y'),
|
|
4859
|
+
kernel='cosine', adjust=adjust
|
|
4860
|
+
) + ggtitle(f'adjust={adjust}')
|
|
4861
|
+
for adjust in adjustments
|
|
4862
|
+
]
|
|
4863
|
+
|
|
4864
|
+
gggrid(plots) + ggsize(800, 200)
|
|
4691
4865
|
|
|
4692
4866
|
"""
|
|
4693
4867
|
return _geom('density',
|
|
@@ -4847,7 +5021,7 @@ def geom_density2d(mapping=None, *, data=None, stat=None, position=None, show_le
|
|
|
4847
5021
|
|
|
4848
5022
|
.. jupyter-execute::
|
|
4849
5023
|
:linenos:
|
|
4850
|
-
:emphasize-lines:
|
|
5024
|
+
:emphasize-lines: 13
|
|
4851
5025
|
|
|
4852
5026
|
import numpy as np
|
|
4853
5027
|
from lets_plot import *
|
|
@@ -4857,19 +5031,23 @@ def geom_density2d(mapping=None, *, data=None, stat=None, position=None, show_le
|
|
|
4857
5031
|
x = np.random.normal(size=n)
|
|
4858
5032
|
y = np.random.normal(size=n)
|
|
4859
5033
|
p = ggplot({'x': x, 'y': y}, aes('x', 'y'))
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
5034
|
+
bandwidths = [0.2, 0.4]
|
|
5035
|
+
sample_sizes = [16, 256]
|
|
5036
|
+
plots = [
|
|
5037
|
+
p + geom_density2d(kernel='epanechikov',
|
|
5038
|
+
bw=bw, n=n
|
|
5039
|
+
) + ggtitle(f'bw={bw}, n={n}')
|
|
5040
|
+
for bw in bandwidths
|
|
5041
|
+
for n in sample_sizes
|
|
5042
|
+
]
|
|
5043
|
+
|
|
5044
|
+
gggrid(plots, ncol=2) + ggsize(600, 650)
|
|
4867
5045
|
|
|
4868
5046
|
|
|
|
4869
5047
|
|
|
4870
5048
|
.. jupyter-execute::
|
|
4871
5049
|
:linenos:
|
|
4872
|
-
:emphasize-lines:
|
|
5050
|
+
:emphasize-lines: 13-14
|
|
4873
5051
|
|
|
4874
5052
|
import numpy as np
|
|
4875
5053
|
from lets_plot import *
|
|
@@ -4879,14 +5057,18 @@ def geom_density2d(mapping=None, *, data=None, stat=None, position=None, show_le
|
|
|
4879
5057
|
x = np.random.normal(size=n)
|
|
4880
5058
|
y = np.random.normal(size=n)
|
|
4881
5059
|
p = ggplot({'x': x, 'y': y}, aes('x', 'y'))
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
5060
|
+
adjustments = [1.5, 2.5]
|
|
5061
|
+
bin_counts = [5, 15]
|
|
5062
|
+
plots = [
|
|
5063
|
+
p + geom_density2d(kernel='cosine',
|
|
5064
|
+
adjust=adjust,
|
|
5065
|
+
bins=bins
|
|
5066
|
+
) + ggtitle(f'adjust={adjust}, bins={bins}')
|
|
5067
|
+
for adjust in adjustments
|
|
5068
|
+
for bins in bin_counts
|
|
5069
|
+
]
|
|
5070
|
+
|
|
5071
|
+
gggrid(plots, ncol=2) + ggsize(600, 650)
|
|
4890
5072
|
|
|
4891
5073
|
|
|
|
4892
5074
|
|
|
@@ -5073,7 +5255,7 @@ def geom_density2df(mapping=None, *, data=None, stat=None, position=None, show_l
|
|
|
5073
5255
|
|
|
5074
5256
|
.. jupyter-execute::
|
|
5075
5257
|
:linenos:
|
|
5076
|
-
:emphasize-lines:
|
|
5258
|
+
:emphasize-lines: 13
|
|
5077
5259
|
|
|
5078
5260
|
import numpy as np
|
|
5079
5261
|
from lets_plot import *
|
|
@@ -5083,14 +5265,16 @@ def geom_density2df(mapping=None, *, data=None, stat=None, position=None, show_l
|
|
|
5083
5265
|
x = np.random.normal(size=n)
|
|
5084
5266
|
y = np.random.normal(size=n)
|
|
5085
5267
|
p = ggplot({'x': x, 'y': y}, aes(x='x', y='y'))
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5268
|
+
bandwidths = [0.2, 0.4]
|
|
5269
|
+
sample_sizes = [16, 256]
|
|
5270
|
+
plots = [
|
|
5271
|
+
p + geom_density2df(kernel='epanechikov', size=.5, color='white',
|
|
5272
|
+
bw=bw, n=n
|
|
5273
|
+
) + ggtitle(f'bw={bw}, n={n}')
|
|
5274
|
+
for bw in bandwidths
|
|
5275
|
+
for n in sample_sizes
|
|
5276
|
+
]
|
|
5277
|
+
gggrid(plots, ncol=2) + ggsize(600, 650)
|
|
5094
5278
|
|
|
5095
5279
|
|
|
|
5096
5280
|
|
|
@@ -5106,15 +5290,18 @@ def geom_density2df(mapping=None, *, data=None, stat=None, position=None, show_l
|
|
|
5106
5290
|
x = np.random.normal(size=n)
|
|
5107
5291
|
y = np.random.normal(size=n)
|
|
5108
5292
|
p = ggplot({'x': x, 'y': y}, aes(x='x', y='y'))
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5293
|
+
adjustments = [1.5, 2.5]
|
|
5294
|
+
bin_counts = [5, 15]
|
|
5295
|
+
plots = [
|
|
5296
|
+
p + geom_density2df(kernel='cosine', size=.5, color='white',
|
|
5297
|
+
adjust=adjust,
|
|
5298
|
+
bins=bins
|
|
5299
|
+
) + ggtitle(f'adjust={adjust}, bins={bins}')
|
|
5300
|
+
for adjust in adjustments
|
|
5301
|
+
for bins in bin_counts
|
|
5302
|
+
]
|
|
5303
|
+
|
|
5304
|
+
gggrid(plots, ncol=2) + ggsize(600, 650)
|
|
5118
5305
|
|
|
5119
5306
|
|
|
|
5120
5307
|
|
|
@@ -6154,7 +6341,7 @@ def geom_rect(mapping=None, *, data=None, stat=None, position=None, show_legend=
|
|
|
6154
6341
|
|
|
6155
6342
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `MultiPoint`, `Line`, `MultiLine`, `Polygon` and `MultiPolygon`.
|
|
6156
6343
|
|
|
6157
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
6344
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_limits()` function.
|
|
6158
6345
|
|
|
6159
6346
|
----
|
|
6160
6347
|
|
|
@@ -6820,7 +7007,7 @@ def geom_text(mapping=None, *, data=None, stat=None, position=None, show_legend=
|
|
|
6820
7007
|
|
|
6821
7008
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Point` and `MultiPoint`.
|
|
6822
7009
|
|
|
6823
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
7010
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_centroids()` function.
|
|
6824
7011
|
|
|
6825
7012
|
----
|
|
6826
7013
|
|
|
@@ -7067,7 +7254,7 @@ def geom_label(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
7067
7254
|
|
|
7068
7255
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Point` and `MultiPoint`.
|
|
7069
7256
|
|
|
7070
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
7257
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_centroids()` function.
|
|
7071
7258
|
|
|
7072
7259
|
----
|
|
7073
7260
|
|
|
@@ -7305,7 +7492,7 @@ def geom_pie(mapping=None, *, data=None, stat=None, position=None, show_legend=N
|
|
|
7305
7492
|
|
|
7306
7493
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Point` and `MultiPoint`.
|
|
7307
7494
|
|
|
7308
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
7495
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_centroids()` function.
|
|
7309
7496
|
|
|
7310
7497
|
----
|
|
7311
7498
|
|
|
@@ -7814,7 +8001,7 @@ def geom_blank(mapping=None, *, data=None, stat=None, position=None, show_legend
|
|
|
7814
8001
|
|
|
7815
8002
|
The `data` and `map` parameters of `GeoDataFrame` type support shapes `Point` and `MultiPoint`.
|
|
7816
8003
|
|
|
7817
|
-
The `map` parameter of `Geocoder` type implicitly invokes `
|
|
8004
|
+
The `map` parameter of `Geocoder` type implicitly invokes `get_centroids()` function.
|
|
7818
8005
|
|
|
7819
8006
|
----
|
|
7820
8007
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) 2025. JetBrains s.r.o.
|
|
2
|
+
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
|
|
3
|
+
|
|
4
|
+
from numbers import Number
|
|
5
|
+
from typing import List, Tuple
|
|
6
|
+
|
|
7
|
+
from ._global_theme import _get_global_theme
|
|
8
|
+
from .subplots import SupPlotsLayoutSpec
|
|
9
|
+
from .subplots import SupPlotsSpec
|
|
10
|
+
from .subplots_util import _strip_theme_if_global
|
|
11
|
+
|
|
12
|
+
__all__ = ['ggbunch']
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def ggbunch(plots: List,
|
|
16
|
+
regions: List[Tuple[float, float, float, float, float, float]]
|
|
17
|
+
) -> SupPlotsSpec:
|
|
18
|
+
"""
|
|
19
|
+
Combine several plots into a single figure with custom layout.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
plots : List
|
|
24
|
+
A list where each element is one of:
|
|
25
|
+
|
|
26
|
+
- a plot specification
|
|
27
|
+
- a subplots specification
|
|
28
|
+
- None
|
|
29
|
+
|
|
30
|
+
regions : List[Tuple]
|
|
31
|
+
Layout parameters for each plot. Each region is specified as
|
|
32
|
+
(x, y, width, height, dx, dy) where:
|
|
33
|
+
|
|
34
|
+
- x, y: Position of the plot's top-left corner in relative coordinates ([0,0] is top-left corner, [1,1] is bottom-right corner of the container).
|
|
35
|
+
- width, height: Size of the plot relative to container dimensions (1 equal to the full container width/height).
|
|
36
|
+
- dx, dy: Pixel offsets to move the region (defaults to 0).
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
`SupPlotsSpec`
|
|
41
|
+
A specification describing the combined figure with all plots and their layout.
|
|
42
|
+
|
|
43
|
+
Examples
|
|
44
|
+
--------
|
|
45
|
+
.. jupyter-execute::
|
|
46
|
+
:linenos:
|
|
47
|
+
:emphasize-lines: 10-14
|
|
48
|
+
|
|
49
|
+
import numpy as np
|
|
50
|
+
from lets_plot import *
|
|
51
|
+
LetsPlot.setup_html()
|
|
52
|
+
np.random.seed(42)
|
|
53
|
+
data = {'x': np.random.gamma(2.0, size=100)}
|
|
54
|
+
p1 = ggplot(data, aes(x='x')) + \\
|
|
55
|
+
geom_histogram(aes(color='x', fill='x'))
|
|
56
|
+
p2 = ggplot(data, aes(x='x')) + \\
|
|
57
|
+
geom_density() + theme_bw() + theme(axis='blank', panel_grid='blank')
|
|
58
|
+
ggbunch(
|
|
59
|
+
[p1, p2],
|
|
60
|
+
[(0, 0, 1, 1),
|
|
61
|
+
(0.5, 0.1, 0.3, 0.3)]
|
|
62
|
+
) + ggsize(400, 300)
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
if not len(plots):
|
|
67
|
+
raise ValueError("Supplots list is empty.")
|
|
68
|
+
|
|
69
|
+
# Validate provided regions
|
|
70
|
+
for i, region in enumerate(regions):
|
|
71
|
+
if len(region) not in (4, 6):
|
|
72
|
+
raise ValueError(f"Region {i} must have 4 or 6 values, got {len(region)}")
|
|
73
|
+
if not all(isinstance(x, Number) for x in region):
|
|
74
|
+
raise ValueError(f"Region {i} contains non-numeric values: {region}")
|
|
75
|
+
|
|
76
|
+
# Validate size is positive
|
|
77
|
+
if any(x <= 0 for x in region[2:4]):
|
|
78
|
+
raise ValueError(f"Region {i} sizes must be positive: {region}")
|
|
79
|
+
|
|
80
|
+
# Convert regions tuples to lists
|
|
81
|
+
regions_list = [list(r) for r in regions]
|
|
82
|
+
layout = SupPlotsLayoutSpec(
|
|
83
|
+
name="free",
|
|
84
|
+
regions=regions_list
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
figures = [_strip_theme_if_global(fig) for fig in plots]
|
|
88
|
+
|
|
89
|
+
figure_spec = SupPlotsSpec(figures=figures, layout=layout)
|
|
90
|
+
|
|
91
|
+
# Apply global theme if defined
|
|
92
|
+
global_theme_options = _get_global_theme()
|
|
93
|
+
if global_theme_options is not None:
|
|
94
|
+
figure_spec += global_theme_options
|
|
95
|
+
|
|
96
|
+
return figure_spec
|
lets_plot/plot/gggrid_.py
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
# Use of this source code is governed by the MIT license that can be found in the LICENSE file.
|
|
4
4
|
#
|
|
5
5
|
|
|
6
|
-
from lets_plot.plot.core import PlotSpec
|
|
7
6
|
from ._global_theme import _get_global_theme
|
|
8
7
|
from .subplots import SupPlotsLayoutSpec
|
|
9
8
|
from .subplots import SupPlotsSpec
|
|
9
|
+
from .subplots_util import _strip_theme_if_global
|
|
10
10
|
|
|
11
11
|
__all__ = ['gggrid']
|
|
12
12
|
|
|
@@ -114,27 +114,12 @@ def gggrid(plots: list, ncol: int = None, *,
|
|
|
114
114
|
align=align
|
|
115
115
|
)
|
|
116
116
|
|
|
117
|
-
# Global Theme
|
|
118
|
-
global_theme_options = _get_global_theme()
|
|
119
|
-
|
|
120
|
-
def _strip_theme_if_global(fig):
|
|
121
|
-
# Strip global theme options from plots in grid (see issue: #966).
|
|
122
|
-
if global_theme_options is not None and fig is not None and 'theme' in fig.props() and fig.props()[
|
|
123
|
-
'theme'] == global_theme_options.props():
|
|
124
|
-
if isinstance(fig, PlotSpec):
|
|
125
|
-
fig = PlotSpec.duplicate(fig)
|
|
126
|
-
fig.props().pop('theme')
|
|
127
|
-
return fig
|
|
128
|
-
elif isinstance(fig, SupPlotsSpec):
|
|
129
|
-
fig = SupPlotsSpec.duplicate(fig)
|
|
130
|
-
fig.props().pop('theme')
|
|
131
|
-
return fig
|
|
132
|
-
return fig
|
|
133
|
-
|
|
134
117
|
figures = [_strip_theme_if_global(fig) for fig in plots]
|
|
135
118
|
|
|
136
119
|
figure_spec = SupPlotsSpec(figures=figures, layout=layout)
|
|
137
120
|
|
|
121
|
+
# Apply global theme if defined
|
|
122
|
+
global_theme_options = _get_global_theme()
|
|
138
123
|
if global_theme_options is not None:
|
|
139
124
|
figure_spec += global_theme_options
|
|
140
125
|
|
lets_plot/plot/plot.py
CHANGED
|
@@ -142,6 +142,9 @@ def ggsize(width, height):
|
|
|
142
142
|
|
|
143
143
|
class GGBunch(FeatureSpec):
|
|
144
144
|
"""
|
|
145
|
+
Class `GGBunch` is deprecated and will be removed in future releases.
|
|
146
|
+
Please, use function `ggbunch()` to combine several plots into a single figure with custom layout.
|
|
147
|
+
|
|
145
148
|
Collection of plots created by ggplot function.
|
|
146
149
|
Use method `add_plot()` to add plot to 'bunch'.
|
|
147
150
|
Each plot can have arbitrary location and size.
|
|
@@ -176,6 +179,10 @@ class GGBunch(FeatureSpec):
|
|
|
176
179
|
"""
|
|
177
180
|
super().__init__('ggbunch', None)
|
|
178
181
|
self.items = []
|
|
182
|
+
print("\n(!) WARN: class GGBunch is deprecated and will be removed in future releases.\n\n"
|
|
183
|
+
" Please, use function ggbunch() to combine several plots into\n"
|
|
184
|
+
" a single figure with custom layout.\n")
|
|
185
|
+
|
|
179
186
|
|
|
180
187
|
def add_plot(self, plot_spec: PlotSpec, x, y, width=None, height=None):
|
|
181
188
|
"""
|