lets-plot 4.8.0rc1__cp313-cp313-macosx_12_0_arm64.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 (95) hide show
  1. lets_plot/__init__.py +283 -0
  2. lets_plot/_global_settings.py +192 -0
  3. lets_plot/_kbridge.py +149 -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 +170 -0
  16. lets_plot/frontend_context/__init__.py +8 -0
  17. lets_plot/frontend_context/_configuration.py +151 -0
  18. lets_plot/frontend_context/_frontend_ctx.py +16 -0
  19. lets_plot/frontend_context/_html_contexts.py +117 -0
  20. lets_plot/frontend_context/_intellij_python_json_ctx.py +38 -0
  21. lets_plot/frontend_context/_json_contexts.py +39 -0
  22. lets_plot/frontend_context/_jupyter_notebook_ctx.py +119 -0
  23. lets_plot/frontend_context/_mime_types.py +7 -0
  24. lets_plot/frontend_context/_static_html_page_ctx.py +27 -0
  25. lets_plot/frontend_context/_static_svg_ctx.py +26 -0
  26. lets_plot/frontend_context/_webbr_html_page_ctx.py +29 -0
  27. lets_plot/frontend_context/sandbox.py +5 -0
  28. lets_plot/geo_data/__init__.py +19 -0
  29. lets_plot/geo_data/core.py +335 -0
  30. lets_plot/geo_data/geocoder.py +988 -0
  31. lets_plot/geo_data/geocodes.py +512 -0
  32. lets_plot/geo_data/gis/__init__.py +0 -0
  33. lets_plot/geo_data/gis/fluent_dict.py +201 -0
  34. lets_plot/geo_data/gis/geocoding_service.py +42 -0
  35. lets_plot/geo_data/gis/geometry.py +91 -0
  36. lets_plot/geo_data/gis/json_request.py +232 -0
  37. lets_plot/geo_data/gis/json_response.py +308 -0
  38. lets_plot/geo_data/gis/request.py +492 -0
  39. lets_plot/geo_data/gis/response.py +247 -0
  40. lets_plot/geo_data/livemap_helper.py +65 -0
  41. lets_plot/geo_data/to_geo_data_frame.py +141 -0
  42. lets_plot/geo_data/type_assertion.py +34 -0
  43. lets_plot/geo_data_internals/__init__.py +4 -0
  44. lets_plot/geo_data_internals/constants.py +13 -0
  45. lets_plot/geo_data_internals/utils.py +33 -0
  46. lets_plot/mapping.py +115 -0
  47. lets_plot/package_data/lets-plot.min.js +3 -0
  48. lets_plot/plot/__init__.py +64 -0
  49. lets_plot/plot/_global_theme.py +14 -0
  50. lets_plot/plot/annotation.py +290 -0
  51. lets_plot/plot/coord.py +242 -0
  52. lets_plot/plot/core.py +1025 -0
  53. lets_plot/plot/expand_limits_.py +78 -0
  54. lets_plot/plot/facet.py +210 -0
  55. lets_plot/plot/font_features.py +71 -0
  56. lets_plot/plot/geom.py +9144 -0
  57. lets_plot/plot/geom_extras.py +53 -0
  58. lets_plot/plot/geom_function_.py +219 -0
  59. lets_plot/plot/geom_imshow_.py +393 -0
  60. lets_plot/plot/geom_livemap_.py +343 -0
  61. lets_plot/plot/ggbunch_.py +96 -0
  62. lets_plot/plot/gggrid_.py +139 -0
  63. lets_plot/plot/ggtb_.py +81 -0
  64. lets_plot/plot/guide.py +231 -0
  65. lets_plot/plot/label.py +187 -0
  66. lets_plot/plot/marginal_layer.py +181 -0
  67. lets_plot/plot/plot.py +245 -0
  68. lets_plot/plot/pos.py +344 -0
  69. lets_plot/plot/sampling.py +338 -0
  70. lets_plot/plot/sandbox_.py +26 -0
  71. lets_plot/plot/scale.py +3580 -0
  72. lets_plot/plot/scale_colormap_mpl.py +300 -0
  73. lets_plot/plot/scale_convenience.py +155 -0
  74. lets_plot/plot/scale_identity_.py +662 -0
  75. lets_plot/plot/scale_position.py +1342 -0
  76. lets_plot/plot/series_meta.py +209 -0
  77. lets_plot/plot/stat.py +585 -0
  78. lets_plot/plot/subplots.py +331 -0
  79. lets_plot/plot/subplots_util.py +24 -0
  80. lets_plot/plot/theme_.py +795 -0
  81. lets_plot/plot/theme_set.py +418 -0
  82. lets_plot/plot/tooltip.py +486 -0
  83. lets_plot/plot/util.py +267 -0
  84. lets_plot/settings_utils.py +244 -0
  85. lets_plot/tilesets.py +429 -0
  86. lets_plot-4.8.0rc1.dist-info/METADATA +220 -0
  87. lets_plot-4.8.0rc1.dist-info/RECORD +95 -0
  88. lets_plot-4.8.0rc1.dist-info/WHEEL +5 -0
  89. lets_plot-4.8.0rc1.dist-info/licenses/LICENSE +21 -0
  90. lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.FreeType +166 -0
  91. lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.ImageMagick +106 -0
  92. lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.expat +21 -0
  93. lets_plot-4.8.0rc1.dist-info/licenses/licenses/LICENSE.fontconfig +200 -0
  94. lets_plot-4.8.0rc1.dist-info/top_level.txt +2 -0
  95. lets_plot_kotlin_bridge.cpython-313-darwin.so +0 -0
