├── .git-blame-ignore-revs
├── .git_archival.txt
├── .gitattributes
├── .github
├── CONTRIBUTING.md
├── FUNDING.yml
└── workflows
│ ├── auto_triage.yml
│ ├── build.yaml
│ ├── docs.yaml
│ ├── nightly_lock.yaml
│ └── test.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── binder
├── environment.yml
└── postBuild
├── doc
├── _ext
│ ├── backend_styling_options.py
│ └── plotting_options_table.py
├── _static
│ ├── custom.css
│ ├── favicon.ico
│ ├── home
│ │ ├── bokeh.gif
│ │ ├── dask.gif
│ │ ├── explorer.gif
│ │ ├── geo.gif
│ │ ├── geopandas.gif
│ │ ├── intake.gif
│ │ ├── interactive_hvplot.gif
│ │ ├── interactive_pandas.gif
│ │ ├── interactive_xarray.gif
│ │ ├── large_data.gif
│ │ ├── layout.gif
│ │ ├── matplotlib.png
│ │ ├── networkx.gif
│ │ ├── overlay.png
│ │ ├── pandas.gif
│ │ ├── plotly.gif
│ │ ├── widgets.gif
│ │ └── xarray.gif
│ ├── images
│ │ ├── heat_and_trees.png
│ │ └── portfolio.png
│ ├── logo.png
│ ├── logo_horizontal.svg
│ ├── logo_stacked.svg
│ └── patch_templates
│ │ └── sourcelink.html
├── about.md
├── assets
│ ├── console.png
│ ├── console_server.gif
│ ├── diagram.png
│ ├── diagram.svg
│ ├── hvplot-wm.png
│ └── streamz_demo.gif
├── conf.py
├── conftest.py
├── developer_guide.md
├── governance
│ └── project-docs
│ │ ├── CONTRIBUTING.md
│ │ ├── GOVERNANCE.md
│ │ ├── LICENSE.md
│ │ └── MEMBERS.md
├── index.md
├── ref
│ ├── api
│ │ ├── index.md
│ │ └── manual
│ │ │ ├── hvplot.hvPlot.area.ipynb
│ │ │ ├── hvplot.hvPlot.bar.ipynb
│ │ │ ├── hvplot.hvPlot.barh.ipynb
│ │ │ ├── hvplot.hvPlot.bivariate.ipynb
│ │ │ ├── hvplot.hvPlot.box.ipynb
│ │ │ ├── hvplot.hvPlot.contour.ipynb
│ │ │ ├── hvplot.hvPlot.contourf.ipynb
│ │ │ ├── hvplot.hvPlot.dataset.ipynb
│ │ │ ├── hvplot.hvPlot.density.md
│ │ │ ├── hvplot.hvPlot.errorbars.ipynb
│ │ │ ├── hvplot.hvPlot.heatmap.ipynb
│ │ │ ├── hvplot.hvPlot.hexbin.ipynb
│ │ │ ├── hvplot.hvPlot.hist.ipynb
│ │ │ ├── hvplot.hvPlot.image.ipynb
│ │ │ ├── hvplot.hvPlot.kde.ipynb
│ │ │ ├── hvplot.hvPlot.labels.ipynb
│ │ │ ├── hvplot.hvPlot.line.ipynb
│ │ │ ├── hvplot.hvPlot.ohlc.ipynb
│ │ │ ├── hvplot.hvPlot.paths.ipynb
│ │ │ ├── hvplot.hvPlot.points.ipynb
│ │ │ ├── hvplot.hvPlot.polygons.ipynb
│ │ │ ├── hvplot.hvPlot.quadmesh.ipynb
│ │ │ ├── hvplot.hvPlot.rgb.ipynb
│ │ │ ├── hvplot.hvPlot.scatter.ipynb
│ │ │ ├── hvplot.hvPlot.step.ipynb
│ │ │ ├── hvplot.hvPlot.table.ipynb
│ │ │ ├── hvplot.hvPlot.vectorfield.ipynb
│ │ │ ├── hvplot.hvPlot.violin.ipynb
│ │ │ ├── hvplot.plotting.andrews_curves.ipynb
│ │ │ ├── hvplot.plotting.lag_plot.ipynb
│ │ │ ├── hvplot.plotting.parallel_coordinates.ipynb
│ │ │ └── hvplot.plotting.scatter_matrix.ipynb
│ ├── api_compatibility
│ │ ├── index.md
│ │ └── pandas
│ │ │ ├── Pandas_API.ipynb
│ │ │ └── index.ipynb
│ ├── data_libraries.ipynb
│ ├── deprecations.md
│ ├── index.md
│ ├── installation.md
│ ├── plotting_extensions.ipynb
│ └── plotting_options
│ │ ├── data.ipynb
│ │ ├── grid_legend.ipynb
│ │ ├── index.md
│ │ └── size_layout.ipynb
├── reference
│ ├── geopandas
│ │ ├── points.ipynb
│ │ └── polygons.ipynb
│ ├── tabular
│ │ ├── andrewscurves.ipynb
│ │ ├── area.ipynb
│ │ ├── bar.ipynb
│ │ ├── barh.ipynb
│ │ ├── bivariate.ipynb
│ │ ├── box.ipynb
│ │ ├── errorbars.ipynb
│ │ ├── heatmap.ipynb
│ │ ├── hexbin.ipynb
│ │ ├── hist.ipynb
│ │ ├── kde.ipynb
│ │ ├── labels.ipynb
│ │ ├── lagplot.ipynb
│ │ ├── line.ipynb
│ │ ├── ohlc.ipynb
│ │ ├── parallelcoordinates.ipynb
│ │ ├── paths.ipynb
│ │ ├── scatter.ipynb
│ │ ├── scattermatrix.ipynb
│ │ ├── step.ipynb
│ │ ├── table.ipynb
│ │ └── violin.ipynb
│ └── xarray
│ │ ├── bar.ipynb
│ │ ├── contour.ipynb
│ │ ├── contourf.ipynb
│ │ ├── hist.ipynb
│ │ ├── image.ipynb
│ │ ├── kde.ipynb
│ │ ├── line.ipynb
│ │ ├── quadmesh.ipynb
│ │ ├── rgb.ipynb
│ │ ├── vectorfield.ipynb
│ │ └── violin.ipynb
├── releases.md
├── roadmap.md
├── topics.html
├── tutorials
│ ├── getting_started.ipynb
│ ├── getting_started_pandas.ipynb
│ └── index.md
└── user_guide
│ ├── Explorer.ipynb
│ ├── Geographic_Data.ipynb
│ ├── Gridded_Data.ipynb
│ ├── Interactive.ipynb
│ ├── Introduction.ipynb
│ ├── Large_Timeseries.ipynb
│ ├── NetworkX.ipynb
│ ├── Plotting.ipynb
│ ├── Plotting_Extensions.ipynb
│ ├── Plotting_with_Matplotlib.ipynb
│ ├── Plotting_with_Plotly.ipynb
│ ├── Statistical_Plots.ipynb
│ ├── Streaming.ipynb
│ ├── Subplots.ipynb
│ ├── Timeseries_Data.ipynb
│ ├── Viewing.ipynb
│ ├── Widgets.ipynb
│ ├── images
│ └── simple.svg
│ └── index.md
├── hvplot
├── __init__.py
├── backend_transforms.py
├── converter.py
├── cudf.py
├── dask.py
├── data
│ └── crime.csv
├── datasets.yaml
├── duckdb.py
├── fugue.py
├── ibis.py
├── intake.py
├── interactive.py
├── networkx.py
├── pandas.py
├── plotting
│ ├── __init__.py
│ ├── andrews_curves.py
│ ├── core.py
│ ├── lag_plot.py
│ ├── parallel_coordinates.py
│ └── scatter_matrix.py
├── polars.py
├── sample_data.py
├── streamz.py
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── data
│ │ ├── README.md
│ │ └── RGB-red.byte.tif
│ ├── plotting
│ │ ├── __init__.py
│ │ ├── testandrewscurves.py
│ │ ├── testcore.py
│ │ ├── testohlc.py
│ │ └── testscattermatrix.py
│ ├── test_links.py
│ ├── testbackend_transforms.py
│ ├── testcharts.py
│ ├── testdeprecations.py
│ ├── testdocstring.py
│ ├── testfugue.py
│ ├── testgeo.py
│ ├── testgeowithoutgv.py
│ ├── testgridplots.py
│ ├── testhelp.py
│ ├── testibis.py
│ ├── testinteractive.py
│ ├── testnetworkx.py
│ ├── testoperations.py
│ ├── testoptions.py
│ ├── testoverrides.py
│ ├── testpanel.py
│ ├── testpatch.py
│ ├── testpatchsignature.py
│ ├── testplotting.py
│ ├── teststatplots.py
│ ├── teststreaming.py
│ ├── testtransforms.py
│ ├── testui.py
│ ├── testutil.py
│ └── util.py
├── ui.py
├── util.py
├── utilities.py
└── xarray.py
├── pixi.toml
├── pyproject.toml
└── scripts
├── conda
├── build.sh
└── recipe
│ └── meta.yaml
├── download_data.py
└── sync_git_tags.py
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Run this command to always ignore formatting commits in `git blame`
2 | # git config blame.ignoreRevsFile .git-blame-ignore-revs
3 |
4 | # Ignore linting/formatting with ruff initial PR (https://github.com/holoviz/hvplot/pull/1320)
5 | 6c33e47b740e0a5093688a855e99559245c553fd
6 |
--------------------------------------------------------------------------------
/.git_archival.txt:
--------------------------------------------------------------------------------
1 | node: 25e6456e3fab40205f442b1df41f6422e560808f
2 | node-date: 2025-05-27T19:39:17+02:00
3 | describe-name: v0.11.3-12-g25e6456e3
4 | ref-names: HEAD -> main
5 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # For setuptools_scm with .git_archival.txt
2 | .git_archival.txt export-subst
3 | # Line Endings configuration file for Git
4 | # Set the default behavior, in case people don't have or can't have core.autocrlf set.
5 | * text=auto
6 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to hvPlot
2 |
3 | Please follow the [contributor guide](https://hvplot.holoviz.org/developer_guide/index.html).
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | open_collective: holoviz
4 |
--------------------------------------------------------------------------------
/.github/workflows/auto_triage.yml:
--------------------------------------------------------------------------------
1 | name: Auto-label new issues with "TRIAGE"
2 |
3 | on:
4 | issues:
5 | types:
6 | - reopened
7 | - opened
8 | jobs:
9 | add-triage-label:
10 | runs-on: ubuntu-latest
11 | permissions:
12 | issues: write
13 | steps:
14 | - run: gh issue edit "$NUMBER" --add-label "$LABELS"
15 | env:
16 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17 | GH_REPO: ${{ github.repository }}
18 | NUMBER: ${{ github.event.issue.number }}
19 | LABELS: TRIAGE
20 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: packages
2 | on:
3 | push:
4 | tags:
5 | - 'v[0-9]+.[0-9]+.[0-9]+'
6 | - 'v[0-9]+.[0-9]+.[0-9]+a[0-9]+'
7 | - 'v[0-9]+.[0-9]+.[0-9]+b[0-9]+'
8 | - 'v[0-9]+.[0-9]+.[0-9]+rc[0-9]+'
9 | # Dry-run only
10 | workflow_dispatch:
11 | schedule:
12 | - cron: '0 15 * * SUN'
13 |
14 | env:
15 | PYTHON_VERSION: "3.11"
16 |
17 | defaults:
18 | run:
19 | shell: bash -e {0}
20 |
21 | jobs:
22 | pixi_lock:
23 | name: Pixi lock
24 | runs-on: ubuntu-latest
25 | steps:
26 | - uses: holoviz-dev/holoviz_tasks/pixi_lock@v0
27 |
28 | conda_build:
29 | name: Build Conda
30 | needs: [pixi_lock]
31 | runs-on: "ubuntu-latest"
32 | steps:
33 | - uses: holoviz-dev/holoviz_tasks/pixi_install@v0
34 | with:
35 | environments: "build"
36 | download-data: false
37 | install: false
38 | - name: conda build
39 | run: pixi run -e build build-conda
40 | - name: Set environment variables
41 | run: |
42 | echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
43 | echo "CONDA_FILE=$(ls dist/*.tar.bz2)" >> $GITHUB_ENV
44 | - name: conda dev upload
45 | if: github.event_name == 'push' && (contains(env.TAG, 'a') || contains(env.TAG, 'b') || contains(env.TAG, 'rc'))
46 | run: pixi run -e build publish-conda --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev $CONDA_FILE
47 | - name: conda main upload
48 | if: github.event_name == 'push' && (!(contains(env.TAG, 'a') || contains(env.TAG, 'b') || contains(env.TAG, 'rc')))
49 | run: pixi run -e build publish-conda --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev --label=main $CONDA_FILE
50 |
51 | pip_build:
52 | name: Build PyPI
53 | needs: [pixi_lock]
54 | runs-on: "ubuntu-latest"
55 | permissions:
56 | id-token: write
57 | steps:
58 | - uses: holoviz-dev/holoviz_tasks/pixi_install@v0
59 | with:
60 | environments: "build"
61 | download-data: false
62 | install: false
63 | - name: Build package
64 | run: pixi run -e build build-pip
65 | - name: Publish to PyPI
66 | if: github.event_name == 'push'
67 | uses: pypa/gh-action-pypi-publish@release/v1
68 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yaml:
--------------------------------------------------------------------------------
1 | name: docs
2 | on:
3 | push:
4 | tags:
5 | - 'v[0-9]+.[0-9]+.[0-9]+'
6 | - 'v[0-9]+.[0-9]+.[0-9]+a[0-9]+'
7 | - 'v[0-9]+.[0-9]+.[0-9]+b[0-9]+'
8 | - 'v[0-9]+.[0-9]+.[0-9]+rc[0-9]+'
9 | workflow_dispatch:
10 | inputs:
11 | target:
12 | description: 'Site to build and deploy'
13 | type: choice
14 | options:
15 | - dev
16 | - main
17 | - dryrun
18 | required: true
19 | default: dryrun
20 | schedule:
21 | - cron: '0 15 * * SUN'
22 |
23 | defaults:
24 | run:
25 | shell: bash -e {0}
26 |
27 | env:
28 | PYTHON_VERSION: "3.11"
29 |
30 | jobs:
31 | pixi_lock:
32 | name: Pixi lock
33 | runs-on: ubuntu-latest
34 | steps:
35 | - uses: holoviz-dev/holoviz_tasks/pixi_lock@v0
36 |
37 | docs_build:
38 | name: Build Documentation
39 | runs-on: 'macos-latest'
40 | timeout-minutes: 120
41 | env:
42 | DISPLAY: ":99.0"
43 | steps:
44 | - uses: holoviz-dev/holoviz_tasks/pixi_install@v0
45 | with:
46 | environments: docs
47 | - name: Build documentation
48 | run: pixi run -e docs docs-build
49 | - name: Set and echo git ref
50 | id: vars
51 | run: |
52 | echo "Deploying from ref ${GITHUB_REF#refs/*/}"
53 | echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
54 | - name: report failure
55 | if: failure()
56 | run: cat /tmp/sphinx-*.log | tail -n 100
57 | - name: Deploy dev
58 | uses: peaceiris/actions-gh-pages@v4
59 | if: |
60 | (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'dev') ||
61 | (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc')))
62 | with:
63 | personal_token: ${{ secrets.ACCESS_TOKEN }}
64 | external_repository: holoviz-dev/hvplot
65 | publish_dir: ./builtdocs
66 | force_orphan: true
67 | exclude_assets: '.doctrees'
68 | - name: Deploy main
69 | if: |
70 | (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'main') ||
71 | (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc')))
72 | uses: peaceiris/actions-gh-pages@v4
73 | with:
74 | github_token: ${{ secrets.GITHUB_TOKEN }}
75 | publish_dir: ./builtdocs
76 | cname: hvplot.holoviz.org
77 | force_orphan: true
78 | exclude_assets: '.doctrees'
79 |
80 | pip_build_docs:
81 | name: Build Documentation (pip)
82 | runs-on: 'ubuntu-latest'
83 | timeout-minutes: 120
84 | env:
85 | DESC: "Documentation build"
86 | MPLBACKEND: "Agg"
87 | MOZ_HEADLESS: 1
88 | DISPLAY: ":99.0"
89 | steps:
90 | - uses: actions/checkout@v4
91 | with:
92 | fetch-depth: 0
93 | - uses: actions/setup-python@v5
94 | with:
95 | python-version: ${{ env.PYTHON_VERSION }}
96 | - name: install
97 | run: pip install -v --prefer-binary -e ."[doc, examples, geo]"
98 | - name: pip list
99 | run: pip list
100 | - name: Set and echo git ref
101 | id: vars
102 | run: |
103 | echo "Deploying from ref ${GITHUB_REF#refs/*/}"
104 | echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
105 | - name: build docs
106 | run: sphinx-build -j auto -b html doc builtdocs
107 | - name: report failure
108 | if: failure()
109 | run: cat /tmp/sphinx-*.log | tail -n 100
110 |
--------------------------------------------------------------------------------
/.github/workflows/nightly_lock.yaml:
--------------------------------------------------------------------------------
1 | name: nightly_lock
2 | on:
3 | workflow_dispatch:
4 | schedule:
5 | - cron: "0 0 * * *"
6 |
7 | env:
8 | PACKAGE: "hvplot"
9 |
10 | jobs:
11 | pixi_lock:
12 | if: ${{ !github.event.repository.fork }}
13 | name: Pixi lock
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 5
16 | steps:
17 | - uses: holoviz-dev/holoviz_tasks/pixi_lock@v0
18 | - name: Upload lock-file to S3
19 | env:
20 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
21 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
22 | AWS_DEFAULT_REGION: "eu-west-1"
23 | run: |
24 | zip $(date +%Y-%m-%d).zip pixi.lock pixi.toml
25 | aws s3 cp ./$(date +%Y-%m-%d).zip s3://assets.holoviz.org/lock/$PACKAGE/
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 |
58 | # Flask stuff:
59 | instance/
60 | .webassets-cache
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # Jupyter Notebook
72 | .ipynb_checkpoints
73 |
74 | # pyenv
75 | .python-version
76 |
77 | # celery beat schedule file
78 | celerybeat-schedule
79 |
80 | # SageMath parsed files
81 | *.sage.py
82 |
83 | # dotenv
84 | .env
85 |
86 | # virtualenv
87 | .venv
88 | venv/
89 | ENV/
90 |
91 | # Spyder project settings
92 | .spyderproject
93 | .spyproject
94 |
95 | # Rope project settings
96 | .ropeproject
97 |
98 | # mkdocs documentation
99 | /site
100 |
101 | # mypy
102 | .mypy_cache/
103 |
104 | # nbsite
105 | # these files normally shouldn't be checked in as they should be
106 | # dynamically built from notebooks
107 | doc/**/*.rst
108 | doc/**/*.json
109 | # thumbnails are downloaded on the fly
110 | doc/reference/*/thumbnails/
111 | # this dir contains the whole website and should not be checked in on main
112 | builtdocs/
113 | # mystnb
114 | jupyter_execute/
115 |
116 | # pip
117 | pip-wheel-metadata/
118 |
119 | # IDE
120 | /.vscode
121 |
122 | # MacOS
123 | .DS_Store
124 |
125 | # Examples artefacts
126 | doc/user_guide/plot.html
127 |
128 | # setuptools_scm
129 | hvplot/_version.py
130 |
131 | # pixi
132 | .pixi
133 | pixi.lock
134 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | default_stages: [pre-commit]
2 | repos:
3 | - repo: https://github.com/pre-commit/pre-commit-hooks
4 | rev: v5.0.0
5 | hooks:
6 | - id: check-builtin-literals
7 | - id: check-case-conflict
8 | - id: check-docstring-first
9 | - id: check-executables-have-shebangs
10 | - id: check-toml
11 | - id: detect-private-key
12 | - id: end-of-file-fixer
13 | exclude: (\.min\.js$|\.svg$)
14 | - id: trailing-whitespace
15 | - repo: https://github.com/astral-sh/ruff-pre-commit
16 | rev: v0.11.8
17 | hooks:
18 | - id: ruff
19 | - id: ruff-format
20 | exclude: \.ipynb$
21 | - repo: https://github.com/hoxbro/clean_notebook
22 | rev: v0.1.17
23 | hooks:
24 | - id: clean-notebook
25 | args: [-i, tags]
26 | - repo: https://github.com/codespell-project/codespell
27 | rev: v2.4.1
28 | hooks:
29 | - id: codespell
30 | exclude: (\.min\.js$|\.svg$|\.html$)
31 | additional_dependencies:
32 | - tomli
33 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | For the release notes, please consult ./doc/releases.md
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | For the code of conduct, see [HoloViz/HoloViz - CODE_OF_CONDUCT.md](https://github.com/holoviz/holoviz/blob/hvplot-gov/CODE_OF_CONDUCT.md).
4 |
5 | The hvPlot Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, HoloViz
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/binder/environment.yml:
--------------------------------------------------------------------------------
1 | name: hvplot
2 | channels:
3 | - conda-forge
4 | - nodefaults
5 | dependencies:
6 | - geoviews>=1.6.0
7 | - numba>=0.51.0
8 | - geopandas>=0.9.0
9 | - xarray>=0.18.2
10 | - networkx>=2.6.3
11 | - streamz>=0.3.0
12 | - intake>=0.6.5
13 | - intake-parquet>=0.2.3
14 | - intake-xarray>=0.5.0
15 | - dask>=2021.3.0
16 | - datashader>=0.6.5
17 | - notebook>=5.4
18 | - rasterio>=1.2.6
19 | - cartopy>= 0.18.0
20 | - pyproj>=3.0.1
21 | - s3fs>=2022.1.0
22 | - scipy>=1.5.3
23 | - pillow>=8.2.0
24 | - selenium>=3.141.0
25 | - spatialpandas>=0.4.3
26 | - scikit-image>=0.17.2
27 | - python-snappy>=0.6.0
28 | - pooch>=1.6.0
29 | - fiona>=1.8.18
30 | - pyepsg>=0.4.0
31 | - matplotlib
32 | - plotly
33 | - pygraphviz
34 | - pip
35 | - pip:
36 | - ..
37 |
--------------------------------------------------------------------------------
/binder/postBuild:
--------------------------------------------------------------------------------
1 | bokeh sampledata
2 |
--------------------------------------------------------------------------------
/doc/_ext/backend_styling_options.py:
--------------------------------------------------------------------------------
1 | from docutils import nodes
2 | from docutils.statemachine import StringList
3 | from sphinx.util.docutils import SphinxDirective
4 |
5 | import holoviews as hv
6 |
7 | from hvplot.util import _get_backend_style_options
8 |
9 |
10 | hv.extension('bokeh', 'matplotlib')
11 |
12 |
13 | class BackendStylingOptionsDirective(SphinxDirective):
14 | """
15 | Display the Bokeh and Matplotlib styling options for a plot method
16 | in a tabs layout.
17 |
18 | .. backend-styling-options:: scatter
19 | """
20 |
21 | has_content = False
22 | required_arguments = 1
23 | optional_arguments = 0
24 | final_argument_whitespace = True
25 |
26 | def run(self):
27 | input_string = self.arguments[0]
28 |
29 | bk_opts = _get_backend_style_options(input_string, 'bokeh')
30 | mpl_opts = _get_backend_style_options(input_string, 'matplotlib')
31 | bk_opts_info = ', '.join(bk_opts)
32 | mpl_opts_info = ', '.join(mpl_opts)
33 | # Sphinx-design syntax
34 | tab_content = f"""
35 | .. tab-set::
36 |
37 | .. tab-item:: Bokeh
38 |
39 | {bk_opts_info}
40 |
41 | .. tab-item:: Matplotlib
42 |
43 | {mpl_opts_info}
44 | """
45 |
46 | container = nodes.container()
47 | container['classes'] = ['backend-styling-options-container']
48 | content_list = StringList(tab_content.splitlines(), source='')
49 | self.state.nested_parse(content_list, 0, container)
50 | return container.children
51 |
52 |
53 | def setup(app):
54 | app.add_directive('backend-styling-options', BackendStylingOptionsDirective)
55 |
56 | return {
57 | 'version': '0.1',
58 | 'parallel_read_safe': True,
59 | 'parallel_write_safe': True,
60 | }
61 |
--------------------------------------------------------------------------------
/doc/_ext/plotting_options_table.py:
--------------------------------------------------------------------------------
1 | """
2 | Sphinx extension to display a table with the options of a specific
3 | options group of the converter. Requires numpydoc
4 |
5 | Usage:
6 |
7 | .. plotting-options-table:: Style Options
8 | """
9 |
10 | import sys
11 |
12 | from textwrap import indent
13 |
14 | from hvplot.util import _get_docstring_group_parameters
15 | from sphinx.util.docutils import SphinxDirective
16 |
17 |
18 | class PlottingOptionsTableDirective(SphinxDirective):
19 | """
20 | Directive to display a plotting option group in a Markdown table.
21 |
22 | .. plotting-options-table:: Data Options
23 | """
24 |
25 | required_arguments = 1
26 | final_argument_whitespace = True
27 |
28 | def run(self):
29 | # Get the key passed to the directive
30 | options_group = self.arguments[0]
31 | parameters = _get_docstring_group_parameters(options_group)
32 | table_rst = ['.. list-table::', ' :header-rows: 1', ' :widths: 25 70', '']
33 | table_rst.append(' * - ')
34 | table_rst.append(' Parameters')
35 | table_rst.append(' - ')
36 | table_rst.append(' Description')
37 |
38 | for param in parameters:
39 | desc = '\n'.join(param.desc)
40 | table_rst.append(' * - ')
41 | table_rst.append(f' **{param.name}** *({param.type})*')
42 | table_rst.append(' - ')
43 | table_rst.append(indent(desc, ' ' * 7))
44 |
45 | raw_rst = '\n'.join(table_rst)
46 |
47 | parsed = self.parse_text_to_nodes(raw_rst)
48 | return parsed
49 |
50 |
51 | def setup(app):
52 | app.add_directive('plotting-options-table', PlottingOptionsTableDirective)
53 |
54 | return {
55 | 'version': '0.1',
56 | 'parallel_read_safe': True,
57 | 'parallel_write_safe': True,
58 | }
59 |
60 |
61 | if __name__ == '__main__':
62 | group = ' '.join(sys.argv[1:])
63 | opts = _get_docstring_group_parameters(group)
64 | print(opts)
65 |
--------------------------------------------------------------------------------
/doc/_static/custom.css:
--------------------------------------------------------------------------------
1 | :root[data-theme="light"] {
2 | --pst-color-primary: rgb(56,123,178);
3 | --pst-color-link: rgb(56,123,178);
4 | --pst-color-link-hover: rgb(254,203,56);
5 | }
6 |
7 | .sphx-glr-thumbcontainer {
8 | height: 210px;
9 | }
10 |
11 | .nav-link {
12 | white-space: nowrap;
13 | }
14 |
15 | .showcase-table {
16 | border-spacing: 15px
17 | }
18 |
19 | .showcase-table td {
20 | border: 0px;
21 | vertical-align: top;
22 | }
23 |
24 | .getting-started-button {
25 | border-radius: 6px !important;
26 | padding: 0.7em 3em !important;
27 | font-size: 1.2em;
28 | }
29 |
--------------------------------------------------------------------------------
/doc/_static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/favicon.ico
--------------------------------------------------------------------------------
/doc/_static/home/bokeh.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/bokeh.gif
--------------------------------------------------------------------------------
/doc/_static/home/dask.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/dask.gif
--------------------------------------------------------------------------------
/doc/_static/home/explorer.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/explorer.gif
--------------------------------------------------------------------------------
/doc/_static/home/geo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/geo.gif
--------------------------------------------------------------------------------
/doc/_static/home/geopandas.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/geopandas.gif
--------------------------------------------------------------------------------
/doc/_static/home/intake.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/intake.gif
--------------------------------------------------------------------------------
/doc/_static/home/interactive_hvplot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/interactive_hvplot.gif
--------------------------------------------------------------------------------
/doc/_static/home/interactive_pandas.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/interactive_pandas.gif
--------------------------------------------------------------------------------
/doc/_static/home/interactive_xarray.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/interactive_xarray.gif
--------------------------------------------------------------------------------
/doc/_static/home/large_data.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/large_data.gif
--------------------------------------------------------------------------------
/doc/_static/home/layout.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/layout.gif
--------------------------------------------------------------------------------
/doc/_static/home/matplotlib.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/matplotlib.png
--------------------------------------------------------------------------------
/doc/_static/home/networkx.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/networkx.gif
--------------------------------------------------------------------------------
/doc/_static/home/overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/overlay.png
--------------------------------------------------------------------------------
/doc/_static/home/pandas.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/pandas.gif
--------------------------------------------------------------------------------
/doc/_static/home/plotly.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/plotly.gif
--------------------------------------------------------------------------------
/doc/_static/home/widgets.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/widgets.gif
--------------------------------------------------------------------------------
/doc/_static/home/xarray.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/home/xarray.gif
--------------------------------------------------------------------------------
/doc/_static/images/heat_and_trees.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/images/heat_and_trees.png
--------------------------------------------------------------------------------
/doc/_static/images/portfolio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/images/portfolio.png
--------------------------------------------------------------------------------
/doc/_static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/_static/logo.png
--------------------------------------------------------------------------------
/doc/_static/patch_templates/sourcelink.html:
--------------------------------------------------------------------------------
1 | {# Added because of https://github.com/pydata/pydata-sphinx-theme/issues/2088 #}
2 | {# Displays a link to the .rst source of the current page. #}
3 | {% if show_source and has_source and sourcename %}
4 |
9 | {% endif %}
10 |
--------------------------------------------------------------------------------
/doc/about.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | hvPlot is completely open source, available under a BSD license freely for both commercial and non-commercial use. hvPlot was originally developed with the support of [Anaconda Inc.](https://www.anaconda.com), and is now maintained by Anaconda developers and community contributors.
4 |
5 | hvPlot is part of the [HoloViz](https://holoviz.org) family of tools. The [holoviz.org](https://holoviz.org) website shows how to use hvPlot together with other libraries to solve complex problems, with detailed tutorials and examples. You can see a variety of projects using hvPlot at [examples.holoviz.org](https://examples.holoviz.org), and you can compare hvPlot to other available tools at [pyviz.org](https://pyviz.org).
6 |
7 | If you have any questions or usage issues visit the [hvPlot Discourse site](https://discourse.holoviz.org/c/hvplot). If you are interested in contributing to hvPlot development to help address some of the [open issues](https://github.com/holoviz/hvplot/issues), see our [developer instructions](https://hvplot.holoviz.org/developer_guide/index.html) to set up your development environment.
8 |
9 | If you like hvPlot and have built something you want to share, tweet a link or screenshot of your latest creation at @HoloViews, along with any other library you used (@HoloViz_org, @Datashader, @BokehPlots, @Matplotlib, etc.). Thanks!
10 |
--------------------------------------------------------------------------------
/doc/assets/console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/assets/console.png
--------------------------------------------------------------------------------
/doc/assets/console_server.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/assets/console_server.gif
--------------------------------------------------------------------------------
/doc/assets/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/assets/diagram.png
--------------------------------------------------------------------------------
/doc/assets/hvplot-wm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/assets/hvplot-wm.png
--------------------------------------------------------------------------------
/doc/assets/streamz_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/doc/assets/streamz_demo.gif
--------------------------------------------------------------------------------
/doc/conftest.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from importlib.util import find_spec
4 |
5 | import dask
6 |
7 | from packaging.version import Version
8 | from bokeh.io.webdriver import webdriver_control
9 |
10 |
11 | collect_ignore_glob = [
12 | 'user_guide/Streaming.ipynb',
13 | ]
14 |
15 | # On MacOs, Python 3.12 and 3.13, got the following error running this:
16 | # `pos = layout(G)`
17 | # => OSError: Format: "dot" not recognized. No formats found.
18 | # Fixed locally by running `dot -c`
19 | if not find_spec('pygraphviz') or (
20 | sys.platform == 'darwin' and sys.version_info[:2] in [(3, 12), (3, 13)]
21 | ):
22 | collect_ignore_glob += [
23 | 'user_guide/NetworkX.ipynb',
24 | ]
25 |
26 | if not find_spec('geoviews'):
27 | collect_ignore_glob += [
28 | 'tutorials/getting_started.ipynb',
29 | 'reference/geopandas/*.ipynb',
30 | 'reference/xarray/contour.ipynb',
31 | 'reference/xarray/contourf.ipynb',
32 | 'reference/xarray/image.ipynb',
33 | 'reference/xarray/quadmesh.ipynb',
34 | 'reference/xarray/vectorfield.ipynb',
35 | 'user_guide/Explorer.ipynb',
36 | 'user_guide/Geographic_Data.ipynb',
37 | 'user_guide/Integrations.ipynb',
38 | ]
39 |
40 | # Gives weird solve on Python 3.9
41 | if not find_spec('ibis') or sys.version_info[:2] == (3, 9):
42 | collect_ignore_glob += [
43 | 'ref/data_libraries.ipynb',
44 | ]
45 |
46 | try:
47 | webdriver_control.create()
48 | except RuntimeError:
49 | # hvplot.save() with bokeh
50 | collect_ignore_glob += [
51 | 'user_guide/Viewing.ipynb',
52 | 'user_guide/NetworkX.ipynb',
53 | ]
54 | finally:
55 | webdriver_control.cleanup()
56 |
57 |
58 | if Version(dask.__version__).release < (2025, 1, 0):
59 | # From Dask 2024.3.0 they now use `dask_expr` by default
60 | # https://github.com/dask/dask/issues/10995
61 | dask.config.set({'dataframe.query-planning': False})
62 |
63 |
64 | # https://github.com/pydata/xarray/pull/9182
65 | try:
66 | import xarray as xr
67 | except ImportError:
68 | pass
69 | else:
70 | import numpy as np
71 |
72 | if Version(np.__version__) >= Version('2.0.0') and Version(xr.__version__) <= Version(
73 | '2024.6.0'
74 | ):
75 | collect_ignore_glob += [
76 | 'user_guide/Gridded_Data.ipynb',
77 | ]
78 |
--------------------------------------------------------------------------------
/doc/governance/project-docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | For the contributing policy, see [HoloViz/HoloViz - CONTRIBUTING.md](https://github.com/holoviz/holoviz/blob/hvplot-gov/doc/governance/project-docs/CONTRIBUTING.md).
4 |
5 | The hvPlot Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
6 |
--------------------------------------------------------------------------------
/doc/governance/project-docs/GOVERNANCE.md:
--------------------------------------------------------------------------------
1 | # Governance Policy
2 |
3 |
4 | The "Project" is herein defined as the activities related to this specific GitHub repository [`hvPlot`](https://github.com/holoviz/hvplot), within the `HoloViz` GitHub Organization.
5 |
6 |
7 | This Project adopts the governance specified by all of the numbered sections of [HoloViz/HoloViz - GOVERNANCE.md](https://github.com/holoviz/holoviz/blob/hvplot-gov/doc/governance/project-docs/GOVERNANCE.md).
8 |
9 |
10 | The hvPlot Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
11 |
--------------------------------------------------------------------------------
/doc/governance/project-docs/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | For the license, see [HoloViz/hvPlot - LICENSE.txt](https://github.com/holoviz/hvplot/blob/main/LICENSE).
4 |
--------------------------------------------------------------------------------
/doc/governance/project-docs/MEMBERS.md:
--------------------------------------------------------------------------------
1 | # Maintainers
2 |
3 | For member policy, see the description at the top of [HoloViz/HoloViz - MEMBERS.md](https://github.com/holoviz/holoviz/blob/hvplot-gov/doc/governance/project-docs/MEMBERS.md).
4 |
5 |
6 | The hvPlot Project’s equivalently named documents take precedence over any external materials referenced within this linked document above.
7 |
8 |
9 | | **NAME** | **Role** | **GitHub Handle** |
10 | | --- | --- | --- |
11 | | Philipp Rudiger | Project Director | [philippjfr](https://github.com/philippjfr) |
12 | | Maxime Liquet | Lead Maintainer | [maximlt](https://github.com/maximlt) |
13 | | Simon Høxbro Hansen | Maintainer | [hoxbro](https://github.com/hoxbro) |
14 | | Andrew Huang | Maintainer | [ahuang11](https://github.com/ahuang11) |
15 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.area.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# hvPlot.area"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "```{eval-rst}\n",
15 | ".. currentmodule:: hvplot\n",
16 | "\n",
17 | ".. automethod:: hvPlot.area\n",
18 | "```\n",
19 | "\n",
20 | "## Backend-specific styling options\n",
21 | "\n",
22 | "```{eval-rst}\n",
23 | ".. backend-styling-options:: area\n",
24 | "```\n",
25 | "\n",
26 | "## Examples \n",
27 | "\n",
28 | "TBD"
29 | ]
30 | }
31 | ],
32 | "metadata": {
33 | "language_info": {
34 | "name": "python",
35 | "pygments_lexer": "ipython3"
36 | }
37 | },
38 | "nbformat": 4,
39 | "nbformat_minor": 4
40 | }
41 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.bar.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "5644213a",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.bar\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.bar\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: bar\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.barh.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "b5550786",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.barh\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.barh\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: barh\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.bivariate.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "a287ab2a",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.bivariate\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.bivariate\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: bivariate\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.box.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "67aa50a9",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.box\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.box\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: box\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.contour.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "5aa3941a",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.contour\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.contour\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: contour\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.contourf.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "b27350ca",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.contourf\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.contourf\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: contourf\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.dataset.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "b27350ca",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.dataset\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.dataset\n",
14 | "```\n",
15 | "\n",
16 | "## Examples\n",
17 | "\n",
18 | "TBD"
19 | ]
20 | }
21 | ],
22 | "metadata": {
23 | "language_info": {
24 | "name": "python",
25 | "pygments_lexer": "ipython3"
26 | }
27 | },
28 | "nbformat": 4,
29 | "nbformat_minor": 4
30 | }
31 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.density.md:
--------------------------------------------------------------------------------
1 | ## hvPlot.density
2 |
3 | `hvPlot.density` is an alias for {meth}`hvPlot.kde `.
4 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.errorbars.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "0ed32b5a",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.errorbars\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.errorbars\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: errorbars\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.heatmap.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "8b1ed2e6",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.heatmap\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.heatmap\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: heatmap\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.hexbin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "bbc8492d",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.hexbin\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.hexbin\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: hexbin\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.hist.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "0fdf6ca7",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.hist\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.hist\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: hist\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.image.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "e495a53c",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.image\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.image\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: image\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.kde.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "60504550",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.kde\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.kde\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: kde\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.labels.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "d4cb57f3",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.labels\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.labels\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: labels\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.line.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "0ff60267",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.line\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.line\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: line\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.ohlc.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "3bc617e1",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.ohlc\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.ohlc\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: ohlc\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.paths.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "a148906a",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.paths\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.paths\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: paths\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 2
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.points.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "12c76e4e",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.points\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.points\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: points\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.polygons.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "59a8362e",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.polygons\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.polygons\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: polygons\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.quadmesh.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "223ae36d",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.quadmesh\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.quadmesh\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: quadmesh\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.rgb.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "c1283248",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.rgb\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.rgb\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: rgb\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.scatter.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "f99cff3c",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.scatter\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.scatter\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: scatter\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.step.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "a4a2bf27",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.step\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.step\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: step\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.table.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "9fed5c11",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.table\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.table\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: table\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.vectorfield.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "37719ebd",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.vectorfield\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.vectorfield\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: vectorfield\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.hvPlot.violin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "092313dc",
6 | "metadata": {},
7 | "source": [
8 | "# hvPlot.violin\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot\n",
12 | "\n",
13 | ".. automethod:: hvPlot.violin\n",
14 | "```\n",
15 | "\n",
16 | "## Backend-specific styling options\n",
17 | "\n",
18 | "```{eval-rst}\n",
19 | ".. backend-styling-options:: violin\n",
20 | "```\n",
21 | "\n",
22 | "## Examples\n",
23 | "\n",
24 | "TBD"
25 | ]
26 | }
27 | ],
28 | "metadata": {
29 | "language_info": {
30 | "name": "python",
31 | "pygments_lexer": "ipython3"
32 | }
33 | },
34 | "nbformat": 4,
35 | "nbformat_minor": 4
36 | }
37 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.plotting.andrews_curves.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "acb844e8",
6 | "metadata": {},
7 | "source": [
8 | "# hvplot.plotting.andrews_curves\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot.plotting\n",
12 | "\n",
13 | ".. autofunction:: andrews_curves\n",
14 | "```\n",
15 | "\n",
16 | "## Examples\n",
17 | "\n",
18 | "TBD"
19 | ]
20 | }
21 | ],
22 | "metadata": {
23 | "language_info": {
24 | "name": "python",
25 | "pygments_lexer": "ipython3"
26 | }
27 | },
28 | "nbformat": 4,
29 | "nbformat_minor": 5
30 | }
31 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.plotting.lag_plot.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "2d7486a8",
6 | "metadata": {},
7 | "source": [
8 | "# hvplot.plotting.lag_plot\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot.plotting\n",
12 | "\n",
13 | ".. autofunction:: lag_plot\n",
14 | "```\n",
15 | "\n",
16 | "## Examples\n",
17 | "\n",
18 | "TBD"
19 | ]
20 | }
21 | ],
22 | "metadata": {
23 | "language_info": {
24 | "name": "python",
25 | "pygments_lexer": "ipython3"
26 | }
27 | },
28 | "nbformat": 4,
29 | "nbformat_minor": 5
30 | }
31 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.plotting.parallel_coordinates.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "fc23da68",
6 | "metadata": {},
7 | "source": [
8 | "# hvplot.plotting.parallelcoordinates\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot.plotting\n",
12 | "\n",
13 | ".. autofunction:: parallel_coordinates\n",
14 | "```\n",
15 | "\n",
16 | "## Examples\n",
17 | "\n",
18 | "TBD"
19 | ]
20 | }
21 | ],
22 | "metadata": {
23 | "language_info": {
24 | "name": "python",
25 | "pygments_lexer": "ipython3"
26 | }
27 | },
28 | "nbformat": 4,
29 | "nbformat_minor": 5
30 | }
31 |
--------------------------------------------------------------------------------
/doc/ref/api/manual/hvplot.plotting.scatter_matrix.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "c807393a",
6 | "metadata": {},
7 | "source": [
8 | "# hvplot.plotting.scatter_matrix\n",
9 | "\n",
10 | "```{eval-rst}\n",
11 | ".. currentmodule:: hvplot.plotting\n",
12 | "\n",
13 | ".. autofunction:: scatter_matrix\n",
14 | "```\n",
15 | "\n",
16 | "## Examples\n",
17 | "\n",
18 | "TBD"
19 | ]
20 | }
21 | ],
22 | "metadata": {
23 | "language_info": {
24 | "name": "python",
25 | "pygments_lexer": "ipython3"
26 | }
27 | },
28 | "nbformat": 4,
29 | "nbformat_minor": 5
30 | }
31 |
--------------------------------------------------------------------------------
/doc/ref/api_compatibility/index.md:
--------------------------------------------------------------------------------
1 | # API compatibility
2 |
3 | This section aims to provide more precise information about the compatibility of hvPlot's plotting API with other libraries.
4 |
5 | ```{toctree}
6 | :titlesonly:
7 | :maxdepth: 2
8 |
9 | Pandas
10 | ```
11 |
--------------------------------------------------------------------------------
/doc/ref/deprecations.md:
--------------------------------------------------------------------------------
1 | # Deprecations and Removals
2 |
3 | List of currently deprecated APIs:
4 |
5 | | Warning | Description |
6 | |-|-|
7 | | `FutureWarning` since `0.12.0` | Passing DuckDB objects to `hvplot.plotting.plot`, use `import hvplot.duckdb` instead. |
8 | | `FutureWarning` since `0.12.0` | `debug` argument |
9 |
10 | List (created after the release of version `0.12.0`) of removed APIs:
11 |
12 | | Removed in | Warning | Description |
13 | |-|-|-|
14 | | | | |
15 |
--------------------------------------------------------------------------------
/doc/ref/index.md:
--------------------------------------------------------------------------------
1 | # Reference
2 |
3 | The reference section includes the API reference and pages that provide detailed information about hvPlot's usage.
4 |
5 | ```{toctree}
6 | :titlesonly:
7 | :includehidden:
8 | :maxdepth: 2
9 |
10 | Installation
11 | Supported data libraries
12 | Supported plotting extensions
13 | Plotting options
14 | API
15 | API compatibility
16 | Deprecations/Removals
17 | ```
18 |
--------------------------------------------------------------------------------
/doc/ref/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | This page lists the primary sources from which hvPlot can be installed.
4 |
5 | ## From PyPI
6 |
7 | hvPlot is distributed on [PyPI](https://pypi.org/project/hvplot/) as a wheel and as a source distribution (sdist).
8 |
9 | ::::{tab-set}
10 |
11 | :::{tab-item} pip
12 |
13 | ```
14 | pip install hvplot
15 | ```
16 |
17 | :::
18 |
19 | :::{tab-item} uv
20 |
21 | ```
22 | uv pip install hvplot
23 | ```
24 |
25 | ::::
26 |
27 | Pre-releases (alpha, beta, release candidate) can also be installed from PyPI.
28 |
29 | ::::{tab-set}
30 |
31 | :::{tab-item} pip
32 |
33 | ```
34 | pip install hvplot --pre
35 | ```
36 |
37 | :::
38 |
39 | :::{tab-item} uv
40 |
41 | ```
42 | uv pip install hvplot --prerelease allow
43 | ```
44 |
45 | ::::
46 |
47 | ## From anaconda.org
48 |
49 | hvPlot is distributed on 3 channels on [anaconda.org](https://anaconda.org/):
50 |
51 | - [`conda-forge`](https://github.com/conda-forge/hvplot-feedstock): Community maintained channel
52 | - [`defaults`](https://github.com/AnacondaRecipes/hvplot-feedstock/): Anaconda maintained channel (free under certain conditions only, check Anaconda's Terms of Services)
53 | - `pyviz`: HoloViz' custom channel
54 |
55 | We recommend installing final releases either from `conda-forge` or `defaults`. Pre-releases are only available from the `pyviz/label/dev` subchannel.
56 |
57 | hvPlot can be installed from these channels using [conda](https://docs.conda.io), [pixi](https://pixi.sh), [mamba/micromamba](https://mamba.readthedocs.io), etc.
58 |
59 | ::::{tab-set}
60 |
61 | :::{tab-item} `conda-forge`
62 |
63 | ```
64 | conda install conda-forge::hvplot
65 | ```
66 |
67 | :::
68 |
69 | :::{tab-item} `defaults`
70 |
71 | ```
72 | conda install defaults::hvplot
73 | ```
74 |
75 | :::
76 |
77 | :::{tab-item} Pre-releases from `pyviz/label/dev`
78 |
79 | ```
80 | conda install pyviz/label/dev::hvplot
81 | ```
82 |
83 | :::
84 |
85 | ::::
86 |
87 | ## From Anaconda Distribution
88 |
89 | If you just started with Python and programming in general, an easy way to install hvPlot on your computer is to download and install the [Anaconda Distribution](https://www.anaconda.com/download) that includes most of the HoloViz packages. Note it is subject to Anaconda's Terms of Services.
90 |
91 | ## From source
92 |
93 | hvPlot can be installed from source by cloning its [GitHub repository](https://github.com/holoviz/hvplot) and running this command:
94 |
95 | ```
96 | pip install -e .
97 | ```
98 |
--------------------------------------------------------------------------------
/doc/ref/plotting_extensions.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Supported plotting extensions\n",
8 | "\n",
9 | "hvPlot supports generating plots with 3 different plotting extensions. Under the hood, hvPlot delegates plotting to HoloViews which itself calls these plotting libraries.\n",
10 | "\n",
11 | "The following below provides a summary of the supported plotting extensions. In the *HoloViews support* column you will find an estimate of how well the extension is supported in HoloViews, and consequently in hvPlot:\n",
12 | "\n",
13 | "- Bokeh has become the de-facto default plotting extension across HoloViz and is the most used and tested one.\n",
14 | "- Matplotlib was originally the unique plotting extension of HoloViews and is still well supported. Being a static plotting library, the extension doesn't benefit from all the interactive features HoloViews can offer (hover, streams, etc.).\n",
15 | "- Plotly is another interactive plotting extension supported by HoloViews, and while it enables some unique features (e.g. 3D plots), it is not as well supported as its counterpart Bokeh.\n",
16 | "\n",
17 | "| Plotting extension | Type | HoloViews support |\n",
18 | "| ---------------------------------- | ----------- | ----------------- |\n",
19 | "| [Bokeh](#plot-ext-bokeh) | Interactive | ⭐⭐⭐ |\n",
20 | "| [Matplotlib](#plot-ext-matplotlib) | Static | ⭐⭐ |\n",
21 | "| [Plotly](#plot-ext-plotly) | Interactive | ⭐ |\n",
22 | "\n",
23 | "Follow the [Plotting Extensions Guide](../user_guide/Plotting_Extensions.ipynb) for more information.\n",
24 | "\n",
25 | ":::{note}\n",
26 | "Similarly to having to support many data sources, supporting three plotting extensions is hard work! We are aware they are not supported equivalently, you will get best support for Bokeh, followed by Matplotlib and finally Plotly. If you encounter any issue with a specific plotting extension please report it on GitHub, we always welcome Pull Requests too!\n",
27 | ":::"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "(plot-ext-bokeh)=\n",
35 | "## Bokeh (default)\n",
36 | "\n",
37 | "TBD"
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "(plot-ext-matplotlib)=\n",
45 | "## Matplotlib\n",
46 | "\n",
47 | "TBD"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "(plot-ext-plotly)=\n",
55 | "## Plotly\n",
56 | "\n",
57 | "TBD"
58 | ]
59 | }
60 | ],
61 | "metadata": {
62 | "language_info": {
63 | "name": "python",
64 | "pygments_lexer": "ipython3"
65 | }
66 | },
67 | "nbformat": 4,
68 | "nbformat_minor": 2
69 | }
70 |
--------------------------------------------------------------------------------
/doc/reference/geopandas/points.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Points"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Using hvplot with geopandas is as simple as loading a geopandas dataframe and calling `hvplot` on it with `geo=True`."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import geopandas as gpd\n",
33 | "\n",
34 | "\n",
35 | "data = {\n",
36 | " 'City': ['London', 'Paris', 'Berlin', 'Madrid', 'Rome', 'Vienna', 'Warsaw', 'Amsterdam'],\n",
37 | " 'Country': ['United Kingdom', 'France', 'Germany', 'Spain', 'Italy', 'Austria', 'Poland', 'Netherlands'],\n",
38 | " 'Latitude': [51.5074, 48.8566, 52.5200, 40.4168, 41.9028, 48.2082, 52.2297, 52.3676],\n",
39 | " 'Longitude': [-0.1278, 2.3522, 13.4050, -3.7038, 12.4964, 16.3738, 21.0122, 4.9041]\n",
40 | "}\n",
41 | "cities = gpd.GeoDataFrame(\n",
42 | " data,\n",
43 | " geometry=gpd.points_from_xy(data['Longitude'], data['Latitude']),\n",
44 | " crs=\"EPSG:4326\",\n",
45 | ")"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "cities.hvplot(geo=True, tiles=True)"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "metadata": {},
60 | "source": [
61 | "You can easily change the tiles, add coastlines, or which fields show up in the hover text:"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "cities.hvplot(tiles='EsriTerrain', coastline=True, hover_cols='all')"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "We can also alter the projection of the data using cartopy:"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "import cartopy.crs as ccrs"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "cities.hvplot(coastline=True, projection=ccrs.Geostationary(central_longitude=10), global_extent=True)"
96 | ]
97 | }
98 | ],
99 | "metadata": {
100 | "language_info": {
101 | "name": "python",
102 | "pygments_lexer": "ipython3"
103 | }
104 | },
105 | "nbformat": 4,
106 | "nbformat_minor": 4
107 | }
108 |
--------------------------------------------------------------------------------
/doc/reference/geopandas/polygons.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Polygons"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Using hvplot with geopandas is as simple as loading a geopandas dataframe and calling `hvplot` on it with `geo=True`."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import geodatasets\n",
33 | "import geopandas as gpd\n",
34 | "\n",
35 | "chicago = gpd.read_file(geodatasets.get_path(\"geoda.chicago_commpop\"))\n",
36 | "chicago.sample(3)"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "chicago.hvplot(geo=True)"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Control the color of the elements using the `c` option."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "chicago.hvplot.polygons(geo=True, c='POP2010', hover_cols='all')"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "You can even color by another series, such as population density:"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "metadata": {},
75 | "outputs": [],
76 | "source": [
77 | "chicago.hvplot.polygons(\n",
78 | " geo=True,\n",
79 | " c=chicago.POP2010/chicago.to_crs('EPSG:32616').area,\n",
80 | " clabel='pop density',\n",
81 | ")"
82 | ]
83 | }
84 | ],
85 | "metadata": {
86 | "language_info": {
87 | "name": "python",
88 | "pygments_lexer": "ipython3"
89 | }
90 | },
91 | "nbformat": 4,
92 | "nbformat_minor": 4
93 | }
94 |
--------------------------------------------------------------------------------
/doc/reference/tabular/andrewscurves.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "285a3796-e7d9-45ba-8b11-418c0535a8c9",
6 | "metadata": {},
7 | "source": [
8 | "# Andrewscurves"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "d8d7bf92-ae63-4122-9457-10c9ada6c6f1",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.pandas # noqa"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "id": "915da73a-0a5f-4a40-aa4b-a65a6002c3e9",
24 | "metadata": {},
25 | "source": [
26 | "Andrews curves provides a mechanism for visualising clusters of multivariate data.\n",
27 | "\n",
28 | "Andrews curves have the functional form:\n",
29 | "\n",
30 | " f(t) = x_1/sqrt(2) + x_2 sin(t) + x_3 cos(t) + x_4 sin(2t) + x_5 cos(2t) + ...\n",
31 | "\n",
32 | "Where *x* coefficients correspond to the values of each dimension and *t* is\n",
33 | "linearly spaced between *-pi* and *+pi*. Each row of frame then corresponds to\n",
34 | "a single curve."
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "id": "d85a9c83-bd5d-4ac2-b1a0-0bb451a484e9",
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "from bokeh.sampledata import iris\n",
45 | "\n",
46 | "iris = iris.flowers"
47 | ]
48 | },
49 | {
50 | "cell_type": "code",
51 | "execution_count": null,
52 | "id": "780fc986-819b-4882-9c44-113b9a211d97",
53 | "metadata": {},
54 | "outputs": [],
55 | "source": [
56 | "iris.head()"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": null,
62 | "id": "4c721441-ecf3-4178-a55f-d43eed7d00a5",
63 | "metadata": {},
64 | "outputs": [],
65 | "source": [
66 | "hvplot.plotting.andrews_curves(\n",
67 | " iris,\n",
68 | " class_column='species',\n",
69 | " samples=20,\n",
70 | ")"
71 | ]
72 | }
73 | ],
74 | "metadata": {
75 | "language_info": {
76 | "name": "python",
77 | "pygments_lexer": "ipython3"
78 | }
79 | },
80 | "nbformat": 4,
81 | "nbformat_minor": 5
82 | }
83 |
--------------------------------------------------------------------------------
/doc/reference/tabular/area.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Area"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`area` can be used to color the area under a line or to color the space between two lines. "
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.degrees import data\n",
33 | "\n",
34 | "data.tail()"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "First we'll look at a single curve, where we are enforcing the y axis must be between 0 and 100 and we set the background color."
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": [
50 | "data.hvplot.area(\n",
51 | " x='Year', y='Computer Science',\n",
52 | " label='% of Computer Science Degrees Earned by Women',\n",
53 | " ylim=(0, 100), width=500, height=400, bgcolor='goldenrod',\n",
54 | ")"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "import pandas as pd\n",
64 | "from bokeh.sampledata.stocks import MSFT\n",
65 | "\n",
66 | "df = pd.DataFrame(MSFT)\n",
67 | "df['date'] = pd.to_datetime(df.date)\n",
68 | "df.head()"
69 | ]
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "To color the area between two curves, include both a `y` and a `y2`."
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {},
82 | "outputs": [],
83 | "source": [
84 | "df[df.date.dt.year == 2000].hvplot.area(x='date', y='low', y2='high')"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "When multiple y values are passed, they are stacked by default."
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": null,
97 | "metadata": {},
98 | "outputs": [],
99 | "source": [
100 | "df.hvplot.area(x='date', y=['open', 'close'])"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "Area plots can also be unstacked:"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": null,
113 | "metadata": {},
114 | "outputs": [],
115 | "source": [
116 | "df.hvplot.area(x='date', y=['open', 'close'], stacked=False,\n",
117 | " groupby='date.year', legend='bottom_right', width=500)"
118 | ]
119 | }
120 | ],
121 | "metadata": {
122 | "language_info": {
123 | "name": "python",
124 | "pygments_lexer": "ipython3"
125 | }
126 | },
127 | "nbformat": 4,
128 | "nbformat_minor": 4
129 | }
130 |
--------------------------------------------------------------------------------
/doc/reference/tabular/barh.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Barh"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`barh()` is similar to `.bar()` but plots bars horizontally rather than vertically. These charts can be created from dataframes with regular `Index` or `MultiIndex`."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.autompg import autompg_clean as df\n",
33 | "\n",
34 | "table = df.groupby(['origin', 'mfr'])['mpg'].mean().sort_values()\n",
35 | "table.head()"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "table.hvplot.barh('mfr', 'mpg', by='origin', stacked=True, legend='bottom_right', height=600)"
45 | ]
46 | }
47 | ],
48 | "metadata": {
49 | "language_info": {
50 | "name": "python",
51 | "pygments_lexer": "ipython3"
52 | }
53 | },
54 | "nbformat": 4,
55 | "nbformat_minor": 4
56 | }
57 |
--------------------------------------------------------------------------------
/doc/reference/tabular/bivariate.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Bivariate"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`bivariate()` is a statistical method for creating a 2D density plot. Bivariate plots can be a useful alternative to scatter plots if your data are too dense to plot each point individually."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.autompg import autompg_clean as df\n",
33 | "\n",
34 | "df.head()"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "df.hvplot.bivariate('accel', 'mpg')"
44 | ]
45 | }
46 | ],
47 | "metadata": {
48 | "language_info": {
49 | "name": "python",
50 | "pygments_lexer": "ipython3"
51 | }
52 | },
53 | "nbformat": 4,
54 | "nbformat_minor": 4
55 | }
56 |
--------------------------------------------------------------------------------
/doc/reference/tabular/box.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Box"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`box` plots are most useful when grouped by additional dimensions."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.sprint import sprint as df\n",
33 | "\n",
34 | "df.head()"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "boxplot = df.hvplot.box(y='Time', by='Medal', height=400, width=400, legend=False)\n",
44 | "boxplot"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "Overlay this plot with the jittered scatter plot of the medalist times using the `*` operator:"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "boxplot * df.hvplot.scatter(y='Time', x='Medal', c='orange').opts(jitter=0.5)"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "Use `groupby` to create a separate plot for each medal type with a widget for selecting between the plots."
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "df.hvplot.box(y='Time', groupby='Medal', by='Country', ylabel='Sprint Time', height=400, width=600)"
77 | ]
78 | }
79 | ],
80 | "metadata": {
81 | "language_info": {
82 | "name": "python",
83 | "pygments_lexer": "ipython3"
84 | }
85 | },
86 | "nbformat": 4,
87 | "nbformat_minor": 4
88 | }
89 |
--------------------------------------------------------------------------------
/doc/reference/tabular/errorbars.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Errorbars"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`errorbars` are most helpful when overlaid with other plot types. To do this we'll use the `*` operator."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata import perceptions\n",
33 | "\n",
34 | "data = perceptions.numberly.describe().transpose().sort_values('mean')\n",
35 | "data"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "First we'll use just one column to set the size of the errorbars around 'mean'."
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "data.hvplot.scatter(y='mean', ylabel='amount') * data.hvplot.errorbars(y='mean', yerr1='std')"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "Then we'll use two columns. Remember that these are not the absolute placements of the ends of the bars, but the distance from the center."
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {},
65 | "outputs": [],
66 | "source": [
67 | "data['yerr1'] = data['mean'] - data['min']\n",
68 | "data['yerr2'] = data['max'] - data['mean']\n",
69 | "data.hvplot.scatter(y='mean', ylabel='amount') * data.hvplot.errorbars(y='mean', yerr1='yerr1', yerr2='yerr2')"
70 | ]
71 | }
72 | ],
73 | "metadata": {
74 | "language_info": {
75 | "name": "python",
76 | "pygments_lexer": "ipython3"
77 | }
78 | },
79 | "nbformat": 4,
80 | "nbformat_minor": 4
81 | }
82 |
--------------------------------------------------------------------------------
/doc/reference/tabular/heatmap.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Heatmap"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`heatmap` can be data has two categorical axes. Data can either be pre-computed into a matrix, or it can be 1d and the aggregation will be computed when rendering."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata import sea_surface_temperature as sst\n",
33 | "\n",
34 | "df = sst.sea_surface_temperature\n",
35 | "df.tail()"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "In the first example, we'll make a sea surface temperature calendar of sorts:"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "df.hvplot.heatmap(x='time.month', y='time.day', C='temperature', \n",
52 | " height=500, width=500, colorbar=False)"
53 | ]
54 | },
55 | {
56 | "cell_type": "markdown",
57 | "metadata": {},
58 | "source": [
59 | "If the value for each section of the heatmap is pre-computed, then use `x='index'` and `y='columns'` to plot those values. Note to see how to make this same plot in bokeh, see the [bokeh docs](https://docs.bokeh.org/en/latest/docs/user_guide/topics/categorical.html#categorical-heatmaps)."
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": null,
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "from bokeh.sampledata.unemployment1948 import data\n",
69 | "\n",
70 | "data = data.set_index('Year').drop('Annual', axis=1).transpose()\n",
71 | "data.head()"
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {},
78 | "outputs": [],
79 | "source": [
80 | "data.hvplot.heatmap(\n",
81 | " x='columns', \n",
82 | " y='index', \n",
83 | " title='US Unemployment 1948—2016', \n",
84 | " cmap=[\"#75968f\", \"#a5bab7\", \"#c9d9d3\", \"#e2e2e2\", \"#dfccce\", \"#ddb7b1\", \"#cc7878\", \"#933b41\", \"#550b1d\"], \n",
85 | " xaxis='top', \n",
86 | " rot=70,\n",
87 | " width=800, height=300).opts(\n",
88 | " toolbar=None, \n",
89 | " fontsize={'title': 10, 'xticks': 5, 'yticks': 5}\n",
90 | ")"
91 | ]
92 | }
93 | ],
94 | "metadata": {
95 | "language_info": {
96 | "name": "python",
97 | "pygments_lexer": "ipython3"
98 | }
99 | },
100 | "nbformat": 4,
101 | "nbformat_minor": 4
102 | }
103 |
--------------------------------------------------------------------------------
/doc/reference/tabular/hexbin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Hexbin"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`.hexbin()` offers a straightforward method for plotting dense data."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import pandas as pd\n",
33 | "from bokeh.sampledata.stocks import AAPL\n",
34 | "\n",
35 | "df = pd.DataFrame(AAPL)\n",
36 | "df.head()"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "df.hvplot.hexbin('open', 'volume', logz=True, clabel='Count',\n",
46 | " height=400, width=500)"
47 | ]
48 | }
49 | ],
50 | "metadata": {
51 | "language_info": {
52 | "name": "python",
53 | "pygments_lexer": "ipython3"
54 | }
55 | },
56 | "nbformat": 4,
57 | "nbformat_minor": 4
58 | }
59 |
--------------------------------------------------------------------------------
/doc/reference/tabular/hist.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Hist"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa\n",
17 | "\n",
18 | "# hvplot.extension(\"matplotlib\")"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "`hist` is often a good way to start looking at continuous data to get a sense of the distribution. Similar methods include [`kde`](kde.ipynb) (also available as `density`)."
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "from bokeh.sampledata.autompg import autompg_clean\n",
35 | "\n",
36 | "autompg_clean.sample(n=5)"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "autompg_clean.hvplot.hist(\"weight\")"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "When using `by` the plots are overlaid by default. To create subplots instead, use `subplots=True`."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "autompg_clean.hvplot.hist(\"weight\", by=\"origin\", subplots=True, width=250)"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "You can also plot histograms of *datetime* data"
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": null,
74 | "metadata": {},
75 | "outputs": [],
76 | "source": [
77 | "import pandas as pd\n",
78 | "from bokeh.sampledata.commits import data as commits\n",
79 | "\n",
80 | "commits = commits.reset_index().sort_values(\"datetime\")\n",
81 | "commits.head(3)"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {},
88 | "outputs": [],
89 | "source": [
90 | "commits.hvplot.hist(\n",
91 | " \"datetime\",\n",
92 | " bin_range=(pd.Timestamp('2012-11-30'), pd.Timestamp('2017-05-01')),\n",
93 | " bins=54, \n",
94 | ")"
95 | ]
96 | },
97 | {
98 | "cell_type": "markdown",
99 | "metadata": {},
100 | "source": [
101 | "If you want to plot the distribution of a categorical column you can calculate the distribution using Pandas' method `value_counts` and plot it using `.hvplot.bar`."
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "autompg_clean[\"mfr\"].value_counts().hvplot.bar(invert=True, flip_yaxis=True, height=500)"
111 | ]
112 | }
113 | ],
114 | "metadata": {
115 | "language_info": {
116 | "name": "python",
117 | "pygments_lexer": "ipython3"
118 | }
119 | },
120 | "nbformat": 4,
121 | "nbformat_minor": 4
122 | }
123 |
--------------------------------------------------------------------------------
/doc/reference/tabular/kde.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Kde"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Kernel density estimate (`kde`) provides a mechanism for showing the distribution and spread of the data. In `hvplot` the method is exposed both as `kde` and `density`."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata import sea_surface_temperature as sst\n",
33 | "\n",
34 | "df = sst.sea_surface_temperature\n",
35 | "df.tail()"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "df.hvplot.kde()"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "There are many options exposed and explorable using tab completion. In this case we'll create a colormap that spans the rainbow and divide the temperature by month."
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "import numpy as np\n",
61 | "import colorcet as cc"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "categorical_cmap = [cc.rainbow[int(i)] for i in np.linspace(0, 255, 12)]"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": null,
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "df.hvplot.kde(by='time.month', cmap=categorical_cmap, legend='top', height=400)"
80 | ]
81 | }
82 | ],
83 | "metadata": {
84 | "language_info": {
85 | "name": "python",
86 | "pygments_lexer": "ipython3"
87 | }
88 | },
89 | "nbformat": 4,
90 | "nbformat_minor": 4
91 | }
92 |
--------------------------------------------------------------------------------
/doc/reference/tabular/labels.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Labels"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`labels` are mostly useful when overlaid on top of other plots. For instance in this case we will plot some capitals as points and then overlay (using the `*` operator) labels."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import pandas as pd\n",
33 | "\n",
34 | "df = pd.DataFrame(\n",
35 | " {'City': ['Buenos Aires', 'Brasilia', 'Santiago', 'Bogota', 'Caracas'],\n",
36 | " 'Country': ['Argentina', 'Brazil', 'Chile', 'Colombia', 'Venezuela'],\n",
37 | " 'Latitude': [-34.58, -15.78, -33.45, 4.60, 10.48],\n",
38 | " 'Longitude': [-58.66, -47.91, -70.66, -74.08, -66.86]})\n",
39 | "df"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": null,
45 | "metadata": {},
46 | "outputs": [],
47 | "source": [
48 | "df.hvplot.points(x='Longitude', y='Latitude', padding=0.2, hover_cols='all', width=300) * \\\n",
49 | "df.hvplot.labels(x='Longitude', y='Latitude', text='City', text_baseline='bottom', hover=False) * \\\n",
50 | "df.hvplot.labels(x='Longitude', y='Latitude', text='Country', text_baseline='top', hover=False)"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": [
57 | "It's also possible to provide a template string containing the names of the columns and reduce the font size."
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {},
64 | "outputs": [],
65 | "source": [
66 | "df.hvplot.points(x='Longitude', y='Latitude', padding=0.2, hover_cols='all', width=300) * \\\n",
67 | "df.hvplot.labels(x='Longitude', y='Latitude', text='@{City}, {Country}', text_baseline='bottom', text_font_size='10px', hover=False)"
68 | ]
69 | }
70 | ],
71 | "metadata": {
72 | "language_info": {
73 | "name": "python",
74 | "pygments_lexer": "ipython3"
75 | }
76 | },
77 | "nbformat": 4,
78 | "nbformat_minor": 4
79 | }
80 |
--------------------------------------------------------------------------------
/doc/reference/tabular/lagplot.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "7eb37c52-8262-4359-a6c1-3214e675fa5d",
6 | "metadata": {},
7 | "source": [
8 | "# Lagplot"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "cb5dd3db-78c4-4a01-ba07-37f718f7425a",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.pandas # noqa\n",
19 | "import numpy as np\n",
20 | "import pandas as pd"
21 | ]
22 | },
23 | {
24 | "cell_type": "markdown",
25 | "id": "c7af165e-4231-49ea-81d7-d07ad81a05da",
26 | "metadata": {},
27 | "source": [
28 | "Lag plots are most commonly used to look for patterns in time series data."
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "815a51ab-5f61-4bea-bb56-e11a0f117718",
34 | "metadata": {},
35 | "source": [
36 | "Given the following time series:"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "id": "283adbd9-3c42-4cb7-8c57-1d0e9fe1d25f",
43 | "metadata": {},
44 | "outputs": [],
45 | "source": [
46 | "np.random.seed(5)\n",
47 | "x = np.cumsum(np.random.normal(loc=1, scale=5, size=50))\n",
48 | "s = pd.Series(x, name='Time series')\n",
49 | "\n",
50 | "s.hvplot()"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "id": "8a877a7d-11cb-4bcb-81e4-3936f061ba65",
56 | "metadata": {},
57 | "source": [
58 | "A lag plot with `lag=1` returns:"
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "id": "52be318e-fccd-461d-9813-c231b6f2997c",
65 | "metadata": {},
66 | "outputs": [],
67 | "source": [
68 | "hvplot.plotting.lag_plot(s, lag=1)"
69 | ]
70 | }
71 | ],
72 | "metadata": {
73 | "language_info": {
74 | "name": "python",
75 | "pygments_lexer": "ipython3"
76 | }
77 | },
78 | "nbformat": 4,
79 | "nbformat_minor": 5
80 | }
81 |
--------------------------------------------------------------------------------
/doc/reference/tabular/line.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Line"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`line` is useful when data is continuous and has a continuous axis."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.degrees import data as deg\n",
33 | "deg.head()"
34 | ]
35 | },
36 | {
37 | "cell_type": "code",
38 | "execution_count": null,
39 | "metadata": {},
40 | "outputs": [],
41 | "source": [
42 | "deg.hvplot.line(x='Year', y=['Art and Performance', 'Business', 'Biology', 'Education', 'Computer Science'], \n",
43 | " value_label='% of Degrees Earned by Women', legend='top', height=500, width=620)"
44 | ]
45 | }
46 | ],
47 | "metadata": {
48 | "language_info": {
49 | "name": "python",
50 | "pygments_lexer": "ipython3"
51 | }
52 | },
53 | "nbformat": 4,
54 | "nbformat_minor": 4
55 | }
56 |
--------------------------------------------------------------------------------
/doc/reference/tabular/ohlc.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Ohlc"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import pandas as pd\n",
17 | "import hvplot.pandas # noqa"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "`ohlc` is a useful chart type to visualize stock movements"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {},
31 | "outputs": [],
32 | "source": [
33 | "from bokeh.sampledata import stocks\n",
34 | "\n",
35 | "df = pd.DataFrame(stocks.AAPL)\n",
36 | "df['date'] = pd.to_datetime(df.date)\n",
37 | "\n",
38 | "df.iloc[-50:].hvplot.ohlc(grid=True)"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "We can control the `neg_color`, `pos_color`, `line_color` and `bar_width`:"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "df.iloc[-50:].hvplot.ohlc(neg_color='indianred', pos_color='chartreuse', line_color='gray', bar_width=0.9, grid=True)"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "metadata": {},
60 | "source": [
61 | "By default `ohlc` will assume the `index` OR the first datetime column should be mapped to the x-axis and the first four non-datetime columns correspond to the O (open), H (high), L (low) and C (close) components. The default call is therefore equivalent to:"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": [
70 | "df.iloc[-50:].hvplot.ohlc('date', ['open', 'low', 'high', 'close'], grid=True)"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "Using the HoloViews `RangeToolLink` we can make it easy to scroll through the data while still seeing an overview of the overall timeseries:"
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {},
84 | "outputs": [],
85 | "source": [
86 | "from holoviews.plotting.links import RangeToolLink\n",
87 | "\n",
88 | "df_2012 = df[df.date > pd.to_datetime('2012')]\n",
89 | "\n",
90 | "ohlc = df_2012.hvplot.ohlc(ylabel='Price ($)', grid=True, xaxis=None)\n",
91 | "overview = df_2012.hvplot.ohlc(yaxis=None, height=150, fields={'date': 'Date'})\n",
92 | "volume = df_2012.hvplot.step('date', 'volume', height=100, xaxis=None)\n",
93 | "\n",
94 | "RangeToolLink(overview.get(0), ohlc.get(0))\n",
95 | "\n",
96 | "layout = (volume + ohlc + overview).cols(1)\n",
97 | "\n",
98 | "layout.opts(merge_tools=False)"
99 | ]
100 | }
101 | ],
102 | "metadata": {
103 | "language_info": {
104 | "name": "python",
105 | "pygments_lexer": "ipython3"
106 | }
107 | },
108 | "nbformat": 4,
109 | "nbformat_minor": 4
110 | }
111 |
--------------------------------------------------------------------------------
/doc/reference/tabular/parallelcoordinates.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "fe36abdf-7ad3-4acf-8143-b8e9eb04c9a9",
6 | "metadata": {},
7 | "source": [
8 | "# Parallelcoordinates"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "98539b4c-af81-4ad7-9fe5-8e1b828ee3d8",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.pandas # noqa"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "id": "0b7674d1-b972-4b43-9e96-18c0d0fcc125",
24 | "metadata": {},
25 | "source": [
26 | "Parallel coordinates are a common way of visualizing and analyzing high-dimensional datasets.\n",
27 | "\n",
28 | "To show a set of points in an n-dimensional space, a backdrop is drawn consisting of n parallel lines, typically vertical and equally spaced. A point in n-dimensional space is represented as a polyline with vertices on the parallel axes; the position of the vertex on the i-th axis corresponds to the i-th coordinate of the point. "
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "id": "b524875d-aaa6-40da-8b1a-9f42f636da6a",
35 | "metadata": {},
36 | "outputs": [],
37 | "source": [
38 | "from bokeh.sampledata import iris\n",
39 | "\n",
40 | "iris = iris.flowers"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "id": "02fa9997-0c52-4ee8-890f-9ce2a6352e3f",
47 | "metadata": {},
48 | "outputs": [],
49 | "source": [
50 | "iris.head()"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "id": "c737ec55-2c45-40dd-92d0-69464607bf7f",
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "hvplot.plotting.parallel_coordinates(\n",
61 | " iris,\n",
62 | " class_column='species',\n",
63 | " cols=['sepal_length', 'petal_length', 'petal_width']\n",
64 | ")"
65 | ]
66 | }
67 | ],
68 | "metadata": {
69 | "language_info": {
70 | "name": "python",
71 | "pygments_lexer": "ipython3"
72 | }
73 | },
74 | "nbformat": 4,
75 | "nbformat_minor": 5
76 | }
77 |
--------------------------------------------------------------------------------
/doc/reference/tabular/paths.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Paths"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import pandas as pd\n",
17 | "import hvplot.pandas # noqa\n",
18 | "import cartopy.crs as ccrs"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "Paths are useful if you are plotting lines on a geographic map."
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "df = pd.DataFrame({\"city\": [\"NY\", \"Delhi\"], \"lon\": [-75, 77.23], \"lat\": [43, 28.61]})"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {},
40 | "source": [
41 | "Notice how the line in blue between New York and Delhi is not straight on a flat PlateCarree map, this is because the Geodetic coordinate system is a truly spherical coordinate system, where a line between two points is defined as the shortest path between those points on the globe rather than 2d Cartesian space."
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {},
48 | "outputs": [],
49 | "source": [
50 | "common_kwargs = dict(\n",
51 | " x=\"lon\",\n",
52 | " y=\"lat\",\n",
53 | " geo=True,\n",
54 | " project=True,\n",
55 | " projection=ccrs.GOOGLE_MERCATOR,\n",
56 | " global_extent=True\n",
57 | ")\n",
58 | "shortest_path = df.hvplot.paths(color=\"blue\", crs=ccrs.Geodetic(), tiles=True, **common_kwargs)\n",
59 | "straight_path = df.hvplot.paths(color=\"grey\", line_dash=\"dashed\", **common_kwargs)\n",
60 | "labels = df.hvplot.labels(text_color=\"black\", text=\"city\", **common_kwargs)\n",
61 | "shortest_path * straight_path * labels"
62 | ]
63 | },
64 | {
65 | "cell_type": "markdown",
66 | "metadata": {},
67 | "source": [
68 | "Example adapted from https://scitools.org.uk/cartopy/docs/latest/matplotlib/intro.html."
69 | ]
70 | }
71 | ],
72 | "metadata": {
73 | "language_info": {
74 | "name": "python",
75 | "pygments_lexer": "ipython3"
76 | }
77 | },
78 | "nbformat": 4,
79 | "nbformat_minor": 2
80 | }
81 |
--------------------------------------------------------------------------------
/doc/reference/tabular/scatter.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Scatter"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`scatter` plots are a good first way to plot data with non continuous axes."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.iris import flowers as df\n",
33 | "\n",
34 | "df.sample(n=5)"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "df.hvplot.scatter(x='sepal_length', y='sepal_width', by='species', \n",
44 | " legend='top', height=400, width=400)"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "As for most other types of hvPlot plots, you can add fields to the hover display using the `hover_cols` argument. It can also take \"all\" as input to show all fields. "
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "df.hvplot.scatter(x='sepal_length', y='sepal_width', s='petal_length', scale=5, by='species', \n",
61 | " legend='top', height=400, width=600,\n",
62 | " hover_cols=[\"species\", \"sepal_length\", \"sepal_width\", \"petal_width\"])"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "You can add the 's' parameter in scatter to specify the marker plot size and add the 'scale' parameter to specify what the scaling factor should be."
70 | ]
71 | }
72 | ],
73 | "metadata": {
74 | "language_info": {
75 | "name": "python",
76 | "pygments_lexer": "ipython3"
77 | }
78 | },
79 | "nbformat": 4,
80 | "nbformat_minor": 4
81 | }
82 |
--------------------------------------------------------------------------------
/doc/reference/tabular/step.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Step"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`step` can be used pretty much anytime line might be used and has many of the same options available. "
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.degrees import data as deg\n",
33 | "deg.sample(n=5)"
34 | ]
35 | },
36 | {
37 | "cell_type": "code",
38 | "execution_count": null,
39 | "metadata": {},
40 | "outputs": [],
41 | "source": [
42 | "deg.hvplot.step(x='Year', y=['Art and Performance', 'Business', 'Biology', 'Education', 'Computer Science'], \n",
43 | " value_label='% of Degrees Earned by Women', legend='top', height=500, width=620)"
44 | ]
45 | }
46 | ],
47 | "metadata": {
48 | "language_info": {
49 | "name": "python",
50 | "pygments_lexer": "ipython3"
51 | }
52 | },
53 | "nbformat": 4,
54 | "nbformat_minor": 4
55 | }
56 |
--------------------------------------------------------------------------------
/doc/reference/tabular/table.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Table"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`table` allows the creation of a holoviews `Table` element with all the options available on that. It can be very useful especially when paired with other visualizations. "
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.autompg import autompg_clean as df\n",
33 | "\n",
34 | "df.head()"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "df.hvplot.table(columns=['origin', 'name', 'yr'], sortable=True, selectable=True)"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "Click on the header to sort on the values in a column and on a row to select that column."
51 | ]
52 | }
53 | ],
54 | "metadata": {
55 | "language_info": {
56 | "name": "python",
57 | "pygments_lexer": "ipython3"
58 | }
59 | },
60 | "nbformat": 4,
61 | "nbformat_minor": 4
62 | }
63 |
--------------------------------------------------------------------------------
/doc/reference/tabular/violin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Violin"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.pandas # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`violin` plots are similar to box plots, but provide a better sense of the distribution of data. Note that `violin` plots depend on the `scipy` library."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from bokeh.sampledata.sprint import sprint as df\n",
33 | "\n",
34 | "df.head()"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "df.hvplot.violin(y='Time', by='Medal', c='Medal', ylabel='Sprint Time',\n",
44 | " cmap=['gold', 'silver', 'brown'], legend=False, \n",
45 | " width=500, height=500, padding=0.4)"
46 | ]
47 | }
48 | ],
49 | "metadata": {
50 | "language_info": {
51 | "name": "python",
52 | "pygments_lexer": "ipython3"
53 | }
54 | },
55 | "nbformat": 4,
56 | "nbformat_minor": 4
57 | }
58 |
--------------------------------------------------------------------------------
/doc/reference/xarray/bar.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "3b507dd1-31f6-4732-bbc7-c82f2135fe1f",
6 | "metadata": {},
7 | "source": [
8 | "# Bar"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "5d0ed0f8-ce26-4c54-9161-d34ca73ae716",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.xarray # noqa\n",
19 | "import xarray as xr"
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "id": "e3f7e297-9576-4c36-9a9f-a4200ccf2d36",
25 | "metadata": {},
26 | "source": [
27 | "## Introduction\n",
28 | "\n",
29 | "A `bar` plot represents **categorical data** with rectangular bars with heights proportional to the **numerical values** that they represent.\n",
30 | "The x-axis represents the categories and the y axis represents the numerical value scale.\n",
31 | "The bars are of equal width which allows for instant comparison of data."
32 | ]
33 | },
34 | {
35 | "cell_type": "markdown",
36 | "id": "af429bbb-9a65-4b5d-b447-ce50b35dfedc",
37 | "metadata": {},
38 | "source": [
39 | "## Data\n",
40 | "\n",
41 | "Let's load some data."
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "id": "8db8fff7-b85f-49ea-b281-4a4d86e0f3ee",
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "ds = xr.tutorial.open_dataset('air_temperature').load()\n",
52 | "air = ds.air\n",
53 | "air1d = air.sel(lon=285.,lat=40.).groupby('time.month').mean()\n",
54 | "air1d"
55 | ]
56 | },
57 | {
58 | "cell_type": "markdown",
59 | "id": "629c5172-9cba-4f5f-bf3b-67e0a390385b",
60 | "metadata": {},
61 | "source": [
62 | "## Basic Bar Plots"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "id": "dfd1afa2-e310-4630-bd30-96e390078caf",
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "air1d.hvplot.bar(y='air', height=500, title=\"Air Temperature by Month\")"
73 | ]
74 | }
75 | ],
76 | "metadata": {
77 | "language_info": {
78 | "name": "python",
79 | "pygments_lexer": "ipython3"
80 | }
81 | },
82 | "nbformat": 4,
83 | "nbformat_minor": 5
84 | }
85 |
--------------------------------------------------------------------------------
/doc/reference/xarray/contour.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Contour"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Similar to [`image`](image.ipynb), `contour` displays values on a 2d grid. But it first segments data into various levels."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import xarray as xr\n",
33 | "\n",
34 | "ds = xr.tutorial.open_dataset('air_temperature')\n",
35 | "ds"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "ds.hvplot.contour()"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "There are lots of options exposed to control the style and contents of the `contour` plot:"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "ds.mean(dim='time').hvplot.contour(z='air', x='lon', y='lat', levels=20, \n",
61 | " clabel='T [K]', label='Mean Air temperature [K]',\n",
62 | " cmap='gray')"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Geographic Data\n",
70 | "\n",
71 | "Include a basemap from a tiling service using the `tiles` option."
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {},
78 | "outputs": [],
79 | "source": [
80 | "ds.hvplot.contour(geo=True, tiles='EsriImagery', levels=20, line_width=2, cmap='reds',)"
81 | ]
82 | }
83 | ],
84 | "metadata": {
85 | "language_info": {
86 | "name": "python",
87 | "pygments_lexer": "ipython3"
88 | }
89 | },
90 | "nbformat": 4,
91 | "nbformat_minor": 4
92 | }
93 |
--------------------------------------------------------------------------------
/doc/reference/xarray/contourf.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Contourf"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "Similar to [`image`](image.ipynb), `contourf` displays values on a 2d grid. But it first segments data into various levels."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import xarray as xr\n",
33 | "\n",
34 | "ds = xr.tutorial.open_dataset('air_temperature')\n",
35 | "ds"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "ds.hvplot.contourf()"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "There are lots of options exposed to control the style and contents of the `contourf` plot:"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "ds.mean(dim='time').hvplot.contourf(z='air', x='lon', y='lat', levels=20,\n",
61 | " clabel='T [K]', label='Mean Air temperature [K]',\n",
62 | " cmap='fire')"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Geographic Data"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "metadata": {},
76 | "outputs": [],
77 | "source": [
78 | "ds.hvplot.contourf(levels=20, geo=True, coastline=True, widget_location='left_top')"
79 | ]
80 | }
81 | ],
82 | "metadata": {
83 | "language_info": {
84 | "name": "python",
85 | "pygments_lexer": "ipython3"
86 | }
87 | },
88 | "nbformat": 4,
89 | "nbformat_minor": 4
90 | }
91 |
--------------------------------------------------------------------------------
/doc/reference/xarray/hist.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Hist"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa\n",
17 | "import xarray as xr"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "`hist` is often a good way to start looking at data to get a sense of the distribution. Similar methods include [`kde`](kde.ipynb) (also available as `density`)."
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {},
31 | "outputs": [],
32 | "source": [
33 | "ds = xr.tutorial.open_dataset('air_temperature').load()\n",
34 | "air = ds.air\n",
35 | "air1d = air.sel(lon=285.,lat=40.)\n",
36 | "air1d"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "air1d.hvplot.hist()"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Customize the plot by changing the title and bar color."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "air1d.hvplot.hist(title=\"Air Temperature over time at lat=40,lon285\", color='gray')"
62 | ]
63 | }
64 | ],
65 | "metadata": {
66 | "language_info": {
67 | "name": "python",
68 | "pygments_lexer": "ipython3"
69 | }
70 | },
71 | "nbformat": 4,
72 | "nbformat_minor": 4
73 | }
74 |
--------------------------------------------------------------------------------
/doc/reference/xarray/image.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Image"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "import xarray as xr\n",
26 | "\n",
27 | "ds = xr.tutorial.open_dataset('air_temperature')\n",
28 | "ds"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "metadata": {},
34 | "source": [
35 | "When data values are available on an x, y grid, they can often be represented as an `image`."
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "ds.hvplot.image()"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "This is equivalent to specifying:"
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "ds.hvplot.image(x='lon', y='lat', z='air', groupby='time', cmap='kbc_r')"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "A simpler case would be to take the temperature at just one day. Here we'll show how to use `clabel` to control the colorbar and also demonstrate how when the data are symmetric around 0, the \"coolwarm\" colormap is used by default."
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "time = '2014-01-01'\n",
77 | "data = ds.sel(time=time).mean('time') - 273 # convert to celsius\n",
78 | "\n",
79 | "data.hvplot.image(x='lon', y='lat', z='air', title=time, clabel='T [C]')"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "We can also override the colorbar ticks and labels with `cticks`, specified as an integer, list of ticks positions, or list of tuples of the tick positions and labels."
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "data.hvplot.image(x='lon', y='lat', z='air', title=time, clabel='T [C]', cticks=[(-40, \"Below Freezing\"), (0, \"Freezing\"), (40, \"Above Freezing\")])"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "## Geographic Data\n",
103 | "\n",
104 | "By setting `coastline=True`, we can add a coastline feature to the plot and coerce it to the proper aspect."
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": null,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "data.hvplot.image(coastline=True)"
114 | ]
115 | }
116 | ],
117 | "metadata": {
118 | "language_info": {
119 | "name": "python",
120 | "pygments_lexer": "ipython3"
121 | }
122 | },
123 | "nbformat": 4,
124 | "nbformat_minor": 4
125 | }
126 |
--------------------------------------------------------------------------------
/doc/reference/xarray/kde.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "a8373dcf-f097-454d-b97a-2f4e7bf20e62",
6 | "metadata": {},
7 | "source": [
8 | "# Kde"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "2ccf9fd5-9d10-4522-961d-7e8d236213b2",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.xarray # noqa\n",
19 | "import xarray as xr"
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "id": "f7ed6c65-2280-4741-b89b-721110628547",
25 | "metadata": {},
26 | "source": [
27 | "Kernel density estimate (`kde`) provides a mechanism for showing the distribution and spread of the data. In `hvplot` the method is exposed both as `kde` and `density`."
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "id": "e8680d48-02b1-4480-96e3-d0fd7807a804",
34 | "metadata": {},
35 | "outputs": [],
36 | "source": [
37 | "ds = xr.tutorial.open_dataset('air_temperature').load()\n",
38 | "air = ds.air\n",
39 | "air1d = air.sel(lat=[25, 50, 75])"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": null,
45 | "id": "f33d3355-deaa-4bdf-befa-af20d2e46d7a",
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "air1d.hvplot.kde('air', by='lat', alpha=0.5)"
50 | ]
51 | }
52 | ],
53 | "metadata": {
54 | "language_info": {
55 | "name": "python",
56 | "pygments_lexer": "ipython3"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 5
61 | }
62 |
--------------------------------------------------------------------------------
/doc/reference/xarray/line.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Line"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa\n",
17 | "import xarray as xr"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "`line` is useful when data is continuous and has a continuous axis."
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {},
31 | "outputs": [],
32 | "source": [
33 | "ds = xr.tutorial.open_dataset('air_temperature').load()\n",
34 | "air = ds.air\n",
35 | "air1d = air.sel(lon=285.,lat=40.)\n",
36 | "air1d"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "air1d.hvplot.line()"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "Customize the plot by changing the title and line color."
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "air1d.hvplot.line(title=\"Air Temperature over time at lat=40,lon285\",line_color='gray')"
62 | ]
63 | }
64 | ],
65 | "metadata": {
66 | "language_info": {
67 | "name": "python",
68 | "pygments_lexer": "ipython3"
69 | }
70 | },
71 | "nbformat": 4,
72 | "nbformat_minor": 4
73 | }
74 |
--------------------------------------------------------------------------------
/doc/reference/xarray/quadmesh.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Quadmesh"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "code",
21 | "execution_count": null,
22 | "metadata": {},
23 | "outputs": [],
24 | "source": [
25 | "import xarray as xr\n",
26 | "\n",
27 | "ds = xr.tutorial.open_dataset('rasm')\n",
28 | "ds"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "metadata": {},
34 | "source": [
35 | "`quadmesh` can be slower that `image`, but it allows you to plot values on an irregular grid by representing each value as a polygon."
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "metadata": {},
42 | "outputs": [],
43 | "source": [
44 | "ds.Tair.hvplot.quadmesh(x='xc', y='yc', geo=True, widget_location='bottom')"
45 | ]
46 | },
47 | {
48 | "cell_type": "markdown",
49 | "metadata": {},
50 | "source": [
51 | "To reduce the render time or the size of the saved plot, use `rasterize` to aggregate the values to the pixel. It is recommended that when rasterizing geo plots, you project **before** rasterizing, by setting `project=True`."
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "ds.Tair.hvplot.quadmesh(x='xc', y='yc', geo=True, widget_location='bottom', rasterize=True, project=True)"
61 | ]
62 | }
63 | ],
64 | "metadata": {
65 | "language_info": {
66 | "name": "python",
67 | "pygments_lexer": "ipython3"
68 | }
69 | },
70 | "nbformat": 4,
71 | "nbformat_minor": 4
72 | }
73 |
--------------------------------------------------------------------------------
/doc/reference/xarray/rgb.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Rgb"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": null,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import hvplot.xarray # noqa"
17 | ]
18 | },
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {},
22 | "source": [
23 | "`rgb` can be used to display images that are distributed as three separate \"channels\" or \"bands\"."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "from hvplot.sample_data import landuse\n",
33 | "\n",
34 | "da = landuse(landuse='airplane', id=90).read()\n",
35 | "da"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {},
41 | "source": [
42 | "Since rgb images are stored starting at the top left pixel, we should start there when plotting to make sure that we get the picture in the correct orientation. To accomplish this, we use `flip_yaxis`."
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "da.hvplot.rgb(x='x', y='y', bands='channel', data_aspect=1, flip_yaxis=True, xaxis=False, yaxis=None)"
52 | ]
53 | }
54 | ],
55 | "metadata": {
56 | "language_info": {
57 | "name": "python",
58 | "pygments_lexer": "ipython3"
59 | }
60 | },
61 | "nbformat": 4,
62 | "nbformat_minor": 4
63 | }
64 |
--------------------------------------------------------------------------------
/doc/reference/xarray/violin.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "cc4ff857-13b2-4f43-97dd-502a0703d276",
6 | "metadata": {},
7 | "source": [
8 | "# Violin"
9 | ]
10 | },
11 | {
12 | "cell_type": "code",
13 | "execution_count": null,
14 | "id": "2ccf9fd5-9d10-4522-961d-7e8d236213b2",
15 | "metadata": {},
16 | "outputs": [],
17 | "source": [
18 | "import hvplot.xarray # noqa\n",
19 | "import xarray as xr"
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "id": "f7ed6c65-2280-4741-b89b-721110628547",
25 | "metadata": {},
26 | "source": [
27 | "`violin` plots are similar to box plots, but provide a better sense of the distribution of data. Note that `violin` plots depend on the `scipy` library."
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "id": "e0f6ecc7-0f6a-4590-9c98-da10a674b9b0",
34 | "metadata": {},
35 | "outputs": [],
36 | "source": [
37 | "ds = xr.tutorial.open_dataset('air_temperature').load()\n",
38 | "air = ds.air\n",
39 | "air"
40 | ]
41 | },
42 | {
43 | "cell_type": "code",
44 | "execution_count": null,
45 | "id": "2a137994-0a9d-4a75-8192-1e4bb4ead6c5",
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "air.hvplot.violin(y='air', by='lat', color='lat', cmap='Category20', title=\"Air Temperature vs. latitude\")"
50 | ]
51 | }
52 | ],
53 | "metadata": {
54 | "language_info": {
55 | "name": "python",
56 | "pygments_lexer": "ipython3"
57 | }
58 | },
59 | "nbformat": 4,
60 | "nbformat_minor": 5
61 | }
62 |
--------------------------------------------------------------------------------
/doc/topics.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
12 | You should have been redirected.
13 | If not, click here to continue.
14 |
15 |
16 |
--------------------------------------------------------------------------------
/doc/tutorials/index.md:
--------------------------------------------------------------------------------
1 | # Tutorials
2 |
3 | Welcome to the Tutorials section. Here, you will find clear, step-by-step guides to help you master hvPlot and explore the full [HoloViz](https://holoviz.org/) ecosystem. Whether you’re just starting out, coming from Pandas or Xarray, or looking to sharpen your skills, these tutorials offer practical examples and hands-on learning to explore and transform your data into compelling visualizations.
4 |
5 | ## Internal tutorials
6 |
7 | ::::{grid} 1 2 2 3
8 | :gutter: 1 1 1 2
9 |
10 | :::{grid-item-card} {octicon}`book;2.5em;sd-mr-1 sd-animate-grow50` Getting Started
11 | :link: getting_started
12 | :link-type: doc
13 |
14 | Get started with hvPlot using this quick tutorial.
15 | :::
16 |
17 | :::{grid-item-card} {octicon}`repo-template;2.5em;sd-mr-1 sd-animate-grow50` Coming From Pandas?
18 | :link: getting_started_pandas
19 | :link-type: doc
20 |
21 | Get started with hvPlot as a Pandas user.
22 | :::
23 |
24 | ::::
25 |
26 | ## External tutorials
27 |
28 | ::::{grid} 1 2 2 3
29 | :gutter: 1 1 1 2
30 |
31 | :::{grid-item-card} {octicon}`link;2.5em;sd-mr-1 sd-animate-grow50` Holoviz Tutorial
32 | :link: https://holoviz.org/tutorial/index.html
33 |
34 | Explore all the HoloViz tools in this comprehensive tutorial.
35 | :::
36 |
37 | ::::
38 |
39 | ```{toctree}
40 | :titlesonly:
41 | :hidden:
42 | :maxdepth: 2
43 |
44 | Getting Started
45 | Using hvPlot as a Pandas user
46 | HoloViz Tutorial
47 | ```
48 |
--------------------------------------------------------------------------------
/doc/user_guide/index.md:
--------------------------------------------------------------------------------
1 | # User Guide
2 |
3 | The user guide provides a detailed introduction to the API and
4 | features of hvPlot. In the [Introduction](Introduction.ipynb) you
5 | will learn how to activate the plotting API and start using it. Next
6 | you will learn to use the API for tabular data and get an overview of
7 | the [types of plots](Plotting.ipynb) you can generate; including how to customize
8 | interactivity using [widgets](Widgets.ipynb). Next is an overview on how to
9 | [display and save plots](Viewing.ipynb) in the notebook, on the
10 | commandline, and from a script. Another section will introduce you to
11 | generating [subplots](Subplots.ipynb) from your data.
12 |
13 | Once the basics are covered you can learn how to use the plotting API
14 | for specific types of data including [streaming data](Streaming.ipynb), [gridded data](Gridded_Data.ipynb)
15 | [network graphs](NetworkX.ipynb), [geographic data](Geographic_Data.ipynb),
16 | and [timeseries data](Timeseries_Data.ipynb). These sections are not meant
17 | to be read in a particular order; you should take a look at any that seem
18 | relevant to your data.
19 |
20 | The [interactive](Interactive.ipynb) user guide introduces you to the
21 | ability to use the APIs of your favorite data analysis libraries
22 | interactively by allowing you to pass in widgets in place of constant
23 | arguments. This will provide you with an invaluable tool to perform
24 | exploratory analyses quickly but also build powerful and complex data
25 | analysis pipelines using APIs you are already familiar with.
26 |
27 | Lastly the [statistical plots](Statistical_Plots.ipynb) section will
28 | take you through a number of specialized plot types modelled on the
29 | pandas.plotting module.
30 |
31 | **Overview**:
32 |
33 | - [Introduction](Introduction)
34 | Introduction to hvPlot and how to start using it.
35 | - [Plotting with Bokeh](Plotting)
36 | Overview of plotting your data with hvPlot and Bokeh.
37 | - [Plotting with Matplotlib](Plotting_with_Matplotlib)
38 | Overview of plotting your data with hvPlot and Matplotib.
39 | - [Plotting with Plotly](Plotting_with_Plotly)
40 | Overview of plotting your data with hvPlot and Plotly.
41 | - [Interactive](Interactive)
42 | Interactive APIs for data exploration.
43 | - [Widgets](Widgets)
44 | Adding and customizing interactivity using Panel widgets.
45 | - [Plotting Extensions](Plotting_Extensions)
46 | Changing the plotting extension.
47 | - [Exploring data](Explorer)
48 | Exploring data with user interface.
49 | - [Viewing](Viewing)
50 | Displaying and saving plots in the notebook, at the command prompt, or in scripts.
51 | - [Subplots](Subplots)
52 | How to generate subplots and grids.
53 | - [Streaming](Streaming)
54 | How to use hvPlot for streaming plots with the streamz library.
55 | - [Gridded Data](Gridded_Data)
56 | How to use hvPlot for plotting XArray-based gridded data.
57 | - [Network Graphs](NetworkX)
58 | How to use hvPlot for plotting NetworkX graphs.
59 | - [Geographic Data](Geographic_Data)
60 | Using GeoViews, Cartopy, GeoPandas and spatialpandas to plot data in geographic coordinate systems.
61 | - [Timeseries Data](Timeseries_Data)
62 | Using hvPlot when working with timeseries data.
63 | - [Large Timeseries Data](Large_Timeseries)
64 | Using hvPlot when working with large timeseries data.
65 | - [Statistical Plots](Statistical_Plots)
66 | A number of statistical plot types modeled on the pandas.plotting module.
67 |
68 | ```{toctree}
69 | :hidden: true
70 | :maxdepth: 2
71 | :titlesonly: true
72 |
73 | Introduction
74 | Plotting with Bokeh
75 | Plotting with Matplotlib
76 | Plotting with Plotly
77 | Interactive
78 | Widgets
79 | Plotting Extensions
80 | Exploring data
81 | Viewing
82 | Subplots
83 | Streaming
84 | Gridded Data
85 | Network Graphs
86 | Geographic Data
87 | Timeseries Data
88 | Large Timeseries
89 | Statistical Plots
90 | ```
91 |
--------------------------------------------------------------------------------
/hvplot/cudf.py:
--------------------------------------------------------------------------------
1 | from .interactive import Interactive
2 |
3 |
4 | def patch(name='hvplot', interactive='interactive', extension='bokeh', logo=False):
5 | from . import hvPlotTabular, post_patch, _module_extensions
6 |
7 | try:
8 | import cudf
9 | except ImportError:
10 | raise ImportError('Could not patch plotting API onto cuDF. cuDF could not be imported.')
11 |
12 | if 'hvplot.cudf' not in _module_extensions:
13 | _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
14 | _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
15 | plot_prop = property(_patch_plot)
16 | setattr(cudf.DataFrame, name, plot_prop)
17 | setattr(cudf.Series, name, plot_prop)
18 |
19 | _patch_interactive = lambda self: Interactive(self) # noqa: E731
20 | _patch_interactive.__doc__ = Interactive.__call__.__doc__
21 | interactive_prop = property(_patch_interactive)
22 | setattr(cudf.DataFrame, interactive, interactive_prop)
23 | setattr(cudf.Series, interactive, interactive_prop)
24 |
25 | _module_extensions.add('hvplot.cudf')
26 |
27 | post_patch(extension, logo)
28 |
29 |
30 | patch()
31 |
--------------------------------------------------------------------------------
/hvplot/dask.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | from .interactive import Interactive
4 |
5 |
6 | class DaskInteractive(Interactive):
7 | @classmethod
8 | def applies(cls, obj):
9 | if 'dask.dataframe' in sys.modules:
10 | import dask.dataframe as dd
11 |
12 | return isinstance(obj, (dd.Series, dd.DataFrame))
13 | return False
14 |
15 | def compute(self):
16 | self._method = 'compute'
17 | return self.__call__()
18 |
19 |
20 | def patch(name='hvplot', interactive='interactive', extension='bokeh', logo=False):
21 | from . import hvPlotTabular, post_patch, _module_extensions
22 |
23 | try:
24 | import dask.dataframe as dd
25 | except ImportError:
26 | raise ImportError('Could not patch plotting API onto dask. Dask could not be imported.')
27 |
28 | if 'hvplot.dask' not in _module_extensions:
29 | _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
30 | _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
31 | plot_prop = property(_patch_plot)
32 | setattr(dd.DataFrame, name, plot_prop)
33 | setattr(dd.Series, name, plot_prop)
34 |
35 | _patch_interactive = lambda self: DaskInteractive(self) # noqa: E731
36 | _patch_interactive.__doc__ = DaskInteractive.__call__.__doc__
37 | interactive_prop = property(_patch_interactive)
38 | setattr(dd.DataFrame, interactive, interactive_prop)
39 | setattr(dd.Series, interactive, interactive_prop)
40 |
41 | _module_extensions.add('hvplot.dask')
42 |
43 | post_patch(extension, logo)
44 |
45 |
46 | patch()
47 |
--------------------------------------------------------------------------------
/hvplot/datasets.yaml:
--------------------------------------------------------------------------------
1 | sources:
2 | airline_flights:
3 | description: Airline Flight data
4 | driver: parquet
5 | cache:
6 | - argkey: urlpath
7 | regex: 'assets.holoviews.org/data/'
8 | type: file
9 | args:
10 | urlpath: 's3://assets.holoviews.org/data/airline_flights.parq'
11 | storage_options:
12 | anon: true
13 | client_kwargs: {'region_name': "eu-west-1"}
14 |
15 | us_crime:
16 | description: US Crime data
17 | driver: csv
18 | args:
19 | urlpath: '{{ CATALOG_DIR }}/data/crime.csv'
20 | metadata:
21 | url: https://web.archive.org/web/20201031163816/https://www.ucrdatatool.gov/Search/Crime/State/StatebyState.cfm
22 | plots:
23 | example:
24 | kind: line
25 | y: ['Robbery', 'Burglary']
26 | x: 'Year'
27 |
28 | landuse:
29 | description: Image matching given landuse and id from UCMerced_LandUse/Image.
30 | origin: http://weegee.vision.ucmerced.edu/datasets/landuse.html
31 | driver: xarray_image
32 | cache:
33 | - argkey: urlpath
34 | regex: 'earth-data/UCMerced_LandUse'
35 | type: file
36 | parameters:
37 | landuse:
38 | description: which landuse to collect
39 | type: str
40 | default: airplane
41 | id:
42 | description: which id to collect
43 | type: int
44 | default: 0
45 | args:
46 | urlpath: "s3://earth-data/UCMerced_LandUse/Images/{{ landuse }}/{{ landuse }}{{ '%02d' % id }}.tif"
47 | storage_options:
48 | anon: true
49 |
--------------------------------------------------------------------------------
/hvplot/duckdb.py:
--------------------------------------------------------------------------------
1 | """Adds the `.hvplot` method to duckdb.DuckDBPyRelation and duckdb.DuckDBPyConnection"""
2 |
3 |
4 | def patch(name='hvplot', interactive='interactive', extension='bokeh', logo=False):
5 | from hvplot.plotting.core import hvPlotTabularDuckDB
6 | from . import post_patch, _module_extensions
7 |
8 | if 'hvplot.duckdb' not in _module_extensions:
9 | try:
10 | import duckdb
11 | except ImportError:
12 | raise ImportError(
13 | 'Could not patch plotting API onto DuckDB. DuckDB could not be imported.'
14 | )
15 |
16 | # Patching for DuckDBPyRelation and DuckDBPyConnection
17 | _patch_duckdb_plot = lambda self: hvPlotTabularDuckDB(self) # noqa: E731
18 | _patch_duckdb_plot.__doc__ = hvPlotTabularDuckDB.__call__.__doc__
19 | plot_prop_duckdb = property(_patch_duckdb_plot)
20 | setattr(duckdb.DuckDBPyRelation, name, plot_prop_duckdb)
21 | setattr(duckdb.DuckDBPyConnection, name, plot_prop_duckdb)
22 | _module_extensions.add('hvplot.duckdb')
23 |
24 | post_patch(extension, logo)
25 |
26 |
27 | patch()
28 |
--------------------------------------------------------------------------------
/hvplot/fugue.py:
--------------------------------------------------------------------------------
1 | """
2 | Experimental support for fugue.
3 | """
4 |
5 | from typing import Any
6 |
7 | import panel as _pn
8 |
9 | from . import hvPlotTabular, post_patch, _module_extensions
10 | from .util import _fugue_ipython
11 |
12 |
13 | def patch(name='hvplot', extension='bokeh', logo=False):
14 | try:
15 | from fugue import DataFrames, Outputter
16 | from fugue.extensions import namespace_candidate, parse_outputter
17 | except ImportError:
18 | raise ImportError(
19 | 'Could not add fugue support as it could not be imported. '
20 | 'Please make sure you have installed fugue in your environment.'
21 | )
22 |
23 | import hvplot.pandas # noqa: F401
24 |
25 | class _Visualize(Outputter):
26 | def __init__(self, func: str) -> None:
27 | super().__init__()
28 | self._func = func
29 | getattr(hvPlotTabular, func) # ensure the func exists
30 |
31 | def process(self, dfs: DataFrames) -> None:
32 | """
33 | Process the dataframes and output the result as
34 | a pn.Column.
35 |
36 | Parameters:
37 | -----------
38 | dfs: fugue.DataFrames
39 | """
40 | charts = []
41 | for df in dfs.values():
42 | params = dict(self.params)
43 | opts: dict[str, Any] = params.pop('opts', {})
44 | chart = getattr(df.as_pandas().hvplot, self._func)(**params).opts(**opts)
45 | charts.append(chart)
46 | col = _pn.Column(*charts)
47 | try:
48 | if not _fugue_ipython:
49 | get_ipython()
50 | except NameError:
51 | col.show() # in script
52 | else:
53 | from IPython.display import display
54 |
55 | display(col) # in notebook
56 |
57 | if 'hvplot.fugue' not in _module_extensions:
58 |
59 | @parse_outputter.candidate(namespace_candidate(name, lambda x: isinstance(x, str)))
60 | def _parse_hvplot(obj: tuple[str, str]) -> Outputter:
61 | return _Visualize(obj[1])
62 |
63 | _module_extensions.add('hvplot.fugue')
64 |
65 | post_patch(extension, logo)
66 |
67 |
68 | patch()
69 |
--------------------------------------------------------------------------------
/hvplot/ibis.py:
--------------------------------------------------------------------------------
1 | """
2 | Experimental support for ibis.
3 | """
4 |
5 |
6 | def patch(name='hvplot', extension='bokeh', logo=False):
7 | from . import hvPlotTabular, post_patch, _module_extensions
8 |
9 | try:
10 | import ibis
11 | except ImportError:
12 | raise ImportError('Could not patch plotting API onto ibis. Ibis could not be imported.')
13 |
14 | if 'hvplot.ibis' not in _module_extensions:
15 | _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
16 | _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
17 | patch_property = property(_patch_plot)
18 | setattr(ibis.Expr, name, patch_property)
19 |
20 | _module_extensions.add('hvplot.ibis')
21 |
22 | post_patch(extension, logo)
23 |
24 |
25 | patch()
26 |
--------------------------------------------------------------------------------
/hvplot/intake.py:
--------------------------------------------------------------------------------
1 | from packaging.version import Version
2 |
3 | from . import hvPlot, post_patch, _module_extensions
4 |
5 |
6 | def patch(name='hvplot', extension='bokeh', logo=False):
7 | try:
8 | import intake
9 | except ImportError:
10 | raise ImportError(
11 | 'Could not patch plotting API onto intake. intake could not be imported.'
12 | )
13 |
14 | if 'hvplot.intake' not in _module_extensions:
15 | _patch_plot = lambda self: hvPlot(self) # noqa: E731
16 | _patch_plot.__doc__ = hvPlot.__call__.__doc__
17 | patch_property = property(_patch_plot)
18 | setattr(intake.source.base.DataSource, name, patch_property)
19 |
20 | _module_extensions.add('hvplot.intake')
21 |
22 | post_patch(extension, logo)
23 |
24 |
25 | try:
26 | import intake.plotting # noqa
27 |
28 | patch()
29 | except Exception:
30 | import intake
31 |
32 | if Version(intake.__version__) <= Version('0.1.5'):
33 | patch()
34 | patch(name='plot')
35 | else:
36 | post_patch(extension='bokeh', logo=False)
37 |
--------------------------------------------------------------------------------
/hvplot/pandas.py:
--------------------------------------------------------------------------------
1 | """Adds the `.hvplot` method to pd.DataFrame and pd.Series"""
2 |
3 | from .interactive import Interactive
4 |
5 |
6 | def patch(name='hvplot', interactive='interactive', extension='bokeh', logo=False):
7 | from . import hvPlotTabular, post_patch, _module_extensions
8 |
9 | try:
10 | import pandas as pd
11 | except ImportError:
12 | raise ImportError(
13 | 'Could not patch plotting API onto pandas. Pandas could not be imported.'
14 | )
15 |
16 | if 'hvplot.pandas' not in _module_extensions:
17 | _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
18 | _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
19 | plot_prop = property(_patch_plot)
20 | setattr(pd.DataFrame, name, plot_prop)
21 | setattr(pd.Series, name, plot_prop)
22 |
23 | _patch_interactive = lambda self: Interactive(self) # noqa: E731
24 | _patch_interactive.__doc__ = Interactive.__call__.__doc__
25 | interactive_prop = property(_patch_interactive)
26 | setattr(pd.DataFrame, interactive, interactive_prop)
27 | setattr(pd.Series, interactive, interactive_prop)
28 | _module_extensions.add('hvplot.pandas')
29 |
30 | post_patch(extension, logo)
31 |
32 |
33 | patch()
34 |
--------------------------------------------------------------------------------
/hvplot/plotting/__init__.py:
--------------------------------------------------------------------------------
1 | import warnings
2 |
3 | import holoviews as hv
4 | from ..util import with_hv_extension, is_duckdb, is_polars, _find_stack_level
5 |
6 | from .core import hvPlot, hvPlotTabular # noqa
7 |
8 | from .andrews_curves import andrews_curves # noqa
9 | from .parallel_coordinates import parallel_coordinates # noqa
10 | from .lag_plot import lag_plot # noqa
11 | from .scatter_matrix import scatter_matrix # noqa
12 |
13 |
14 | @with_hv_extension
15 | def plot(data, kind, **kwargs):
16 | # drop reuse_plot
17 | kwargs.pop('reuse_plot', None)
18 |
19 | # replace with shared_axes
20 | sharex = kwargs.pop('sharex', None)
21 | sharey = kwargs.pop('sharey', None)
22 | if sharex is not None and sharey is not None:
23 | kwargs['shared_axes'] = sharex or sharey
24 | elif sharex is not None:
25 | kwargs['shared_axes'] = sharex
26 | elif sharey is not None:
27 | kwargs['shared_axes'] = sharey
28 |
29 | # drop all kwargs that are set to None
30 | no_none_kwargs = {}
31 | for k, v in kwargs.items():
32 | if v is not None:
33 | no_none_kwargs[k] = v
34 |
35 | if is_polars(data):
36 | from .core import hvPlotTabularPolars
37 |
38 | return hvPlotTabularPolars(data)(kind=kind, **no_none_kwargs)
39 |
40 | elif is_duckdb(data):
41 | warnings.warn(
42 | 'Allowing to pass DuckDB data objects to the plot function is '
43 | 'deprecated and will be removed in a future version. '
44 | 'Use `import hvplot.duckdb` instead.',
45 | FutureWarning,
46 | stacklevel=_find_stack_level(),
47 | )
48 | from .core import hvPlotTabularDuckDB
49 |
50 | return hvPlotTabularDuckDB(data)(kind=kind, **no_none_kwargs)
51 | return hvPlotTabular(data)(kind=kind, **no_none_kwargs)
52 |
53 |
54 | def boxplot_series(*args, **kwargs):
55 | return plot(*args, kind='box', **kwargs)
56 |
57 |
58 | def boxplot_frame(*args, **kwargs):
59 | return plot(*args, kind='box', **kwargs)
60 |
61 |
62 | def boxplot_frame_groupby(grouped, **kwargs):
63 | width = kwargs.pop('width', 300)
64 | subplots = kwargs.pop('subplots', True)
65 | layout = hv.Layout if subplots else hv.Overlay
66 | plots = [
67 | plot(data=data, kind='box', title=name, width=width, **kwargs) for name, data in grouped
68 | ]
69 | return layout(plots)
70 |
71 |
72 | def hist_series(*args, **kwargs):
73 | return plot(*args, kind='hist', **kwargs)
74 |
75 |
76 | def hist_frame(*args, **kwargs):
77 | return plot(*args, kind='hist', **kwargs)
78 |
--------------------------------------------------------------------------------
/hvplot/plotting/andrews_curves.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 | import holoviews as hv
5 | import colorcet as cc
6 |
7 | from ..backend_transforms import _transfer_opts_cur_backend
8 | from ..util import with_hv_extension
9 |
10 |
11 | @with_hv_extension
12 | def andrews_curves(
13 | data,
14 | class_column,
15 | samples=200,
16 | alpha=0.5,
17 | width=600,
18 | height=300,
19 | cmap=None,
20 | colormap=None,
21 | **kwds,
22 | ):
23 | """
24 | Generate a plot of Andrews curves, for visualising clusters of
25 | multivariate data.
26 |
27 | Andrews curves have the functional form:
28 |
29 | .. math::
30 | f(t) = \\frac{x_1}{\\sqrt{2}} + x_2 \\sin(t) + x_3 \\cos(t) +
31 | x_4 \\sin(2t) + x_5 \\cos(2t) + \\cdots
32 |
33 | Where :math:`x` coefficients correspond to the values of each dimension
34 | and :math:`t` is linearly spaced between :math:`-\\pi` and :math:`+\\pi`.
35 | Each row of frame then corresponds to a single curve.
36 |
37 | Parameters
38 | ----------
39 | frame : DataFrame
40 | Data to be plotted, preferably normalized to (0.0, 1.0)
41 | class_column : str
42 | Column name containing class names
43 | samples : int, optional
44 | Number of samples to draw
45 | alpha : float, optional
46 | The transparency of the lines
47 | cmap/colormap : str or colormap object
48 | Colormap to use for groups
49 |
50 | Returns
51 | -------
52 | obj : HoloViews object
53 | The HoloViews representation of the plot.
54 |
55 | See Also
56 | --------
57 | pandas.plotting.parallel_coordinates : matplotlib version of this routine
58 | """
59 | t = np.linspace(-np.pi, np.pi, samples)
60 | vals = data.drop(class_column, axis=1).values.T
61 |
62 | curves = np.outer(vals[0] / np.sqrt(2), np.ones_like(t))
63 | for i in range(1, len(vals)):
64 | ft = ((i + 1) // 2) * t
65 | if i % 2 == 1:
66 | curves += np.outer(vals[i], np.sin(ft))
67 | else:
68 | curves += np.outer(vals[i], np.cos(ft))
69 |
70 | df = pd.DataFrame(
71 | {
72 | 't': np.tile(t, curves.shape[0]),
73 | 'sample': np.repeat(np.arange(curves.shape[0]), curves.shape[1]),
74 | 'value': curves.ravel(),
75 | class_column: np.repeat(data[class_column], samples),
76 | }
77 | )
78 |
79 | labelled = ['x']
80 | options = {
81 | 'Overlay': dict(legend_limit=5000),
82 | 'Curve': dict(kwds, labelled=labelled, alpha=alpha, width=width, height=height, **kwds),
83 | }
84 | dataset = hv.Dataset(df)
85 | groups = dataset.to(hv.Curve, 't', 'value').overlay('sample').items()
86 |
87 | if cmap and colormap:
88 | raise TypeError('Only specify one of `cmap` and `colormap`.')
89 | cmap = cmap or colormap or cc.palette['glasbey_category10']
90 | colors = hv.plotting.util.process_cmap(cmap, categorical=True, ncolors=len(groups))
91 |
92 | el = hv.Overlay(
93 | [
94 | curve.relabel(k).options('Curve', color=c, backend='bokeh')
95 | for c, (k, v) in zip(colors, groups)
96 | for curve in v
97 | ]
98 | ).options(options, backend='bokeh')
99 | el = _transfer_opts_cur_backend(el)
100 | return el
101 |
--------------------------------------------------------------------------------
/hvplot/plotting/lag_plot.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 |
4 | from ..util import with_hv_extension
5 | from .core import hvPlotTabular
6 |
7 |
8 | @with_hv_extension
9 | def lag_plot(data, lag=1, **kwds):
10 | """Lag plot for time series.
11 |
12 | A lag plot is a scatter plot of a time series against a lag of itself. It helps
13 | in visualizing the temporal dependence between observations by plotting the values
14 | at time `t` on the x-axis and the values at time `t + lag` on the y-axis.
15 |
16 | Parameters
17 | ----------
18 | data : Series
19 | The time series to visualize.
20 | lag : int, default 1
21 | Lag length of the scatter plot.
22 | **kwds : optional
23 | hvplot.scatter options
24 |
25 | Returns
26 | -------
27 | obj : HoloViews object
28 | The HoloViews representation of the plot.
29 | """
30 | if lag != int(lag) or int(lag) <= 0:
31 | raise ValueError('lag must be a positive integer')
32 | lag = int(lag)
33 |
34 | values = data.values
35 | y1 = 'y(t)'
36 | y2 = f'y(t + {lag})'
37 | lags = pd.DataFrame({y1: values[:-lag].T.ravel(), y2: values[lag:].T.ravel()})
38 | if isinstance(data, pd.DataFrame):
39 | lags['variable'] = np.repeat(data.columns, lags.shape[0] / data.shape[1])
40 | kwds['c'] = 'variable'
41 | return hvPlotTabular(lags)(y1, y2, kind='scatter', **kwds)
42 |
--------------------------------------------------------------------------------
/hvplot/plotting/parallel_coordinates.py:
--------------------------------------------------------------------------------
1 | import holoviews as hv
2 | import colorcet as cc
3 |
4 | from ..backend_transforms import _transfer_opts_cur_backend
5 | from ..util import with_hv_extension
6 |
7 |
8 | @with_hv_extension
9 | def parallel_coordinates(
10 | data,
11 | class_column,
12 | cols=None,
13 | alpha=0.5,
14 | width=600,
15 | height=300,
16 | var_name='variable',
17 | value_name='value',
18 | cmap=None,
19 | colormap=None,
20 | **kwds,
21 | ):
22 | """
23 | Parallel coordinates plotting.
24 |
25 | To show a set of points in an n-dimensional space, a backdrop is drawn
26 | consisting of n parallel lines. A point in n-dimensional space is
27 | represented as a polyline with vertices on the parallel axes; the
28 | position of the vertex on the i-th axis corresponds to the i-th coordinate
29 | of the point.
30 |
31 | Parameters
32 | ----------
33 | frame : DataFrame
34 | The DataFrame to be plotted.
35 | class_column : str
36 | Column name containing class names
37 | cols : list, optional
38 | A list of column names to use
39 | alpha : float, optional
40 | The transparency of the lines
41 | cmap/colormap : str or colormap object
42 | Colormap to use for groups
43 |
44 | Returns
45 | -------
46 | obj : HoloViews object
47 | The HoloViews representation of the plot.
48 |
49 | See Also
50 | --------
51 | pandas.plotting.parallel_coordinates : matplotlib version of this routine
52 | """
53 | # Transform the dataframe to be used in Vega-Lite
54 | if cols is not None:
55 | data = data[list(cols) + [class_column]]
56 | cols = data.columns
57 | df = data.reset_index()
58 | index = (set(df.columns) - set(cols)).pop()
59 | assert index in df.columns
60 | df = df.melt([index, class_column], var_name=var_name, value_name=value_name)
61 |
62 | labelled = [] if var_name == 'variable' else ['x']
63 | if value_name != 'value':
64 | labelled.append('y')
65 | options = {
66 | 'Curve': dict(kwds, labelled=labelled, alpha=alpha, width=width, height=height),
67 | 'Overlay': dict(legend_limit=5000),
68 | }
69 |
70 | dataset = hv.Dataset(df)
71 | groups = dataset.to(hv.Curve, var_name, value_name).overlay(index).items()
72 |
73 | if cmap and colormap:
74 | raise TypeError('Only specify one of `cmap` and `colormap`.')
75 | cmap = cmap or colormap or cc.palette['glasbey_category10']
76 | colors = hv.plotting.util.process_cmap(cmap, categorical=True, ncolors=len(groups))
77 |
78 | el = hv.Overlay(
79 | [
80 | curve.relabel(k).options('Curve', color=c, backend='bokeh')
81 | for c, (k, v) in zip(colors, groups)
82 | for curve in v
83 | ]
84 | ).options(options, backend='bokeh')
85 | el = _transfer_opts_cur_backend(el)
86 | return el
87 |
--------------------------------------------------------------------------------
/hvplot/polars.py:
--------------------------------------------------------------------------------
1 | """Adds the `.hvplot` method to pl.DataFrame, pl.LazyFrame and pl.Series"""
2 |
3 | from hvplot import post_patch, _module_extensions
4 | from hvplot.plotting.core import hvPlotTabularPolars
5 |
6 |
7 | def patch(name='hvplot', extension='bokeh', logo=False):
8 | try:
9 | import polars as pl
10 | except ImportError:
11 | raise ImportError(
12 | 'Could not patch plotting API onto Polars. Polars could not be imported.'
13 | )
14 | if 'hvplot.polars' not in _module_extensions:
15 | pl.api.register_dataframe_namespace(name)(hvPlotTabularPolars)
16 | pl.api.register_series_namespace(name)(hvPlotTabularPolars)
17 | pl.api.register_lazyframe_namespace(name)(hvPlotTabularPolars)
18 | _module_extensions.add('hvplot.polars')
19 |
20 | post_patch(extension, logo)
21 |
22 |
23 | patch()
24 |
--------------------------------------------------------------------------------
/hvplot/sample_data.py:
--------------------------------------------------------------------------------
1 | """
2 | Loads hvPlot sample data using intake catalogue.
3 | """
4 |
5 | import os
6 |
7 | try:
8 | from intake import open_catalog
9 | import intake_parquet # noqa
10 | import intake_xarray # noqa
11 | import s3fs # noqa
12 | except ImportError:
13 | raise ImportError(
14 | """Loading hvPlot sample data requires:
15 | * intake
16 | * intake-parquet
17 | * intake-xarray
18 | * s3fs
19 | Install these using conda or pip before loading data."""
20 | )
21 |
22 | _file_path = os.path.dirname(__file__)
23 | _cat_path = os.path.join(_file_path, 'datasets.yaml')
24 |
25 | # Load catalogue
26 | catalogue = open_catalog(_cat_path)
27 |
28 | # Add catalogue entries to namespace
29 | for _c in catalogue:
30 | globals()[_c] = catalogue[_c]
31 |
--------------------------------------------------------------------------------
/hvplot/streamz.py:
--------------------------------------------------------------------------------
1 | def patch(name='hvplot', extension='bokeh', logo=False):
2 | from . import hvPlotTabular, post_patch, _module_extensions
3 |
4 | try:
5 | import streamz.dataframe as sdf
6 | except ImportError:
7 | raise ImportError(
8 | 'Could not patch plotting API onto streamz. Streamz could not be imported.'
9 | )
10 | if 'hvplot.streamz' not in _module_extensions:
11 | _patch_plot = lambda self: hvPlotTabular(self) # noqa: E731
12 | _patch_plot.__doc__ = hvPlotTabular.__call__.__doc__
13 | patch_property = property(_patch_plot)
14 | setattr(sdf.DataFrame, name, patch_property)
15 | setattr(sdf.DataFrames, name, patch_property)
16 | setattr(sdf.Series, name, patch_property)
17 | setattr(sdf.Seriess, name, patch_property)
18 |
19 | _module_extensions.add('hvplot.streamz')
20 |
21 | post_patch(extension, logo)
22 |
23 |
24 | patch()
25 |
--------------------------------------------------------------------------------
/hvplot/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/hvplot/tests/__init__.py
--------------------------------------------------------------------------------
/hvplot/tests/conftest.py:
--------------------------------------------------------------------------------
1 | import dask
2 | import param
3 | import pytest
4 |
5 | from packaging.version import Version
6 |
7 | param.parameterized.warnings_as_exceptions = True
8 |
9 | optional_markers = {
10 | 'geo': {
11 | 'help': 'Run the tests that require GeoViews',
12 | 'marker-descr': 'Geo test marker',
13 | 'skip-reason': 'Test only runs with the --geo option.',
14 | },
15 | }
16 |
17 |
18 | def pytest_addoption(parser):
19 | for marker, info in optional_markers.items():
20 | parser.addoption(f'--{marker}', action='store_true', default=False, help=info['help'])
21 |
22 |
23 | def pytest_configure(config):
24 | for marker, info in optional_markers.items():
25 | config.addinivalue_line('markers', '{}: {}'.format(marker, info['marker-descr']))
26 |
27 |
28 | def pytest_collection_modifyitems(config, items):
29 | skipped, selected = [], []
30 | markers = [m for m in optional_markers if config.getoption(f'--{m}')]
31 | empty = not markers
32 | for item in items:
33 | if empty and any(m in item.keywords for m in optional_markers):
34 | skipped.append(item)
35 | elif empty:
36 | selected.append(item)
37 | elif not empty and any(m in item.keywords for m in markers):
38 | selected.append(item)
39 | else:
40 | skipped.append(item)
41 |
42 | config.hook.pytest_deselected(items=skipped)
43 | items[:] = selected
44 |
45 |
46 | if Version(dask.__version__).release < (2025, 1, 0):
47 | # From Dask 2024.3.0 they now use `dask_expr` by default
48 | # https://github.com/dask/dask/issues/10995
49 | dask.config.set({'dataframe.query-planning': False})
50 |
51 |
52 | @pytest.fixture
53 | def disable_param_warnings_as_exceptions():
54 | original = param.parameterized.warnings_as_exceptions
55 | param.parameterized.warnings_as_exceptions = False
56 | try:
57 | yield
58 | finally:
59 | param.parameterized.warnings_as_exceptions = original
60 |
--------------------------------------------------------------------------------
/hvplot/tests/data/README.md:
--------------------------------------------------------------------------------
1 | # Test data
2 |
3 | Test files required by the test suite:
4 |
5 | * The RGB-red.byte.tif file was obtained from [rasterio](https://github.com/rasterio/rasterio) test suite and downsampled to reduce its size. The original image is derived from USGS Landsat 7 ETM imagery and is licensed under the [CC0 1.0 Universal (CC0 1.0) Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/).
6 |
--------------------------------------------------------------------------------
/hvplot/tests/data/RGB-red.byte.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/hvplot/tests/data/RGB-red.byte.tif
--------------------------------------------------------------------------------
/hvplot/tests/plotting/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holoviz/hvplot/25e6456e3fab40205f442b1df41f6422e560808f/hvplot/tests/plotting/__init__.py
--------------------------------------------------------------------------------
/hvplot/tests/plotting/testandrewscurves.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 | import pytest
4 |
5 | from hvplot.plotting import andrews_curves
6 |
7 |
8 | @pytest.fixture
9 | def df():
10 | return pd.DataFrame(
11 | {
12 | 'class': ['A', 'B', 'C'],
13 | 'x': [0, 2, 1],
14 | 'y': [1, 1, 2],
15 | 'z': [2, 1, 1],
16 | }
17 | )
18 |
19 |
20 | def test_andrews_curves_x_axis_data(df):
21 | curves = andrews_curves(df, 'class')
22 | assert len(curves) == len(df)
23 | c1 = curves.get(('Curve', 'A'))
24 | assert c1.data['t'].between(-np.pi, np.pi).all()
25 |
--------------------------------------------------------------------------------
/hvplot/tests/plotting/testcore.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 | import hvplot.pandas # noqa
4 | import pytest
5 |
6 | from hvplot import hvPlotTabular
7 | from hvplot.tests.util import makeDataFrame
8 |
9 | try:
10 | import polars as pl
11 | import hvplot.polars # noqa
12 |
13 | skip_polar = False
14 | except ImportError:
15 |
16 | class pl:
17 | DataFrame = None
18 | LazyFrame = None
19 | Series = None
20 |
21 | skip_polar = True
22 |
23 | try:
24 | import dask.dataframe as dd
25 | import hvplot.dask # noqa
26 | except ImportError:
27 | dd = None
28 |
29 |
30 | TYPES = {t for t in dir(hvPlotTabular) if not t.startswith('_') and t != 'explorer'}
31 | FRAME_TYPES = TYPES - {'bivariate', 'heatmap', 'hexbin', 'labels', 'vectorfield'}
32 | SERIES_TYPES = FRAME_TYPES - {'points', 'polygons', 'ohlc', 'paths'}
33 | frame_kinds = pytest.mark.parametrize('kind', sorted(FRAME_TYPES))
34 | series_kinds = pytest.mark.parametrize('kind', sorted(SERIES_TYPES))
35 |
36 | y_combinations = pytest.mark.parametrize(
37 | 'y',
38 | (
39 | ['A', 'B', 'C', 'D'],
40 | ('A', 'B', 'C', 'D'),
41 | {'A', 'B', 'C', 'D'},
42 | np.array(['A', 'B', 'C', 'D']),
43 | pd.Index(['A', 'B', 'C', 'D']),
44 | pd.Series(['A', 'B', 'C', 'D']),
45 | ),
46 | ids=lambda x: type(x).__name__,
47 | )
48 |
49 |
50 | @frame_kinds
51 | @y_combinations
52 | def test_dataframe_pandas(kind, y):
53 | df = makeDataFrame()
54 | df.hvplot(y=y, kind=kind)
55 |
56 |
57 | @series_kinds
58 | def test_series_pandas(kind):
59 | ser = pd.Series(np.random.rand(10), name='A')
60 | ser.hvplot(kind=kind)
61 |
62 |
63 | @pytest.mark.skipif(dd is None, reason='dask not installed')
64 | @frame_kinds
65 | @y_combinations
66 | def test_dataframe_dask(kind, y):
67 | df = dd.from_pandas(makeDataFrame(), npartitions=2)
68 | assert isinstance(df, dd.DataFrame)
69 | df.hvplot(y=y, kind=kind)
70 |
71 |
72 | @pytest.mark.skipif(dd is None, reason='dask not installed')
73 | @series_kinds
74 | def test_series_dask(kind):
75 | ser = dd.from_pandas(pd.Series(np.random.rand(10), name='A'), npartitions=2)
76 | assert isinstance(ser, dd.Series)
77 | ser.hvplot(kind=kind)
78 |
79 |
80 | @pytest.mark.skipif(skip_polar, reason='polars not installed')
81 | @pytest.mark.parametrize('cast', (pl.DataFrame, pl.LazyFrame))
82 | @frame_kinds
83 | @y_combinations
84 | def test_dataframe_polars(kind, y, cast):
85 | df = cast(makeDataFrame())
86 | assert isinstance(df, cast)
87 | df.hvplot(y=y, kind=kind)
88 |
89 |
90 | @pytest.mark.skipif(skip_polar, reason='polars not installed')
91 | @series_kinds
92 | def test_series_polars(kind):
93 | ser = pl.Series(values=np.random.rand(10), name='A')
94 | assert isinstance(ser, pl.Series)
95 | ser.hvplot(kind=kind)
96 |
--------------------------------------------------------------------------------
/hvplot/tests/plotting/testohlc.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 | import hvplot.pandas # noqa
3 |
4 |
5 | df = pd.DataFrame(
6 | {
7 | 'Open': [100.00, 101.25, 102.75],
8 | 'High': [104.10, 105.50, 110.00],
9 | 'Low': [94.00, 97.10, 99.20],
10 | 'Close': [101.15, 99.70, 109.50],
11 | 'Volume': [10012, 5000, 18000],
12 | },
13 | index=[pd.Timestamp('2022-08-01'), pd.Timestamp('2022-08-03'), pd.Timestamp('2022-08-04')],
14 | )
15 |
16 | ohlc_cols = ['Open', 'High', 'Low', 'Close']
17 |
18 |
19 | def test_ohlc_hover_cols():
20 | plot = df.hvplot.ohlc(y=ohlc_cols, hover_cols=['Volume'])
21 | segments = plot.Segments.I
22 | assert 'Volume' in segments
23 | tooltips = segments.opts.get('plot').kwargs['tools'][0].tooltips
24 | assert len(tooltips) == len(df.columns) + 1
25 | assert tooltips[-1] == ('Volume', '@Volume')
26 |
27 |
28 | def test_ohlc_hover_cols_all():
29 | plot = df.hvplot.ohlc(y=ohlc_cols, hover_cols='all')
30 | segments = plot.Segments.I
31 | assert 'Volume' in segments
32 | tooltips = segments.opts.get('plot').kwargs['tools'][0].tooltips
33 | assert len(tooltips) == len(df.columns) + 1
34 | assert tooltips[-1] == ('Volume', '@Volume')
35 |
36 |
37 | def test_ohlc_date_tooltip_format():
38 | plot = df.hvplot.ohlc(y=ohlc_cols)
39 | segments = plot.Segments.I
40 | hover_tool = segments.opts.get('plot').kwargs['tools'][0]
41 | tooltips = hover_tool.tooltips
42 | x_label, x_tooltip = tooltips[0]
43 | assert '{%F %T}' in x_tooltip
44 | formatter_key = '@' + x_label
45 | formatter = hover_tool.formatters
46 | assert formatter[formatter_key] == 'datetime'
47 |
48 |
49 | def test_ohlc_non_datetime_x_axis():
50 | df = pd.DataFrame(
51 | {
52 | 'Open': [100.00, 101.25, 102.75],
53 | 'High': [104.10, 105.50, 110.00],
54 | 'Low': [94.00, 97.10, 99.20],
55 | 'Close': [101.15, 99.70, 109.50],
56 | 'Volume': [10012, 5000, 18000],
57 | },
58 | index=[1, 2, 3],
59 | )
60 |
61 | ohlc_cols = ['Open', 'High', 'Low', 'Close']
62 |
63 | plot = df.hvplot.ohlc(y=ohlc_cols)
64 | segments = plot.Segments.I
65 | hover_tool = segments.opts.get('plot').kwargs['tools'][0]
66 | tooltips = hover_tool.tooltips
67 | x_label, x_tooltip = tooltips[0]
68 | assert '{%F}' not in x_tooltip
69 | formatter_key = '@' + x_label
70 | assert formatter_key not in hover_tool.formatters
71 |
72 |
73 | def test_ohlc_non_index_date_col():
74 | df = pd.DataFrame(
75 | {
76 | 'Date': [
77 | pd.Timestamp('2022-08-01'),
78 | pd.Timestamp('2022-08-03'),
79 | pd.Timestamp('2022-08-04'),
80 | ],
81 | 'Open': [100.00, 101.25, 102.75],
82 | 'High': [104.10, 105.50, 110.00],
83 | 'Low': [94.00, 97.10, 99.20],
84 | 'Close': [101.15, 99.70, 109.50],
85 | 'Volume': [10012, 5000, 18000],
86 | },
87 | )
88 | plot = df.hvplot.ohlc(hover_cols='all', use_index=False)
89 | segments = plot.Segments.I
90 | hover_tool = segments.opts.get('plot').kwargs['tools'][0]
91 | tooltips = hover_tool.tooltips
92 | assert len(tooltips) == len(df.columns)
93 | assert tooltips[0] == ('Date', '@Date{%F %T}')
94 |
--------------------------------------------------------------------------------
/hvplot/tests/test_links.py:
--------------------------------------------------------------------------------
1 | """Urls in docstrings etc. should be valid and secure, i.e.
2 |
3 | - exist, i.e. provide a 200 response
4 | - use https:// instead of http:// unless
5 | - https:// is not supported by the web site
6 | - https:// cannot be used. For example in SVGs.
7 | """
8 |
9 | import pathlib
10 | import re
11 | from concurrent.futures import ThreadPoolExecutor, as_completed
12 | from urllib.request import urlopen
13 | import glob
14 |
15 | import pytest
16 |
17 | # Note: The regex will find urls from code cells in notebooks ending with '\\' because the are really inside \"some_url\"
18 | URL_REGEX = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))" # pylint: disable=line-too-long
19 | ROOT = pathlib.Path(__file__).parent
20 | PACKAGE_ROOT = ROOT.parent
21 | MAX_WORKERS = 10
22 | POST_FIXES = ['.py', '.ipynb', '.md', '.yaml']
23 | SKIP_URLS = [
24 | 'https://anaconda.org/anaconda/hvplot',
25 | 'https://anaconda.org/conda-forge/hvplot',
26 | 'https://anaconda.org/pyviz/hvplot',
27 | 'https://creativecommons.org/publicdomain/zero/1.0/',
28 | 'https://github.com/rasterio/rasterio',
29 | 'https://www.dask.org',
30 | 'pyproject.toml/equivalent',
31 | ]
32 |
33 |
34 | def _get_files_to_check():
35 | for post_fix in POST_FIXES:
36 | for file in glob.glob('**/*' + post_fix, recursive=True):
37 | yield pathlib.Path(file)
38 |
39 |
40 | FIXTURES = [pytest.param(file, id=str(file)) for file in _get_files_to_check()]
41 |
42 |
43 | def _skip_url(url: str):
44 | if url in SKIP_URLS:
45 | return True
46 | if url.startswith('https://github.com/holoviz/hvplot/pull/'):
47 | return True
48 | if url.startswith('https://img.shields.io'):
49 | return True
50 | if url.startswith('assets.holoviews.org/data/'):
51 | return True
52 | if url.startswith('Math.PI'):
53 | return True
54 | return False
55 |
56 |
57 | def _clean_url(url: str):
58 | if url.endswith('\\'):
59 | return url[0:-1]
60 | return url
61 |
62 |
63 | def _find_urls(text):
64 | url = re.findall(URL_REGEX, text)
65 | return {_clean_url(x[0]) for x in url if not _skip_url(x[0])}
66 |
67 |
68 | def _request_a_response(url):
69 | return urlopen(url)
70 |
71 |
72 | def _verify_urls(urls):
73 | """Returns True if all urls are valid"""
74 | futures = {}
75 | with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
76 | futures = {}
77 | for url in urls:
78 | futures[executor.submit(_request_a_response, url)] = url
79 |
80 | for future in as_completed(futures):
81 | url = futures[future]
82 | try:
83 | result = future.result()
84 | except Exception as ex:
85 | raise ValueError(f'The url {url} raised an exception') from ex
86 | if not result.status == 200:
87 | raise ValueError(f'The url {url} responded with status {result.status}, not 200.')
88 |
89 | return True
90 |
91 |
92 | # @pytest.mark.parametrize(["file"], FIXTURES)
93 | # def test_urls(file: pathlib.Path):
94 | # """The urls is docstring should be valid"""
95 | # # Given
96 | # text = file.read_text()
97 | # urls = _find_urls(text)
98 | # # When/ Then
99 | # assert _verify_urls(urls)
100 |
--------------------------------------------------------------------------------
/hvplot/tests/testbackend_transforms.py:
--------------------------------------------------------------------------------
1 | import holoviews
2 | import pytest
3 | from holoviews.core import Store
4 | from holoviews.element import Area, Curve
5 |
6 | from hvplot.backend_transforms import (
7 | _transfer_opts,
8 | _transform_size_to_mpl,
9 | _is_interactive_opt,
10 | )
11 |
12 |
13 | @pytest.mark.parametrize(
14 | ('width', 'height', 'aspect', 'opts'),
15 | (
16 | (300, 100, None, {'aspect': 3.0, 'fig_size': 100.0}),
17 | (300, None, 3, {'aspect': 3, 'fig_size': 100.0}),
18 | (None, 300, 3, {'aspect': 3, 'fig_size': 100.0}),
19 | (300, None, None, {'fig_size': 100.0}),
20 | (None, 300, None, {'fig_size': 100.0}),
21 | ),
22 | )
23 | def test_transform_size_to_mpl(width, height, aspect, opts):
24 | assert _transform_size_to_mpl(width, height, aspect) == opts
25 |
26 |
27 | @pytest.mark.parametrize(
28 | ('element', 'opt', 'val', 'backend', 'opt_kind', 'transf_opt', 'transf_val'),
29 | (
30 | (Curve([]), 'line_dash', 'dashed', 'matplotlib', 'style', 'linestyle', 'dashed'),
31 | (Curve([]), 'line_alpha', 0.123, 'matplotlib', 'style', None, None),
32 | (Area([]), 'line_cap', 'square', 'matplotlib', 'style', 'capstyle', 'projecting'),
33 | (Curve([]), 'line_dash', 'dashed', 'plotly', 'style', 'dash', 'dash'),
34 | ),
35 | )
36 | def test_transfer_opts(element, opt, val, backend, opt_kind, transf_opt, transf_val):
37 | current_backend = Store.current_backend
38 | if backend not in Store.registry:
39 | holoviews.extension(backend)
40 | Store.set_current_backend(backend)
41 | try:
42 | element = element.opts(backend='bokeh', **{opt: val})
43 | new_element = element.apply(_transfer_opts, backend=backend)
44 | new_opts = new_element.opts.get(opt_kind).kwargs
45 | if transf_opt is None:
46 | assert val not in new_opts.values()
47 | else:
48 | assert transf_opt in new_opts
49 | assert new_opts[transf_opt] == transf_val
50 | finally:
51 | Store.set_current_backend(current_backend)
52 |
53 |
54 | @pytest.mark.parametrize(
55 | ('opt', 'val', 'backend', 'opt_kind', 'transf_opt', 'transf_val'),
56 | (
57 | ('line_dash', 'dashed', 'matplotlib', 'style', 'linestyle', 'dashed'),
58 | ('line_dash', 'dashed', 'plotly', 'style', 'dash', 'dash'),
59 | ),
60 | )
61 | def test_transfer_opts_compositeoverlay(opt, val, backend, opt_kind, transf_opt, transf_val):
62 | current_backend = Store.current_backend
63 | if backend not in Store.registry:
64 | holoviews.extension(backend)
65 | Store.set_current_backend(backend)
66 | try:
67 | element = Area([]) * Curve([]).opts(backend='bokeh', **{opt: val})
68 | new_element = element.apply(_transfer_opts, backend=backend)
69 | transformed_element = new_element.Curve.I
70 | new_opts = transformed_element.opts.get(opt_kind).kwargs
71 | assert transf_opt in new_opts
72 | assert new_opts[transf_opt] == transf_val
73 | finally:
74 | Store.set_current_backend(current_backend)
75 |
76 |
77 | @pytest.mark.parametrize(
78 | ('bk_option', 'expected'),
79 | (
80 | ('height', False),
81 | ('hover_line_alpha', True),
82 | ('nonselection_line_alpha', True),
83 | ('muted_line_alpha', True),
84 | ('selection_line_alpha', True),
85 | ('annular_muted_alpha', True),
86 | ),
87 | )
88 | def test_is_interactive_opt(bk_option, expected):
89 | assert _is_interactive_opt(bk_option) == expected
90 |
--------------------------------------------------------------------------------
/hvplot/tests/testdeprecations.py:
--------------------------------------------------------------------------------
1 | """
2 | Tests for deprecation warnings.
3 | """
4 |
5 | import pandas as pd
6 | import pytest
7 |
8 | from hvplot.converter import HoloViewsConverter
9 | from hvplot.plotting import plot
10 | from hvplot.tests.util import makeDataFrame
11 |
12 |
13 | def test_converter_argument_debug(disable_param_warnings_as_exceptions):
14 | df = pd.DataFrame({'x': [0, 1], 'y': [0, 1]})
15 | with pytest.warns(FutureWarning):
16 | HoloViewsConverter(df, 'x', 'y', debug=True)
17 |
18 |
19 | def test_plotting_plot_duckdb():
20 | duckdb = pytest.importorskip('duckdb')
21 | connection = duckdb.connect(':memory:')
22 | relation = duckdb.from_df(makeDataFrame(), connection=connection)
23 | with pytest.warns(FutureWarning):
24 | plot(relation, 'line')
25 |
--------------------------------------------------------------------------------
/hvplot/tests/testdocstring.py:
--------------------------------------------------------------------------------
1 | import itertools
2 |
3 | import pytest
4 |
5 | pytest.importorskip('numpydoc')
6 |
7 | from hvplot.converter import HoloViewsConverter # noqa: E402
8 | from hvplot.util import _get_docstring_group_parameters # noqa: E402
9 |
10 |
11 | @pytest.mark.parametrize('section', HoloViewsConverter._docstring_sections.values())
12 | def test_docstring_converter_sections_present(section):
13 | assert section in HoloViewsConverter.__doc__
14 |
15 |
16 | @pytest.mark.parametrize('section', HoloViewsConverter._docstring_sections.values())
17 | def test_docstring_converter_sections_include_parameters(section):
18 | assert _get_docstring_group_parameters(section)
19 |
20 |
21 | def parse_docstring_for_param_names(section_title):
22 | parameters = _get_docstring_group_parameters(section_title)
23 | parameter_names = []
24 | for param in parameters:
25 | sparams = param.name.split('/')
26 | parameter_names.extend(sparams)
27 | return parameter_names
28 |
29 |
30 | @pytest.mark.parametrize(
31 | 'section, options',
32 | [(k, v) for k, v in HoloViewsConverter._options_groups.items()],
33 | )
34 | def test_docstring_converter_options_match_per_section(section, options):
35 | section_title = HoloViewsConverter._docstring_sections[section]
36 | parameter_names = parse_docstring_for_param_names(section_title)
37 | assert set(options) == set(parameter_names)
38 |
39 |
40 | def test_docstring_converter_no_duplicate_and_match_options():
41 | all_doc_params = []
42 | for section_title in HoloViewsConverter._docstring_sections.values():
43 | params = parse_docstring_for_param_names(section_title)
44 | all_doc_params.extend(params)
45 |
46 | assert len(all_doc_params) == len(set(all_doc_params))
47 |
48 | all_options = list(itertools.chain(*HoloViewsConverter._options_groups.values()))
49 |
50 | assert len(all_options) == len(set(all_options))
51 |
52 | assert set(all_doc_params) == set(all_options)
53 |
--------------------------------------------------------------------------------
/hvplot/tests/testfugue.py:
--------------------------------------------------------------------------------
1 | """Fugue test suite"""
2 |
3 | import hvplot
4 | import pandas as pd
5 | import pytest
6 |
7 | # Patch required before importing hvplot.fugue
8 | hvplot.util._fugue_ipython = True
9 |
10 | try:
11 | import fugue.api as fa
12 | import fugue_sql_antlr # noqa: F401
13 | import hvplot.fugue # noqa: F401
14 | except ImportError:
15 | pytest.skip(allow_module_level=True)
16 |
17 |
18 | @pytest.fixture
19 | def table():
20 | df = pd.DataFrame(
21 | {
22 | 'g': ['a', 'b', 'a', 'b', 'a', 'b'],
23 | 'x': [1, 2, 3, 4, 5, 6],
24 | 'y': [1, 2, 3, 4, 5, 6],
25 | }
26 | )
27 | return df
28 |
29 |
30 | def test_fugure_ipython_line(table, capsys):
31 | """hvplot works with Fugue"""
32 | fa.fugue_sql(
33 | """
34 | OUTPUT table USING hvplot:line(
35 | x="x",
36 | y="y",
37 | by="g",
38 | size=100,
39 | opts={"width": 500, "height": 500}
40 | )
41 | """
42 | )
43 | # Check that the output contains the following:
44 | # Column
45 | # [0] HoloViews(NdOverlay)
46 | output = capsys.readouterr().out
47 | assert output == 'Column\n [0] HoloViews(NdOverlay)\n'
48 |
--------------------------------------------------------------------------------
/hvplot/tests/testgeowithoutgv.py:
--------------------------------------------------------------------------------
1 | """
2 | Geo tests **without** importing GeoViews.
3 | """
4 |
5 | import holoviews as hv
6 | import hvplot.pandas # noqa
7 | import numpy as np
8 | import pandas as pd
9 | import pytest
10 |
11 | from hvplot.util import is_geodataframe
12 |
13 | try:
14 | import dask.dataframe as dd
15 | import hvplot.dask # noqa
16 | except ImportError:
17 | dd = None
18 |
19 | try:
20 | import spatialpandas as spd
21 | except ModuleNotFoundError:
22 | spd = None
23 |
24 |
25 | bk_renderer = hv.Store.renderers['bokeh']
26 |
27 |
28 | @pytest.fixture
29 | def simple_df():
30 | return pd.DataFrame(np.random.rand(10, 2), columns=['x', 'y'])
31 |
32 |
33 | class TestAnnotationNotGeo:
34 | def test_plot_tiles_doesnt_set_geo(self, simple_df):
35 | plot = simple_df.hvplot.points('x', 'y', tiles=True)
36 | assert len(plot) == 2
37 | assert isinstance(plot.get(0), hv.Tiles)
38 | assert 'openstreetmap' in plot.get(0).data
39 | assert 'x_' in plot.get(1).data
40 | assert 'y_' in plot.get(1).data
41 | bk_plot = bk_renderer.get_plot(plot)
42 | assert bk_plot.projection == 'mercator'
43 |
44 | def test_plot_specific_tiles_doesnt_set_geo(self, simple_df):
45 | plot = simple_df.hvplot.points('x', 'y', tiles='ESRI')
46 | assert len(plot) == 2
47 | assert isinstance(plot.get(0), hv.Tiles)
48 | assert 'ArcGIS' in plot.get(0).data
49 | assert 'x_' in plot.get(1).data
50 | assert 'y_' in plot.get(1).data
51 | bk_plot = bk_renderer.get_plot(plot)
52 | assert bk_plot.projection == 'mercator'
53 |
54 | def test_plot_with_specific_tile_class(self, simple_df):
55 | plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery)
56 | assert len(plot) == 2
57 | assert isinstance(plot.get(0), hv.Tiles)
58 | assert 'ArcGIS' in plot.get(0).data
59 | bk_plot = bk_renderer.get_plot(plot)
60 | assert bk_plot.projection == 'mercator'
61 |
62 | def test_plot_with_specific_tile_obj(self, simple_df):
63 | plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery())
64 | assert len(plot) == 2
65 | assert isinstance(plot.get(0), hv.Tiles)
66 | assert 'ArcGIS' in plot.get(0).data
67 | assert 'x_' in plot.get(1).data
68 | assert 'y_' in plot.get(1).data
69 | bk_plot = bk_renderer.get_plot(plot)
70 | assert bk_plot.projection == 'mercator'
71 |
72 | def test_plot_with_xyzservices_tileprovider(self, simple_df):
73 | xyzservices = pytest.importorskip('xyzservices')
74 | plot = simple_df.hvplot.points('x', 'y', tiles=xyzservices.providers.Esri.WorldImagery)
75 | assert 'x_' in plot.get(1).data
76 | assert 'y_' in plot.get(1).data
77 | assert len(plot) == 2
78 | assert isinstance(plot.get(0), hv.Tiles)
79 | assert isinstance(plot.get(0).data, xyzservices.TileProvider)
80 | bk_plot = bk_renderer.get_plot(plot)
81 | assert bk_plot.projection == 'mercator'
82 |
83 | @pytest.mark.skipif(dd is None, reason='dask not installed')
84 | def test_plot_with_dask(self, simple_df):
85 | ddf = dd.from_pandas(simple_df, npartitions=2)
86 | plot = ddf.hvplot.points('x', 'y', tiles=True)
87 | assert 'x_' not in plot.get(1).data
88 | assert 'y_' not in plot.get(1).data
89 | assert len(plot) == 2
90 | assert isinstance(plot.get(0), hv.Tiles)
91 | bk_plot = bk_renderer.get_plot(plot)
92 | assert bk_plot.projection == 'mercator'
93 |
94 | @pytest.mark.skipif(spd is None, reason='spatialpandas not installed')
95 | def test_plot_without_crs(self):
96 | square = spd.geometry.Polygon([(0.0, 0), (0, 1), (1, 1), (1, 0)])
97 | sdf = spd.GeoDataFrame({'geometry': spd.GeoSeries([square, square]), 'name': ['A', 'B']})
98 | plot = sdf.hvplot.polygons(tiles=True)
99 |
100 | assert len(plot) == 2
101 | assert is_geodataframe(sdf)
102 | assert not hasattr(sdf, 'crs')
103 | assert isinstance(plot.get(0), hv.Tiles)
104 | assert isinstance(plot.get(1), hv.Polygons)
105 | bk_plot = bk_renderer.get_plot(plot)
106 | assert bk_plot.projection == 'mercator' # projection enabled due to `tiles=True`
107 |
--------------------------------------------------------------------------------
/hvplot/tests/testhelp.py:
--------------------------------------------------------------------------------
1 | import hvplot.pandas
2 | import pytest
3 |
4 | from holoviews.core import Store
5 | from holoviews.element import Curve
6 |
7 | from hvplot.util import _get_doc_and_signature
8 |
9 |
10 | @pytest.fixture
11 | def reset_default_backend():
12 | yield
13 | hvplot.extension('bokeh')
14 | hvplot.extension.compatibility = None
15 |
16 |
17 | def test_help_style_extension_output(reset_default_backend):
18 | # default, after e.g. import hvplot.pandas
19 | docstring, signature = _get_doc_and_signature(
20 | cls=hvplot.hvPlot,
21 | kind='line',
22 | completions=False,
23 | docstring=False,
24 | generic=False,
25 | style=True,
26 | signature=None,
27 | )
28 | assert docstring == '\nStyling options\n---------------\n' + '\n'.join(
29 | sorted(Store.registry['bokeh'][Curve].style_opts)
30 | )
31 |
32 | # The current backend becomes matplotlib
33 | hvplot.extension('matplotlib', 'plotly')
34 | docstring, signature = _get_doc_and_signature(
35 | cls=hvplot.hvPlot,
36 | kind='line',
37 | completions=False,
38 | docstring=False,
39 | generic=False,
40 | style=True,
41 | signature=None,
42 | )
43 | assert docstring == '\nStyling options\n---------------\n' + '\n'.join(
44 | sorted(Store.registry['matplotlib'][Curve].style_opts)
45 | )
46 |
47 | # The current backend becomes plotly
48 | hvplot.output(backend='plotly')
49 | docstring, signature = _get_doc_and_signature(
50 | cls=hvplot.hvPlot,
51 | kind='line',
52 | completions=False,
53 | docstring=False,
54 | generic=False,
55 | style=True,
56 | signature=None,
57 | )
58 | assert docstring == '\nStyling options\n---------------\n' + '\n'.join(
59 | sorted(Store.registry['plotly'][Curve].style_opts)
60 | )
61 |
62 |
63 | @pytest.mark.usefixtures('disable_param_warnings_as_exceptions')
64 | def test_help_style_compatibility(reset_default_backend):
65 | # The current backend is plotly but the style options are those of matplotlib
66 | hvplot.extension('plotly', 'matplotlib', compatibility='matplotlib')
67 | docstring, signature = _get_doc_and_signature(
68 | cls=hvplot.hvPlot,
69 | kind='line',
70 | completions=False,
71 | docstring=False,
72 | generic=False,
73 | style=True,
74 | signature=None,
75 | )
76 | assert docstring == '\nStyling options\n---------------\n' + '\n'.join(
77 | sorted(Store.registry['matplotlib'][Curve].style_opts)
78 | )
79 |
--------------------------------------------------------------------------------
/hvplot/tests/testibis.py:
--------------------------------------------------------------------------------
1 | """Basic ibis tests"""
2 |
3 | import numpy as np
4 | import pandas as pd
5 | import pytest
6 |
7 | try:
8 | import hvplot.ibis # noqa
9 | import ibis
10 | except ImportError:
11 | pytest.skip(allow_module_level=True)
12 |
13 |
14 | def test_ibis_hist():
15 | df = pd.DataFrame(dict(x=np.arange(10)))
16 | table = ibis.memtable(df)
17 | table.hvplot.hist('x')
18 |
--------------------------------------------------------------------------------
/hvplot/tests/testnetworkx.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase, SkipTest
2 |
3 | try:
4 | import numpy as np
5 | import networkx as nx
6 | import hvplot.networkx as hvnx
7 | except ImportError:
8 | raise SkipTest('NetworkX not available')
9 |
10 |
11 | class TestOptions(TestCase):
12 | def setUp(self):
13 | # Create nodes (1-10) in unsorted order
14 | nodes = np.array([1, 4, 5, 10, 8, 9, 3, 7, 2, 6])
15 | edges = list(zip(nodes[:-1], nodes[1:]))
16 |
17 | g = nx.Graph()
18 | g.add_nodes_from(nodes)
19 | g.add_edges_from(edges)
20 |
21 | self.nodes = nodes
22 | self.g = g
23 |
24 | def test_nodes_are_not_sorted(self):
25 | plot = hvnx.draw(self.g)
26 | assert all(self.nodes == plot.nodes.dimension_values(2))
27 |
28 | def test_default_hover_tooltip(self):
29 | from bokeh.models import HoverTool
30 |
31 | plot = hvnx.draw(self.g)
32 | hover = next(t for t in plot.opts['tools'] if isinstance(t, HoverTool))
33 | assert [('index', '@{index_hover}')] == hover.tooltips
34 |
--------------------------------------------------------------------------------
/hvplot/tests/testoverrides.py:
--------------------------------------------------------------------------------
1 | from collections import OrderedDict
2 |
3 | import numpy as np
4 | import pandas as pd
5 | import pytest
6 | import xarray as xr
7 |
8 | from hvplot.plotting import hvPlot, hvPlotTabular
9 | from holoviews import Store, Scatter
10 | from holoviews.element.comparison import ComparisonTestCase
11 |
12 |
13 | class TestOverrides(ComparisonTestCase):
14 | def setUp(self):
15 | import hvplot.pandas # noqa
16 |
17 | self.df = pd.DataFrame([[1, 2], [3, 4], [5, 6]], columns=['x', 'y'])
18 |
19 | def test_define_default_options(self):
20 | hvplot = hvPlotTabular(self.df, width=42, height=42)
21 | curve = hvplot(y='y')
22 | opts = Store.lookup_options('bokeh', curve, 'plot')
23 | self.assertEqual(opts.options.get('width'), 42)
24 | self.assertEqual(opts.options.get('height'), 42)
25 |
26 | def test_define_custom_method(self):
27 | hvplot = hvPlotTabular(self.df, {'custom_scatter': {'width': 42, 'height': 42}})
28 | custom_scatter = hvplot.custom_scatter(y='y')
29 | scatter = hvplot.scatter(y='y')
30 | custom_opts = Store.lookup_options('bokeh', custom_scatter, 'plot')
31 | opts = Store.lookup_options('bokeh', scatter, 'plot')
32 | self.assertEqual(custom_opts.options.get('width'), 42)
33 | self.assertEqual(custom_opts.options.get('height'), 42)
34 | self.assertNotEqual(opts.options.get('width'), 42)
35 | self.assertNotEqual(opts.options.get('height'), 42)
36 |
37 | def test_define_customize_method(self):
38 | hvplot = hvPlotTabular(self.df, {'scatter': {'width': 42, 'height': 42}})
39 | custom_scatter = hvplot.scatter(y='y')
40 | curve = hvplot.line(y='y')
41 | custom_opts = Store.lookup_options('bokeh', custom_scatter, 'plot')
42 | opts = Store.lookup_options('bokeh', curve, 'plot')
43 | self.assertEqual(custom_opts.options.get('width'), 42)
44 | self.assertEqual(custom_opts.options.get('height'), 42)
45 | self.assertNotEqual(opts.options.get('width'), 42)
46 | self.assertNotEqual(opts.options.get('height'), 42)
47 |
48 | @pytest.mark.usefixtures('disable_param_warnings_as_exceptions')
49 | def test_attempt_to_override_kind_on_method(self):
50 | hvplot = hvPlotTabular(self.df, {'scatter': {'kind': 'line'}})
51 | self.assertIsInstance(hvplot.scatter(y='y'), Scatter)
52 |
53 | def test_pandas_query_metadata(self):
54 | hvplot = hvPlotTabular(self.df, query='x>2')
55 | assert len(hvplot._data) == 2
56 |
57 |
58 | class TestXArrayOverrides(ComparisonTestCase):
59 | def setUp(self):
60 | coords = OrderedDict([('time', [0, 1]), ('lat', [0, 1]), ('lon', [0, 1])])
61 | self.da_img_by_time = xr.DataArray(
62 | np.arange(8).reshape((2, 2, 2)), coords, ['time', 'lat', 'lon']
63 | ).assign_coords(lat1=xr.DataArray([2, 3], dims=['lat']))
64 |
65 | def test_xarray_isel_scalar_metadata(self):
66 | hvplot = hvPlot(self.da_img_by_time, isel={'time': 1})
67 | assert hvplot._data.ndim == 2
68 |
69 | def test_xarray_isel_nonscalar_metadata(self):
70 | hvplot = hvPlot(self.da_img_by_time, isel={'time': [1]})
71 | assert hvplot._data.ndim == 3
72 | assert len(hvplot._data.time) == 1
73 |
74 | def test_xarray_sel_metadata(self):
75 | hvplot = hvPlot(self.da_img_by_time, sel={'time': 1})
76 | assert hvplot._data.ndim == 2
77 |
--------------------------------------------------------------------------------
/hvplot/tests/testpanel.py:
--------------------------------------------------------------------------------
1 | """
2 | Tests for panel widgets and param objects as arguments
3 | """
4 |
5 | from unittest import TestCase
6 |
7 | import panel as pn
8 |
9 | from hvplot.util import process_xarray # noqa
10 |
11 |
12 | def look_for_class(panel, classname, items=None):
13 | """
14 | Descend a panel object and find any instances of the given class
15 | """
16 | if items is None:
17 | items = []
18 | if isinstance(panel, pn.layout.ListPanel):
19 | for p in panel:
20 | items = look_for_class(p, classname, items)
21 | elif isinstance(panel, classname):
22 | items.append(panel)
23 | return items
24 |
25 |
26 | class TestPanelObjects(TestCase):
27 | def setUp(self):
28 | import hvplot.pandas # noqa
29 | from bokeh.sampledata.iris import flowers
30 |
31 | self.flowers = flowers
32 | self.cols = list(self.flowers.columns[:-1])
33 |
34 | def test_using_explicit_widgets_works(self):
35 | x = pn.widgets.Select(name='x', value='sepal_length', options=self.cols)
36 | y = pn.widgets.Select(name='y', value='sepal_width', options=self.cols)
37 | kind = pn.widgets.Select(name='kind', value='scatter', options=['bivariate', 'scatter'])
38 | by_species = pn.widgets.Checkbox(name='By species')
39 | color = pn.widgets.ColorPicker(value='#ff0000')
40 |
41 | @pn.depends(by_species.param.value, color.param.value)
42 | def by_species_fn(by_species, color):
43 | return 'species' if by_species else color
44 |
45 | self.flowers.hvplot(x, y=y, kind=kind.param.value, c=color)
46 |
47 | def test_casting_widgets_to_different_classes(self):
48 | pane = self.flowers.hvplot.scatter(
49 | groupby='species', legend='top_right', widgets={'species': pn.widgets.DiscreteSlider}
50 | )
51 |
52 | assert len(look_for_class(pane, pn.widgets.DiscreteSlider)) == 1
53 |
54 | def test_using_explicit_widgets_with_groupby_does_not_raise_error(self):
55 | x = pn.widgets.Select(name='x', value='sepal_length', options=self.cols)
56 | y = pn.widgets.Select(name='y', value='sepal_width', options=self.cols)
57 |
58 | pane = self.flowers.hvplot(x, y, groupby='species')
59 | assert isinstance(pane, pn.param.ParamFunction)
60 |
--------------------------------------------------------------------------------
/hvplot/tests/testpatchsignature.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess
3 | import sys
4 |
5 | from hvplot.converter import HoloViewsConverter
6 | from hvplot.util import _PatchHvplotDocstrings, _in_ipython, _parse_docstring_sections
7 |
8 |
9 | def run_script(script, env_vars=None):
10 | env_vars = env_vars or {}
11 | process = subprocess.run(
12 | [sys.executable, '-c', script],
13 | text=True,
14 | capture_output=True,
15 | env=os.environ | env_vars,
16 | )
17 | if process.returncode != 0:
18 | raise RuntimeError(f'Subprocess failed: {process.stderr}')
19 | return process.stdout.strip()
20 |
21 |
22 | def test_no_automatic_patching():
23 | script = """
24 | import inspect
25 | from hvplot import hvPlot
26 |
27 | print(inspect.signature(hvPlot.line))
28 | """
29 | assert not _in_ipython()
30 | out = run_script(script)
31 | assert out == '(self, x=None, y=None, **kwds)'
32 |
33 |
34 | def test_no_automatic_patching_extension_import():
35 | script = """
36 | import inspect
37 | import hvplot.pandas
38 |
39 | print(inspect.signature(hvplot.hvPlot.line))
40 | """
41 | assert not _in_ipython()
42 | out = run_script(script)
43 | assert out == '(self, x=None, y=None, **kwds)'
44 |
45 |
46 | def test_patching_env_var():
47 | script = """
48 | import inspect
49 | from hvplot import hvPlot
50 |
51 | print(inspect.signature(hvPlot.line))
52 | """
53 | assert not _in_ipython()
54 | out = run_script(script, {'HVPLOT_PATCH_PLOT_DOCSTRING_SIGNATURE': 'true'})
55 | assert out != '(self, x=None, y=None, **kwds)'
56 | assert 'xlim' in out
57 |
58 |
59 | def test_patch_hvplot_docstrings():
60 | patchd = _PatchHvplotDocstrings()
61 | assert patchd.orig
62 | try:
63 | patchd()
64 | for (cls, _kind), (osig, odoc) in patchd.orig.items():
65 | obj = getattr(cls, _kind)
66 | assert obj.__signature__ != osig
67 | assert obj.__doc__ != odoc
68 | finally:
69 | patchd.reset()
70 | for (cls, _kind), (osig, odoc) in patchd.orig.items():
71 | obj = getattr(cls, _kind)
72 | assert obj.__signature__ == osig
73 | assert obj.__doc__ == odoc
74 |
75 |
76 | def test_converter_docstrings_sections():
77 | sections = _parse_docstring_sections(HoloViewsConverter.__doc__)
78 | assert set(sections) == set(HoloViewsConverter._docstring_sections.values())
79 |
80 |
81 | def test_converter_options_docstrings():
82 | assert (
83 | HoloViewsConverter._docstring_sections.keys() == HoloViewsConverter._options_groups.keys()
84 | )
85 |
--------------------------------------------------------------------------------
/hvplot/tests/teststatplots.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 | import xarray as xr
4 |
5 | from holoviews import Store
6 |
7 | import hvplot.xarray # noqa: F401
8 |
9 |
10 | def test_violin_from_xarray_with_by_and_color():
11 | latitudes = np.linspace(-90, 90, 180)
12 | longitudes = np.linspace(-180, 180, 360)
13 | times = pd.date_range('2023-01-01', periods=365, freq='D')
14 | data = np.random.random((365, 180, 360))
15 | da = xr.DataArray(
16 | data,
17 | coords={'time': times, 'lat': latitudes, 'lon': longitudes},
18 | dims=['time', 'lat', 'lon'],
19 | name='temperature',
20 | )
21 | plot = da.hvplot.violin(y='temperature', by='lat', color='lat')
22 | assert plot.kdims == ['lat']
23 | opts = Store.lookup_options('bokeh', plot, 'style')
24 | assert opts.kwargs['violin_fill_color'] == 'lat'
25 |
--------------------------------------------------------------------------------
/hvplot/tests/teststreaming.py:
--------------------------------------------------------------------------------
1 | from unittest import TestCase
2 |
3 | import pandas as pd
4 |
5 | from holoviews.streams import Buffer, Pipe
6 |
7 |
8 | class TestExplicitStreamPlotting(TestCase):
9 | def setUp(self):
10 | import hvplot.pandas # noqa
11 |
12 | self.df = pd.DataFrame([[1, 2], [3, 4], [5, 6]], columns=['x', 'y'])
13 |
14 | def test_pipe_stream(self):
15 | stream = Pipe(data=self.df)
16 | plot = self.df.hvplot('x', 'y', stream=stream)
17 | pd.testing.assert_frame_equal(plot[()].data, self.df)
18 | new_df = pd.DataFrame([[7, 8], [9, 10]], columns=['x', 'y'])
19 | stream.send(new_df)
20 | pd.testing.assert_frame_equal(plot[()].data, new_df)
21 |
22 | def test_buffer_stream(self):
23 | stream = Buffer(data=self.df, index=False)
24 | plot = self.df.hvplot('x', 'y', stream=stream)
25 | pd.testing.assert_frame_equal(plot[()].data, self.df)
26 | new_df = pd.DataFrame([[7, 8], [9, 10]], columns=['x', 'y'])
27 | stream.send(new_df)
28 | pd.testing.assert_frame_equal(plot[()].data, pd.concat([self.df, new_df]))
29 |
--------------------------------------------------------------------------------
/hvplot/tests/testtransforms.py:
--------------------------------------------------------------------------------
1 | from unittest import SkipTest
2 |
3 | import holoviews as hv
4 | import numpy as np
5 | import pandas as pd
6 |
7 | from holoviews.element.comparison import ComparisonTestCase
8 |
9 |
10 | class TestPandasTransforms(ComparisonTestCase):
11 | def setUp(self):
12 | import hvplot.pandas # noqa
13 |
14 | def test_pandas_transform(self):
15 | demo_df = pd.DataFrame({'value': np.random.randn(50), 'probability': np.random.rand(50)})
16 | percent = hv.dim('probability') * 100
17 | scatter = demo_df.hvplot.scatter(
18 | x='value', y='probability', transforms=dict(probability=percent)
19 | )
20 | self.assertEqual((scatter.data['probability']).values, demo_df['probability'].values * 100)
21 |
22 |
23 | class TestXArrayTransforms(ComparisonTestCase):
24 | def setUp(self):
25 | try:
26 | import xarray as xr # noqa
27 | except ImportError:
28 | raise SkipTest('xarray not available')
29 | import hvplot.xarray # noqa
30 |
31 | def test_xarray_transform(self):
32 | import xarray as xr
33 |
34 | data = np.arange(0, 60).reshape(6, 10)
35 | x = np.arange(10)
36 | y = np.arange(6)
37 | da = xr.DataArray(data, coords={'y': y, 'x': x}, dims=('y', 'x'), name='value')
38 | img = da.hvplot.image(transforms=dict(value=hv.dim('value') * 10))
39 | self.assertEqual(img.data.value.data, da.data * 10)
40 |
--------------------------------------------------------------------------------
/hvplot/tests/util.py:
--------------------------------------------------------------------------------
1 | import string
2 |
3 | from datetime import datetime
4 |
5 | import numpy as np
6 | import pandas as pd
7 |
8 |
9 | # Pandas removed its make<> test utilities in version 2.2.0.
10 |
11 | _N = 30
12 | _K = 4
13 |
14 |
15 | def getCols(k):
16 | return string.ascii_uppercase[:k]
17 |
18 |
19 | def rands_array(nchars, size, dtype='O', replace=True):
20 | """
21 | Generate an array of byte strings.
22 | """
23 | chars = np.array(list(string.ascii_letters + string.digits), dtype=(np.str_, 1))
24 | retval = (
25 | np.random.default_rng(2)
26 | .choice(chars, size=nchars * np.prod(size), replace=replace)
27 | .view((np.str_, nchars))
28 | .reshape(size)
29 | )
30 | return retval.astype(dtype)
31 |
32 |
33 | def makeStringIndex(k=10, name=None):
34 | return pd.Index(rands_array(nchars=10, size=k), name=name)
35 |
36 |
37 | def makeMixedDataFrame():
38 | data = {
39 | 'A': [0.0, 1.0, 2.0, 3.0, 4.0],
40 | 'B': [0.0, 1.0, 0.0, 1.0, 0.0],
41 | 'C': ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'],
42 | 'D': pd.bdate_range('1/1/2009', periods=5),
43 | }
44 | return pd.DataFrame(data)
45 |
46 |
47 | def getSeriesData():
48 | index = makeStringIndex(_N)
49 | return {
50 | c: pd.Series(np.random.default_rng(i).standard_normal(_N), index=index)
51 | for i, c in enumerate(getCols(_K))
52 | }
53 |
54 |
55 | def makeDataFrame():
56 | data = getSeriesData()
57 | return pd.DataFrame(data)
58 |
59 |
60 | def makeDateIndex(k=10, freq='B', name=None, **kwargs):
61 | dt = datetime(2000, 1, 1)
62 | dr = pd.bdate_range(dt, periods=k, freq=freq, name=name)
63 | return pd.DatetimeIndex(dr, name=name, **kwargs)
64 |
65 |
66 | def makeTimeSeries(nper=None, freq='B', name=None):
67 | if nper is None:
68 | nper = _N
69 | return pd.Series(
70 | np.random.default_rng(2).standard_normal(nper),
71 | index=makeDateIndex(nper, freq=freq),
72 | name=name,
73 | )
74 |
75 |
76 | def getTimeSeriesData(nper=None, freq='B'):
77 | return {c: makeTimeSeries(nper, freq) for c in getCols(_K)}
78 |
79 |
80 | def makeTimeDataFrame(nper=None, freq='B'):
81 | data = getTimeSeriesData(nper, freq)
82 | return pd.DataFrame(data)
83 |
--------------------------------------------------------------------------------
/hvplot/xarray.py:
--------------------------------------------------------------------------------
1 | import xarray as xr
2 |
3 | from panel.widgets import Widget
4 |
5 | from .interactive import Interactive
6 |
7 |
8 | class XArrayInteractive(Interactive):
9 | @classmethod
10 | def applies(cls, obj):
11 | return isinstance(obj, (xr.DataArray, xr.Dataset))
12 |
13 | def sel(self, **kwargs):
14 | processed = {}
15 | for k, v in kwargs.items():
16 | if isinstance(v, type) and issubclass(v, Widget):
17 | if hasattr(v, 'end'):
18 | values = self._current[k].values
19 | v = v(name=k, start=values.min(), end=values.max())
20 | if hasattr(v, 'options'):
21 | v = v(name=k, options={str(v): v for v in self._current[k].values})
22 | processed[k] = v
23 | self._method = 'sel'
24 | return self.__call__(**processed)
25 |
26 | sel.__doc__ = xr.DataArray.sel.__doc__
27 |
28 | def isel(self, **kwargs):
29 | processed = {}
30 | for k, v in kwargs.items():
31 | if isinstance(v, type) and issubclass(v, Widget):
32 | if hasattr(v, 'end'):
33 | v = v(name=k, end=len(self._current[k]))
34 | processed[k] = v
35 | self._method = 'isel'
36 | return self.__call__(**processed)
37 |
38 | isel.__doc__ = xr.DataArray.isel.__doc__
39 |
40 |
41 | def patch(name='hvplot', interactive='interactive', extension='bokeh', logo=False):
42 | from . import hvPlot, post_patch, _module_extensions
43 |
44 | try:
45 | import xarray as xr
46 | except ImportError:
47 | raise ImportError(
48 | 'Could not patch plotting API onto xarray. xarray could not be imported.'
49 | )
50 |
51 | # Remove the class docstring as it very developer focused
52 | XArrayInteractive.__doc__ = ''
53 |
54 | if 'hvplot.xarray' not in _module_extensions:
55 | xr.register_dataset_accessor(name)(hvPlot)
56 | xr.register_dataarray_accessor(name)(hvPlot)
57 | xr.register_dataset_accessor(interactive)(XArrayInteractive)
58 | xr.register_dataarray_accessor(interactive)(XArrayInteractive)
59 | _module_extensions.add('hvplot.xarray')
60 |
61 | post_patch(extension, logo)
62 |
63 |
64 | patch()
65 |
--------------------------------------------------------------------------------
/scripts/conda/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euxo pipefail
4 |
5 | PACKAGE="hvplot"
6 |
7 | python -m build --sdist .
8 |
9 | VERSION=$(python -c "import $PACKAGE; print($PACKAGE._version.__version__)")
10 | export VERSION
11 |
12 | conda build scripts/conda/recipe --no-anaconda-upload --no-verify -c conda-forge --package-format 1
13 |
14 | mv "$CONDA_PREFIX/conda-bld/noarch/$PACKAGE-$VERSION-py_0.tar.bz2" dist
15 |
--------------------------------------------------------------------------------
/scripts/conda/recipe/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set pyproject = load_file_data('../../../pyproject.toml', from_recipe_dir=True) %}
2 | {% set buildsystem = pyproject['build-system'] %}
3 | {% set project = pyproject['project'] %}
4 |
5 | {% set name = project['name'] %}
6 | {% set version = VERSION %}
7 |
8 | package:
9 | name: {{ name|lower }}
10 | version: {{ version }}
11 |
12 | source:
13 | url: ../../../dist/{{ name }}-{{ version }}.tar.gz
14 |
15 | build:
16 | noarch: python
17 | script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
18 |
19 | requirements:
20 | build:
21 | - python {{ project['requires-python'] }}
22 | - pip
23 | {% for dep in buildsystem['requires'] %}
24 | - {{ dep }}
25 | {% endfor %}
26 | run:
27 | - python {{ project['requires-python'] }}
28 | {% for dep in project['dependencies'] %}
29 | - {{ dep }}
30 | {% endfor %}
31 |
32 | test:
33 | requires:
34 | - pip
35 | {% for dep in project['optional-dependencies']['tests-core'] %}
36 | {% if 'dask[dataframe]' in dep %}
37 | - {{ dep | replace("[dataframe]", "") }}
38 | {% elif 'bokeh_sampledata' in dep %}
39 | - {{ dep | replace("; python_version >= '3.10'", "") }}
40 | {% else %}
41 | - {{ dep }}
42 | {% endif %}
43 | {% endfor %}
44 | source_files:
45 | - pyproject.toml
46 | imports:
47 | - hvplot
48 | - hvplot.pandas
49 | commands:
50 | - python -c "import hvplot; ver = hvplot.__version__; assert ver != '0.0.0' and ver != 'unknown'"
51 | - pip check
52 | - pytest hvplot
53 |
54 | about:
55 | home: {{ project['urls']['Homepage'] }}
56 | summary: {{ project['description'] }}
57 | license: {{ project['license']['text'] }}
58 | license_file: LICENSE
59 |
--------------------------------------------------------------------------------
/scripts/download_data.py:
--------------------------------------------------------------------------------
1 | import bokeh
2 | from packaging.version import Version
3 |
4 | if Version(bokeh.__version__).release < (3, 5, 0):
5 | import bokeh.sampledata
6 |
7 | bokeh.sampledata.download()
8 | print('bokeh data downloaded.')
9 |
10 | try:
11 | import pooch # noqa: F401
12 | import scipy # noqa: F401
13 | import xarray as xr
14 |
15 | xr.tutorial.open_dataset('air_temperature')
16 | xr.tutorial.open_dataset('rasm')
17 | print('xarray data downloaded.')
18 | except ModuleNotFoundError as e:
19 | print(f'ModuleNotFoundError when attempting to download xarray datasets : {e}')
20 |
--------------------------------------------------------------------------------
/scripts/sync_git_tags.py:
--------------------------------------------------------------------------------
1 | """
2 | Script to sync tags from upstream repository to forked repository
3 | """
4 |
5 | import sys
6 | from subprocess import run
7 |
8 |
9 | def main(package: str) -> None:
10 | origin = run(['git', 'remote', 'get-url', 'origin'], check=True, capture_output=True)
11 | upstream = run(['git', 'remote', 'get-url', 'upstream'], check=False, capture_output=True)
12 | url = (
13 | f'https://github.com/holoviz/{package}.git'
14 | if origin.stdout.startswith(b'http')
15 | else f'git@github.com:holoviz/{package}.git'
16 | )
17 |
18 | if url == origin.stdout.strip().decode():
19 | print('Not a forked repository, exiting.')
20 | return
21 | elif upstream.returncode:
22 | print(f'Adding {url!r} as remote upstream')
23 | run(['git', 'remote', 'add', 'upstream', url], check=True, capture_output=True)
24 |
25 | print(f'Syncing tags from {package} repository with your forked repository')
26 | run(['git', 'fetch', '--tags', 'upstream'], check=True, capture_output=True)
27 | run(['git', 'push', '--tags'], check=True, capture_output=True)
28 |
29 |
30 | if __name__ == '__main__':
31 | main(sys.argv[1])
32 |
--------------------------------------------------------------------------------