4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.

- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.

- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)

## [5.23.0] - 2024-07-23

### Updated
Expand Down
12 changes: 0 additions & 12 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -3538,12 +3538,6 @@ def to_html(self, *args, **kwargs):
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -3647,12 +3641,6 @@ def write_html(self, *args, **kwargs):
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
43 changes: 4 additions & 39 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -249,7 +249,6 @@ def __init__(
self,
connected=False,
full_html=False,
requirejs=True,
global_init=False,
config=None,
auto_play=False,
Expand All@@ -261,7 +260,6 @@ def __init__(
self.auto_play = auto_play
self.connected = connected
self.global_init = global_init
self.requirejs = requirejs
self.full_html = full_html
self.animation_opts = animation_opts
self.post_script = post_script
Expand All@@ -275,27 +273,13 @@ def activate(self):
)
)

if not self.requirejs:
raise ValueError("global_init is only supported with requirejs=True")

if self.connected:
# Connected so we configure requirejs with the plotly CDN
script = """\
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
requirejs.config({{
paths: {{
'plotly': ['{plotly_cdn}']
}}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">import \"{plotly_cdn}\"</script>
Comment thread
archmoj marked this conversation as resolved.
""".format(
win_config=_window_plotly_config,
mathjax_config=_mathjax_config,
Expand All@@ -309,16 +293,8 @@ def activate(self):
<script type="text/javascript">
{win_config}
{mathjax_config}
if (typeof require !== 'undefined') {{
require.undef("plotly");
define('plotly', function(require, exports, module) {{
{script}
}});
require(['plotly'], function(Plotly) {{
window._Plotly = Plotly;
}});
}}
</script>
<script type="module">{script}</script>
""".format(
script=get_plotlyjs(),
win_config=_window_plotly_config,
Expand All@@ -331,10 +307,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand DownExpand Up@@ -416,7 +389,6 @@ def __init__(
super(NotebookRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -444,7 +416,6 @@ def __init__(
super(KaggleRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -472,7 +443,6 @@ def __init__(
super(AzureRenderer, self).__init__(
connected=True,
full_html=False,
requirejs=True,
global_init=True,
config=config,
auto_play=auto_play,
Expand All@@ -497,7 +467,6 @@ def __init__(
super(ColabRenderer, self).__init__(
connected=True,
full_html=True,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand DownExpand Up@@ -832,7 +801,6 @@ def __init__(
super(SphinxGalleryHtmlRenderer, self).__init__(
connected=connected,
full_html=False,
requirejs=False,
global_init=False,
config=config,
auto_play=auto_play,
Expand All@@ -844,10 +812,7 @@ def to_mimebundle(self, fig_dict):

from plotly.io import to_html

if self.requirejs:
include_plotlyjs = "require"
include_mathjax = False
elif self.connected:
if self.connected:
include_plotlyjs = "cdn"
include_mathjax = "cdn"
else:
Expand Down
32 changes: 3 additions & 29 deletions packages/python/plotly/plotly/io/_html.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -67,12 +67,6 @@ def to_html(
plotly.min.js bundle that is assumed to reside in the same
directory as the HTML file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand DownExpand Up@@ -254,20 +248,10 @@ def to_html(
if isinstance(include_plotlyjs, str):
include_plotlyjs = include_plotlyjs.lower()

# Start/end of requirejs block (if any)
require_start = ""
require_end = ""

# Init and load
load_plotlyjs = ""

# Init plotlyjs. This block needs to run before plotly.js is loaded in
# order for MathJax configuration to work properly
if include_plotlyjs == "require":
require_start = 'require(["plotly"], function(Plotly) {'
require_end = "});"

elif include_plotlyjs == "cdn":
if include_plotlyjs == "cdn":
load_plotlyjs = """\
{win_config}
<script charset="utf-8" src="{cdn_url}"></script>\
Expand DownExpand Up@@ -343,10 +327,8 @@ def to_html(
<div id="{id}" class="plotly-graph-div" \
style="height:{height}; width:{width};"></div>\
<script type="text/javascript">\
{require_start}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
{require_end}\
window.PLOTLYENV=window.PLOTLYENV || {{}};{base_url_line}\
{script};\
</script>\
</div>""".format(
mathjax_script=mathjax_script,
Expand All@@ -355,9 +337,7 @@ def to_html(
width=div_width,
height=div_height,
base_url_line=base_url_line,
require_start=require_start,
script=script,
require_end=require_end,
).strip()

if full_html:
Expand DownExpand Up@@ -433,12 +413,6 @@ def write_html(
directory because the plotly.js source code will be included only
once per output directory, rather than once per output file.

If 'require', Plotly.js is loaded using require.js. This option
assumes that require.js is globally available and that it has been
globally configured to know how to find Plotly.js as 'plotly'.
This option is not advised when full_html=True as it will result
in a non-functional html file.

If a string that ends in '.js', a script tag is included that
references the specified path. This approach can be used to point
the resulting HTML file to an alternative CDN or local bundle.
Expand Down
17 changes: 3 additions & 14 deletions packages/python/plotly/plotly/tests/test_io/test_renderers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,14 +145,6 @@ def assert_offline(html):
assert get_plotlyjs() in html


def assert_requirejs(html):
assert 'require(["plotly"]' in html


def assert_not_requirejs(html):
assert 'require(["plotly"]' not in html


def test_colab_renderer_show(fig1):
pio.renderers.default = "colab"

Expand All@@ -170,7 +162,6 @@ def test_colab_renderer_show(fig1):
html = mock_arg1["text/html"]
assert_full_html(html)
assert_html_renderer_connected(html)
assert_not_requirejs(html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -213,7 +204,6 @@ def test_notebook_connected_show(fig1, name, connected):
# Check html display contents
bundle_html = mock_arg1["text/html"]
assert_not_full_html(bundle_html)
assert_requirejs(bundle_html)

# check kwargs
mock_kwargs = mock_call_args[1]
Expand DownExpand Up@@ -275,7 +265,6 @@ def open_url(url, new=0, autoraise=True):
html = response.content.decode("utf8")
assert_full_html(html)
assert_offline(html)
assert_not_requirejs(html)


# Validation
Expand DownExpand Up@@ -317,12 +306,12 @@ def test_repr_html(renderer):
+ '"></script> '
'<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
'style="height:100%; width:100%;"></div> <script type="text/javascript">'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
" window.PLOTLYENV=window.PLOTLYENV || {};"
' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
' [], {"template":{}},'
' {"responsive": true} ) };'
" </script> </div>"
" </script> </div>"
)
if "text/html" in bundle:
str_bundle = bundle["text/html"]
Expand Down