xarray-plotly 0.0.13__tar.gz → 0.0.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.github/dependabot.yml +4 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.github/workflows/ci.yml +3 -3
- xarray_plotly-0.0.16/.github/workflows/dependabot-auto-merge.yml +39 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.github/workflows/docs.yml +4 -2
- xarray_plotly-0.0.16/.github/workflows/latest-deps.yml +35 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.github/workflows/pr-title.yml +8 -9
- xarray_plotly-0.0.16/.github/workflows/publish.yaml +66 -0
- xarray_plotly-0.0.16/.github/workflows/release.yaml +27 -0
- xarray_plotly-0.0.16/.readthedocs.yaml +18 -0
- xarray_plotly-0.0.16/.release-please-manifest.json +3 -0
- xarray_plotly-0.0.16/CHANGELOG.md +30 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/CONTRIBUTING.md +4 -7
- {xarray_plotly-0.0.13/xarray_plotly.egg-info → xarray_plotly-0.0.16}/PKG-INFO +1 -15
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/combining.ipynb +140 -16
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/dimensions.ipynb +11 -1
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/pyproject.toml +13 -12
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/tests/test_accessor.py +103 -1
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/tests/test_common.py +17 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/tests/test_figures.py +375 -2
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/__init__.py +4 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/accessor.py +38 -3
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/common.py +36 -3
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/config.py +1 -1
- xarray_plotly-0.0.16/xarray_plotly/figures.py +973 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/plotting.py +69 -17
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16/xarray_plotly.egg-info}/PKG-INFO +1 -15
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly.egg-info/SOURCES.txt +4 -2
- xarray_plotly-0.0.16/xarray_plotly.egg-info/requires.txt +3 -0
- xarray_plotly-0.0.13/.github/workflows/dependabot-auto-merge.yml +0 -24
- xarray_plotly-0.0.13/.github/workflows/release-please.yml +0 -19
- xarray_plotly-0.0.13/.github/workflows/release.yml +0 -24
- xarray_plotly-0.0.13/.release-please-manifest.json +0 -3
- xarray_plotly-0.0.13/CHANGELOG.md +0 -8
- xarray_plotly-0.0.13/xarray_plotly/figures.py +0 -467
- xarray_plotly-0.0.13/xarray_plotly.egg-info/requires.txt +0 -19
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.gitignore +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.pre-commit-config.yaml +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/.release-please-config.json +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/LICENSE +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/README.md +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/api.md +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/datasets.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/fast_bar.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/figure.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/kwargs.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/manipulation.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/examples/plot-types.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/getting-started.ipynb +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/docs/index.md +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/mkdocs.yml +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/setup.cfg +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/tests/__init__.py +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/tests/test_config.py +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly/py.typed +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly.egg-info/dependency_links.txt +0 -0
- {xarray_plotly-0.0.13 → xarray_plotly-0.0.16}/xarray_plotly.egg-info/top_level.txt +0 -0
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
run: uv python install ${{ matrix.python-version }}
|
|
24
24
|
|
|
25
25
|
- name: Install dependencies
|
|
26
|
-
run: uv sync --
|
|
26
|
+
run: uv sync --group dev
|
|
27
27
|
|
|
28
28
|
- name: Lint
|
|
29
29
|
run: uv run ruff check .
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
run: uv run pytest --cov=xarray_plotly --cov-report=xml
|
|
39
39
|
|
|
40
40
|
- name: Upload coverage
|
|
41
|
-
uses: codecov/codecov-action@
|
|
41
|
+
uses: codecov/codecov-action@v6
|
|
42
42
|
if: matrix.python-version == '3.12'
|
|
43
43
|
with:
|
|
44
44
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -53,7 +53,7 @@ jobs:
|
|
|
53
53
|
uses: astral-sh/setup-uv@v7
|
|
54
54
|
|
|
55
55
|
- name: Install dependencies
|
|
56
|
-
run: uv sync --
|
|
56
|
+
run: uv sync --group docs
|
|
57
57
|
|
|
58
58
|
- name: Build docs
|
|
59
59
|
run: uv run mkdocs build
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
pull-requests: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
auto-merge:
|
|
12
|
+
name: Auto-merge patch
|
|
13
|
+
if: github.actor == 'dependabot[bot]'
|
|
14
|
+
runs-on: ubuntu-24.04
|
|
15
|
+
steps:
|
|
16
|
+
- uses: dependabot/fetch-metadata@v3
|
|
17
|
+
id: metadata
|
|
18
|
+
|
|
19
|
+
- name: Generate app token
|
|
20
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
|
|
21
|
+
id: app-token
|
|
22
|
+
uses: actions/create-github-app-token@v3
|
|
23
|
+
with:
|
|
24
|
+
app-id: ${{ secrets.APP_ID }}
|
|
25
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
26
|
+
|
|
27
|
+
- name: Approve PR
|
|
28
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
|
|
29
|
+
run: gh pr review "$PR" --approve
|
|
30
|
+
env:
|
|
31
|
+
PR: ${{ github.event.pull_request.html_url }}
|
|
32
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
33
|
+
|
|
34
|
+
- name: Enable auto-merge
|
|
35
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
|
|
36
|
+
run: gh pr merge "$PR" --auto --squash
|
|
37
|
+
env:
|
|
38
|
+
PR: ${{ github.event.pull_request.html_url }}
|
|
39
|
+
GH_TOKEN: ${{ github.token }}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
name: Docs
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
4
6
|
pull_request:
|
|
5
7
|
branches: [main]
|
|
6
8
|
workflow_dispatch: # Manual trigger
|
|
7
9
|
workflow_run:
|
|
8
|
-
workflows: ["
|
|
10
|
+
workflows: ["Publish"]
|
|
9
11
|
types: [completed]
|
|
10
12
|
|
|
11
13
|
permissions:
|
|
@@ -30,7 +32,7 @@ jobs:
|
|
|
30
32
|
uses: astral-sh/setup-uv@v7
|
|
31
33
|
|
|
32
34
|
- name: Install dependencies
|
|
33
|
-
run: uv sync --
|
|
35
|
+
run: uv sync --group docs
|
|
34
36
|
|
|
35
37
|
- name: Build docs
|
|
36
38
|
run: uv run mkdocs build
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Test Latest Dependencies
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Every Monday at 07:00 UTC
|
|
6
|
+
- cron: "0 7 * * 1"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test-latest:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 30
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.10", "3.13"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v7
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
run: uv python install ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install with latest dependencies
|
|
28
|
+
run: uv sync --group dev --upgrade
|
|
29
|
+
|
|
30
|
+
- name: Test
|
|
31
|
+
run: uv run pytest --cov=xarray_plotly
|
|
32
|
+
|
|
33
|
+
- name: Print dependency versions
|
|
34
|
+
if: always()
|
|
35
|
+
run: uv pip list | grep -iE "xarray|plotly|pandas" || true
|
|
@@ -2,13 +2,15 @@ name: PR Title Check
|
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
|
-
types: [opened, edited,
|
|
5
|
+
types: [opened, edited, reopened]
|
|
6
|
+
push:
|
|
7
|
+
branches: ['release-please--**']
|
|
6
8
|
|
|
7
9
|
jobs:
|
|
8
10
|
validate:
|
|
9
11
|
runs-on: ubuntu-latest
|
|
10
12
|
steps:
|
|
11
|
-
- uses: amannn/action-semantic-pull-request@
|
|
13
|
+
- uses: amannn/action-semantic-pull-request@v6
|
|
12
14
|
env:
|
|
13
15
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
14
16
|
with:
|
|
@@ -17,15 +19,12 @@ jobs:
|
|
|
17
19
|
types: |
|
|
18
20
|
feat
|
|
19
21
|
fix
|
|
20
|
-
|
|
21
|
-
style
|
|
22
|
-
refactor
|
|
23
|
-
perf
|
|
22
|
+
refac
|
|
24
23
|
test
|
|
25
|
-
|
|
26
|
-
ci
|
|
24
|
+
docs
|
|
27
25
|
chore
|
|
28
|
-
|
|
26
|
+
ci
|
|
27
|
+
perf
|
|
29
28
|
# Scope is optional
|
|
30
29
|
requireScope: false
|
|
31
30
|
# Subject (description) requirements
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
concurrency:
|
|
8
|
+
group: publish-${{ github.ref_name }}
|
|
9
|
+
cancel-in-progress: false
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
id-token: write
|
|
14
|
+
attestations: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
publish:
|
|
18
|
+
name: Build & publish to PyPI
|
|
19
|
+
runs-on: ubuntu-24.04
|
|
20
|
+
timeout-minutes: 10
|
|
21
|
+
environment:
|
|
22
|
+
name: pypi
|
|
23
|
+
url: https://pypi.org/project/xarray_plotly
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
|
+
with:
|
|
27
|
+
ref: ${{ github.ref_name }}
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
|
|
30
|
+
- uses: astral-sh/setup-uv@v7
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- uses: actions/setup-python@v6
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.12"
|
|
37
|
+
|
|
38
|
+
- name: Build
|
|
39
|
+
run: uv build
|
|
40
|
+
|
|
41
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
42
|
+
|
|
43
|
+
github-release:
|
|
44
|
+
name: Create GitHub Release
|
|
45
|
+
needs: [publish]
|
|
46
|
+
if: github.event_name == 'push' && needs.publish.result == 'success'
|
|
47
|
+
runs-on: ubuntu-24.04
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@v6
|
|
50
|
+
with:
|
|
51
|
+
ref: ${{ github.ref_name }}
|
|
52
|
+
|
|
53
|
+
- name: Create GitHub Release
|
|
54
|
+
run: |
|
|
55
|
+
if gh release view "$TAG" &>/dev/null; then
|
|
56
|
+
echo "Release $TAG already exists, skipping."
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
if [[ "$TAG" == *-* ]]; then
|
|
60
|
+
gh release create "$TAG" --generate-notes --prerelease
|
|
61
|
+
else
|
|
62
|
+
gh release create "$TAG" --generate-notes
|
|
63
|
+
fi
|
|
64
|
+
env:
|
|
65
|
+
GH_TOKEN: ${{ github.token }}
|
|
66
|
+
TAG: ${{ github.ref_name }}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
pull-requests: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release-please:
|
|
13
|
+
name: Release Please
|
|
14
|
+
runs-on: ubuntu-24.04
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/create-github-app-token@v3
|
|
17
|
+
id: app-token
|
|
18
|
+
with:
|
|
19
|
+
app-id: ${{ secrets.APP_ID }}
|
|
20
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
21
|
+
|
|
22
|
+
- uses: googleapis/release-please-action@v5
|
|
23
|
+
id: release
|
|
24
|
+
with:
|
|
25
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
26
|
+
config-file: .release-please-config.json
|
|
27
|
+
manifest-file: .release-please-manifest.json
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
mkdocs:
|
|
4
|
+
configuration: mkdocs.yml
|
|
5
|
+
|
|
6
|
+
build:
|
|
7
|
+
os: ubuntu-24.04
|
|
8
|
+
tools:
|
|
9
|
+
python: "3.13"
|
|
10
|
+
jobs:
|
|
11
|
+
pre_create_environment:
|
|
12
|
+
- asdf plugin add uv
|
|
13
|
+
- asdf install uv latest
|
|
14
|
+
- asdf global uv latest
|
|
15
|
+
create_environment:
|
|
16
|
+
- uv venv "${READTHEDOCS_VIRTUALENV_PATH}"
|
|
17
|
+
install:
|
|
18
|
+
- UV_PROJECT_ENVIRONMENT="${READTHEDOCS_VIRTUALENV_PATH}" uv sync --group docs
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.0.16](https://github.com/FBumann/xarray_plotly/compare/v0.0.15...v0.0.16) (2026-06-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **imshow:** support facet_row for subplot rows (plotly>=6.7) ([#82](https://github.com/FBumann/xarray_plotly/issues/82)) ([55b503b](https://github.com/FBumann/xarray_plotly/commit/55b503b37d598c845631c7b35adcea3a8f1e3ed9))
|
|
9
|
+
* **plotting:** add facet_titles kwarg to strip dim= prefix ([#77](https://github.com/FBumann/xarray_plotly/issues/77)) ([1433a95](https://github.com/FBumann/xarray_plotly/commit/1433a95c45cacb5f49c35e6f63794d668f6278ab))
|
|
10
|
+
|
|
11
|
+
## [0.0.15](https://github.com/FBumann/xarray_plotly/compare/v0.0.14...v0.0.15) (2026-03-23)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* legend, style persistence, and axis ranges in combined figures ([#53](https://github.com/FBumann/xarray_plotly/issues/53)) ([28fccc3](https://github.com/FBumann/xarray_plotly/commit/28fccc3d32da334625e626096bfcbf78e3c65de6))
|
|
17
|
+
|
|
18
|
+
## [0.0.14](https://github.com/FBumann/xarray_plotly/compare/v0.0.13...v0.0.14) (2026-03-09)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* continuous colorscale strings with discrete-only chart types ([#46](https://github.com/FBumann/xarray_plotly/issues/46)) ([cc865b5](https://github.com/FBumann/xarray_plotly/commit/cc865b5c1d2f7a2921b8e27c23546a883a974279))
|
|
24
|
+
|
|
25
|
+
## [0.0.13](https://github.com/FBumann/xarray_plotly/compare/v0.0.12...v0.0.13) (2026-01-28)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* secondary y axis match and visibility when faceted ([#32](https://github.com/FBumann/xarray_plotly/issues/32)) ([10da229](https://github.com/FBumann/xarray_plotly/commit/10da229282377a229054321e8ff98e3fd6825939))
|
|
@@ -42,11 +42,8 @@ uv run ruff format .
|
|
|
42
42
|
|
|
43
43
|
## Releases
|
|
44
44
|
|
|
45
|
-
Releases are automated via
|
|
45
|
+
Releases are fully automated via [Release Please](https://github.com/googleapis/release-please).
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
2. Push: `git push && git push --tags`
|
|
51
|
-
|
|
52
|
-
The CI will automatically publish to PyPI and deploy updated docs.
|
|
47
|
+
1. Merge PRs to `main` using [conventional commit](https://www.conventionalcommits.org/) prefixes (`feat:`, `fix:`, etc.)
|
|
48
|
+
2. Release Please automatically creates/updates a release PR with changelog and version bump
|
|
49
|
+
3. Merge the release PR to publish to PyPI and deploy updated docs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarray_plotly
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.16
|
|
4
4
|
Summary: Interactive Plotly Express plotting accessor for xarray
|
|
5
5
|
Author: Felix
|
|
6
6
|
License: MIT
|
|
@@ -24,20 +24,6 @@ License-File: LICENSE
|
|
|
24
24
|
Requires-Dist: xarray>=2023.1.0
|
|
25
25
|
Requires-Dist: plotly>=5.0.0
|
|
26
26
|
Requires-Dist: pandas>=1.5.0
|
|
27
|
-
Provides-Extra: dev
|
|
28
|
-
Requires-Dist: pytest==9.0.2; extra == "dev"
|
|
29
|
-
Requires-Dist: pytest-cov==7.0.0; extra == "dev"
|
|
30
|
-
Requires-Dist: mypy==1.19.1; extra == "dev"
|
|
31
|
-
Requires-Dist: ruff==0.14.14; extra == "dev"
|
|
32
|
-
Requires-Dist: pre-commit==4.5.1; extra == "dev"
|
|
33
|
-
Requires-Dist: nbstripout==0.9.0; extra == "dev"
|
|
34
|
-
Provides-Extra: docs
|
|
35
|
-
Requires-Dist: mkdocs==1.6.1; extra == "docs"
|
|
36
|
-
Requires-Dist: mkdocs-material==9.7.1; extra == "docs"
|
|
37
|
-
Requires-Dist: mkdocstrings[python]==1.0.1; extra == "docs"
|
|
38
|
-
Requires-Dist: mkdocs-jupyter==0.25.1; extra == "docs"
|
|
39
|
-
Requires-Dist: mkdocs-plotly-plugin==0.1.3; extra == "docs"
|
|
40
|
-
Requires-Dist: jupyter==1.1.1; extra == "docs"
|
|
41
27
|
Dynamic: license-file
|
|
42
28
|
|
|
43
29
|
# xarray_plotly
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"xarray-plotly provides helper functions to combine multiple figures:\n",
|
|
11
11
|
"\n",
|
|
12
12
|
"- **`overlay`**: Overlay traces on the same axes\n",
|
|
13
|
-
"- **`add_secondary_y`**: Plot with two independent y-axes"
|
|
13
|
+
"- **`add_secondary_y`**: Plot with two independent y-axes\n",
|
|
14
|
+
"- **`subplots`**: Arrange independent figures in a grid"
|
|
14
15
|
]
|
|
15
16
|
},
|
|
16
17
|
{
|
|
@@ -23,7 +24,7 @@
|
|
|
23
24
|
"import plotly.express as px\n",
|
|
24
25
|
"import xarray as xr\n",
|
|
25
26
|
"\n",
|
|
26
|
-
"from xarray_plotly import add_secondary_y, config, overlay, xpx\n",
|
|
27
|
+
"from xarray_plotly import add_secondary_y, config, overlay, subplots, xpx\n",
|
|
27
28
|
"\n",
|
|
28
29
|
"config.notebook()"
|
|
29
30
|
]
|
|
@@ -440,6 +441,128 @@
|
|
|
440
441
|
"cell_type": "markdown",
|
|
441
442
|
"id": "27",
|
|
442
443
|
"metadata": {},
|
|
444
|
+
"source": [
|
|
445
|
+
"## subplots\n",
|
|
446
|
+
"\n",
|
|
447
|
+
"Arrange independent figures side-by-side in a grid. Each figure gets its own\n",
|
|
448
|
+
"subplot cell with axes and title automatically derived from the source figure."
|
|
449
|
+
]
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"cell_type": "markdown",
|
|
453
|
+
"id": "28",
|
|
454
|
+
"metadata": {},
|
|
455
|
+
"source": [
|
|
456
|
+
"### Different Variables Side by Side"
|
|
457
|
+
]
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"cell_type": "code",
|
|
461
|
+
"execution_count": null,
|
|
462
|
+
"id": "29",
|
|
463
|
+
"metadata": {},
|
|
464
|
+
"outputs": [],
|
|
465
|
+
"source": [
|
|
466
|
+
"# One figure per variable, arranged in a row\n",
|
|
467
|
+
"us_pop = population.sel(country=\"United States\")\n",
|
|
468
|
+
"us_gdp = gdp_per_capita.sel(country=\"United States\")\n",
|
|
469
|
+
"us_life = life_expectancy.sel(country=\"United States\")\n",
|
|
470
|
+
"\n",
|
|
471
|
+
"pop_fig = xpx(us_pop).bar(title=\"Population\")\n",
|
|
472
|
+
"gdp_fig = xpx(us_gdp).line(title=\"GDP per Capita\")\n",
|
|
473
|
+
"life_fig = xpx(us_life).line(title=\"Life Expectancy\")\n",
|
|
474
|
+
"\n",
|
|
475
|
+
"grid = subplots(pop_fig, gdp_fig, life_fig, cols=3)\n",
|
|
476
|
+
"grid.update_layout(title=\"United States Overview\", height=350, showlegend=False)\n",
|
|
477
|
+
"grid"
|
|
478
|
+
]
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"cell_type": "markdown",
|
|
482
|
+
"id": "30",
|
|
483
|
+
"metadata": {},
|
|
484
|
+
"source": [
|
|
485
|
+
"### 2x2 Grid\n",
|
|
486
|
+
"\n",
|
|
487
|
+
"Use `cols=2` and pass four figures for a 2x2 layout."
|
|
488
|
+
]
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"cell_type": "code",
|
|
492
|
+
"execution_count": null,
|
|
493
|
+
"id": "31",
|
|
494
|
+
"metadata": {},
|
|
495
|
+
"outputs": [],
|
|
496
|
+
"source": [
|
|
497
|
+
"# One subplot per country\n",
|
|
498
|
+
"fig_us = xpx(population.sel(country=\"United States\")).bar(title=\"United States\")\n",
|
|
499
|
+
"fig_cn = xpx(population.sel(country=\"China\")).bar(title=\"China\")\n",
|
|
500
|
+
"fig_de = xpx(population.sel(country=\"Germany\")).bar(title=\"Germany\")\n",
|
|
501
|
+
"fig_br = xpx(population.sel(country=\"Brazil\")).bar(title=\"Brazil\")\n",
|
|
502
|
+
"\n",
|
|
503
|
+
"grid = subplots(fig_us, fig_cn, fig_de, fig_br, cols=2)\n",
|
|
504
|
+
"grid.update_layout(height=500, showlegend=False)\n",
|
|
505
|
+
"grid"
|
|
506
|
+
]
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
"cell_type": "markdown",
|
|
510
|
+
"id": "32",
|
|
511
|
+
"metadata": {},
|
|
512
|
+
"source": [
|
|
513
|
+
"### Mixed Chart Types\n",
|
|
514
|
+
"\n",
|
|
515
|
+
"Each cell can use a different chart type. Subplot titles fall back to the\n",
|
|
516
|
+
"y-axis label when no explicit title is set."
|
|
517
|
+
]
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"cell_type": "code",
|
|
521
|
+
"execution_count": null,
|
|
522
|
+
"id": "33",
|
|
523
|
+
"metadata": {},
|
|
524
|
+
"outputs": [],
|
|
525
|
+
"source": [
|
|
526
|
+
"# No explicit title — subplot titles come from the y-axis label (DataArray name)\n",
|
|
527
|
+
"pop_bar = xpx(us_pop).bar()\n",
|
|
528
|
+
"gdp_line = xpx(us_gdp).line()\n",
|
|
529
|
+
"life_scatter = xpx(us_life).scatter()\n",
|
|
530
|
+
"\n",
|
|
531
|
+
"grid = subplots(pop_bar, gdp_line, life_scatter, cols=3)\n",
|
|
532
|
+
"grid.update_layout(height=350, showlegend=False)\n",
|
|
533
|
+
"grid"
|
|
534
|
+
]
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"cell_type": "markdown",
|
|
538
|
+
"id": "34",
|
|
539
|
+
"metadata": {},
|
|
540
|
+
"source": [
|
|
541
|
+
"### With Facets\n",
|
|
542
|
+
"\n",
|
|
543
|
+
"Faceted figures can be composed — each figure's internal subplots are remapped into the grid cell."
|
|
544
|
+
]
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"cell_type": "code",
|
|
548
|
+
"execution_count": null,
|
|
549
|
+
"id": "35",
|
|
550
|
+
"metadata": {},
|
|
551
|
+
"outputs": [],
|
|
552
|
+
"source": [
|
|
553
|
+
"# Faceted bar on top, faceted line below\n",
|
|
554
|
+
"pop_faceted = xpx(population).bar(facet_col=\"country\")\n",
|
|
555
|
+
"gdp_faceted = xpx(gdp_per_capita).line(facet_col=\"country\")\n",
|
|
556
|
+
"\n",
|
|
557
|
+
"grid = subplots(pop_faceted, gdp_faceted, cols=1)\n",
|
|
558
|
+
"grid.update_layout(height=600, showlegend=False)\n",
|
|
559
|
+
"grid"
|
|
560
|
+
]
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
"cell_type": "markdown",
|
|
564
|
+
"id": "36",
|
|
565
|
+
"metadata": {},
|
|
443
566
|
"source": [
|
|
444
567
|
"---\n",
|
|
445
568
|
"\n",
|
|
@@ -450,7 +573,7 @@
|
|
|
450
573
|
},
|
|
451
574
|
{
|
|
452
575
|
"cell_type": "markdown",
|
|
453
|
-
"id": "
|
|
576
|
+
"id": "37",
|
|
454
577
|
"metadata": {},
|
|
455
578
|
"source": [
|
|
456
579
|
"### overlay: Mismatched Facet Structure\n",
|
|
@@ -461,7 +584,7 @@
|
|
|
461
584
|
{
|
|
462
585
|
"cell_type": "code",
|
|
463
586
|
"execution_count": null,
|
|
464
|
-
"id": "
|
|
587
|
+
"id": "38",
|
|
465
588
|
"metadata": {},
|
|
466
589
|
"outputs": [],
|
|
467
590
|
"source": [
|
|
@@ -479,7 +602,7 @@
|
|
|
479
602
|
},
|
|
480
603
|
{
|
|
481
604
|
"cell_type": "markdown",
|
|
482
|
-
"id": "
|
|
605
|
+
"id": "39",
|
|
483
606
|
"metadata": {},
|
|
484
607
|
"source": [
|
|
485
608
|
"### overlay: Animated Overlay on Static Base\n",
|
|
@@ -490,7 +613,7 @@
|
|
|
490
613
|
{
|
|
491
614
|
"cell_type": "code",
|
|
492
615
|
"execution_count": null,
|
|
493
|
-
"id": "
|
|
616
|
+
"id": "40",
|
|
494
617
|
"metadata": {},
|
|
495
618
|
"outputs": [],
|
|
496
619
|
"source": [
|
|
@@ -508,7 +631,7 @@
|
|
|
508
631
|
},
|
|
509
632
|
{
|
|
510
633
|
"cell_type": "markdown",
|
|
511
|
-
"id": "
|
|
634
|
+
"id": "41",
|
|
512
635
|
"metadata": {},
|
|
513
636
|
"source": [
|
|
514
637
|
"### overlay: Mismatched Animation Frames\n",
|
|
@@ -519,7 +642,7 @@
|
|
|
519
642
|
{
|
|
520
643
|
"cell_type": "code",
|
|
521
644
|
"execution_count": null,
|
|
522
|
-
"id": "
|
|
645
|
+
"id": "42",
|
|
523
646
|
"metadata": {},
|
|
524
647
|
"outputs": [],
|
|
525
648
|
"source": [
|
|
@@ -535,7 +658,7 @@
|
|
|
535
658
|
},
|
|
536
659
|
{
|
|
537
660
|
"cell_type": "markdown",
|
|
538
|
-
"id": "
|
|
661
|
+
"id": "43",
|
|
539
662
|
"metadata": {},
|
|
540
663
|
"source": [
|
|
541
664
|
"### add_secondary_y: Mismatched Facet Structure\n",
|
|
@@ -546,7 +669,7 @@
|
|
|
546
669
|
{
|
|
547
670
|
"cell_type": "code",
|
|
548
671
|
"execution_count": null,
|
|
549
|
-
"id": "
|
|
672
|
+
"id": "44",
|
|
550
673
|
"metadata": {},
|
|
551
674
|
"outputs": [],
|
|
552
675
|
"source": [
|
|
@@ -564,7 +687,7 @@
|
|
|
564
687
|
},
|
|
565
688
|
{
|
|
566
689
|
"cell_type": "markdown",
|
|
567
|
-
"id": "
|
|
690
|
+
"id": "45",
|
|
568
691
|
"metadata": {},
|
|
569
692
|
"source": [
|
|
570
693
|
"### add_secondary_y: Animated Secondary on Static Base\n",
|
|
@@ -575,7 +698,7 @@
|
|
|
575
698
|
{
|
|
576
699
|
"cell_type": "code",
|
|
577
700
|
"execution_count": null,
|
|
578
|
-
"id": "
|
|
701
|
+
"id": "46",
|
|
579
702
|
"metadata": {},
|
|
580
703
|
"outputs": [],
|
|
581
704
|
"source": [
|
|
@@ -593,7 +716,7 @@
|
|
|
593
716
|
},
|
|
594
717
|
{
|
|
595
718
|
"cell_type": "markdown",
|
|
596
|
-
"id": "
|
|
719
|
+
"id": "47",
|
|
597
720
|
"metadata": {},
|
|
598
721
|
"source": [
|
|
599
722
|
"### add_secondary_y: Mismatched Animation Frames"
|
|
@@ -602,7 +725,7 @@
|
|
|
602
725
|
{
|
|
603
726
|
"cell_type": "code",
|
|
604
727
|
"execution_count": null,
|
|
605
|
-
"id": "
|
|
728
|
+
"id": "48",
|
|
606
729
|
"metadata": {},
|
|
607
730
|
"outputs": [],
|
|
608
731
|
"source": [
|
|
@@ -618,7 +741,7 @@
|
|
|
618
741
|
},
|
|
619
742
|
{
|
|
620
743
|
"cell_type": "markdown",
|
|
621
|
-
"id": "
|
|
744
|
+
"id": "49",
|
|
622
745
|
"metadata": {},
|
|
623
746
|
"source": [
|
|
624
747
|
"## Summary\n",
|
|
@@ -626,7 +749,8 @@
|
|
|
626
749
|
"| Function | Facets | Animation | Static + Animated |\n",
|
|
627
750
|
"|----------|--------|-----------|-------------------|\n",
|
|
628
751
|
"| `overlay` | Yes (must match) | Yes (frames must match) | Static overlay on animated base OK |\n",
|
|
629
|
-
"| `add_secondary_y` | Yes (must match) | Yes (frames must match) | Static secondary on animated base OK
|
|
752
|
+
"| `add_secondary_y` | Yes (must match) | Yes (frames must match) | Static secondary on animated base OK |\n",
|
|
753
|
+
"| `subplots` | Yes (remapped into cells) | No | N/A |"
|
|
630
754
|
]
|
|
631
755
|
}
|
|
632
756
|
],
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
"| line | x, color, line_dash, facet_col, facet_row, animation_frame |\n",
|
|
135
135
|
"| scatter | x, color, symbol, facet_col, facet_row, animation_frame |\n",
|
|
136
136
|
"| bar | x, color, facet_col, facet_row, animation_frame |\n",
|
|
137
|
-
"| imshow |
|
|
137
|
+
"| imshow | y, x, facet_col, facet_row, animation_frame |"
|
|
138
138
|
]
|
|
139
139
|
},
|
|
140
140
|
{
|
|
@@ -186,6 +186,16 @@
|
|
|
186
186
|
"xpx(data_3d).line(x=\"year\", facet_col=\"metric\", facet_row=\"country\")"
|
|
187
187
|
]
|
|
188
188
|
},
|
|
189
|
+
{
|
|
190
|
+
"cell_type": "code",
|
|
191
|
+
"execution_count": null,
|
|
192
|
+
"metadata": {},
|
|
193
|
+
"outputs": [],
|
|
194
|
+
"source": [
|
|
195
|
+
"# Heatmap grids: imshow supports facet_col and facet_row (requires plotly>=6.7)\n",
|
|
196
|
+
"xpx(data_3d).imshow(facet_row=\"metric\")"
|
|
197
|
+
]
|
|
198
|
+
},
|
|
189
199
|
{
|
|
190
200
|
"cell_type": "markdown",
|
|
191
201
|
"metadata": {},
|