xarray-plotly 0.0.1__tar.gz → 0.0.3__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.3/.github/dependabot.yml +25 -0
- xarray_plotly-0.0.3/.github/workflows/dependabot-auto-merge.yml +24 -0
- xarray_plotly-0.0.3/PKG-INFO +89 -0
- xarray_plotly-0.0.3/README.md +47 -0
- xarray_plotly-0.0.3/docs/api.md +28 -0
- xarray_plotly-0.0.3/docs/examples/advanced.ipynb +320 -0
- xarray_plotly-0.0.3/docs/examples/plot-types.ipynb +382 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/docs/getting-started.ipynb +30 -34
- xarray_plotly-0.0.3/docs/index.md +11 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/mkdocs.yml +1 -1
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/pyproject.toml +12 -11
- xarray_plotly-0.0.3/xarray_plotly/__init__.py +81 -0
- xarray_plotly-0.0.3/xarray_plotly/accessor.py +275 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly/common.py +45 -63
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly/config.py +48 -73
- xarray_plotly-0.0.3/xarray_plotly.egg-info/PKG-INFO +89 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/SOURCES.txt +2 -0
- xarray_plotly-0.0.3/xarray_plotly.egg-info/requires.txt +19 -0
- xarray_plotly-0.0.1/PKG-INFO +0 -175
- xarray_plotly-0.0.1/README.md +0 -134
- xarray_plotly-0.0.1/docs/api.md +0 -90
- xarray_plotly-0.0.1/docs/examples/advanced.ipynb +0 -425
- xarray_plotly-0.0.1/docs/examples/plot-types.ipynb +0 -381
- xarray_plotly-0.0.1/docs/index.md +0 -90
- xarray_plotly-0.0.1/xarray_plotly/__init__.py +0 -73
- xarray_plotly-0.0.1/xarray_plotly/accessor.py +0 -336
- xarray_plotly-0.0.1/xarray_plotly.egg-info/PKG-INFO +0 -175
- xarray_plotly-0.0.1/xarray_plotly.egg-info/requires.txt +0 -18
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/.github/workflows/ci.yml +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/.github/workflows/docs.yml +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/.github/workflows/release.yml +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/.gitignore +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/.pre-commit-config.yaml +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/CONTRIBUTING.md +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/LICENSE +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/setup.cfg +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/tests/__init__.py +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/tests/test_accessor.py +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/tests/test_common.py +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/tests/test_config.py +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly/plotting.py +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly/py.typed +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/dependency_links.txt +0 -0
- {xarray_plotly-0.0.1 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
groups:
|
|
8
|
+
dev-dependencies:
|
|
9
|
+
patterns:
|
|
10
|
+
- "pytest*"
|
|
11
|
+
- "mypy"
|
|
12
|
+
- "ruff"
|
|
13
|
+
- "pre-commit"
|
|
14
|
+
- "nbstripout"
|
|
15
|
+
docs-dependencies:
|
|
16
|
+
patterns:
|
|
17
|
+
- "mkdocs*"
|
|
18
|
+
- "pooch"
|
|
19
|
+
- "netcdf4"
|
|
20
|
+
- "jupyter"
|
|
21
|
+
|
|
22
|
+
- package-ecosystem: "github-actions"
|
|
23
|
+
directory: "/"
|
|
24
|
+
schedule:
|
|
25
|
+
interval: "weekly"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
on: pull_request
|
|
3
|
+
|
|
4
|
+
permissions:
|
|
5
|
+
contents: write
|
|
6
|
+
pull-requests: write
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
dependabot:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
if: github.actor == 'dependabot[bot]'
|
|
12
|
+
steps:
|
|
13
|
+
- name: Dependabot metadata
|
|
14
|
+
id: metadata
|
|
15
|
+
uses: dependabot/fetch-metadata@v2
|
|
16
|
+
with:
|
|
17
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
18
|
+
|
|
19
|
+
- name: Auto-merge minor and patch updates
|
|
20
|
+
if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'
|
|
21
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
22
|
+
env:
|
|
23
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
24
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xarray_plotly
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Summary: Interactive Plotly Express plotting accessor for xarray
|
|
5
|
+
Author: Felix
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FBumann/xarray_plotly
|
|
8
|
+
Project-URL: Documentation, https://fbumann.github.io/xarray_plotly
|
|
9
|
+
Project-URL: Repository, https://github.com/FBumann/xarray_plotly
|
|
10
|
+
Keywords: xarray,plotly,visualization,interactive,plotting
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: xarray>=2023.1.0
|
|
25
|
+
Requires-Dist: plotly>=5.0.0
|
|
26
|
+
Requires-Dist: pandas>=1.5.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest==8.3.5; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov==6.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy==1.14.1; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff==0.9.2; extra == "dev"
|
|
32
|
+
Requires-Dist: pre-commit==4.0.1; extra == "dev"
|
|
33
|
+
Requires-Dist: nbstripout==0.8.1; extra == "dev"
|
|
34
|
+
Provides-Extra: docs
|
|
35
|
+
Requires-Dist: mkdocs==1.6.1; extra == "docs"
|
|
36
|
+
Requires-Dist: mkdocs-material==9.5.49; extra == "docs"
|
|
37
|
+
Requires-Dist: mkdocstrings[python]==0.27.0; 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
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
# xarray_plotly
|
|
44
|
+
|
|
45
|
+
**Interactive Plotly Express plotting for xarray**
|
|
46
|
+
|
|
47
|
+
[](https://badge.fury.io/py/xarray_plotly)
|
|
48
|
+
[](https://pypi.org/project/xarray_plotly/)
|
|
49
|
+
[](https://github.com/FBumann/xarray_plotly/actions)
|
|
50
|
+
[](https://fbumann.github.io/xarray_plotly/)
|
|
51
|
+
[](https://opensource.org/licenses/MIT)
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install xarray_plotly
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import xarray as xr
|
|
63
|
+
import numpy as np
|
|
64
|
+
import xarray_plotly # registers the accessor
|
|
65
|
+
|
|
66
|
+
da = xr.DataArray(
|
|
67
|
+
np.random.randn(100, 3).cumsum(axis=0),
|
|
68
|
+
dims=["time", "city"],
|
|
69
|
+
coords={"time": np.arange(100), "city": ["NYC", "LA", "Chicago"]},
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Accessor style
|
|
73
|
+
fig = da.plotly.line()
|
|
74
|
+
fig.show()
|
|
75
|
+
|
|
76
|
+
# Or with xpx() for IDE code completion
|
|
77
|
+
from xarray_plotly import xpx
|
|
78
|
+
fig = xpx(da).line()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Why `xpx()`?** The accessor (`da.plotly`) works but IDEs can't provide code completion for it. This is because xarray accessors are registered dynamically at runtime, making them invisible to static type checkers. The `xpx()` function provides the same functionality with full IDE support. This limitation could only be solved by xarray itself, if at all — it may be a fundamental Python limitation.
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
Full documentation: [https://fbumann.github.io/xarray_plotly](https://fbumann.github.io/xarray_plotly)
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# xarray_plotly
|
|
2
|
+
|
|
3
|
+
**Interactive Plotly Express plotting for xarray**
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/py/xarray_plotly)
|
|
6
|
+
[](https://pypi.org/project/xarray_plotly/)
|
|
7
|
+
[](https://github.com/FBumann/xarray_plotly/actions)
|
|
8
|
+
[](https://fbumann.github.io/xarray_plotly/)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install xarray_plotly
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import xarray as xr
|
|
21
|
+
import numpy as np
|
|
22
|
+
import xarray_plotly # registers the accessor
|
|
23
|
+
|
|
24
|
+
da = xr.DataArray(
|
|
25
|
+
np.random.randn(100, 3).cumsum(axis=0),
|
|
26
|
+
dims=["time", "city"],
|
|
27
|
+
coords={"time": np.arange(100), "city": ["NYC", "LA", "Chicago"]},
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Accessor style
|
|
31
|
+
fig = da.plotly.line()
|
|
32
|
+
fig.show()
|
|
33
|
+
|
|
34
|
+
# Or with xpx() for IDE code completion
|
|
35
|
+
from xarray_plotly import xpx
|
|
36
|
+
fig = xpx(da).line()
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Why `xpx()`?** The accessor (`da.plotly`) works but IDEs can't provide code completion for it. This is because xarray accessors are registered dynamically at runtime, making them invisible to static type checkers. The `xpx()` function provides the same functionality with full IDE support. This limitation could only be solved by xarray itself, if at all — it may be a fundamental Python limitation.
|
|
40
|
+
|
|
41
|
+
## Documentation
|
|
42
|
+
|
|
43
|
+
Full documentation: [https://fbumann.github.io/xarray_plotly](https://fbumann.github.io/xarray_plotly)
|
|
44
|
+
|
|
45
|
+
## License
|
|
46
|
+
|
|
47
|
+
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
::: xarray_plotly.xpx
|
|
4
|
+
|
|
5
|
+
::: xarray_plotly.accessor.DataArrayPlotlyAccessor
|
|
6
|
+
options:
|
|
7
|
+
members:
|
|
8
|
+
- line
|
|
9
|
+
- bar
|
|
10
|
+
- area
|
|
11
|
+
- scatter
|
|
12
|
+
- box
|
|
13
|
+
- imshow
|
|
14
|
+
|
|
15
|
+
::: xarray_plotly.config
|
|
16
|
+
options:
|
|
17
|
+
members:
|
|
18
|
+
- notebook
|
|
19
|
+
- get_options
|
|
20
|
+
- set_options
|
|
21
|
+
- Options
|
|
22
|
+
|
|
23
|
+
::: xarray_plotly.common
|
|
24
|
+
options:
|
|
25
|
+
members:
|
|
26
|
+
- auto
|
|
27
|
+
- SLOT_ORDERS
|
|
28
|
+
- assign_slots
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {},
|
|
6
|
+
"source": [
|
|
7
|
+
"# Advanced Usage\n",
|
|
8
|
+
"\n",
|
|
9
|
+
"This notebook covers advanced Plotly customization. All kwargs are passed directly to [Plotly Express](https://plotly.com/python/plotly-express/), and figures can be modified using the full [Plotly Graph Objects API](https://plotly.com/python/graph-objects/)."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"cell_type": "code",
|
|
14
|
+
"execution_count": null,
|
|
15
|
+
"metadata": {},
|
|
16
|
+
"outputs": [],
|
|
17
|
+
"source": [
|
|
18
|
+
"import plotly.express as px\n",
|
|
19
|
+
"import plotly.graph_objects as go\n",
|
|
20
|
+
"import xarray as xr\n",
|
|
21
|
+
"\n",
|
|
22
|
+
"from xarray_plotly import config, xpx\n",
|
|
23
|
+
"\n",
|
|
24
|
+
"config.notebook()"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"cell_type": "code",
|
|
29
|
+
"execution_count": null,
|
|
30
|
+
"metadata": {},
|
|
31
|
+
"outputs": [],
|
|
32
|
+
"source": [
|
|
33
|
+
"# Load sample data\n",
|
|
34
|
+
"df_stocks = px.data.stocks().set_index(\"date\")\n",
|
|
35
|
+
"df_stocks.index = df_stocks.index.astype(\"datetime64[ns]\")\n",
|
|
36
|
+
"\n",
|
|
37
|
+
"stocks = xr.DataArray(\n",
|
|
38
|
+
" df_stocks.values,\n",
|
|
39
|
+
" dims=[\"date\", \"company\"],\n",
|
|
40
|
+
" coords={\"date\": df_stocks.index, \"company\": df_stocks.columns.tolist()},\n",
|
|
41
|
+
" name=\"price\",\n",
|
|
42
|
+
")\n",
|
|
43
|
+
"\n",
|
|
44
|
+
"df_gap = px.data.gapminder()\n",
|
|
45
|
+
"countries = [\"United States\", \"China\", \"Germany\", \"Brazil\", \"Nigeria\"]\n",
|
|
46
|
+
"df_life = df_gap[df_gap[\"country\"].isin(countries)].pivot(\n",
|
|
47
|
+
" index=\"year\", columns=\"country\", values=\"lifeExp\"\n",
|
|
48
|
+
")\n",
|
|
49
|
+
"life_exp = xr.DataArray(\n",
|
|
50
|
+
" df_life.values,\n",
|
|
51
|
+
" dims=[\"year\", \"country\"],\n",
|
|
52
|
+
" coords={\"year\": df_life.index, \"country\": df_life.columns.tolist()},\n",
|
|
53
|
+
" name=\"life_exp\",\n",
|
|
54
|
+
")"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"cell_type": "markdown",
|
|
59
|
+
"metadata": {},
|
|
60
|
+
"source": [
|
|
61
|
+
"## Passing Kwargs to Plotly Express\n",
|
|
62
|
+
"\n",
|
|
63
|
+
"All keyword arguments are passed directly to [Plotly Express functions](https://plotly.com/python-api-reference/plotly.express.html):"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"cell_type": "code",
|
|
68
|
+
"execution_count": null,
|
|
69
|
+
"metadata": {},
|
|
70
|
+
"outputs": [],
|
|
71
|
+
"source": [
|
|
72
|
+
"# All px.line kwargs work: template, labels, colors, etc.\n",
|
|
73
|
+
"fig = xpx(stocks).line(\n",
|
|
74
|
+
" title=\"Stock Performance\",\n",
|
|
75
|
+
" template=\"plotly_white\",\n",
|
|
76
|
+
" labels={\"price\": \"Normalized Price\", \"date\": \"Date\", \"company\": \"Ticker\"},\n",
|
|
77
|
+
" color_discrete_sequence=px.colors.qualitative.Set2,\n",
|
|
78
|
+
")\n",
|
|
79
|
+
"fig"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"cell_type": "code",
|
|
84
|
+
"execution_count": null,
|
|
85
|
+
"metadata": {},
|
|
86
|
+
"outputs": [],
|
|
87
|
+
"source": [
|
|
88
|
+
"# px.imshow kwargs: colorscale, midpoint, aspect\n",
|
|
89
|
+
"# See: https://plotly.com/python/imshow/\n",
|
|
90
|
+
"life_change = life_exp - life_exp.isel(year=0)\n",
|
|
91
|
+
"\n",
|
|
92
|
+
"fig = xpx(life_change).imshow(\n",
|
|
93
|
+
" color_continuous_scale=\"RdBu\",\n",
|
|
94
|
+
" color_continuous_midpoint=0,\n",
|
|
95
|
+
" aspect=\"auto\",\n",
|
|
96
|
+
" title=\"Life Expectancy Change Since 1952\",\n",
|
|
97
|
+
")\n",
|
|
98
|
+
"fig"
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"cell_type": "code",
|
|
103
|
+
"execution_count": null,
|
|
104
|
+
"metadata": {},
|
|
105
|
+
"outputs": [],
|
|
106
|
+
"source": [
|
|
107
|
+
"# px.bar kwargs: barmode, text_auto\n",
|
|
108
|
+
"# See: https://plotly.com/python/bar-charts/\n",
|
|
109
|
+
"fig = xpx(life_exp.sel(year=[1952, 1982, 2007])).bar(\n",
|
|
110
|
+
" barmode=\"group\",\n",
|
|
111
|
+
" text_auto=\".1f\",\n",
|
|
112
|
+
" title=\"Life Expectancy\",\n",
|
|
113
|
+
")\n",
|
|
114
|
+
"fig"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"cell_type": "markdown",
|
|
119
|
+
"metadata": {},
|
|
120
|
+
"source": [
|
|
121
|
+
"## Modifying Figures After Creation\n",
|
|
122
|
+
"\n",
|
|
123
|
+
"All methods return a Plotly `Figure`. Use the [Figure API](https://plotly.com/python/creating-and-updating-figures/) to customize:"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"cell_type": "markdown",
|
|
128
|
+
"metadata": {},
|
|
129
|
+
"source": [
|
|
130
|
+
"### update_layout\n",
|
|
131
|
+
"\n",
|
|
132
|
+
"Modify [layout properties](https://plotly.com/python/reference/layout/): legend, margins, fonts, etc."
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"cell_type": "code",
|
|
137
|
+
"execution_count": null,
|
|
138
|
+
"metadata": {},
|
|
139
|
+
"outputs": [],
|
|
140
|
+
"source": [
|
|
141
|
+
"fig = xpx(stocks).line()\n",
|
|
142
|
+
"\n",
|
|
143
|
+
"fig.update_layout(\n",
|
|
144
|
+
" title={\"text\": \"Stock Prices\", \"x\": 0.5, \"font\": {\"size\": 24}},\n",
|
|
145
|
+
" legend={\n",
|
|
146
|
+
" \"orientation\": \"h\",\n",
|
|
147
|
+
" \"yanchor\": \"bottom\",\n",
|
|
148
|
+
" \"y\": 1.02,\n",
|
|
149
|
+
" \"xanchor\": \"center\",\n",
|
|
150
|
+
" \"x\": 0.5,\n",
|
|
151
|
+
" },\n",
|
|
152
|
+
" margin={\"t\": 80},\n",
|
|
153
|
+
")\n",
|
|
154
|
+
"fig"
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"cell_type": "markdown",
|
|
159
|
+
"metadata": {},
|
|
160
|
+
"source": [
|
|
161
|
+
"### update_traces\n",
|
|
162
|
+
"\n",
|
|
163
|
+
"Modify [trace properties](https://plotly.com/python/reference/): line width, markers, opacity, etc."
|
|
164
|
+
]
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"cell_type": "code",
|
|
168
|
+
"execution_count": null,
|
|
169
|
+
"metadata": {},
|
|
170
|
+
"outputs": [],
|
|
171
|
+
"source": [
|
|
172
|
+
"fig = xpx(stocks).line()\n",
|
|
173
|
+
"fig.update_traces(line={\"width\": 3})\n",
|
|
174
|
+
"fig.update_layout(title=\"Thicker Lines\")\n",
|
|
175
|
+
"fig"
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"cell_type": "code",
|
|
180
|
+
"execution_count": null,
|
|
181
|
+
"metadata": {},
|
|
182
|
+
"outputs": [],
|
|
183
|
+
"source": [
|
|
184
|
+
"fig = xpx(stocks).scatter()\n",
|
|
185
|
+
"fig.update_traces(marker={\"size\": 12, \"opacity\": 0.7, \"line\": {\"width\": 1, \"color\": \"white\"}})\n",
|
|
186
|
+
"fig.update_layout(title=\"Custom Markers\")\n",
|
|
187
|
+
"fig"
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"cell_type": "markdown",
|
|
192
|
+
"metadata": {},
|
|
193
|
+
"source": [
|
|
194
|
+
"### update_xaxes / update_yaxes\n",
|
|
195
|
+
"\n",
|
|
196
|
+
"Modify [axis properties](https://plotly.com/python/axes/): range slider, tick format, etc."
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"cell_type": "code",
|
|
201
|
+
"execution_count": null,
|
|
202
|
+
"metadata": {},
|
|
203
|
+
"outputs": [],
|
|
204
|
+
"source": [
|
|
205
|
+
"fig = xpx(stocks).line(title=\"With Range Slider\")\n",
|
|
206
|
+
"fig.update_xaxes(rangeslider_visible=True)\n",
|
|
207
|
+
"fig.update_yaxes(tickformat=\".0%\")\n",
|
|
208
|
+
"fig"
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"cell_type": "markdown",
|
|
213
|
+
"metadata": {},
|
|
214
|
+
"source": [
|
|
215
|
+
"### Adding Shapes and Annotations\n",
|
|
216
|
+
"\n",
|
|
217
|
+
"Add reference lines, [shapes](https://plotly.com/python/shapes/), and [annotations](https://plotly.com/python/text-and-annotations/):"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"cell_type": "code",
|
|
222
|
+
"execution_count": null,
|
|
223
|
+
"metadata": {},
|
|
224
|
+
"outputs": [],
|
|
225
|
+
"source": [
|
|
226
|
+
"fig = xpx(stocks).line(title=\"With Reference Lines and Annotations\")\n",
|
|
227
|
+
"\n",
|
|
228
|
+
"fig.add_hline(y=1.0, line_dash=\"dash\", line_color=\"gray\", annotation_text=\"Baseline\")\n",
|
|
229
|
+
"fig.add_vline(x=\"2018-10-01\", line_dash=\"dot\", line_color=\"red\")\n",
|
|
230
|
+
"\n",
|
|
231
|
+
"fig.add_annotation(\n",
|
|
232
|
+
" x=\"2018-10-01\",\n",
|
|
233
|
+
" y=1.4,\n",
|
|
234
|
+
" text=\"Market correction\",\n",
|
|
235
|
+
" showarrow=True,\n",
|
|
236
|
+
" arrowhead=2,\n",
|
|
237
|
+
" ax=40,\n",
|
|
238
|
+
" ay=-40,\n",
|
|
239
|
+
")\n",
|
|
240
|
+
"fig"
|
|
241
|
+
]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"cell_type": "markdown",
|
|
245
|
+
"metadata": {},
|
|
246
|
+
"source": [
|
|
247
|
+
"### Adding Traces with Graph Objects\n",
|
|
248
|
+
"\n",
|
|
249
|
+
"Add custom traces using [Plotly Graph Objects](https://plotly.com/python/graph-objects/):"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"cell_type": "code",
|
|
254
|
+
"execution_count": null,
|
|
255
|
+
"metadata": {},
|
|
256
|
+
"outputs": [],
|
|
257
|
+
"source": [
|
|
258
|
+
"fig = xpx(stocks.sel(company=\"GOOG\")).line(title=\"GOOG with Moving Average\")\n",
|
|
259
|
+
"\n",
|
|
260
|
+
"# Add moving average as a new trace\n",
|
|
261
|
+
"goog = stocks.sel(company=\"GOOG\")\n",
|
|
262
|
+
"ma_20 = goog.rolling(date=20, center=True).mean()\n",
|
|
263
|
+
"\n",
|
|
264
|
+
"fig.add_trace(\n",
|
|
265
|
+
" go.Scatter(\n",
|
|
266
|
+
" x=ma_20.coords[\"date\"].values,\n",
|
|
267
|
+
" y=ma_20.values,\n",
|
|
268
|
+
" mode=\"lines\",\n",
|
|
269
|
+
" name=\"20-day MA\",\n",
|
|
270
|
+
" line={\"dash\": \"dash\", \"color\": \"red\", \"width\": 2},\n",
|
|
271
|
+
" )\n",
|
|
272
|
+
")\n",
|
|
273
|
+
"fig"
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"cell_type": "markdown",
|
|
278
|
+
"metadata": {},
|
|
279
|
+
"source": [
|
|
280
|
+
"## Exporting Figures\n",
|
|
281
|
+
"\n",
|
|
282
|
+
"See [static image export](https://plotly.com/python/static-image-export/) and [HTML export](https://plotly.com/python/interactive-html-export/).\n",
|
|
283
|
+
"\n",
|
|
284
|
+
"```python\n",
|
|
285
|
+
"# Interactive HTML\n",
|
|
286
|
+
"fig.write_html(\"plot.html\")\n",
|
|
287
|
+
"\n",
|
|
288
|
+
"# Static images (requires: pip install kaleido)\n",
|
|
289
|
+
"fig.write_image(\"plot.png\", scale=2)\n",
|
|
290
|
+
"fig.write_image(\"plot.svg\")\n",
|
|
291
|
+
"fig.write_image(\"plot.pdf\")\n",
|
|
292
|
+
"```"
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"cell_type": "markdown",
|
|
297
|
+
"metadata": {},
|
|
298
|
+
"source": [
|
|
299
|
+
"## More Resources\n",
|
|
300
|
+
"\n",
|
|
301
|
+
"- [Plotly Express API](https://plotly.com/python-api-reference/plotly.express.html)\n",
|
|
302
|
+
"- [Figure Reference](https://plotly.com/python/reference/)\n",
|
|
303
|
+
"- [Plotly Tutorials](https://plotly.com/python/)"
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
],
|
|
307
|
+
"metadata": {
|
|
308
|
+
"kernelspec": {
|
|
309
|
+
"display_name": "Python 3",
|
|
310
|
+
"language": "python",
|
|
311
|
+
"name": "python3"
|
|
312
|
+
},
|
|
313
|
+
"language_info": {
|
|
314
|
+
"name": "python",
|
|
315
|
+
"version": "3.12.0"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
"nbformat": 4,
|
|
319
|
+
"nbformat_minor": 4
|
|
320
|
+
}
|