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,209 @@
1
+ # Copyright (c) 2024. 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
+ from datetime import datetime, date, time
4
+ from typing import Union, Dict, Iterable, Optional
5
+
6
+ from lets_plot._type_utils import is_polars_dataframe
7
+ from lets_plot.plot.util import is_pandas_data_frame
8
+
9
+ try:
10
+ import numpy
11
+ except ImportError:
12
+ numpy = None
13
+
14
+ try:
15
+ import pandas
16
+ except ImportError:
17
+ pass
18
+
19
+ try:
20
+ import polars as pl
21
+ from polars.datatypes.group import INTEGER_DTYPES as PL_INTEGER_DTYPES
22
+ from polars.datatypes.group import FLOAT_DTYPES as PL_FLOAT_DTYPES
23
+ except ImportError:
24
+ pass
25
+
26
+ TYPE_INTEGER = 'int'
27
+ TYPE_FLOATING = 'float'
28
+ TYPE_STRING = 'str'
29
+ TYPE_BOOLEAN = 'bool'
30
+ TYPE_DATE_TIME = 'datetime'
31
+ TYPE_DATE = 'date' # Local date (no time zone)
32
+ TYPE_TIME = 'time' # Local time (we ignore time zone even if it is present)
33
+ TYPE_UNKNOWN = 'unknown'
34
+
35
+
36
+ def _infer_type(data: Union[Dict, 'pandas.DataFrame', 'polars.DataFrame']) -> Dict[str, str]:
37
+ type_info = {}
38
+
39
+ if is_pandas_data_frame(data):
40
+ for var_name, var_content in data.items():
41
+ type_info[var_name] = _infer_type_pandas_dataframe(var_name, var_content)
42
+ elif is_polars_dataframe(data):
43
+ for var_name, var_type in data.schema.items():
44
+ type_info[var_name] = _infer_type_polars_dataframe(var_name, var_type)
45
+ elif isinstance(data, dict):
46
+ for var_name, var_content in data.items():
47
+ type_info[var_name] = _infer_type_dict(var_name, var_content)
48
+
49
+ return type_info
50
+
51
+
52
+ def _infer_type_pandas_dataframe(var_name: str, var_content) -> str:
53
+ if var_content.empty:
54
+ return TYPE_UNKNOWN
55
+ elif var_content.isna().all():
56
+ return TYPE_UNKNOWN
57
+
58
+ lp_dtype = TYPE_UNKNOWN
59
+ time_zone = None
60
+ pandas_dtype = pandas.api.types.infer_dtype(var_content.values, skipna=True)
61
+
62
+ if pandas_dtype == "categorical":
63
+ dtype = var_content.cat.categories.dtype
64
+
65
+ if numpy.issubdtype(dtype, numpy.integer):
66
+ lp_dtype = TYPE_INTEGER
67
+ elif numpy.issubdtype(dtype, numpy.floating):
68
+ lp_dtype = TYPE_FLOATING
69
+ elif numpy.issubdtype(dtype, numpy.object_):
70
+ # Check if all elements are strings
71
+ if all(isinstance(x, str) for x in var_content.cat.categories):
72
+ lp_dtype = TYPE_STRING
73
+ else:
74
+ # see https://pandas.pydata.org/docs/reference/api/pandas.api.types.infer_dtype.html
75
+ if pandas_dtype == 'string':
76
+ lp_dtype = TYPE_STRING
77
+ elif pandas_dtype == 'floating':
78
+ lp_dtype = TYPE_FLOATING
79
+ elif pandas_dtype == 'integer':
80
+ lp_dtype = TYPE_INTEGER
81
+ elif pandas_dtype == 'boolean':
82
+ lp_dtype = TYPE_BOOLEAN
83
+
84
+ elif pandas_dtype == 'datetime64' or pandas_dtype == 'datetime':
85
+ lp_dtype = TYPE_DATE_TIME
86
+ elif pandas_dtype == "date":
87
+ lp_dtype = TYPE_DATE
88
+ elif pandas_dtype == "time":
89
+ lp_dtype = TYPE_TIME
90
+
91
+ elif pandas_dtype == 'empty': # for columns with all None values
92
+ lp_dtype = TYPE_UNKNOWN
93
+ else:
94
+ lp_dtype = 'unknown(pandas:' + pandas_dtype + ')'
95
+
96
+ return lp_dtype
97
+
98
+
99
+ def _infer_type_polars_dataframe(var_name: str, var_type) -> str:
100
+ lp_dtype = TYPE_UNKNOWN
101
+
102
+ # https://docs.pola.rs/api/python/stable/reference/datatypes.html
103
+ if isinstance(var_type, pl.datatypes.Enum):
104
+ # In the current version of Polars, Enum is always a string
105
+ # https://docs.pola.rs/api/python/stable/reference/datatypes.html#string
106
+ return TYPE_STRING
107
+ elif isinstance(var_type, pl.datatypes.Categorical):
108
+ return TYPE_STRING
109
+ elif var_type in PL_FLOAT_DTYPES:
110
+ lp_dtype = TYPE_FLOATING
111
+ elif var_type in PL_INTEGER_DTYPES:
112
+ lp_dtype = TYPE_INTEGER
113
+ elif var_type == pl.datatypes.String:
114
+ lp_dtype = TYPE_STRING
115
+ elif var_type == pl.datatypes.Boolean:
116
+ lp_dtype = TYPE_BOOLEAN
117
+
118
+ elif var_type == pl.datatypes.Datetime:
119
+ lp_dtype = TYPE_DATE_TIME
120
+ elif var_type == pl.datatypes.Date:
121
+ lp_dtype = TYPE_DATE
122
+ elif var_type == pl.datatypes.Time:
123
+ lp_dtype = TYPE_TIME
124
+
125
+ else:
126
+ lp_dtype = 'unknown(polars:' + str(var_type) + ')'
127
+
128
+ return lp_dtype
129
+
130
+
131
+ def _infer_type_dict(var_name: str, var_content) -> str:
132
+ if isinstance(var_content, Iterable):
133
+ if not any(True for _ in var_content): # empty
134
+ return TYPE_UNKNOWN
135
+ else:
136
+ return TYPE_UNKNOWN
137
+
138
+ type_set = set(type(val) for val in var_content)
139
+ if type(None) in type_set:
140
+ type_set.remove(type(None))
141
+
142
+ if len(type_set) == 0:
143
+ return TYPE_UNKNOWN
144
+
145
+ if len(type_set) > 1:
146
+ if all(issubclass(type_obj, int) or issubclass(type_obj, float) for type_obj in type_set):
147
+ return TYPE_FLOATING
148
+ else:
149
+ return 'unknown(mixed types)'
150
+
151
+ lp_dtype = TYPE_UNKNOWN
152
+ type_obj = list(type_set)[0]
153
+ if type_obj == bool:
154
+ lp_dtype = TYPE_BOOLEAN
155
+ elif issubclass(type_obj, int):
156
+ lp_dtype = TYPE_INTEGER
157
+ elif issubclass(type_obj, float):
158
+ lp_dtype = TYPE_FLOATING
159
+ elif issubclass(type_obj, str):
160
+ lp_dtype = TYPE_STRING
161
+
162
+ elif issubclass(type_obj, datetime):
163
+ lp_dtype = TYPE_DATE_TIME
164
+ elif issubclass(type_obj, date) and not issubclass(type_obj, datetime):
165
+ lp_dtype = TYPE_DATE
166
+ elif issubclass(type_obj, time):
167
+ lp_dtype = TYPE_TIME
168
+
169
+ elif numpy and issubclass(type_obj, numpy.datetime64):
170
+ lp_dtype = TYPE_DATE_TIME
171
+ elif numpy and issubclass(type_obj, numpy.timedelta64):
172
+ # ToDo: time delta?
173
+ # lp_dtype = TYPE_DATE_TIME
174
+ lp_dtype = 'unknown(python:' + str(type_obj) + ')'
175
+
176
+ elif numpy and issubclass(type_obj, numpy.integer):
177
+ lp_dtype = TYPE_INTEGER
178
+ elif numpy and issubclass(type_obj, numpy.floating):
179
+ lp_dtype = TYPE_FLOATING
180
+ else:
181
+ lp_dtype = 'unknown(python:' + str(type_obj) + ')'
182
+
183
+ return lp_dtype
184
+
185
+
186
+ def _detect_time_zone(var_name: str, data: Union[Dict, 'pandas.DataFrame', 'polars.DataFrame']) -> Optional[str]:
187
+ if is_pandas_data_frame(data):
188
+ if var_name in data:
189
+ var_content = data[var_name]
190
+ if hasattr(var_content, 'dt') and hasattr(var_content.dt, 'tz') and var_content.dt.tz is not None:
191
+ return str(var_content.dt.tz)
192
+ elif is_polars_dataframe(data):
193
+ if var_name in data.columns:
194
+ col_dtype = data[var_name].dtype
195
+ if hasattr(col_dtype, 'time_zone'):
196
+ if col_dtype.time_zone is not None:
197
+ return str(col_dtype.time_zone)
198
+ elif isinstance(data, dict):
199
+ if var_name in data:
200
+ var_content = data[var_name]
201
+ if isinstance(var_content, Iterable):
202
+ for val in var_content:
203
+ if isinstance(val, datetime) and val.tzinfo is not None:
204
+ return str(val.tzinfo)
205
+
206
+ # NumPy datetime64 objects don't store timezone information,
207
+ # so we can't extract it from them.
208
+
209
+ return None