@@ -0,0 +1,170 @@
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
+ import os
5
+ from os.path import join
6
+ from typing import Union, Optional
7
+
8
+ from ..plot.core import PlotSpec
9
+ from ..plot.core import _to_svg, _to_html, _export_as_raster
10
+ from ..plot.plot import GGBunch
11
+ from ..plot.subplots import SupPlotsSpec
12
+
13
+ __all__ = ['ggsave']
14
+
15
+ _DEF_EXPORT_DIR = "lets-plot-images"
16
+
17
+
18
+ def ggsave(plot: Union[PlotSpec, SupPlotsSpec, GGBunch], filename: str, *, path: str = None, iframe: bool = True,
19
+ scale: float = None, w: Optional[float] = None, h: Optional[float] = None, unit: Optional[str] = None,
20
+ dpi: Optional[int] = None) -> str:
21
+ """
22
+ Export plot to a file.
23
+ Supported formats: PNG, SVG, PDF, HTML.
24
+
25
+ The exported file is created in the directory ${user.dir}/lets-plot-images
26
+ if not specified otherwise (see the ``path`` parameter).
27
+
28
+ Parameters
29
+ ----------
30
+ plot : ``PlotSpec``
31
+ Plot specification to export.
32
+ filename : str
33
+ Name of the file. It must end with a file extension corresponding
34
+ to one of the supported formats: SVG, HTML (or HTM), PNG, PDF (requires the pillow library).
35
+ path : str
36
+ Path to a directory to save image files in.
37
+ By default, it is ${user.dir}/lets-plot-images.
38
+ iframe : bool, default=True
39
+ Whether to wrap the HTML page into an iFrame.
40
+ Only applicable when exporting to HTML.
41
+ Some browsers may not display some UTF-8 characters correctly when setting iframe=True
42
+ scale : float, default=2.0
43
+ Scaling factor for raster output.
44
+ Only applicable when exporting to PNG or PDF.
45
+ w : float, default=None
46
+ Width of the output image in units.
47
+ Only applicable when exporting to SVG, PNG, or PDF.
48
+ h : float, default=None
49
+ Height of the output image in units.
50
+ Only applicable when exporting to SVG, PNG, or PDF.
51
+ unit : {'in', 'cm', 'mm', 'px'}, default='in'
52
+ Unit of the output image. One of: 'in', 'cm', 'mm' or 'px'.
53
+ Only applicable when exporting to SVG, PNG, or PDF.
54
+ dpi : int, default=300
55
+ Resolution in dots per inch.
56
+ Only applicable when exporting to PNG or PDF.
57
+ The default value depends on the unit:
58
+
59
+ - for 'px' it is 96 (output image will have the same pixel size as ``w``, and ``h`` values)
60
+ - for physical units ('in', 'cm', 'mm') it is 300.
61
+
62
+ Returns
63
+ -------
64
+ str
65
+ Absolute pathname of the created file.
66
+
67
+ Notes
68
+ -----
69
+ Large plot dimensions without units require explicit unit specification.
70
+ When ``w`` or ``h`` value exceeds 20 without specifying units (e.g., ``ggsave(p, 300, 400)``),
71
+ we ask to specify units explicitly:
72
+ ``ggsave(p, 300, 400, unit='px')`` or ``ggsave(p, 3, 4, unit='in')``.
73
+
74
+ ----
75
+
76
+ The output format is inferred from the filename extension.
77
+
78
+ For PNG, and PDF formats:
79
+
80
+ - If ``w``, ``h``, ``unit``, and ``dpi`` are all specified:
81
+
82
+ - The plot's pixel size (default or set by `ggsize() <https://lets-plot.org/python/pages/api/lets_plot.ggsize.html>`__) is ignored.
83
+ - The output size is calculated using the specified ``w``, ``h``, ``unit`` and ``dpi``.
84
+
85
+ - The plot is resized to fit the specified ``w`` x ``h`` area, which may affect the layout, tick labels, and other elements.
86
+
87
+ - If only ``dpi`` is specified:
88
+
89
+ - The plot's pixel size (default or set by `ggsize() <https://lets-plot.org/python/pages/api/lets_plot.ggsize.html>`__) is converted to inches using the standard display PPI of 96.
90
+ - The output size is then calculated based on the specified DPI.
91
+
92
+ - The plot maintains its aspect ratio, preserving layout, tick labels, and other visual elements.
93
+ - Useful for printing - the plot will appear nearly the same size as on screen.
94
+
95
+ - If ``w``, ``h`` are not specified:
96
+
97
+ - The ``scale`` parameter is used to determine the output size.
98
+
99
+ - The plot maintains its aspect ratio, preserving layout, tick labels, and other visual elements.
100
+ - Useful for generating high-resolution images suitable for publication.
101
+
102
+ For SVG format:
103
+
104
+ - If ``w``, ``h``, and ``unit`` are specified:
105
+
106
+ - The plot's pixel size (default or set by `ggsize() <https://lets-plot.org/python/pages/api/lets_plot.ggsize.html>`__) is ignored.
107
+ - The output size is calculated using the specified ``w``, ``h``, and ``unit``.
108
+
109
+ ----
110
+
111
+ Plots with ``geom_livemap()`` can be saved to HTML only.
112
+
113
+
114
+ Examples
115
+ --------
116
+ .. jupyter-execute::
117
+ :linenos:
118
+ :emphasize-lines: 6
119
+
120
+ from IPython.display import Image
121
+ from lets_plot import *
122
+ LetsPlot.setup_html()
123
+ filename = 'plot.png'
124
+ plot = ggplot() + geom_point(x=0, y=0) + ggtitle(filename)
125
+ fullpath = ggsave(plot, filename, w=4, h=3)
126
+ Image(filename=fullpath, width=600, height=450)
127
+
128
+ |
129
+
130
+ .. jupyter-execute::
131
+ :linenos:
132
+ :emphasize-lines: 6
133
+
134
+ from IPython.display import HTML
135
+ from lets_plot import *
136
+ LetsPlot.setup_html()
137
+ filename = 'plot.html'
138
+ plot = ggplot() + geom_point(x=0, y=0) + ggtitle(filename)
139
+ fullpath = ggsave(plot, filename, iframe=False)
140
+ HTML(filename=fullpath)
141
+
142
+ """
143
+
144
+ if not (isinstance(plot, PlotSpec) or isinstance(plot, SupPlotsSpec) or isinstance(plot, GGBunch)):
145
+ raise ValueError("PlotSpec, SupPlotsSpec or GGBunch expected but was: {}".format(type(plot)))
146
+
147
+ filename = filename.strip()
148
+ name, ext = os.path.splitext(filename)
149
+
150
+ if not name:
151
+ raise ValueError("Malformed filename: '{}'.".format(filename))
152
+ if not ext:
153
+ raise ValueError("Missing file extension: '{}'.".format(filename))
154
+
155
+ if not path:
156
+ path = join(os.getcwd(), _DEF_EXPORT_DIR)
157
+
158
+ pathname = join(path, filename)
159
+
160
+ ext = ext[1:].lower()
161
+ if ext == 'svg':
162
+ return _to_svg(plot, pathname, w=w, h=h, unit=unit)
163
+ elif ext in ['html', 'htm']:
164
+ return _to_html(plot, pathname, iframe=iframe)
165
+ elif ext in ['png', 'pdf']:
166
+ return _export_as_raster(plot, pathname, scale, export_format=ext, w=w, h=h, unit=unit, dpi=dpi)
167
+ else:
168
+ raise ValueError(
169
+ "Unsupported file extension: '{}'\nPlease use one of: 'png', 'svg', 'pdf', 'html', 'htm'".format(ext)
170
+ )
@@ -0,0 +1,8 @@
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
+
6
+ from ._configuration import *
7
+
8
+ __all__ = _configuration.__all__
@@ -0,0 +1,151 @@
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 Dict, Any
6
+
7
+ from ._frontend_ctx import FrontendContext
8
+ from ._html_contexts import _create_html_frontend_context, _use_isolated_frame, _create_wb_html_frontend_context
9
+ from ._json_contexts import _create_json_frontend_context, _is_Intellij_Python_Lets_Plot_Plugin
10
+ from ._mime_types import TEXT_HTML, LETS_PLOT_JSON
11
+ from ._static_svg_ctx import StaticSvgImageContext
12
+ from ._webbr_html_page_ctx import WebBrHtmlPageContext
13
+ from .._version import __version__
14
+ from ..plot.core import PlotSpec
15
+ from ..plot.plot import GGBunch
16
+ from ..plot.subplots import SupPlotsSpec
17
+
18
+ __all__ = []
19
+
20
+ _frontend_contexts: Dict[str, FrontendContext] = {}
21
+
22
+ _default_mimetype = TEXT_HTML
23
+ if _is_Intellij_Python_Lets_Plot_Plugin():
24
+ _default_mimetype = LETS_PLOT_JSON
25
+ _frontend_contexts[LETS_PLOT_JSON] = _create_json_frontend_context()
26
+
27
+
28
+ def _setup_html_context(*,
29
+ isolated_frame: bool = None,
30
+ offline: bool,
31
+ no_js: bool,
32
+ show_status: bool) -> None:
33
+ """
34
+ Configures Lets-Plot HTML output.
35
+
36
+ Parameters
37
+ ----------
38
+ isolated_frame : bool
39
+ True - generate HTLM which can be used in `iframe` or in a standalone HTML document
40
+ False - pre-load Lets-Plot JS library. Notebook cell output will only consist of HTML for the plot rendering.
41
+ Default: None - auto-detect.
42
+ offline : bool
43
+ True - full Lets-Plot JS bundle will be added to the notebook. Use this option if you would like
44
+ to work with notebook without the Internet connection.
45
+ False - load Lets-Plot JS library from CDN.
46
+ no_js : bool
47
+ True - do not generate HTML+JS as an output - just static SVG image.
48
+ show_status : bool
49
+ Whether to show status of loading of the Lets-Plot JS library.
50
+ Only applicable when the Lets-Plot JS library is preloaded.
51
+
52
+ """
53
+ global _default_mimetype
54
+ if _default_mimetype == LETS_PLOT_JSON:
55
+ # Plots will be rendered by Lets-Plot IntelliJ plugin.
56
+ # No other contexts are needed.
57
+ if show_status:
58
+ print(
59
+ 'Lets-Plot v{}: output mimetype {} configured by default. No need for HTML output.'.format(__version__,
60
+ LETS_PLOT_JSON))
61
+ return
62
+
63
+ if no_js:
64
+ ctx = StaticSvgImageContext()
65
+ else:
66
+ ctx = _create_html_frontend_context(isolated_frame, offline=offline)
67
+
68
+ ctx.configure(verbose=show_status)
69
+ _frontend_contexts[TEXT_HTML] = ctx
70
+
71
+
72
+ def _setup_wb_html_context(*,
73
+ exec: str,
74
+ new: bool) -> None:
75
+ """
76
+ Configures Lets-Plot HTML output for showing in a browser.
77
+
78
+ Parameters
79
+ ----------
80
+ exec : str, optional
81
+ Command to execute to open the plot in a web browser.
82
+ If not specified, the default browser will be used.
83
+ new : bool, default=False
84
+ If True, the URL is opened in a new window of the web browser.
85
+ If False, the URL is opened in the already opened web browser window.
86
+ """
87
+ ctx = _create_wb_html_frontend_context(exec, new)
88
+ _frontend_contexts[TEXT_HTML] = ctx
89
+
90
+
91
+ def _display_plot(spec: Any):
92
+ """
93
+ Draw plot or `bunch` of plots in the current frontend context
94
+ :param spec: PlotSpec or GGBunch object
95
+ """
96
+ if not (isinstance(spec, PlotSpec) or isinstance(spec, SupPlotsSpec) or isinstance(spec, GGBunch)):
97
+ raise ValueError("PlotSpec or SupPlotsSpec expected but was: {}".format(type(spec)))
98
+
99
+ if _default_mimetype == TEXT_HTML:
100
+ if TEXT_HTML not in _frontend_contexts:
101
+ raise RuntimeError(
102
+ "HTML frontend not configured. Before displaying plots, please call either:\n"
103
+ "- LetsPlot.setup_html() for displaying HTML output inplace\n"
104
+ "- LetsPlot.setup_show_ext() for displaying HTML output in an external web browser\n"
105
+ )
106
+
107
+ if isinstance(_frontend_contexts[TEXT_HTML], WebBrHtmlPageContext):
108
+ _frontend_contexts[TEXT_HTML].show(spec.as_dict())
109
+ return
110
+
111
+ plot_html = _as_html(spec.as_dict())
112
+ try:
113
+ from IPython.display import display_html
114
+ display_html(plot_html, raw=True)
115
+ return
116
+ except ImportError:
117
+ pass
118
+
119
+ print(spec.as_dict())
120
+ return
121
+
122
+ if _default_mimetype == LETS_PLOT_JSON:
123
+ _frontend_contexts[LETS_PLOT_JSON].show(spec.as_dict())
124
+ return
125
+
126
+ # fallback to plain text.
127
+ print(spec.as_dict())
128
+
129
+
130
+ def _as_html(plot_spec: Dict) -> str:
131
+ """
132
+ Creates plot HTML using 'html' frontend context.
133
+
134
+ :param plot_spec: dict
135
+ """
136
+ if TEXT_HTML not in _frontend_contexts:
137
+ if _use_isolated_frame():
138
+ # 'Isolated' HTML context can be setup lazily.
139
+ _setup_html_context(isolated_frame=True,
140
+ offline=False,
141
+ no_js=False,
142
+ show_status=False)
143
+ else:
144
+ return """\
145
+ <div style="color:darkred;">
146
+ Lets-plot `html` is not configured.<br>
147
+ Try to use `LetsPlot.setup_html()` before first occurrence of plot.
148
+ </div>
149
+ """
150
+
151
+ return _frontend_contexts[TEXT_HTML].as_str(plot_spec)
@@ -0,0 +1,16 @@
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 Dict
6
+
7
+
8
+ class FrontendContext:
9
+ def configure(self, verbose: bool):
10
+ pass
11
+
12
+ def as_str(self, plot_spec: Dict) -> str:
13
+ pass
14
+
15
+ def show(self, plot_spec: Dict) -> str:
16
+ pass
@@ -0,0 +1,117 @@
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
+ import os
5
+
6
+ from ._frontend_ctx import FrontendContext
7
+ from ._jupyter_notebook_ctx import JupyterNotebookContext
8
+ from ._static_html_page_ctx import StaticHtmlPageContext
9
+ from ._webbr_html_page_ctx import WebBrHtmlPageContext
10
+ from .._global_settings import has_global_value, get_global_bool, HTML_ISOLATED_FRAME
11
+
12
+
13
+ def _create_html_frontend_context(isolated_frame: bool = None, offline: bool = None) -> FrontendContext:
14
+ """
15
+ Configures Lets-Plot HTML output.
16
+
17
+ Parameters
18
+ ----------
19
+ isolated_frame : bool, optional, default None - auto-detect
20
+ If True, generate HTLM which can be used in `iframe` or in a standalone HTML document
21
+ If False, pre-load Lets-Plot JS library. Notebook cell output will only consist of HTML for the plot rendering.
22
+
23
+ offline : bool, optional, default None - evaluated to 'connected' mode in production environment.
24
+ If True, full Lets-Plot JS bundle will be added to the notebook. Use this option if you would like
25
+ to work with notebook without the Internet connection.
26
+ If False, load Lets-Plot JS library from CDN.
27
+ """
28
+ if isolated_frame is None:
29
+ isolated_frame = _use_isolated_frame()
30
+
31
+ if isolated_frame:
32
+ return StaticHtmlPageContext(offline)
33
+ else:
34
+ return JupyterNotebookContext(offline)
35
+
36
+
37
+ def _create_wb_html_frontend_context(exec: str, new: bool) -> FrontendContext:
38
+ """
39
+ Configures Lets-Plot HTML output for showing in web browser.
40
+
41
+ Parameters
42
+ ----------
43
+ exec : str, optional
44
+ The name of the web browser to use.
45
+ If not specified, the default browser will be used.
46
+ new : bool, default=False
47
+ If True, the URL is opened in a new window of the web browser.
48
+ If False, the URL is opened in the already opened web browser window.
49
+ """
50
+ return WebBrHtmlPageContext(exec, new)
51
+
52
+
53
+ def _use_isolated_frame() -> bool:
54
+ # check environment
55
+ if has_global_value(HTML_ISOLATED_FRAME):
56
+ return get_global_bool(HTML_ISOLATED_FRAME)
57
+
58
+ return _detect_isolated_frame()
59
+
60
+
61
+ def _detect_isolated_frame() -> bool:
62
+ if not _is_IPython_display():
63
+ return True # isolated HTML page to show somehow
64
+
65
+ # Most online notebook platforms are showing cell output in iframe and require
66
+ # a self-contained HTML which includes both:
67
+ # - the script loading JS library and
68
+ # - the script that uses this JS lib to create plot.
69
+
70
+ # Try to detect the platform.
71
+ try:
72
+ import google.colab
73
+ return True # Colab -> iframe
74
+ except ImportError:
75
+ pass
76
+
77
+ if os.path.exists("/kaggle/input"):
78
+ return False # Kaggle -> no iframe
79
+
80
+ if "AZURE_NOTEBOOKS_HOST" in os.environ:
81
+ return True # Azure Notebook -> iframe
82
+
83
+ if "DEEPNOTE_PROJECT_ID" in os.environ:
84
+ return True # Deepnote Notebook -> iframe
85
+
86
+ if "databricks" in str(os.environ):
87
+ # Databricks notebook -> iframe
88
+ # As proposed: https://github.com/JetBrains/lets-plot/issues/602
89
+ return True
90
+
91
+ if "NEXTJOURNAL" in str(os.environ):
92
+ return True # NextJournal notebook -> iframe
93
+
94
+ if os.getenv("PLOTLY_RENDERER") == "colab":
95
+ # good enouth - something colab-like
96
+ return True # Colab -> iframe
97
+
98
+ # ToDo: other platforms: vscode, nteract, cocalc
99
+
100
+ try:
101
+ shell = get_ipython().__class__.__name__
102
+ if shell == 'ZMQInteractiveShell':
103
+ return False # Jupyter notebook or qtconsole -> load JS librarty once per notebook
104
+ elif shell == 'TerminalInteractiveShell':
105
+ return True # Terminal running IPython -> an isolated HTML page to show somehow
106
+ else:
107
+ return True # Other type (?)
108
+ except NameError:
109
+ return True # some other env (even standard Python interpreter) -> an isolated HTML page to show somehow
110
+
111
+
112
+ def _is_IPython_display() -> bool:
113
+ try:
114
+ from IPython.display import display_html
115
+ return True
116
+ except ImportError:
117
+ return False
@@ -0,0 +1,38 @@
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
+
6
+ from typing import Dict, Tuple
7
+
8
+ from ._frontend_ctx import FrontendContext
9
+ from ._mime_types import LETS_PLOT_JSON
10
+ from .._type_utils import standardize_dict
11
+
12
+
13
+ class IntellijPythonJsonContext(FrontendContext):
14
+
15
+ def configure(self, verbose: bool):
16
+ pass
17
+
18
+ def show(self, plot_spec: Dict) -> str:
19
+ plot_spec_std = standardize_dict(plot_spec)
20
+ data_object = DisplayDataObject(plot_spec_std)
21
+
22
+ # See intellij.python.helpers module in IDEA
23
+ from datalore.display import display
24
+ display(data_object)
25
+
26
+
27
+ class DisplayDataObject():
28
+
29
+ def __init__(self, plot_spec: Dict) -> None:
30
+ super().__init__()
31
+ self.data_object = (LETS_PLOT_JSON, plot_spec)
32
+
33
+ def _repr_display_(self) -> Tuple[str, Dict]:
34
+ """
35
+ Special method discovered and invoked by datalore.display.display()
36
+ See: IDEA/community/python/helpers/pycharm_display/datalore/display/display_.py
37
+ """
38
+ return self.data_object
@@ -0,0 +1,39 @@
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
+ import os
5
+
6
+ from ._frontend_ctx import FrontendContext
7
+ from ._intellij_python_json_ctx import IntellijPythonJsonContext
8
+
9
+
10
+ def _create_json_frontend_context() -> FrontendContext:
11
+ """
12
+ Configures Lets-Plot JSON output.
13
+
14
+ Such context requires a Lets-Plot JSON interpreter plugged in to the frontend env (like PyCharm)
15
+ """
16
+
17
+ if _is_Intellij_Python_Lets_Plot_Plugin():
18
+ return IntellijPythonJsonContext()
19
+
20
+ # ToDo: GenericJsonFrontendContext
21
+ raise RuntimeError("Couldn't detect Intellij Python environment")
22
+
23
+
24
+ def _is_Intellij_Python_Lets_Plot_Plugin() -> bool:
25
+ try:
26
+ # An empty marker module defined by Intellij Lets-Plot plugin
27
+ # import lets_plot_intellij_python_plugin <---- the old way.
28
+
29
+
30
+ # The check above is not working with PyCharm remote interpreter: https://github.com/JetBrains/lets-plot/issues/348
31
+
32
+ # 1) The "datalore.display" is present in both PyCharm and Datalore env.
33
+ # See `intellij.python.helpers` module in IDEA.
34
+ from datalore.display import display
35
+
36
+ # 2) The "DATALORE_HOME" is only present in Datalore env but not in PyCharm env.
37
+ return "DATALORE_HOME" not in os.environ
38
+ except ImportError:
39
+ return False
@@ -0,0 +1,119 @@
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
+ import os
6
+ import pkgutil
7
+ import random
8
+ import string
9
+ from typing import Dict
10
+
11
+ try:
12
+ from IPython.display import display_html
13
+ except ImportError:
14
+ display_html = None
15
+
16
+ from ._frontend_ctx import FrontendContext
17
+ from .. import _kbridge as kbr
18
+ from .._global_settings import get_js_cdn_url
19
+ from .._global_settings import JS_BASE_URL, JS_NAME
20
+ from .._version import __version__
21
+
22
+ # Data-attributes used to store extra information about the meaning of 'script' elements
23
+ _ATT_SCRIPT_KIND = 'data-lets-plot-script'
24
+ _SCRIPT_KIND_LIB_LOADING = 'library'
25
+ _SCRIPT_KIND_PLOT = 'plot'
26
+
27
+
28
+ class JupyterNotebookContext(FrontendContext):
29
+
30
+ def __init__(self, offline: bool) -> None:
31
+ super().__init__()
32
+ self.connected = not offline
33
+
34
+ def configure(self, verbose: bool):
35
+ if self.connected:
36
+ # noinspection PyTypeChecker
37
+ display_html(self._configure_connected_script(verbose), raw=True)
38
+ else:
39
+ # noinspection PyTypeChecker
40
+ display_html(self._configure_embedded_script(verbose), raw=True)
41
+
42
+ def as_str(self, plot_spec: Dict) -> str:
43
+ return kbr._generate_dynamic_display_html(plot_spec)
44
+
45
+ @staticmethod
46
+ def _configure_connected_script(verbose: bool) -> str:
47
+ url = get_js_cdn_url()
48
+ output_id = JupyterNotebookContext._rand_string()
49
+ success_message = """
50
+ var div = document.createElement("div");
51
+ div.style.color = 'darkblue';
52
+ div.textContent = 'Lets-Plot JS successfully loaded.';
53
+ document.getElementById("{id}").appendChild(div);
54
+ """.format(id=output_id) if verbose else ""
55
+
56
+ return """
57
+ <div id="{id}"></div>
58
+ <script type="text/javascript" {data_attr}="{script_kind}">
59
+ if(!window.letsPlotCallQueue) {{
60
+ window.letsPlotCallQueue = [];
61
+ }};
62
+ window.letsPlotCall = function(f) {{
63
+ window.letsPlotCallQueue.push(f);
64
+ }};
65
+ (function() {{
66
+ var script = document.createElement("script");
67
+ script.type = "text/javascript";
68
+ script.src = "{url}";
69
+ script.onload = function() {{
70
+ window.letsPlotCall = function(f) {{f();}};
71
+ window.letsPlotCallQueue.forEach(function(f) {{f();}});
72
+ window.letsPlotCallQueue = [];
73
+ {success_message}
74
+ }};
75
+ script.onerror = function(event) {{
76
+ window.letsPlotCall = function(f) {{}}; // noop
77
+ window.letsPlotCallQueue = [];
78
+ var div = document.createElement("div");
79
+ div.style.color = 'darkred';
80
+ div.textContent = 'Error loading Lets-Plot JS';
81
+ document.getElementById("{id}").appendChild(div);
82
+ }};
83
+ var e = document.getElementById("{id}");
84
+ e.appendChild(script);
85
+ }})()
86
+ </script>
87
+ """.format(
88
+ data_attr=_ATT_SCRIPT_KIND,
89
+ script_kind=_SCRIPT_KIND_LIB_LOADING,
90
+ id=output_id,
91
+ url=url,
92
+ success_message=success_message)
93
+
94
+ @staticmethod
95
+ def _configure_embedded_script(verbose: bool) -> str:
96
+ js_name = "lets-plot.min.js"
97
+ path = os.path.join("package_data", js_name)
98
+ js_code = pkgutil.get_data("lets_plot", path).decode("utf-8")
99
+ success_message = '<div style="color:darkblue;">Lets-Plot JS is embedded.</div>' if verbose else ""
100
+
101
+ return """
102
+ <script type="text/javascript" {data_attr}="{script_kind}">
103
+ window.letsPlotCall = function(f) {{f();}};
104
+ console.log('Embedding: {js_name}');
105
+ {js_code}
106
+ </script>
107
+ {success_message}
108
+ """.format(
109
+ data_attr=_ATT_SCRIPT_KIND,
110
+ script_kind=_SCRIPT_KIND_LIB_LOADING,
111
+ js_code=js_code,
112
+ js_name=js_name,
113
+ success_message=success_message)
114
+
115
+ @staticmethod
116
+ def _rand_string(size=6) -> str:
117
+ alphabet = string.ascii_letters + string.digits
118
+ # noinspection PyShadowingBuiltins
119
+ return ''.join([random.choice(alphabet) for _ in range(size)])
@@ -0,0 +1,7 @@
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
+ # Supported MIME types
5
+ TEXT_HTML = "text/html"
6
+ LETS_PLOT_JSON = "application/vnd.lets-plot.v1+json"
7
+