Skip to content

Commit 12bf5ca

Browse files
authored
Merge branch 'main' into fix-single-color-palette-5805
2 parents e298f4c + 84498cc commit 12bf5ca

71 files changed

Lines changed: 1037 additions & 459 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/build-package.yml‎

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,6 @@ permissions:
1111
contents: read
1212

1313
jobs:
14-
plotlyjs-dev-build:
15-
name: plotly.js dev build
16-
runs-on: ubuntu-latest
17-
steps:
18-
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
19-
- name: Set up Python
20-
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
21-
with:
22-
python-version: "3.12"
23-
- name: Set up Node
24-
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
25-
with:
26-
node-version: "22"
27-
- name: Set up uv
28-
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
29-
- name: Install dependencies
30-
run: |
31-
uv venv
32-
source .venv/bin/activate
33-
uv sync --locked --extra dev_optional
34-
- name: Update plotly.js to dev
35-
run: |
36-
source .venv/bin/activate
37-
python commands.py updateplotlyjsdev
38-
- name: Test core (excluding nodev)
39-
run: |
40-
source .venv/bin/activate
41-
pytest -k 'not nodev' tests/test_core
42-
- name: Build source distribution packages
43-
run: |
44-
source .venv/bin/activate
45-
uv sync --locked --extra dev_build
46-
python -m build --sdist --wheel -o dist
47-
- name: Upload dist artifacts
48-
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
49-
with:
50-
name: plotlyjs-dev-build-dist
51-
path: dist/
52-
if-no-files-found: error
53-
5414
full-build:
5515
name: Full prod build
5616
runs-on: ubuntu-latest
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Test plotly.js dev
2+
3+
# Run codegen and the core tests against the plot-schema.json on plotly.js main
4+
# once a week. This catches plotly.js schema changes that break codegen or
5+
# validation before the next plotly.js release.
6+
on:
7+
schedule:
8+
- cron: "0 9 * * 1" # Monday 09:00 UTC
9+
workflow_dispatch:
10+
inputs:
11+
plotlyjs_ref:
12+
description: "plotly.js branch, tag, or commit SHA to test"
13+
required: false
14+
default: "main"
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
test-plotlyjs-dev:
21+
name: Test against plotly.js dev schema
22+
runs-on: ubuntu-latest
23+
steps:
24+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25+
with:
26+
persist-credentials: false
27+
- name: Set up Python
28+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
29+
with:
30+
python-version: "3.12"
31+
- name: Set up uv
32+
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
33+
- name: Install dependencies
34+
run: |
35+
uv venv
36+
source .venv/bin/activate
37+
uv sync --locked --extra dev_optional
38+
- name: Download plot-schema.json from plotly.js
39+
# plotly.js CI keeps test/plot-schema.json identical to the built schema
40+
env:
41+
PLOTLYJS_REF: ${{ inputs.plotlyjs_ref || 'main' }}
42+
run: |
43+
curl -fsSL -o codegen/resources/plot-schema.json \
44+
"https://raw.githubusercontent.com/plotly/plotly.js/${PLOTLYJS_REF}/test/plot-schema.json"
45+
- name: Run codegen
46+
run: |
47+
source .venv/bin/activate
48+
python commands.py codegen
49+
- name: Test core (excluding nodev)
50+
run: |
51+
source .venv/bin/activate
52+
pytest -k 'not nodev' tests/test_core
53+
54+
report-failure:
55+
name: Open an issue for a failed scheduled run
56+
needs: test-plotlyjs-dev
57+
# Manual runs can test any plotly.js ref, so only report scheduled runs
58+
if: failure() && github.event_name == 'schedule'
59+
runs-on: ubuntu-latest
60+
permissions:
61+
issues: write
62+
steps:
63+
- name: Open or update the failure issue
64+
env:
65+
GH_TOKEN: ${{ github.token }}
66+
GH_REPO: ${{ github.repository }}
67+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
68+
TITLE: "Weekly plotly.js dev test failed"
69+
run: |
70+
BODY="The weekly test against the plot-schema.json on plotly.js main failed: ${RUN_URL}"
71+
# Comment on an open issue from an earlier failure instead of opening a duplicate
72+
EXISTING=$(gh issue list --state open --search "in:title \"${TITLE}\"" \
73+
--json number,title --jq "map(select(.title == \"${TITLE}\")) | .[0].number // empty")
74+
if [ -n "${EXISTING}" ]; then
75+
gh issue comment "${EXISTING}" --body "${BODY}"
76+
else
77+
gh issue create --title "${TITLE}" --body "${BODY}"
78+
fi

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## Unreleased
66

