lets-plot 4.8.1rc1__cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.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.
Files changed (97) hide show
  1. lets_plot/__init__.py +382 -0
  2. lets_plot/_global_settings.py +192 -0
  3. lets_plot/_kbridge.py +197 -0
  4. lets_plot/_type_utils.py +133 -0
  5. lets_plot/_version.py +6 -0
  6. lets_plot/bistro/__init__.py +16 -0
  7. lets_plot/bistro/_plot2d_common.py +106 -0
  8. lets_plot/bistro/corr.py +448 -0
  9. lets_plot/bistro/im.py +196 -0
  10. lets_plot/bistro/joint.py +192 -0
  11. lets_plot/bistro/qq.py +207 -0
  12. lets_plot/bistro/residual.py +341 -0
  13. lets_plot/bistro/waterfall.py +332 -0
  14. lets_plot/export/__init__.py +6 -0
  15. lets_plot/export/ggsave_.py +172 -0
  16. lets_plot/frontend_context/__init__.py +8 -0
  17. lets_plot/frontend_context/_configuration.py +140 -0
  18. lets_plot/frontend_context/_dynamic_configure_html.py +115 -0
  19. lets_plot/frontend_context/_frontend_ctx.py +16 -0
  20. lets_plot/frontend_context/_html_contexts.py +223 -0
  21. lets_plot/frontend_context/_intellij_python_json_ctx.py +38 -0
  22. lets_plot/frontend_context/_isolated_webview_panel_ctx.py +81 -0
  23. lets_plot/frontend_context/_json_contexts.py +39 -0
  24. lets_plot/frontend_context/_jupyter_notebook_ctx.py +82 -0
  25. lets_plot/frontend_context/_mime_types.py +7 -0
  26. lets_plot/frontend_context/_static_html_page_ctx.py +76 -0
  27. lets_plot/frontend_context/_static_svg_ctx.py +26 -0
  28. lets_plot/frontend_context/_webbr_html_page_ctx.py +29 -0
  29. lets_plot/frontend_context/sandbox.py +5 -0
  30. lets_plot/geo_data/__init__.py +19 -0
  31. lets_plot/geo_data/core.py +335 -0
  32. lets_plot/geo_data/geocoder.py +988 -0
  33. lets_plot/geo_data/geocodes.py +512 -0
  34. lets_plot/geo_data/gis/__init__.py +0 -0
  35. lets_plot/geo_data/gis/fluent_dict.py +201 -0
  36. lets_plot/geo_data/gis/geocoding_service.py +42 -0
  37. lets_plot/geo_data/gis/geometry.py +91 -0
  38. lets_plot/geo_data/gis/json_request.py +232 -0
  39. lets_plot/geo_data/gis/json_response.py +308 -0
  40. lets_plot/geo_data/gis/request.py +492 -0
  41. lets_plot/geo_data/gis/response.py +247 -0
  42. lets_plot/geo_data/livemap_helper.py +65 -0
  43. lets_plot/geo_data/to_geo_data_frame.py +141 -0
  44. lets_plot/geo_data/type_assertion.py +34 -0
  45. lets_plot/geo_data_internals/__init__.py +4 -0
  46. lets_plot/geo_data_internals/constants.py +13 -0
  47. lets_plot/geo_data_internals/utils.py +33 -0
  48. lets_plot/mapping.py +115 -0
  49. lets_plot/package_data/lets-plot.min.js +3 -0
  50. lets_plot/plot/__init__.py +64 -0
  51. lets_plot/plot/_global_theme.py +14 -0
  52. lets_plot/plot/annotation.py +290 -0
  53. lets_plot/plot/coord.py +242 -0
  54. lets_plot/plot/core.py +1071 -0
  55. lets_plot/plot/expand_limits_.py +78 -0
  56. lets_plot/plot/facet.py +210 -0
  57. lets_plot/plot/font_features.py +71 -0
  58. lets_plot/plot/geom.py +9146 -0
  59. lets_plot/plot/geom_extras.py +53 -0
  60. lets_plot/plot/geom_function_.py +219 -0
  61. lets_plot/plot/geom_imshow_.py +393 -0
  62. lets_plot/plot/geom_livemap_.py +343 -0
  63. lets_plot/plot/ggbunch_.py +96 -0
  64. lets_plot/plot/gggrid_.py +139 -0
  65. lets_plot/plot/ggtb_.py +81 -0
  66. lets_plot/plot/guide.py +231 -0
  67. lets_plot/plot/label.py +187 -0
  68. lets_plot/plot/marginal_layer.py +181 -0
  69. lets_plot/plot/plot.py +245 -0
  70. lets_plot/plot/pos.py +344 -0
  71. lets_plot/plot/sampling.py +338 -0
  72. lets_plot/plot/sandbox_.py +26 -0
  73. lets_plot/plot/scale.py +3580 -0
  74. lets_plot/plot/scale_colormap_mpl.py +300 -0
  75. lets_plot/plot/scale_convenience.py +155 -0
  76. lets_plot/plot/scale_identity_.py +653 -0
  77. lets_plot/plot/scale_position.py +1342 -0
  78. lets_plot/plot/series_meta.py +209 -0
  79. lets_plot/plot/stat.py +585 -0
  80. lets_plot/plot/subplots.py +331 -0
  81. lets_plot/plot/subplots_util.py +24 -0
  82. lets_plot/plot/theme_.py +790 -0
  83. lets_plot/plot/theme_set.py +418 -0
  84. lets_plot/plot/tooltip.py +486 -0
  85. lets_plot/plot/util.py +267 -0
  86. lets_plot/settings_utils.py +244 -0
  87. lets_plot/tilesets.py +429 -0
  88. lets_plot-4.8.1rc1.dist-info/METADATA +221 -0
  89. lets_plot-4.8.1rc1.dist-info/RECORD +97 -0
  90. lets_plot-4.8.1rc1.dist-info/WHEEL +6 -0
  91. lets_plot-4.8.1rc1.dist-info/licenses/LICENSE +21 -0
  92. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.FreeType +166 -0
  93. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.ImageMagick +106 -0
  94. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.expat +21 -0
  95. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.fontconfig +200 -0
  96. lets_plot-4.8.1rc1.dist-info/top_level.txt +2 -0
  97. lets_plot_kotlin_bridge.cpython-311-x86_64-linux-gnu.so +0 -0
