Skip to content

Commit 036adcc

Browse files
committed
Merge branch 'main' into doc-prod-to-main-merge
2 parents 6765536 + 9c18a8b commit 036adcc

Some content is hidden

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

42 files changed

+1156
-867
lines changed

.github/workflows/check-js-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
cd js
3030
npm ci
3131
npm run build
32+
npm ls
3233
- name: Check JupyterLab build artifacts
3334
run: |
3435
# 1. Hash contents of all static files, sort by content hash

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,23 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## Unreleased
66

7+
## [6.3.1] - 2025-10-02
8+
9+
### Updated
10+
- Update Plotly.js from version 3.1.0 to version 3.1.1. See the Plotly.js [release notes](https://github.com/plotly/plotly.js/releases) for more information. [[#5357](https://github.com/plotly/plotly.py/pull/5357)]. Notable changes include:
11+
- Fix issue preventing Scattergl plots with text elements from rendering [[plotly.js#7563](https://github.com/plotly/plotly.js/pull/7563)]
12+
- Use native legends when converting from matplotlib [[#5312](https://github.com/plotly/plotly.py/pull/5312)], with thanks to @robertoffmoura to the contribution!
13+
- Allow `shared_yaxes` to work with secondary axes [[#5180](https://github.com/plotly/plotly.py/pull/5180)], with thanks to @gmjw for the contribution!
14+
15+
### Fixed
16+
- Fix issue where width/height in plot layout were not respected during Kaleido image export [[#5325](https://github.com/plotly/plotly.py/pull/5325)]
17+
- Fix typo in default argument to `_ternary_contour.py` [[#5315](https://github.com/plotly/plotly.py/pull/5315)], with thanks to @Lexachoc for the contribution!
18+
- Fix incorrect `fig.show()` behavior when `ipython` is installed [[#5258](https://github.com/plotly/plotly.py/pull/5258)]
19+
720
## [6.3.0] - 2025-08-12
821

922
### Updated
10-
- Updated Plotly.js from version 3.0.1 to version 3.1.0. See the plotly.js [release notes](https://github.com/plotly/plotly.js/releases) for more information. [[#5318](https://github.com/plotly/plotly.py/pull/5318)]
23+
- Updated Plotly.js from version 3.0.1 to version 3.1.0. See the Plotly.js [release notes](https://github.com/plotly/plotly.js/releases) for more information. [[#5318](https://github.com/plotly/plotly.py/pull/5318)]
1124

1225
### Added
1326
- Exposed `plotly.io.get_chrome()` as a function which can be called from within a Python script. [[#5282](https://github.com/plotly/plotly.py/pull/5282)]

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.1
1313
doi: 10.5281/zenodo.14503524
14-
date-released: 2024-09-12
14+
date-released: 2025-10-02
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

RELEASE.md

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
## Release process - full release of `plotly` package
55

6-
This is the release process for releasing `plotly.py` version `X.Y.Z`, including changelogs, Github release and forum announcement.
6+
This is the release process for releasing plotly.py version `X.Y.Z`, including changelogs, GitHub release and forum announcement.
77

88
### Finalize changelog
99

@@ -18,54 +18,99 @@ been updated, include this as the first `Updated` entry. Call out any
1818
notable changes as sub-bullets (new trace types in particular), and provide
1919
a link to the plotly.js CHANGELOG.
2020

21-
### Finalize versions
21+
### Update version numbers
22+
23+
**Create a release branch `git checkout -b release-X.Y.Z` _from the tip of `origin/main`_.**
24+
25+
- Manually update the versions to `X.Y.Z` in the files specified below:
26+
- `pyproject.toml`
27+
- update version
28+
- `CHANGELOG.md`
29+
- update version and release date
30+
- finalize changelog entries according to instructions above
31+
- `CITATION.cff`
32+
- update version and release date
33+
- Run `uv lock` to update the version number in the `uv.lock` file (do not update manually)
34+
- Commit and push your changes to the release branch:
35+
```sh
36+
$ git add -u
37+
$ git commit -m "version changes for vX.Y.Z"
38+
$ git push
39+
```
40+
- Create a GitHub pull request from `release-X.Y.Z` to `main` and wait for CI to be green
41+
- On the release branch, create and push a tag for the release:
42+
```sh
43+
$ git tag vX.Y.Z
44+
$ git push origin vX.Y.Z
45+
```
46+
47+
### Manual QA in Jupyter
48+
49+
We don't currently have automated tests for Jupyter, so we do this QA step manually.
50+
51+
The `full_build` job in the `release_build` workflow in CircleCI produces a tarball of artifacts `output.tgz`
52+
which you should download and decompress, which will give you a directory called `output`. The filenames within
53+
will contain version numbers; make sure the version numbers are correct.
54+
55+
Set up an environment with Jupyter, AnyWidget, and Pandas installed (`pip install jupyter anywidget pandas`). Then:
56+
57+
- unzip downloaded `output.tgz`
58+
- `pip uninstall plotly`
59+
- `pip install path/to/output/dist/plotly-X.Y.Z-py3-none-any.whl`
60+
61+
You'll want to check, in both JupyterLab (launch with `jupyter lab`) and Jupyter Notebook (launch with `jupyter notebook`),
62+
that `go.Figure()` and `go.FigureWidget()` work as expected.
2263
23-
**Create a branch `git checkout -b release-X.Y.Z` *from the tip of `origin/main`*.**
64+
Notes:
65+
- **Start by creating a brand new notebook each time** so that there is no caching of previous results
66+
- **Do not run the Jupyter commands from the root `plotly.py/` directory on your machine** because Jupyter may be confused
67+
by metadata from previous plotly.py builds
2468
25-
Manually update the versions to `X.Y.Z` in the files specified below.
69+
Code for testing `go.Figure()`:
70+
```python
71+
import plotly
72+
import plotly.graph_objects as go
2673

27-
- `pyproject.toml`
28-
+ update version
29-
- `CHANGELOG.md`
30-
+ update the release date
31-
- Commit your changes on the branch:
32-
+ `git commit -a -m "version changes for vX.Y.Z"`
33-
- Create a tag for Github release
34-
+ `git tag vX.Y.Z`
35-
+ `git push --atomic origin release-X.Y.Z vX.Y.Z`
36-
- Create a Github pull request from `release-X.Y.Z` to `main` and wait for CI to be green
74+
print(plotly.__version__) # Make sure version is correct
75+
fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4], y=[1, 3, 2, 4]))
76+
fig.show() # Figure should render in notebook
77+
```
3778

38-
### Download and QA CI Artifacts
79+
Code for testing `go.FigureWidget()`:
80+
```python
81+
import plotly
82+
import plotly.graph_objects as go
3983

40-
The `full_build` job in the `release_build` workflow in CircleCI produces a tarball of artifacts `output.tgz` which you should download and decompress, which will give you a directory called `output`. The filenames contained within will contain version numbers.
84+
print(plotly.__version__) # Make sure version is correct
85+
fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4], y=[1, 3, 2, 4]))
86+
figure_widget = go.FigureWidget(fig)
87+
figure_widget # Figure should render in notebook
88+
```
4189

42-
To locally install the PyPI dist, make sure you have an environment with JupyterLab installed (maybe one created with `conda create -n condatest python=3.10 jupyter anywidget pandas`):
90+
Once these are verified working, you can move on to publishing the release.
4391

44-
- `tar xzf output.tgz`
45-
- `pip uninstall plotly`
46-
- `conda uninstall plotly` (just in case!)
47-
- `pip install path/to/output/dist/plotly-X.Y.X-py3-none-any.whl`
92+
### Merge the release PR and make a GitHub release
4893

49-
You'll want to check, in both Lab and Notebook, **in a brand new notebook in each** so that there is no caching of previous results, that `go.Figure()` and `go.FigureWidget()` work without error.
94+
- Merge the pull request you created above into `main`
95+
- Go to https://github.com/plotly/plotly.py/releases and "Draft a new release"
96+
- Enter the `vX.Y.Z` tag you created already above and make "Release title" the same string as the tag.
97+
- Copy the changelog section for this version into "Describe this release"
98+
- Upload the build artifacts downloaded in the previous step (`.tar` and `.whl`)
5099

51-
### Publishing
100+
### Publishing to PyPI
52101

53-
Once you're satisfied that things render in Lab and Notebook in Widget and regular mode,
54-
you can publish the artifacts. **You will need special credentials from Plotly leadership to do this.**.
102+
The final step is to publish the release to PyPI. **You will need special permissions from Plotly leadership to do this.**.
55103

104+
You must install first install [Twine](https://pypi.org/project/twine/) (`pip install twine`) if not already installed.
56105

57106
Publishing to PyPI:
58107
```bash
59108
(plotly_dev) $ cd path/to/output
60109
(plotly_dev) $ twine upload plotly-X.Y.Z*
61110
```
62111

63-
### Merge the PR and make a Release
64-
65-
1. Merge the pull request you created above into `main`
66-
2. Go to https://github.com/plotly/plotly.py/releases and "Draft a new release"
67-
3. Enter the `vX.Y.Z` tag you created already above and make "Release title" the same string as the tag.
68-
4. Copy the changelog section for this version as the "Describe this release"
112+
You will be prompted to enter an API token; this can be generated in your PyPI account settings.
113+
Your account must have permissions to publish to the `plotly` project on PyPI.
69114

70115
### Update documentation site
71116

@@ -76,18 +121,18 @@ Publishing to PyPI:
76121
start by doing it first if not. Then merge `main` into `doc-prod` to deploy the doc related
77122
to features in the release.
78123
3. in a clone of the [`graphing-library-docs` repo](https://github.com/plotly/graphing-library-docs):
79-
1. bump the version of Plotly.py in `_data/pyversion.json`
80-
2. bump the version of Plotly.js with `cd _data && python get_plotschema.py <PLOTLY.JS VERSION>` fixing any errors that come up.
81-
- If Plotly.js contains any new traces or trace or layout attributes, you'll get a warning `“missing key in attributes: <attribute-name>`. To resolve, add the attribute to the relevant section in `/_data/orderings.json` in the position you want it to appear in the reference docs.
124+
1. bump the version of plotly.py in `_data/pyversion.json`
125+
2. bump the version of plotly.js with `cd _data && python get_plotschema.py <PLOTLY.JS VERSION>` fixing any errors that come up.
126+
- If plotly.js contains any new traces or trace or layout attributes, you'll get a warning `“missing key in attributes: <attribute-name>`. To resolve, add the attribute to the relevant section in `/_data/orderings.json` in the position you want it to appear in the reference docs.
82127
3. rebuild the Algolia `schema` index with `ALGOLIA_API_KEY=<key> make update_ref_search`
83128
4. Rebuild the Algolia `python` index with `ALGOLIA_API_KEY=<key> make update_python_search`
84129
5. Commit and push the changes to `master` in that repo
85130

86131
### Notify Stakeholders
87132

88-
* Post an announcement to the Plotly Python forum, with links to the README installation instructions and to the CHANGELOG.
133+
* Post an announcement to the [Plotly Python forum](https://community.plotly.com/c/plotly-python/5), with links to the README installation instructions and to the CHANGELOG.
89134
* Update the previous announcement to point to this one
90-
* Update the Github Release entry and CHANGELOG entry to have the nice title and a link to the announcement
135+
* Update the GitHub Release entry and CHANGELOG entry to have the nice title and a link to the announcement
91136
* Follow up on issues resolved in this release or forum posts with better answers as of this release
92137

93138
## Release process - Release *Candidate* of `plotly` package

codegen/resources/plot-schema.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4008,7 +4008,7 @@
40084008
"valType": "string"
40094009
},
40104010
"type": {
4011-
"description": "Sets the layer type, that is the how the layer data set in `source` will be rendered With `sourcetype` set to *geojson*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. but note that *line* and *fill* are not compatible with Point GeoJSON geometries. With `sourcetype` set to *vector*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. With `sourcetype` set to *raster* or `*image*`, only the *raster* value is allowed.",
4011+
"description": "Sets the layer type, that is the how the layer data set in `source` will be rendered With `sourcetype` set to *geojson*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. but note that *line* and *fill* are not compatible with Point GeoJSON geometries. With `sourcetype` set to *vector*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. With `sourcetype` set to *raster* or *image*, only the *raster* value is allowed.",
40124012
"dflt": "circle",
40134013
"editType": "plot",
40144014
"valType": "enumerated",
@@ -4414,7 +4414,7 @@
44144414
"valType": "string"
44154415
},
44164416
"type": {
4417-
"description": "Sets the layer type, that is the how the layer data set in `source` will be rendered With `sourcetype` set to *geojson*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. but note that *line* and *fill* are not compatible with Point GeoJSON geometries. With `sourcetype` set to *vector*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. With `sourcetype` set to *raster* or `*image*`, only the *raster* value is allowed.",
4417+
"description": "Sets the layer type, that is the how the layer data set in `source` will be rendered With `sourcetype` set to *geojson*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. but note that *line* and *fill* are not compatible with Point GeoJSON geometries. With `sourcetype` set to *vector*, the following values are allowed: *circle*, *line*, *fill* and *symbol*. With `sourcetype` set to *raster* or *image*, only the *raster* value is allowed.",
44184418
"dflt": "circle",
44194419
"editType": "plot",
44204420
"valType": "enumerated",
@@ -47932,7 +47932,7 @@
4793247932
"valType": "number"
4793347933
},
4793447934
"source": {
47935-
"description": "Specifies the data URI of the image to be visualized. The URI consists of \"data:image/[<media subtype>][;base64],<data>\"",
47935+
"description": "Specifies the data URI of the image to be visualized. The URI consists of \"data:image/[<media subtype\\\\>][;base64\\\\],<data\\\\>\"",
4793647936
"editType": "calc",
4793747937
"valType": "string"
4793847938
},
@@ -53288,7 +53288,7 @@
5328853288
]
5328953289
},
5329053290
"hovertemplate": {
53291-
"description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, *xother* will be added to those with different x positions from the first point. An underscore before or after *(x|y)other* will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. This value here applies when hovering over dimensions. Note that `*categorycount`, *colorcount* and *bandcolorcount* are only available when `hoveron` contains the *color* flagFinally, the template string has access to variables `count`, `probability`, `category`, `categorycount`, `colorcount` and `bandcolorcount`. Anything contained in tag `<extra>` is displayed in the secondary box, for example `<extra>%{fullData.name}</extra>`. To hide the secondary box completely, use an empty tag `<extra></extra>`.",
53291+
"description": "Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example \"y: %{y}\" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, *xother* will be added to those with different x positions from the first point. An underscore before or after *(x|y)other* will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. This value here applies when hovering over dimensions. Note that *categorycount*, *colorcount* and *bandcolorcount* are only available when `hoveron` contains the *color* flag. Finally, the template string has access to variables `count`, `probability`, `category`, `categorycount`, `colorcount` and `bandcolorcount`. Anything contained in tag `<extra>` is displayed in the secondary box, for example `<extra>%{fullData.name}</extra>`. To hide the secondary box completely, use an empty tag `<extra></extra>`.",
5329253292
"dflt": "",
5329353293
"editType": "plot",
5329453294
"valType": "string"

commands.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ def update_plotlyjs_dev(args, outdir):
296296
perform_codegen(outdir)
297297

298298

299-
def parse_args():
300-
"""Parse command-line arguments."""
299+
def make_parser():
300+
"""Make argument parser."""
301301

302302
parser = argparse.ArgumentParser()
303303
subparsers = parser.add_subparsers(dest="cmd", help="Available subcommands")
@@ -322,6 +322,11 @@ def parse_args():
322322

323323
subparsers.add_parser("updateplotlyjs", help="update plotly.js")
324324

325+
return parser
326+
327+
328+
def parse_args(parser: argparse.ArgumentParser):
329+
"""Parse command line arguments."""
325330
return parser.parse_args()
326331

327332

@@ -331,7 +336,8 @@ def main():
331336
project_root = os.path.dirname(os.path.realpath(__file__))
332337
outdir = os.path.join(project_root, "plotly")
333338

334-
args = parse_args()
339+
parser = make_parser()
340+
args = parse_args(parser)
335341

336342
if args.cmd == "codegen":
337343
perform_codegen(outdir, noformat=args.noformat)
@@ -350,6 +356,10 @@ def main():
350356
print(version)
351357
update_plotlyjs(version, outdir)
352358

359+
elif args.cmd is None:
360+
parser.print_help()
361+
sys.exit(1)
362+
353363
else:
354364
print(f"unknown command {args.cmd}", file=sys.stderr)
355365
sys.exit(1)

doc/apidoc/plotly.figure_factory.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
create_distplot
1919
create_facet_grid
2020
create_gantt
21-
create_hexbin_mapbox
21+
create_hexbin_map
2222
create_ohlc
2323
create_quiver
2424
create_scatterplotmatrix

0 commit comments

Comments
 (0)