7+
### Added
8+
- Add support for converting matplotlib reference lines (`axhline`, `axvline`, and horizontal/vertical `axline`) as well as axes-coordinate lines into Plotly layout shapes in `mpl_to_plotly`, including support for date axes [[#5719](https://github.com/plotly/plotly.py/pull/5719)], with thanks to @robertoffmoura for the contribution!
9+
710
### Fixed
811
- Fix single-color requests in `n_colors` and `sample_colorscale` raising `ZeroDivisionError` [[#5805](https://github.com/plotly/plotly.py/issues/5805)].
912
- Fix `mpl_to_plotly` tick marker mirroring, axis positioning, and trace visibility for twinned and overlaid subplots (such as `twinx` and `twiny`) [[#5310](https://github.com/plotly/plotly.py/pull/5310)], with thanks to @robertoffmoura for the contribution!
@@ -14,10 +17,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1417
- Fix `mpl_to_plotly` dropping matplotlib stairs plots by rendering `StepPatch` artists as step lines or filled step areas from their path vertices and edge style [[#5698](https://github.com/plotly/plotly.py/pull/5698)], with thanks to @robertoffmoura for the contribution!
1518
- Fix `mpl_to_plotly` showing unwanted legends with placeholder or internal label entries (`_nolegend_`, `_childN`) by defaulting `layout.showlegend=False` unless the matplotlib figure explicitly defines a legend [[#5699](https://github.com/plotly/plotly.py/pull/5699)], with thanks to @robertoffmoura for the contribution!
1619
- Fix `mpl_to_plotly` crashing on figures with fully transparent or alpha-carrying colors, such as boxplot outlier markers (`facecolor="none"`), rgba line colors, and `color="none"` text and axis labels; all matplotlib colors are now exported through a single helper that maps `"none"` to transparent rgba and keeps or overrides alpha as matplotlib does [[#5700](https://github.com/plotly/plotly.py/pull/5700)], with thanks to @robertoffmoura for the contribution!
20+
- Fix serialization of box/lasso select data for figures with multiple subplots [[#5710](https://github.com/plotly/plotly.py/pull/5710)], with thanks to @flpi-sun for the contribution!
1721
- Export tick label colors to the plotly tickfont in `mpl_to_plotly` [[#5716](https://github.com/plotly/plotly.py/pull/5716)], with thanks to @robertoffmoura for the contribution!
22+
- Fix `convert_dash` mapping dotted lines (`linestyle=':'`) to invalid `'circle'` in Plotly, correctly converting them to `'dot'` and preserving custom dash patterns as pixel lists, [[#5719](https://github.com/plotly/plotly.py/pull/5719)] with thanks to @robertoffmoura for the contribution!
1823
- Fix Plotly Express mutating lists passed to the `x` or `y` arguments in wide mode [[#5727](https://github.com/plotly/plotly.py/pull/5727)], with thanks to @cpruijsen for the contribution!
1924
- Fix `px.sunburst`, `px.treemap` and `px.icicle` listing sectors in a different order on every run when `path` is used with a Polars DataFrame; sectors now follow their order of first appearance for all dataframe backends [[#5766](https://github.com/plotly/plotly.py/pull/5766)], with thanks to @Irahan2 for the contribution!
2025
- Fix `mpl_to_plotly` conversion of matplotlib contour lines and line collections: close contour rings ending with `Z` codes, support dash styles, convert date x-axes, separate disjoint subpaths with `None` separators, hide line collection traces from the legend by default, and group consecutive same-style lines into single traces [[#5770](https://github.com/plotly/plotly.py/pull/5770)], with thanks to @robertoffmoura for the contribution!
26+
- Fix `plotly.io.write_images` ignoring `layout.width`/`layout.height` (and the template's) and exporting every figure at the default 700x500 size; it now uses the same width/height priority as `write_image` and `to_image` [[#5784](https://github.com/plotly/plotly.py/pull/5784)], with thanks to @breken-ai for the contribution!
27+
- Fix color utilities mutating the list of colors passed to them [[#5836](https://github.com/plotly/plotly.py/pull/5836)], with thanks to @Enesuygurs for the contribution!
28+
2129

2230
## [7.1.0] - 2026-09-15
2331

‎CONTRIBUTING.md‎

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ Steps to update plotly.js:
283283

284284
This command does the following:
285285

286-
- Downloads new versions of `plot-schema.json` and `plotly.min.js` from the [plotly.js GitHub repository](https://github.com/plotly/plotly.js)
286+
- Downloads new versions of `plot-schema.json` and `plotly.min.js` from the [`plotly.js` npm package](https://www.npmjs.com/package/plotly.js)
287287
and places them in `codegen/resources/` and `plotly/package_data/`, respectively.
288288
- Updates `plotly/offline/_plotlyjs_version.py` with the new version
289289
- Regenerates all of the classes under `graph_objs/` (`go.Figure`, `go.Layout`, etc.), and `plotly/validators/_validators.json`, based on the new schema
@@ -318,23 +318,9 @@ and places them in `codegen/resources/` and `plotly/package_data/`, respectively
318318

319319
7. Add a changelog entry to `CHANGELOG.md` with a link to the PR. We typically mention the version update, link to the plotly.js GitHub release page, and list out the most important changes. Follow the format of previous plotly.js version bump changelog updates.
320320

321-
### Using a Development Branch of Plotly.js
321+
### Using a Development Version of Plotly.js
322322

323-
If your development branch is in [the plotly.js repository](https://github.com/plotly/plotly.js)
324-
you can update to development versions of `plotly.js` with this command:
325-
326-
```bash
327-
python commands.py updateplotlyjsdev --devrepo reponame --devbranch branchname
328-
```
329-
330-
This downloads `dist/plotly.min.js` and `dist/plot-schema.json` from the latest commit of the branch `branchname` of the repo `reponame`.
331-
If `--devrepo` or `--devbranch` are omitted,
332-
`updateplotlyjsdev` defaults to `plotly/plotly.js` and `main` respectively.
333-
334-
### Local Repository
335-
336-
If you have a local repository of `plotly.js` you'd like to try,
337-
you can prepare the package by running the following commands
323+
To test plotly.py against a local repository of `plotly.js`, prepare the package by running the following commands
338324
*in your local plotly.js repository*:
339325

340326
```bash
@@ -347,7 +333,7 @@ You can then run the following command
347333
*in your local plotly.py repository*:
348334

349335
```bash
350-
python commands.py updateplotlyjsdev --local /path/to/your/plotly.js/
336+
python commands.py updateplotlyjsdev /path/to/your/plotly.js/
351337
```
352338

353339
## Documentation for `commands.py`
@@ -362,5 +348,5 @@ Usage: `python commands.py <subcommand> <args>`
362348
| `lint` | Lint all Python code in `plotly/`. |
363349
| `format` | Format all Python code in `plotly/`. |
364350
| `updateplotlyjs` | Update `plotly.min.js` and `plot-schema.json` to match the `plotly.js` version specified in `js/package.json`, run codegen to regenerate the Python files, then run `npm install` in `js/` to refresh `js/package-lock.json`. Set `SKIP_NPM=1` to skip the npm step. |
365-
| `updateplotlyjsdev [--devrepo REPONAME --devbranch BRANCHNAME] \| [--local PATH]` | Update `plot-schema.json` and `plotly.min.js` to match the version in the provided plotly.js repo name and branch name, OR local path. Then, run codegen to regenerate the Python files. |
351+
| `updateplotlyjsdev PATH` | Update `plot-schema.json` and `plotly.min.js` from the local plotly.js repository at `PATH`. Then, run codegen to regenerate the Python files. |
366352
| `bumpversion X.Y.Z` | Update the plotly.py version number to X.Y.Z across all files where it needs to be updated. |

‎_plotly_utils/colors/__init__.py‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ def validate_colors(colors, colortype="tuple"):
338338
else:
339339
colors = list(colors)
340340

341+
else:
342+
# copy the list so that neither the caller's list nor
343+
# DEFAULT_PLOTLY_COLORS is modified in place below
344+
colors = list(colors)
345+
341346
# convert color elements in list to tuple color
342347
for j, each_color in enumerate(colors):
343348
if "rgb" in each_color:
@@ -377,6 +382,9 @@ def validate_colors_dict(colors, colortype="tuple"):
377382
"""
378383
Validates dictionary of color(s)
379384
"""
385+
# copy the dict so that the caller's dict is not modified in place below
386+
colors = dict(colors)
387+
380388
# validate each color element in the dictionary
381389
for key in colors:
382390
if "rgb" in colors[key]:
@@ -454,7 +462,7 @@ def convert_colors_to_same_type(
454462
colors_list = list(colors)
455463

456464
elif isinstance(colors, list):
457-
colors_list = colors
465+
colors_list = list(colors)
458466

459467
# validate scale
460468
if scale is not None:
@@ -498,6 +506,9 @@ def convert_dict_colors_to_same_type(colors_dict, colortype="rgb"):
498506
499507
:param (dict) colors_dict: a dictionary whose values are single colors
500508
"""
509+
# copy the dict so that the caller's dict is not modified in place below
510+
colors_dict = dict(colors_dict)
511+
501512
for key in colors_dict:
502513
if "#" in colors_dict[key]:
503514
colors_dict[key] = color_parser(colors_dict[key], hex_to_rgb)
@@ -820,6 +831,10 @@ def convert_colorscale_to_rgb(colorscale):
820831
converting a colorscale with tuple colors (each coordinate between 0
821832
and 1) into a colorscale with the colors transformed into rgb colors
822833
"""
834+
# copy the colorscale and its [scale, color] pairs so that the caller's
835+
# colorscale is not modified in place below
836+
colorscale = [list(color) for color in colorscale]
837+
823838
for color in colorscale:
824839
color[1] = convert_to_RGB_255(color[1])
825840

0 commit comments

Comments
 (0)