@@ -0,0 +1,448 @@
1
+ # Copyright (c) 2020. 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
+
5
+ """Correlation matrix implementation module"""
6
+ from typing import Any
7
+
8
+ from lets_plot.plot.util import is_pandas_data_frame
9
+
10
+ try:
11
+ import numpy
12
+ except ImportError:
13
+ numpy = None
14
+
15
+ try:
16
+ import pandas
17
+ except ImportError:
18
+ pandas = None
19
+
20
+ from lets_plot.plot.core import PlotSpec
21
+
22
+ __all__ = ['corr_plot']
23
+
24
+
25
+ def _is_corr_matrix(data: Any):
26
+ if is_pandas_data_frame(data):
27
+ if data.shape[0] != data.shape[1]:
28
+ return False
29
+
30
+ if not (all(col_type == 'float64' for col_type in data.dtypes)):
31
+ return False
32
+
33
+ for column in data:
34
+ import math
35
+ if not all(math.isnan(v) or (1.0 >= v >= -1.0) for v in data[column]):
36
+ return False
37
+
38
+ return True
39
+
40
+ elif isinstance(data, dict):
41
+ m = len(data.keys())
42
+ for column in data.values():
43
+ if not isinstance(column, (list, tuple)):
44
+ return False
45
+
46
+ if len(column) != m:
47
+ return False
48
+
49
+ import math
50
+ for v in column:
51
+ if not isinstance(v, float):
52
+ return False
53
+
54
+ if math.isnan(v):
55
+ return True
56
+
57
+ if 1.0 >= v >= -1.0:
58
+ return True
59
+
60
+ return False
61
+
62
+ return True
63
+ else:
64
+ return False
65
+
66
+
67
+ class corr_plot:
68
+ """
69
+ This class is intended to build correlation matrix plot.
70
+
71
+ Notes
72
+ -----
73
+ To hide axis tooltips, set 'blank' or the result of `element_blank() <https://lets-plot.org/python/pages/api/lets_plot.element_blank.html>`__
74
+ 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>`__.
75
+
76
+ Examples
77
+ --------
78
+ .. jupyter-execute::
79
+ :linenos:
80
+ :emphasize-lines: 7
81
+
82
+ import numpy as np
83
+ from lets_plot import *
84
+ from lets_plot.bistro.corr import *
85
+ LetsPlot.setup_html()
86
+ np.random.seed(42)
87
+ data = {var: np.random.poisson(size=10) for var in 'abcdef'}
88
+ corr_plot(data).tiles().build()
89
+
90
+ |
91
+
92
+ .. jupyter-execute::
93
+ :linenos:
94
+ :emphasize-lines: 7-9
95
+
96
+ import numpy as np
97
+ from lets_plot import *
98
+ from lets_plot.bistro.corr import *
99
+ LetsPlot.setup_html()
100
+ np.random.seed(42)
101
+ data = {var: np.random.uniform(size=10) for var in 'abcd'}
102
+ corr_plot(data).tiles(type='upper', diag=True)\\
103
+ .labels(type='upper', diag=True, map_size=True, color='black')\\
104
+ .palette_RdBu().build()
105
+
106
+ |
107
+
108
+ .. jupyter-execute::
109
+ :linenos:
110
+ :emphasize-lines: 7-9
111
+
112
+ import numpy as np
113
+ from lets_plot import *
114
+ from lets_plot.bistro.corr import *
115
+ LetsPlot.setup_html()
116
+ np.random.seed(42)
117
+ data = {var: np.random.normal(size=10) for var in 'abcdef'}
118
+ corr_plot(data, flip=False, threshold=.4).points().labels()\\
119
+ .palette_gradient(low='#d73027', mid='#ffffbf', high='#1a9850')\\
120
+ .build()
121
+
122
+ """
123
+
124
+ def _duplicate(self):
125
+ dup = corr_plot(
126
+ data=self._data,
127
+ show_legend=self._show_legend,
128
+ flip=self._reverse_y,
129
+ threshold=self.threshold
130
+ )
131
+
132
+ dup._color_scale = self._color_scale
133
+ dup._fill_scale = self._fill_scale
134
+ dup._points_params = self._points_params
135
+ dup._tiles_params = self._tiles_params
136
+ dup._labels_params = self._labels_params
137
+ dup._labels_map_size = self._labels_map_size
138
+ dup._palette = self._palette
139
+ dup._low = self._low
140
+ dup._mid = self._mid
141
+ dup._high = self._high
142
+
143
+ return dup
144
+
145
+ def __init__(self, data, show_legend=True, flip=True, threshold=None):
146
+ """
147
+ Parameters
148
+ ----------
149
+ data : dict or Pandas or Polars ``DataFrame``
150
+ Correlation matrix or data (correlation will be calculated for each variable pair).
151
+ Data will be recognized as correlation matrix if it has a square shape and all values are
152
+ in range -1.0..+1.0 or NaN.
153
+ show_legend : bool, default=True
154
+ If True legend is shown.
155
+ flip : bool, default=True
156
+ If True the y axis is flipped.
157
+ threshold : float, default=0.0
158
+ Minimal correlation abs value to be included in result.
159
+ Accept values between 0 and 1.
160
+
161
+ """
162
+
163
+ self._data = data
164
+ self._show_legend = show_legend
165
+ self._reverse_y = flip if flip else False
166
+ self.threshold = threshold
167
+ self._color_scale = None
168
+ self._fill_scale = None
169
+ self._points_params = None
170
+ self._tiles_params = None
171
+ self._labels_params = None
172
+ self._labels_map_size = None
173
+ self._palette = None
174
+ self._low = None
175
+ self._mid = None
176
+ self._high = None
177
+
178
+ def points(self, type=None, diag=None):
179
+ """
180
+ Method defines correlation matrix layer drawn by points to the plot.
181
+
182
+ Parameters
183
+ ----------
184
+ type : {'upper', 'lower', 'full'}
185
+ Type of matrix. Default - contextual.
186
+ diag : bool
187
+ Determines whether to fill the main diagonal with values or not.
188
+ Default - contextual.
189
+
190
+ Returns
191
+ -------
192
+ ``corr_plot``
193
+ Correlation plot specification.
194
+ """
195
+ return self._duplicate()._set_points(type, diag)
196
+
197
+ def labels(self, type=None, diag=None, map_size=None, color=None):
198
+ """
199
+ Method defines correlation matrix layer drawn with geom_text to the plot.
200
+
201
+ Parameters
202
+ ----------
203
+ type : {'upper', 'lower', 'full'}
204
+ Type of matrix. Default - contextual.
205
+ diag : bool
206
+ Determines whether to fill the main diagonal with values or not.
207
+ Default - contextual.
208
+ map_size : bool
209
+ If True, then absolute value of correlation is mapped to text size.
210
+ If False - the text size is constant. Default - contextual.
211
+ color : str
212
+ Set text color.
213
+ For more info see `Color and Fill <https://lets-plot.org/python/pages/aesthetics.html#color-and-fill>`__.
214
+ Default - contextual.
215
+
216
+ Returns
217
+ -------
218
+ ``corr_plot``
219
+ Correlation plot specification.
220
+ """
221
+ return self._duplicate()._set_labels(type, diag, map_size, color)
222
+
223
+ def tiles(self, type=None, diag=None):
224
+ """
225
+ Method defines correlation matrix layer drawn as square tiles to the plot.
226
+
227
+ Parameters
228
+ ----------
229
+ type : {'upper', 'lower', 'full'}
230
+ Type of matrix. Default - contextual.
231
+ diag : bool
232
+ Determines whether to fill the main diagonal with values or not.
233
+ Default - contextual.
234
+
235
+ Returns
236
+ -------
237
+ ``corr_plot``
238
+ Correlation plot specification.
239
+ """
240
+ return self._duplicate()._set_tiles(type, diag)
241
+
242
+ def palette_gradient(self, low, mid, high):
243
+ """
244
+ Set `scale_color_gradient2() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_gradient2.html>`__ and
245
+ `scale_fill_gradient() <https://lets-plot.org/python/pages/api/lets_plot.scale_fill_gradient.html>`__ for corr plot.
246
+
247
+ Parameters
248
+ ----------
249
+ low : str
250
+ Color for low end of gradient (correlation -1).
251
+ mid : str
252
+ Color for mid point (correlation 0).
253
+ high : str
254
+ Color for high end of gradient (correlation 1).
255
+
256
+ Returns
257
+ -------
258
+ ``corr_plot``
259
+ Correlation plot specification.
260
+ """
261
+ return self._duplicate()._set_gradient_palette(low, mid, high)
262
+
263
+ def palette_BrBG(self):
264
+ """
265
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with BrBG palette for corr plot.
266
+
267
+ Returns
268
+ -------
269
+ ``corr_plot``
270
+ Correlation plot specification.
271
+ """
272
+ return self._set_brewer_palette('BrBG')
273
+
274
+ def palette_PiYG(self):
275
+ """
276
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with PiYG palette for corr plot.
277
+
278
+ Returns
279
+ -------
280
+ ``corr_plot``
281
+ Correlation plot specification.
282
+ """
283
+ return self._duplicate()._set_brewer_palette('PiYG')
284
+
285
+ def palette_PRGn(self):
286
+ """
287
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with PRGn palette for corr plot.
288
+
289
+ Returns
290
+ -------
291
+ ``corr_plot``
292
+ Correlation plot specification.
293
+ """
294
+ return self._duplicate()._set_brewer_palette('PRGn')
295
+
296
+ def palette_PuOr(self):
297
+ """
298
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with PuOr palette for corr plot.
299
+
300
+ Returns
301
+ -------
302
+ ``corr_plot``
303
+ Correlation plot specification.
304
+ """
305
+ return self._duplicate()._set_brewer_palette('PuOr')
306
+
307
+ def palette_RdBu(self):
308
+ """
309
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with RdBu palette for corr plot.
310
+
311
+ Returns
312
+ -------
313
+ ``corr_plot``
314
+ Correlation plot specification.
315
+ """
316
+ return self._duplicate()._set_brewer_palette('RdBu')
317
+
318
+ def palette_RdGy(self):
319
+ """
320
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with RdGy palette for corr plot.
321
+
322
+ Returns
323
+ -------
324
+ ``corr_plot``
325
+ Correlation plot specification.
326
+ """
327
+ return self._duplicate()._set_brewer_palette('RdGy')
328
+
329
+ def palette_RdYlBu(self):
330
+ """
331
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with RdYlBu palette for corr plot.
332
+
333
+ Returns
334
+ -------
335
+ ``corr_plot``
336
+ Correlation plot specification.
337
+ """
338
+ return self._duplicate()._set_brewer_palette('RdYlBu')
339
+
340
+ def palette_RdYlGn(self):
341
+ """
342
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with RdYlGn palette for corr plot.
343
+
344
+ Returns
345
+ -------
346
+ ``corr_plot``
347
+ Correlation plot specification.
348
+ """
349
+ return self._duplicate()._set_brewer_palette('RdYlGn')
350
+
351
+ def palette_Spectral(self):
352
+ """
353
+ Set `scale_color_brewer() <https://lets-plot.org/python/pages/api/lets_plot.scale_color_brewer.html>`__ with Spectral palette for corr plot.
354
+
355
+ Returns
356
+ -------
357
+ ``corr_plot``
358
+ Correlation plot specification.
359
+ """
360
+ return self._duplicate()._set_brewer_palette('Spectral')
361
+
362
+ def _set_points(self, type=None, diag=None):
363
+ self._points_params = {'type': type, 'diag': diag, 'threshold': self.threshold}
364
+ return self
365
+
366
+ def _set_labels(self, type=None, diag=None, map_size=None, color=None):
367
+ self._labels_params = {'type': type, 'diag': diag, 'color': color, 'threshold': self.threshold}
368
+ self._labels_map_size = map_size
369
+ return self
370
+
371
+ def _set_tiles(self, type=None, diag=None):
372
+ self._tiles_params = {'type': type, 'diag': diag, 'threshold': self.threshold}
373
+ return self
374
+
375
+ def _set_gradient_palette(self, low, mid, high):
376
+ self._palette = 'gradient'
377
+ self._low = low
378
+ self._mid = mid
379
+ self._high = high
380
+ return self
381
+
382
+ def _set_brewer_palette(self, palette):
383
+ self._palette = palette
384
+ self._low = None
385
+ self._mid = None
386
+ self._high = None
387
+ return self
388
+
389
+ def build(self) -> PlotSpec:
390
+ """
391
+ This method creates PlotSpec object.
392
+
393
+ Returns
394
+ -------
395
+ ``PlotSpec``
396
+ Plot specification.
397
+ """
398
+
399
+ if self._points_params is not None:
400
+ point_params = {
401
+ 'type': self._points_params['type'],
402
+ 'diag': self._points_params['diag']
403
+ }
404
+ else:
405
+ point_params = None
406
+
407
+ if self._labels_params is not None:
408
+ label_params = {
409
+ 'type': self._labels_params['type'],
410
+ 'diag': self._labels_params['diag'],
411
+ 'color': self._labels_params['color'],
412
+ 'map_size': self._labels_map_size
413
+ }
414
+ else:
415
+ label_params = None
416
+
417
+ if self._tiles_params is not None:
418
+ tile_params = {
419
+ 'type': self._tiles_params['type'],
420
+ 'diag': self._tiles_params['diag']
421
+ }
422
+ else:
423
+ tile_params = None
424
+
425
+ data = self._data
426
+ if _is_corr_matrix(data):
427
+ coefficients = True
428
+ else:
429
+ if is_pandas_data_frame(data):
430
+ data = data.corr(numeric_only=True)
431
+ coefficients = True
432
+ else:
433
+ coefficients = False
434
+
435
+ return PlotSpec(data=data, mapping=None, scales=[], layers=[], bistro={
436
+ 'name': 'corr',
437
+ 'coefficients': coefficients,
438
+ 'show_legend': self._show_legend,
439
+ 'flip': self._reverse_y,
440
+ 'threshold': self.threshold,
441
+ 'palette': self._palette,
442
+ 'low': self._low,
443
+ 'mid': self._mid,
444
+ 'high': self._high,
445
+ 'point_params': point_params,
446
+ 'tile_params': tile_params,
447
+ 'label_params': label_params
448
+ })
lets_plot/bistro/im.py ADDED
@@ -0,0 +1,196 @@
1
+ #
2
+ # Copyright (c) 2019. JetBrains s.r.o.
3
+ # Use of this source code is governed by the MIT license that can be found in the LICENSE file.
4
+ #
5
+ from typing import Any
6
+
7
+ from lets_plot._type_utils import is_ndarray
8
+ from lets_plot.plot.geom_imshow_ import geom_imshow
9
+ from lets_plot.plot.ggbunch_ import ggbunch
10
+ from lets_plot.plot.plot import ggplot, ggsize, GGBunch
11
+ from lets_plot.plot.scale_position import scale_x_continuous, scale_y_continuous
12
+ from lets_plot.plot.subplots import SupPlotsSpec
13
+ from lets_plot.plot.theme_ import theme
14
+
15
+ __all__ = ['image_matrix']
16
+
17
+
18
+ def image_matrix(image_data_array,
19
+ cmap=None, *,
20
+ norm=None,
21
+ vmin=None,
22
+ vmax=None,
23
+ scale=1,
24
+ spacer=1,
25
+ ) -> SupPlotsSpec:
26
+ """
27
+ Display a set of images in a grid.
28
+ Dimensions of the grid are determined by the shape of the input Numpy 2D array.
29
+
30
+ Each element of the input 2D array is an 2D or 3D Numpy array itself
31
+ specifying either a grayscale image (2D array) or a color RGB(A) image (3D array).
32
+ For more information on image arrays please see the documentation of geom_imshow() function.
33
+
34
+ Parameters
35
+ ----------
36
+ image_data_array : ``ndarray``
37
+ 2D ``numpy.ndarray`` containing images.
38
+ cmap : str, optional
39
+ Name of colormap. For example "viridis", "magma", "plasma", "inferno", or any other colormap
40
+ which is supported by the Palettable package (https://github.com/jiffyclub/palettable)
41
+ This parameter is ignored for RGB(A) images.
42
+ norm : bool, optional, default=True
43
+ True - luminance values in grey-scale image will be scaled to [0-255] range using a linear scaler.
44
+ False - disables scaling of luminance values in grey-scale image.
45
+ This parameter is ignored for RGB(A) images.
46
+ vmin, vmax : number, optional
47
+ Define the data range used for luminance normalization in grey-scale images.
48
+ This parameter is ignored for RGB(A) images or if parameter ``norm=False``.
49
+ scale : float, default=1.0
50
+ Specify the image size magnification factor.
51
+ spacer : number, default=1
52
+ Specify the number of pixels between images.
53
+
54
+ Returns
55
+ -------
56
+ ``SupPlotsSpec``
57
+ A specification describing the combined figure with all plots and their layout.
58
+
59
+ Examples
60
+ --------
61
+ .. jupyter-execute::
62
+ :linenos:
63
+ :emphasize-lines: 9
64
+
65
+ import numpy as np
66
+ from lets_plot import *
67
+ from lets_plot.bistro.im import *
68
+ LetsPlot.setup_html()
69
+ np.random.seed(42)
70
+ image = np.random.randint(256, size=(64, 64, 3))
71
+ matrix = np.empty((2, 3), dtype=object)
72
+ matrix.fill(image)
73
+ image_matrix(matrix)
74
+
75
+ |
76
+
77
+ .. jupyter-execute::
78
+ :linenos:
79
+ :emphasize-lines: 12
80
+
81
+ import numpy as np
82
+ from lets_plot import *
83
+ from lets_plot.bistro.im import *
84
+ LetsPlot.setup_html()
85
+ rows, cols = 3, 3
86
+ matrix = np.empty((rows, cols), dtype=object)
87
+ for r in range(rows):
88
+ for c in range(cols):
89
+ w, h = 32 + 16 * c, 32 + 16 * r
90
+ matrix[r][c] = 256 * np.linspace(np.linspace(0, .5, w), \\
91
+ np.linspace(.5, .5, w), h)
92
+ image_matrix(matrix, norm=False, scale=1.5)
93
+
94
+ """
95
+
96
+ if not is_ndarray(image_data_array):
97
+ raise Exception("Invalid image_data_array: 2d ndarray is expacted but was {}".format(type(image_data_array)))
98
+
99
+ if image_data_array.ndim != 2:
100
+ raise Exception("Invalid image_data_array: 2-dimentional ndarray is expacted but was {}-dimentional".format(
101
+ image_data_array.ndim))
102
+
103
+ rows, cols = image_data_array.shape
104
+ if cols * rows <= 0:
105
+ return
106
+
107
+ w_max = 0
108
+ h_max = 0
109
+ for row in range(rows):
110
+ for col in range(cols):
111
+ image_data = image_data_array[row][col]
112
+ if image_data is None:
113
+ continue
114
+
115
+ _assert_image_data(image_data)
116
+ h, w = image_data.shape[0:2]
117
+ h, w = _expand_h_w(h, w, scale)
118
+ w_max = max(w_max, w)
119
+ h_max = max(h_max, h)
120
+
121
+ # no gaps between image and plot edges
122
+ options = scale_x_continuous(expand=[0, 0])
123
+ options += scale_y_continuous(expand=[0, 0])
124
+
125
+ # clear all plot decorations, reset plot margins
126
+ options += theme(axis='blank', panel_grid='blank')
127
+ options += theme(plot_inset=0, plot_margin=0, panel_inset=0)
128
+
129
+ figures = []
130
+ regions = []
131
+
132
+ bunch_width = cols * w_max + (cols - 1) * spacer
133
+ bunch_height = rows * h_max + (rows - 1) * spacer
134
+
135
+ for row in range(rows):
136
+ for col in range(cols):
137
+ figures.append(None)
138
+ regions.append((0, 0, 0, 0))
139
+
140
+ image_data = image_data_array[row][col]
141
+ if image_data is None:
142
+ continue
143
+
144
+ h, w = image_data.shape[0:2]
145
+ h, w = _expand_h_w(h, w, scale)
146
+ p = ggplot() + geom_imshow(
147
+ image_data=image_data,
148
+ cmap=cmap,
149
+ norm=norm,
150
+ vmin=vmin,
151
+ vmax=vmax,
152
+ show_legend=False
153
+ )
154
+ p += options
155
+ figures[len(figures) - 1] = p
156
+ regions[len(figures) - 1] = (
157
+ col * (w_max + spacer) / bunch_width,
158
+ row * (h_max + spacer) / bunch_height,
159
+ w / bunch_width,
160
+ h / bunch_height
161
+ )
162
+
163
+ return ggbunch(
164
+ plots=figures,
165
+ regions=regions
166
+ ) + ggsize(
167
+ bunch_width,
168
+ bunch_height
169
+ )
170
+
171
+
172
+ def _assert_image_data(image_data: Any) -> None:
173
+ try:
174
+ import numpy as np
175
+ if not isinstance(image_data, np.ndarray):
176
+ raise Exception("Invalid image_data: ndarray is expacted but was {}".format(type(image_data)))
177
+
178
+ if image_data.ndim not in (2, 3):
179
+ raise Exception(
180
+ "Invalid image_data: 2d or 3d array is expacted but was {}-dimentional".format(image_data.ndim))
181
+ except ImportError:
182
+ pass
183
+
184
+
185
+ def _expand_h_w(h, w, scale):
186
+ if scale:
187
+ h *= scale
188
+ w *= scale
189
+
190
+ # Mininum plot geom area size: 50 x 50
191
+ h = 50 if h < 50 else h
192
+ w = 50 if w < 50 else w
193
+
194
+ # Currently plot has not customizable 10px padding on the right and the bottom
195
+ # return h + 10, w + 10
196
+ return h, w