xarray-plotly 0.0.2__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.
Files changed (37) hide show
  1. xarray_plotly-0.0.3/.github/dependabot.yml +25 -0
  2. xarray_plotly-0.0.3/.github/workflows/dependabot-auto-merge.yml +24 -0
  3. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/PKG-INFO +17 -12
  4. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/README.md +4 -0
  5. xarray_plotly-0.0.3/docs/examples/advanced.ipynb +320 -0
  6. xarray_plotly-0.0.3/docs/examples/plot-types.ipynb +382 -0
  7. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/docs/getting-started.ipynb +30 -34
  8. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/pyproject.toml +12 -11
  9. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/PKG-INFO +17 -12
  10. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/SOURCES.txt +2 -0
  11. xarray_plotly-0.0.3/xarray_plotly.egg-info/requires.txt +19 -0
  12. xarray_plotly-0.0.2/docs/examples/advanced.ipynb +0 -425
  13. xarray_plotly-0.0.2/docs/examples/plot-types.ipynb +0 -381
  14. xarray_plotly-0.0.2/xarray_plotly.egg-info/requires.txt +0 -18
  15. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/.github/workflows/ci.yml +0 -0
  16. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/.github/workflows/docs.yml +0 -0
  17. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/.github/workflows/release.yml +0 -0
  18. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/.gitignore +0 -0
  19. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/.pre-commit-config.yaml +0 -0
  20. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/CONTRIBUTING.md +0 -0
  21. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/LICENSE +0 -0
  22. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/docs/api.md +0 -0
  23. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/docs/index.md +0 -0
  24. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/mkdocs.yml +0 -0
  25. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/setup.cfg +0 -0
  26. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/tests/__init__.py +0 -0
  27. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/tests/test_accessor.py +0 -0
  28. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/tests/test_common.py +0 -0
  29. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/tests/test_config.py +0 -0
  30. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/__init__.py +0 -0
  31. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/accessor.py +0 -0
  32. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/common.py +0 -0
  33. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/config.py +0 -0
  34. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/plotting.py +0 -0
  35. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly/py.typed +0 -0
  36. {xarray_plotly-0.0.2 → xarray_plotly-0.0.3}/xarray_plotly.egg-info/dependency_links.txt +0 -0
  37. {xarray_plotly-0.0.2 → 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 }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xarray_plotly
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: Interactive Plotly Express plotting accessor for xarray
5
5
  Author: Felix
6
6
  License: MIT
@@ -25,18 +25,19 @@ Requires-Dist: xarray>=2023.1.0
25
25
  Requires-Dist: plotly>=5.0.0
26
26
  Requires-Dist: pandas>=1.5.0
27
27
  Provides-Extra: dev
28
- Requires-Dist: pytest>=7.0; extra == "dev"
29
- Requires-Dist: pytest-cov>=4.0; extra == "dev"
30
- Requires-Dist: mypy>=1.0; extra == "dev"
31
- Requires-Dist: ruff>=0.4; extra == "dev"
32
- Requires-Dist: pre-commit>=3.0; extra == "dev"
33
- Requires-Dist: nbstripout>=0.6; 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
34
  Provides-Extra: docs
35
- Requires-Dist: mkdocs>=1.5; extra == "docs"
36
- Requires-Dist: mkdocs-material>=9.0; extra == "docs"
37
- Requires-Dist: mkdocstrings[python]>=0.24; extra == "docs"
38
- Requires-Dist: mkdocs-jupyter>=0.24; extra == "docs"
39
- Requires-Dist: mkdocs-plotly-plugin>=0.1; 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"
40
41
  Dynamic: license-file
41
42
 
42
43
  # xarray_plotly
@@ -45,7 +46,9 @@ Dynamic: license-file
45
46
 
46
47
  [![PyPI version](https://badge.fury.io/py/xarray_plotly.svg)](https://badge.fury.io/py/xarray_plotly)
47
48
  [![Python](https://img.shields.io/pypi/pyversions/xarray_plotly.svg)](https://pypi.org/project/xarray_plotly/)
49
+ [![CI](https://github.com/FBumann/xarray_plotly/actions/workflows/ci.yml/badge.svg)](https://github.com/FBumann/xarray_plotly/actions)
48
50
  [![Docs](https://img.shields.io/badge/docs-fbumann.github.io-blue)](https://fbumann.github.io/xarray_plotly/)
51
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
49
52
 
50
53
  ## Installation
51
54
 
@@ -75,6 +78,8 @@ from xarray_plotly import xpx
75
78
  fig = xpx(da).line()
76
79
  ```
77
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
+
78
83
  ## Documentation
79
84
 
80
85
  Full documentation: [https://fbumann.github.io/xarray_plotly](https://fbumann.github.io/xarray_plotly)
@@ -4,7 +4,9 @@
4
4
 
5
5
  [![PyPI version](https://badge.fury.io/py/xarray_plotly.svg)](https://badge.fury.io/py/xarray_plotly)
6
6
  [![Python](https://img.shields.io/pypi/pyversions/xarray_plotly.svg)](https://pypi.org/project/xarray_plotly/)
7
+ [![CI](https://github.com/FBumann/xarray_plotly/actions/workflows/ci.yml/badge.svg)](https://github.com/FBumann/xarray_plotly/actions)
7
8
  [![Docs](https://img.shields.io/badge/docs-fbumann.github.io-blue)](https://fbumann.github.io/xarray_plotly/)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
10
 
9
11
  ## Installation
10
12
 
@@ -34,6 +36,8 @@ from xarray_plotly import xpx
34
36
  fig = xpx(da).line()
35
37
  ```
36
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
+
37
41
  ## Documentation
38
42
 
39
43
  Full documentation: [https://fbumann.github.io/xarray_plotly](https://fbumann.github.io/xarray_plotly)
@@ -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
+ }