Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8cff585

Browse files
Merge branch 'main' into changes-for-main
2 parents 2d36a86 + 2d6771f commit 8cff585

File tree

4 files changed

+98
-5
lines changed

4 files changed

+98
-5
lines changed

‎CITATION.cff‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ authors:
99
- family-names: "Parmer"
1010
given-names: "Chris"
1111
title: "An interactive, open-source, and browser-based graphing library for Python"
12-
version: 5.24.1
12+
version: 6.3.0
1313
doi: 10.5281/zenodo.14503524
14-
date-released: 2024-09-12
14+
date-released: 2025-08-12
1515
url: "https://github.com/plotly/plotly.py"
16+

‎CONTRIBUTING.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,20 @@ you can install all packages with:
120120
pip install -e '.[dev]'
121121
```
122122

123+
If you're testing local changes in Jupyter Lab or Jupyter Notebook, you'll want to run these commands when you're setting up your development environment:
124+
```bash
125+
pip install jupyter
126+
jupyter labextension develop .
127+
```
128+
If you don't run that command, your figure will not render in the Jupyter Lab/ Jupyter Notebook editors.
129+
130+
If you're changing any of the code under the `js/` directory, you'll also want to run these commands:
131+
```
132+
cd js/
133+
npm ci
134+
npm run build
135+
```
136+
123137
These commands also create an *editable install* of plotly.py
124138
so that you can test your changes iteratively without having to rebuild the plotly.py package explicitly;
125139
for more information please see

‎plotly/io/_kaleido.py‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,13 +376,31 @@ def to_image(
376376
if defaults.mathjax:
377377
kopts["mathjax"] = defaults.mathjax
378378

379-
# TODO: Refactor to make it possible to use a shared Kaleido instance here
379+
width = (
380+
width
381+
or fig_dict.get("layout", {}).get("width")
382+
or fig_dict.get("layout", {})
383+
.get("template", {})
384+
.get("layout", {})
385+
.get("width")
386+
or defaults.default_width
387+
)
388+
height = (
389+
height
390+
or fig_dict.get("layout", {}).get("height")
391+
or fig_dict.get("layout", {})
392+
.get("template", {})
393+
.get("layout", {})
394+
.get("height")
395+
or defaults.default_height
396+
)
397+
380398
img_bytes = kaleido.calc_fig_sync(
381399
fig_dict,
382400
opts=dict(
383401
format=format or defaults.default_format,
384-
width=widthordefaults.default_width,
385-
height=heightordefaults.default_height,
402+
width=width,
403+
height=height,
386404
scale=scale or defaults.default_scale,
387405
),
388406
topojson=defaults.topojson,

‎tests/test_optional/test_kaleido/test_kaleido.py‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from pathlib import Path
55
import tempfile
66
from unittest.mock import patch
7+
import xml.etree.ElementTree as ET
78

89
from pdfrw import PdfReader
910
from PIL import Image
@@ -16,6 +17,26 @@
1617
fig = {"data": [], "layout": {"title": {"text": "figure title"}}}
1718

1819

20+
def create_figure(width=None, height=None):
21+
"""Create a simple figure with optional layout dimensions."""
22+
layout = {}
23+
if width:
24+
layout["width"] = width
25+
if height:
26+
layout["height"] = height
27+
28+
return go.Figure(data=[go.Scatter(x=[1, 2, 3], y=[1, 2, 3])], layout=layout)
29+
30+
31+
def parse_svg_dimensions(svg_bytes):
32+
"""Parse width and height from SVG bytes."""
33+
svg_str = svg_bytes.decode("utf-8")
34+
root = ET.fromstring(svg_str)
35+
width = root.get("width")
36+
height = root.get("height")
37+
return int(width) if width else None, int(height) if height else None
38+
39+
1940
def check_image(path_or_buffer, size=(700, 500), format="PNG"):
2041
if format == "PDF":
2142
img = PdfReader(path_or_buffer)
@@ -314,3 +335,42 @@ def test_get_chrome():
314335

315336
# Verify that kaleido.get_chrome_sync was called
316337
mock_get_chrome.assert_called_once()
338+
339+
340+
def test_width_height_priority():
341+
"""Test width/height priority: arguments > layout.width/height > defaults."""
342+
343+
# Test case 1: Arguments override layout
344+
fig = create_figure(width=800, height=600)
345+
svg_bytes = pio.to_image(fig, format="svg", width=1000, height=900)
346+
width, height = parse_svg_dimensions(svg_bytes)
347+
assert width == 1000 and height == 900, (
348+
"Arguments should override layout dimensions"
349+
)
350+
351+
# Test case 2: Layout dimensions used when no arguments
352+
fig = create_figure(width=800, height=600)
353+
svg_bytes = pio.to_image(fig, format="svg")
354+
width, height = parse_svg_dimensions(svg_bytes)
355+
assert width == 800 and height == 600, (
356+
"Layout dimensions should be used when no arguments provided"
357+
)
358+
359+
# Test case 3: Partial override (only width argument)
360+
fig = create_figure(width=800, height=600)
361+
svg_bytes = pio.to_image(fig, format="svg", width=1200)
362+
width, height = parse_svg_dimensions(svg_bytes)
363+
assert width == 1200 and height == 600, (
364+
"Width argument should override layout, height should use layout"
365+
)
366+
367+
# Test case 4: Defaults used when no layout or arguments
368+
fig = create_figure()
369+
svg_bytes = pio.to_image(fig, format="svg")
370+
width, height = parse_svg_dimensions(svg_bytes)
371+
assert width == pio.defaults.default_width, (
372+
"Default width should be used when no layout or argument"
373+
)
374+
assert height == pio.defaults.default_height, (
375+
"Default height should be used when no layout or argument"
376+
)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /