diff --git a/.github/release.yml b/.github/release.yml index cbccb3e8f3..b30419292b 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -15,7 +15,7 @@ changelog: - "type: compatibility" - title: Documentation labels: - - "type: doc" + - "type: docs" - title: Maintenance labels: - "type: maintenance" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 69ffbe9516..519e489f61 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -2,111 +2,144 @@ name: packages on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+a[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+b[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+rc[0-9]+' - # Dry-run only + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+a[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+b[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+" workflow_dispatch: schedule: - - cron: '0 14 * * SUN' + - cron: "0 14 * * SUN" + +defaults: + run: + shell: bash -el {0} + +env: + SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" + PYTHON_VERSION: "3.11" + PACKAGE: "holoviews" jobs: + waiting_room: + name: Waiting Room + runs-on: ubuntu-latest + needs: [conda_build, pip_install] + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + environment: + name: publish + steps: + - run: echo "All builds have finished, have been approved, and ready to publish" + conda_build: - name: Build Conda Packages - runs-on: 'ubuntu-latest' - defaults: - run: - shell: bash -l {0} - env: - CHANS_DEV: "-c pyviz/label/dev -c bokeh" - PKG_TEST_PYTHON: "--test-python=py39" - PYTHON_VERSION: "3.9" - CHANS: "-c pyviz" - MPLBACKEND: "Agg" - CONDA_UPLOAD_TOKEN: ${{ secrets.CONDA_UPLOAD_TOKEN }} - SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" + name: Build Conda + runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: "100" - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - python-version: ${{ env.PYTHON_VERSION }} - name: Fetch unshallow run: git fetch --prune --tags --unshallow -f - - name: Set output - id: vars - run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + - uses: conda-incubator/setup-miniconda@v3 + with: + miniconda-version: "latest" - name: conda setup run: | - conda config --set always_yes True - conda config --append channels pyviz/label/dev - conda config --append channels conda-forge # pyct is for running setup.py - conda install -y conda-build anaconda-client build pyct + conda install -y conda-build build pyct -c pyviz/label/dev - name: conda build run: | - bash ./scripts/build_conda.sh + source ./scripts/build_conda.sh + echo "CONDA_FILE="$CONDA_PREFIX/conda-bld/noarch/$PACKAGE-$VERSION-py_0.tar.bz2"" >> $GITHUB_ENV + - uses: actions/upload-artifact@v4 + if: always() + with: + name: conda + path: ${{ env.CONDA_FILE }} + if-no-files-found: error + + conda_publish: + name: Publish Conda + runs-on: ubuntu-latest + needs: [conda_build, waiting_room] + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v4 + with: + name: conda + path: dist/ + - name: Set environment variables + run: | + echo "TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + echo "CONDA_FILE=$(ls dist/*.tar.bz2)" >> $GITHUB_ENV + - uses: conda-incubator/setup-miniconda@v3 + with: + miniconda-version: "latest" + - name: conda setup + run: | + conda install -y anaconda-client - name: conda dev upload - if: (github.event_name == 'push' && (contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + if: contains(env.TAG, 'a') || contains(env.TAG, 'b') || contains(env.TAG, 'rc') run: | - VERSION="$(echo "$(ls dist/*.whl)" | cut -d- -f2)" - FILE="$CONDA_PREFIX/conda-bld/noarch/holoviews-$VERSION-py_0.tar.bz2" - anaconda --token $CONDA_UPLOAD_TOKEN upload --user pyviz --label=dev $FILE + anaconda --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev $CONDA_FILE - name: conda main upload - if: (github.event_name == 'push' && !(contains(steps.vars.outputs.tag, 'a') || contains(steps.vars.outputs.tag, 'b') || contains(steps.vars.outputs.tag, 'rc'))) + if: (!(contains(env.TAG, 'a') || contains(env.TAG, 'b') || contains(env.TAG, 'rc'))) run: | - VERSION="$(echo "$(ls dist/*.whl)" | cut -d- -f2)" - FILE="$CONDA_PREFIX/conda-bld/noarch/holoviews-$VERSION-py_0.tar.bz2" - anaconda --token $CONDA_UPLOAD_TOKEN upload --user pyviz --label=dev --label=main $FILE + anaconda --token ${{ secrets.CONDA_UPLOAD_TOKEN }} upload --user pyviz --label=dev --label=main $CONDA_FILE + pip_build: - name: Build PyPI Packages - runs-on: 'ubuntu-latest' - defaults: - run: - shell: bash -l {0} - env: - CHANS_DEV: "-c pyviz/label/dev -c bokeh" - PKG_TEST_PYTHON: "--test-python=py39" - PYTHON_VERSION: "3.9" - CHANS: "-c pyviz" - MPLBACKEND: "Agg" - PPU: ${{ secrets.PPU }} - PPP: ${{ secrets.PPP }} - PYPI: "https://upload.pypi.org/legacy/" + name: Build PyPI + runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: "100" - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - python-version: 3.9 - name: Fetch unshallow run: git fetch --prune --tags --unshallow -f - - name: conda setup - run: | - conda install -c pyviz "pyctdev>=0.5" - doit ecosystem_setup - doit env_create $CHANS_DEV --python=$PYTHON_VERSION - - name: env setup - run: | - conda activate test-environment - doit develop_install $CHANS_DEV - pip uninstall -y holoviews - doit pip_on_conda - - name: doit env_capture - run: | - conda activate test-environment - doit env_capture - - name: pip build - run: | - conda activate test-environment - doit ecosystem=pip package_build --test-group=simple - - name: pip upload - if: github.event_name == 'push' + - uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + - name: Install build run: | - conda activate test-environment - doit ecosystem=pip package_upload -u $PPU -p $PPP -r $PYPI + python -m pip install build + - name: Build package + run: python -m build . + - uses: actions/upload-artifact@v4 + if: always() + with: + name: pip + path: dist/ + if-no-files-found: error + + pip_install: + name: Install PyPI + runs-on: "ubuntu-latest" + needs: [pip_build] + steps: + - uses: actions/setup-python@v5 + with: + python-version: ${{ env.PYTHON_VERSION }} + - uses: actions/download-artifact@v4 + with: + name: pip + path: dist/ + - name: Install package + run: python -m pip install dist/*.whl + - name: Test package + run: python -c "import $PACKAGE; print($PACKAGE.__version__)" + + pip_publish: + name: Publish PyPI + runs-on: ubuntu-latest + needs: [pip_build, waiting_room] + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v4 + with: + name: pip + path: dist/ + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: ${{ secrets.PPU }} + password: ${{ secrets.PPP }} + repository-url: "https://upload.pypi.org/legacy/" diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 240caafb83..578df685c2 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -2,28 +2,28 @@ name: docs on: push: tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+a[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+b[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+rc[0-9]+' + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+a[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+b[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+" workflow_dispatch: inputs: target: - description: 'Site to build and deploy, or dry-run' + description: "Site to build and deploy, or dry-run" type: choice options: - - dev - - main - - dryrun + - dev + - main + - dryrun required: true default: dryrun schedule: - - cron: '0 14 * * SUN' + - cron: "0 14 * * SUN" jobs: build_docs: name: Documentation - runs-on: 'ubuntu-latest' + runs-on: "ubuntu-latest" timeout-minutes: 120 defaults: run: @@ -40,11 +40,11 @@ jobs: PANEL_EMBED_JSON: "true" PANEL_EMBED_JSON_PREFIX: "json" steps: - - uses: holoviz-dev/holoviz_tasks/install@v0.1a19 + - uses: holoviz-dev/holoviz_tasks/install@v0 with: name: Documentation python-version: "3.10" - channel-priority: strict + channel-priority: flexible channels: pyviz/label/dev,conda-forge,nodefaults envs: "-o doc" cache: true @@ -52,10 +52,10 @@ jobs: - name: Set output id: vars run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT - - name: bokeh sampledata + - name: Download data run: | conda activate test-environment - bokeh sampledata + bash scripts/download_data.sh - name: generate rst run: | conda activate test-environment diff --git a/.github/workflows/downstream_tests.yaml b/.github/workflows/downstream_tests.yaml index b669e08ba4..4ee679e0ce 100644 --- a/.github/workflows/downstream_tests.yaml +++ b/.github/workflows/downstream_tests.yaml @@ -18,6 +18,6 @@ jobs: downstream_tests: uses: holoviz-dev/holoviz_tasks/.github/workflows/run_downstream_tests.yaml@main with: - downstream_repos_as_json: "{\"downstream_repo\":[\"hvplot\", \"geoviews\"]}" + downstream_repos_as_json: '{"downstream_repo":["hvplot", "geoviews"]}' secrets: ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d6a270b93d..57e3226018 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -5,15 +5,33 @@ on: - main pull_request: branches: - - '*' + - "*" workflow_dispatch: + inputs: + target: + description: "How much of the test suite to run" + type: choice + default: default + options: + - default + - full + - downstream + cache: + description: "Use cache" + type: boolean + default: true + schedule: - - cron: '0 14 * * SUN' + - cron: "0 14 * * SUN" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash -el {0} + env: SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" DISPLAY: ":99.0" @@ -30,69 +48,128 @@ env: jobs: pre_commit: name: Run pre-commit - runs-on: 'ubuntu-latest' + runs-on: "ubuntu-latest" steps: - - uses: holoviz-dev/holoviz_tasks/pre-commit@v0.1a17 + - uses: holoviz-dev/holoviz_tasks/pre-commit@v0 + + setup: + name: Setup workflow + runs-on: ubuntu-latest + permissions: + pull-requests: read + outputs: + code_change: ${{ steps.filter.outputs.code }} + matrix: ${{ env.MATRIX }} + steps: + - uses: actions/checkout@v3 + if: github.event_name != 'pull_request' + - name: Check for code changes + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'holoviews/**' + - 'examples/**' + - 'setup.py' + - 'pyproject.toml' + - '.github/workflows/test.yaml' + - name: Set matrix option + run: | + if [[ '${{ github.event_name }}' == 'workflow_dispatch' ]]; then + OPTION=${{ github.event.inputs.target }} + elif [[ '${{ github.event_name }}' == 'schedule' ]]; then + OPTION="full" + elif [[ '${{ github.event_name }}' == 'push' && '${{ github.ref_type }}' == 'tag' ]]; then + OPTION="full" + else + OPTION="default" + fi + echo "MATRIX_OPTION=$OPTION" >> $GITHUB_ENV + - name: Set test matrix with 'default' option + if: env.MATRIX_OPTION == 'default' + run: | + MATRIX=$(jq -nsc '{ + "os": ["ubuntu-latest", "macos-latest", "windows-latest"], + "python-version": ["3.9", "3.12"] + }') + echo "MATRIX=$MATRIX" >> $GITHUB_ENV + - name: Set test matrix with 'full' option + if: env.MATRIX_OPTION == 'full' + run: | + MATRIX=$(jq -nsc '{ + "os": ["ubuntu-latest", "macos-latest", "windows-latest"], + "python-version": ["3.9", "3.10", "3.11", "3.12"] + }') + echo "MATRIX=$MATRIX" >> $GITHUB_ENV + - name: Set test matrix with 'downstream' option + if: env.MATRIX_OPTION == 'downstream' + run: | + MATRIX=$(jq -nsc '{ + "os": ["ubuntu-latest"], + "python-version": ["3.11"] + }') + echo "MATRIX=$MATRIX" >> $GITHUB_ENV unit_test_suite: name: Unit tests on Python ${{ matrix.python-version }}, ${{ matrix.os }} - needs: [pre_commit] + needs: [pre_commit, setup] runs-on: ${{ matrix.os }} strategy: fail-fast: false - matrix: - os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.9', '3.11'] - include: - - os: 'ubuntu-latest' - python-version: '3.10' + matrix: ${{ fromJson(needs.setup.outputs.matrix) }} timeout-minutes: 120 - defaults: - run: - shell: bash -el {0} env: DESC: "Python ${{ matrix.python-version }}, ${{ matrix.os }} unit tests" PYTHON_VERSION: ${{ matrix.python-version }} steps: - - uses: holoviz-dev/holoviz_tasks/install@v0.1a17 + - uses: holoviz-dev/holoviz_tasks/install@v0 + if: needs.setup.outputs.code_change == 'true' with: name: unit_test_suite python-version: ${{ matrix.python-version }} - channel-priority: strict + channel-priority: flexible channels: pyviz/label/dev,conda-forge,nodefaults envs: "-o flakes -o tests -o examples_tests -o tests_ci" - cache: true + cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} conda-update: true id: install - - name: bokeh sampledata + - name: Check packages latest version + if: needs.setup.outputs.code_change == 'true' + run: | + conda activate test-environment + python scripts/check_latest_packages.py bokeh panel param datashader + - name: Download data + if: needs.setup.outputs.code_change == 'true' run: | conda activate test-environment - bokeh sampledata + bash scripts/download_data.sh - name: doit test_unit + if: needs.setup.outputs.code_change == 'true' run: | conda activate test-environment doit test_unit - name: test examples + if: needs.setup.outputs.code_change == 'true' run: | conda activate test-environment doit test_examples - name: codecov + if: needs.setup.outputs.code_change == 'true' run: | conda activate test-environment codecov + ui_test_suite: name: UI tests on Python ${{ matrix.python-version }}, ${{ matrix.os }} - needs: [pre_commit] + needs: [pre_commit, setup] runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: ['ubuntu-latest'] - python-version: ['3.9'] + os: ["ubuntu-latest"] + python-version: ["3.9"] timeout-minutes: 60 - defaults: - run: - shell: bash -el {0} env: DESC: "Python ${{ matrix.python-version }}, ${{ matrix.os }} UI tests" PANEL_LOG_LEVEL: info @@ -101,76 +178,65 @@ jobs: # it as one of the sources. PYCTDEV_SELF_CHANNEL: "pyviz/label/dev" steps: - - uses: holoviz-dev/holoviz_tasks/install@v0.1a17 + - uses: holoviz-dev/holoviz_tasks/install@v0 + if: needs.setup.outputs.code_change == 'true' with: name: ui_test_suite python-version: ${{ matrix.python-version }} - channels: pyviz/label/dev,bokeh,conda-forge,nodefaults + channels: pyviz/label/dev,conda-forge,nodefaults envs: "-o recommended -o tests -o build -o tests_ci" - cache: true + cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} playwright: true id: install - - name: doit env_capture - run: | - conda activate test-environment - doit env_capture - name: doit test_ui + if: needs.setup.outputs.code_change == 'true' run: | conda activate test-environment doit test_ui - name: Upload coverage to Codecov + if: needs.setup.outputs.code_change == 'true' uses: codecov/codecov-action@v3 with: files: ./coverage.xml flags: ui-tests fail_ci_if_error: false # optional (default = false) + core_test_suite: name: Core tests on Python ${{ matrix.python-version }}, ${{ matrix.os }} - needs: [pre_commit] + needs: [pre_commit, setup] runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: ['ubuntu-latest'] - python-version: ['3.12'] + os: ["ubuntu-latest"] + python-version: ["3.12"] timeout-minutes: 120 - defaults: - run: - shell: bash -el {0} env: DESC: "Python ${{ matrix.python-version }}, ${{ matrix.os }} core tests" PYTHON_VERSION: ${{ matrix.python-version }} steps: - # Add back when this works on Python 3.12 - # - uses: holoviz-dev/holoviz_tasks/install@v0.1a17 - # with: - # name: core_test_suite - # python-version: ${{ matrix.python-version }} - # # channel-priority: strict - # channels: pyviz/label/dev,conda-forge,nodefaults - # envs: "-o tests_core -o tests_ci" - # cache: true - # conda-update: true - # id: install - - uses: actions/checkout@v3 + - uses: holoviz-dev/holoviz_tasks/install@v0 + if: needs.setup.outputs.code_change == 'true' with: - fetch-depth: "100" - - name: Fetch unshallow - run: git fetch --prune --tags --unshallow -f - - uses: actions/setup-python@v4 - with: - python-version: 3.12 - - run: | - python -m pip install -ve '.[tests_core, tests_ci]' - - name: bokeh sampledata + name: core_test_suite + python-version: ${{ matrix.python-version }} + # channel-priority: strict + channels: pyviz/label/dev,conda-forge,nodefaults + envs: "-o tests_core -o tests_ci" + cache: ${{ github.event.inputs.cache || github.event.inputs.cache == '' }} + id: install + - name: Download data + if: needs.setup.outputs.code_change == 'true' run: | - # conda activate test-environment - bokeh sampledata + conda activate test-environment + bash scripts/download_data.sh - name: Check packages latest version + if: needs.setup.outputs.code_change == 'true' run: | - # conda activate test-environment - python scripts/check_latest_packages.py + conda activate test-environment + python scripts/check_latest_packages.py numpy pandas bokeh panel param - name: doit test_unit + if: needs.setup.outputs.code_change == 'true' run: | - # conda activate test-environment + conda activate test-environment pytest holoviews diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6c59e8a313..602951f640 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,20 +20,21 @@ repos: - id: check-json - id: detect-private-key - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.6 + rev: v0.3.4 hooks: - id: ruff files: holoviews/|scripts/ - repo: https://github.com/hoxbro/clean_notebook - rev: v0.1.13 + rev: v0.1.14 hooks: - id: clean-notebook + args: [--strip-trailing-newlines] - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: - - id: codespell - additional_dependencies: - - tomli + - id: codespell + additional_dependencies: + - tomli - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.10.0 hooks: @@ -41,6 +42,14 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.9.0.6 + rev: v0.10.0.1 hooks: - id: shellcheck + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + exclude: conda.recipe/meta.yaml + types_or: + - markdown + - yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f9f7cd01..e42d6f75da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,76 @@ -Version 1.18.1 -============== -**November 8, 2023** +# Version 1.18.3 +**February 12, 2024** -This release contains a small number of bug fixes and compatibility updates — many thanks to @philippjfr and @Hoxbro for their contributions. +This micro release includes bug fixes. + +Bug fixes: + +- Fix BoundsX and BoundsY regression ([#6099](https://github.com/holoviz/holoviews/pull/6099)) +- Fix rasterize regression ([#6102](https://github.com/holoviz/holoviews/pull/6102)) +- Fix link selection for empty Layout ([#6110](https://github.com/holoviz/holoviews/pull/6110)) +- Don't pin notebook in conda recipe for pyviz channel ([#6108](https://github.com/holoviz/holoviews/pull/6108)) + +# Version 1.18.2 + +**February 5, 2024** + +This micro release includes a number of bug fixes and documentation updates, as well as compatibility updates for xarray 2023.12 and Pandas 2.2. +Many thanks to the new contributors @junietoc, @JulianGiles, and @magic-lantern, as well as the returning contributors @ianthomas23, @maximlt, @TheoMathurin, @philippjfr, @ahuang11, and @Hoxbro. + +Enhancements: + +- Update contour line calculations to use ContourPy's `LineType.ChunkCombinedNan` ([#5985](https://github.com/holoviz/holoviews/pull/5985)) +- Use sys.executable for `check_output` ([#5983](https://github.com/holoviz/holoviews/pull/5983)) +- Updates to `show_versions` ([#6072](https://github.com/holoviz/holoviews/pull/6072), [#6081](https://github.com/holoviz/holoviews/pull/6081)) + +Bug fixes: + +- Support `color_key` in `datashade` when intermediate step is an `ImageStack` ([#5994](https://github.com/holoviz/holoviews/pull/5994)) +- Fix hist on overlay ([#5995](https://github.com/holoviz/holoviews/pull/5995)) +- Set proper context before triggering streams ([#6000](https://github.com/holoviz/holoviews/pull/6000)) +- Support partial bound function ([#6009](https://github.com/holoviz/holoviews/pull/6009)) +- Add `norm` in `init_artists` in holoviews/plotting/mpl/raster.py ([#6029](https://github.com/holoviz/holoviews/pull/6029)) +- Fix linking elements that are transformed by a Compositor ([#6003](https://github.com/holoviz/holoviews/pull/6003)) +- Add datetime hover information for selector ([#6023](https://github.com/holoviz/holoviews/pull/6023), [#6039](https://github.com/holoviz/holoviews/pull/6039)) +- Only evaluate `rx` if it is a Reactive Expression ([#6014](https://github.com/holoviz/holoviews/pull/6014)) +- Ensure partial methods can be used as dmap callables ([#6063](https://github.com/holoviz/holoviews/pull/6063)) +- Del frame after stack level is found in `deprecated` ([#6085](https://github.com/holoviz/holoviews/pull/6085)) + +Compatibility: + +- Compatibility updates with xarray 2023.12 ([#6026](https://github.com/holoviz/holoviews/pull/6026)) +- Add extra check to detect if we are in jupyterlite ([#6007](https://github.com/holoviz/holoviews/pull/6007)) +- Compatibility updates with Pandas 2.2 ([#6074](https://github.com/holoviz/holoviews/pull/6074), [#6078](https://github.com/holoviz/holoviews/pull/6078)) +- Add Comm `on_open` handler to initialize the server comm ([#6076](https://github.com/holoviz/holoviews/pull/6076)) + +Documentation: + +- Fix docs ([#5996](https://github.com/holoviz/holoviews/pull/5996)) +- Fix Param usage in the Plot and Renderers guide ([#6001](https://github.com/holoviz/holoviews/pull/6001)) +- Fixing URLs to bokeh project ([#6005](https://github.com/holoviz/holoviews/pull/6005)) +- Fix to broken urls in example gallery pages ([#6038](https://github.com/holoviz/holoviews/pull/6038)) +- Replace Google Analytics with GoatCounter ([#6048](https://github.com/holoviz/holoviews/pull/6048)) +- Add downloads badges ([#6088](https://github.com/holoviz/holoviews/pull/6088)) + +Maintenance: + +- Change to pytest-rerunfailures ([#5984](https://github.com/holoviz/holoviews/pull/5984)) +- Holoviews maintenance ([#5987](https://github.com/holoviz/holoviews/pull/5987)) +- Add `log_cli_level = "INFO"` to pytest ([#5989](https://github.com/holoviz/holoviews/pull/5989)) +- Add shell pre-commit hook ([#5991](https://github.com/holoviz/holoviews/pull/5991)) +- Enable Bugbear 904 ([#5992](https://github.com/holoviz/holoviews/pull/5992)) +- Part 1, modernize test suite ([#5954](https://github.com/holoviz/holoviews/pull/5954)) +- Enforce labels ([#5996](https://github.com/holoviz/holoviews/pull/5997)) +- Add lower pin to scipy ([#6032](https://github.com/holoviz/holoviews/pull/6032)) +- Skip Deploying_Bokeh_Apps.ipynb on Windows ([#6070](https://github.com/holoviz/holoviews/pull/6070)) +- Fix failing Windows tests ([#6087](https://github.com/holoviz/holoviews/pull/6087)) + +# Version 1.18.1 + +**November 8, 2023** +This release contains a small number of bug fixes and compatibility updates — many thanks to @philippjfr and @Hoxbro for their contributions. Bug fixes: @@ -23,16 +89,14 @@ Maintenance: - General maintenance ([#5955](https://github.com/holoviz/holoviews/pull/5955)) +# Version 1.18.0 -Version 1.18.0 -============== **October 18, 2023** This release includes new features, improvements, and bug fixes. Among these are the new elements. First is the `ImageStack` element allows you to easily visualize a 3D array, while the `VLines`, `HLines`, `VSpans`, and `HSpans` elements allow you to visualize vertical and horizontal lines and spans easily. In addition, this release includes support for subcoordinate systems in the y-axis and various other enhancements and bug fixes. This release adds support for the newest Python 3.12 and Bokeh 3.3 and drops support for Python 3.8 and Bokeh 2. Many thanks to the new contributors @MeggyCal, along with our returning contributors @ahuang11, @ianthomas23, @jlstevens, @maximlt, @philippjfr, and @Hoxbro. - New features: - Implementation of `ImageStack` ([#5751](https://github.com/holoviz/holoviews/pull/5751), [#5945](https://github.com/holoviz/holoviews/pull/5945)) @@ -74,7 +138,7 @@ Compatibility: Documentation: -- Add *Linking Bokeh plots* guide to the table of contents ([#5900](https://github.com/holoviz/holoviews/pull/5900)) +- Add _Linking Bokeh plots_ guide to the table of contents ([#5900](https://github.com/holoviz/holoviews/pull/5900)) Maintenance: @@ -86,15 +150,12 @@ Maintenance: - Add sorting of imports ([#5937](https://github.com/holoviz/holoviews/pull/5937)) - Enable Bugbear lint ([#5861](https://github.com/holoviz/holoviews/pull/5861)) +# Version 1.17.1 -Version 1.17.1 -============== **August 16, 2023** - This release contains a small number of important bug fixes and regressions — many thanks to @ianthomas23, @maximlt, @philippjfr, and @Hoxbro for their contributions. - Enhancements: - Improve support for `hv.NdOverlay` and `hv.Overlay` in downsample1d ([#5856](https://github.com/holoviz/holoviews/pull/5856)) @@ -120,9 +181,8 @@ Maintenance: - Update Ruff in pre-commit and report panel communication in `hv.show_versions` ([#5853](https://github.com/holoviz/holoviews/pull/5853)) - Cleanup imports ([#5846](https://github.com/holoviz/holoviews/pull/5846)) +# Version 1.17.0 -Version 1.17.0 -============== **July 24, 2023** This release brings one of the most requested features - interactive twin-axis support! Another feature added in this release is the ability to easily set custom options on plot components with `backend_opts`, making it much easier to customize your plots. Datashaders `where` and `summary` aggregators are now supported, and `rasterize` now has a `selector` option, making it easy to get extra information about your rasterized data. Lastly, Bokeh figures with the same labels will synchronize muteness or visibility across different figures. @@ -142,7 +202,7 @@ Enhancements: - Add option for initial ranges to RangeToolLink ([#5800](https://github.com/holoviz/holoviews/pull/5800)) - Allow resample's `pixel_ratio` to go below 1 ([#5813](https://github.com/holoviz/holoviews/pull/5813), [#5817](https://github.com/holoviz/holoviews/pull/5817)) -Add the ability for `VectorField` to instantiate from UV coordinates ([#5797](https://github.com/holoviz/holoviews/pull/5797)) + Add the ability for `VectorField` to instantiate from UV coordinates ([#5797](https://github.com/holoviz/holoviews/pull/5797)) - Handle the `nodata` option for rasterized RGB image ([#5774](https://github.com/holoviz/holoviews/pull/5774)) Bug fixes: @@ -182,9 +242,8 @@ Maintenance: - Update pre-commit and lint ([#5747](https://github.com/holoviz/holoviews/pull/5747), [#5768](https://github.com/holoviz/holoviews/pull/5768), [#5777](https://github.com/holoviz/holoviews/pull/5777)) - Setup infrastructure for UI tests and add first linked streams tests ([#5764](https://github.com/holoviz/holoviews/pull/5764)) +# Version 1.16.2 -Version 1.16.2 -============== **June 8, 2023** This release includes a breaking change as notebooks will no longer be inlining as default. This change will reduce the size of the notebook files and, more importantly, address an upstream issue in Jupyter where running `hv.extension` would give an error when used in a notebook. @@ -203,16 +262,14 @@ Maintenance: - Fix failing tests ([#5742](https://github.com/holoviz/holoviews/pull/5742)) - Misc. mainteance ([#5717](https://github.com/holoviz/holoviews/pull/5717)) +# Version 1.16.1 -Version 1.16.1 -============== **June 2, 2023** This release contains a small number of important bug fixes and enhancements. Many thanks to @philippjfr and @Hoxbro. This release includes a breaking change as notebooks will no longer be inlining as default. This change will reduce the size of the notebook files and, more importantly, address an upstream issue in Jupyter where running `hv.extension` would give an error when used in a notebook. - Critical bug fixes and compatibility: - Add `enable_mathjax` and set it and inline to `False` ([#5729](https://github.com/holoviz/holoviews/pull/5729)) @@ -224,14 +281,12 @@ Enhancements: - Ignore known model warning in VS Code ([#5734](https://github.com/holoviz/holoviews/pull/5734)) - Add workaround for plots where the objects in a figure would overlap ([#5733](https://github.com/holoviz/holoviews/pull/5733)) - Documentation: - Upgrade to latest `nbsite` and `pydata-sphinx-theme` ([#5724](https://github.com/holoviz/holoviews/pull/5724), [#5735](https://github.com/holoviz/holoviews/pull/5735)) +# Version 1.16.0 -Version 1.16.0 -============== **May 9, 2023** This release includes many new features, improvements, and bug fixes. Among the highlights are support for Bokeh 3.1 and Panel 1.0, both of which come with a wide range of new features and enhancements. Time series support has also been improved, with auto-ranging along one axis, a new downsample algorithm, and having WebGL enabled by default. In addition, the release includes various other enhancements and bug fixes. @@ -241,7 +296,6 @@ We would like to thank the many users who contributed to this release by filing This minor version will be the last to support Python 3.7. The next minor version will require Python 3.8 or higher. In the next release, `holoviews.annotate` will start giving a deprecation warning about its future move to the new package [HoloNote](https://github.com/holoviz/holonote). - New features: - Support for Bokeh 3.1 and Panel 1.0 ([#5388](https://github.com/holoviz/holoviews/pull/5388), [#5620](https://github.com/holoviz/holoviews/pull/5620), [#5640](https://github.com/holoviz/holoviews/pull/5640), [#5679](https://github.com/holoviz/holoviews/pull/5679), [#5683](https://github.com/holoviz/holoviews/pull/5683), [#5692](https://github.com/holoviz/holoviews/pull/5692), [#5703](https://github.com/holoviz/holoviews/pull/5703)) @@ -259,7 +313,6 @@ Enhancements: - Add support for extra `Hovertool` variables in a Bokeh's `quadmesh` with 2D coordinates (with tests) ([#5638](https://github.com/holoviz/holoviews/pull/5638)) - Change `hv.Rectangles` to internally use Bokeh `Quad` and not `Rect` to support logarithmic axis in WebGL ([#5664](https://github.com/holoviz/holoviews/pull/5664), [#5702](https://github.com/holoviz/holoviews/pull/5702)) - Bug fixes: - Ensure `spatial_select` in non-zero indexed DataFrame is applied right ([#5625](https://github.com/holoviz/holoviews/pull/5625)) @@ -280,7 +333,6 @@ Compatibility: - Improve error message for categorical data when used with `datashade` ([#5643](https://github.com/holoviz/holoviews/pull/5643)) - Don't disable Jedi completion by default ([#5701](https://github.com/holoviz/holoviews/pull/5701)) - Documentation: - Fix an incorrect number stated regarding available axis types ([#5623](https://github.com/holoviz/holoviews/pull/5623)) @@ -288,16 +340,14 @@ Documentation: - Fix formatting on FAQ ([#5630](https://github.com/holoviz/holoviews/pull/5630)) - Fix anchor links ([#5677](https://github.com/holoviz/holoviews/pull/5677)) - Maintenance: - Use `clean-notebook`, `codespell`, and `ruff` in `pre-commit` ([#5594](https://github.com/holoviz/holoviews/pull/5594), [#5627](https://github.com/holoviz/holoviews/pull/5627), [#5653](https://github.com/holoviz/holoviews/pull/5653)) - General maintenance ([#5607](https://github.com/holoviz/holoviews/pull/5607), [#5611](https://github.com/holoviz/holoviews/pull/5611), [#5612](https://github.com/holoviz/holoviews/pull/5612), [#5649](https://github.com/holoviz/holoviews/pull/5649)) - Known issues: -- `BoxEditTool` is not yet supported with the new internals of `hv.Rectangle`. +- `BoxEditTool` is not yet supported with the new internals of `hv.Rectangle`. Removals: @@ -305,15 +355,13 @@ Removals: - Remove deprecated tile sources ([#5654](https://github.com/holoviz/holoviews/pull/5654)) - Removed support for `apply_groups` for old option groups signature ([#5497](https://github.com/holoviz/holoviews/pull/5497)) +# Version 1.15.4 -Version 1.15.4 -============== **January 16, 2023** This release contains a small number of enhancements and important bug fixes. Many thanks to our new contributors @mmorys, @jj-github-jj, and @sandhujasmine, but also our returning contributors @droumis, @jlstevens, @MarcSkovMadsen, @maximlt, @philippjfr, @stanwest, and @Hoxbro. - Enhancements: - Make lasso select mask values using a Dask-compatible method ([#5568](https://github.com/holoviz/holoviews/pull/5568)) @@ -353,9 +401,8 @@ Maintenance: - Update binder link and dependency pinning ([#5583](https://github.com/holoviz/holoviews/pull/5583)) - Update copyright to only contain start year ([#5580](https://github.com/holoviz/holoviews/pull/5580)) +# Version 1.15.3 -Version 1.15.3 -============== **December 6, 2022** This release contains a small number of important bug fixes and @@ -364,25 +411,25 @@ adds support for Python 3.11. Many thanks to our maintainers Bug Fixes: - - Fix for empty opts warning and incorrect clearing semantics - ([#5496](https://github.com/holoviz/holoviews/pull/5496)) - - Fix potential race condition in the Options system - ([#5535](https://github.com/holoviz/holoviews/pull/5535)) +- Fix for empty opts warning and incorrect clearing semantics + ([#5496](https://github.com/holoviz/holoviews/pull/5496)) +- Fix potential race condition in the Options system + ([#5535](https://github.com/holoviz/holoviews/pull/5535)) Enhancements: - - Add support to Python 3.11 - ([#5513](https://github.com/holoviz/holoviews/pull/5513)) - - Cleanup the top `__init__` module - ([#5516](https://github.com/holoviz/holoviews/pull/5516)) +- Add support to Python 3.11 + ([#5513](https://github.com/holoviz/holoviews/pull/5513)) +- Cleanup the top `__init__` module + ([#5516](https://github.com/holoviz/holoviews/pull/5516)) Documentation: - - Fixes to release notes and CHANGELOG - ([#5506](https://github.com/holoviz/holoviews/pull/5506)) +- Fixes to release notes and CHANGELOG + ([#5506](https://github.com/holoviz/holoviews/pull/5506)) + +# Version 1.15.2 -Version 1.15.2 -============== **November 3, 2022** This release contains a small number of important bug fixes. Many thanks @@ -419,8 +466,8 @@ be deprecated in future. - Upgrade warning for invalid dataframe column names ([#5472](https://github.com/holoviz/holoviews/pull/5472)) -Version 1.15.1 -============== +# Version 1.15.1 + **October 4, 2022** This release contains a small number of important bug fixes. Many thanks @@ -447,7 +494,7 @@ Enhancements: ([#5455](https://github.com/holoviz/holoviews/pull/5455)) - Add pre-commit hooks to CI actions and fixes to pytest configuration ([#5385](https://github.com/holoviz/holoviews/pull/5385), - [#5440](https://github.com/holoviz/holoviews/pull/5440)) + [#5440](https://github.com/holoviz/holoviews/pull/5440)) Bug Fixes: @@ -472,10 +519,10 @@ Bug Fixes: - Many thanks to @Hoxbro for many miscellaneous plotting fixes, including fixes to plotting of `BoxWhisker`, `VectorField` elements ([#5397](https://github.com/holoviz/holoviews/pull/5397), - [#5450](https://github.com/holoviz/holoviews/pull/5450), - [#5400](https://github.com/holoviz/holoviews/pull/5400), - [#5409](https://github.com/holoviz/holoviews/pull/5409), - [#5460](https://github.com/holoviz/holoviews/pull/5460))) + [#5450](https://github.com/holoviz/holoviews/pull/5450), + [#5400](https://github.com/holoviz/holoviews/pull/5400), + [#5409](https://github.com/holoviz/holoviews/pull/5409), + [#5460](https://github.com/holoviz/holoviews/pull/5460))) - Fixes to documentation building GitHub Action ([#5320](https://github.com/holoviz/holoviews/pull/5456), ([#5320](https://github.com/holoviz/holoviews/pull/5467))) @@ -500,8 +547,8 @@ issuing a `DeprecationWarning` that should not be visible to users. - Issue DeprecationWarning for invalid DataFrame column types ([#5457](https://github.com/holoviz/holoviews/pull/5457)) -Version 1.15.0 -============== +# Version 1.15.0 + **July 6, 2022** This is a major release with a large number of new features and bug @@ -552,7 +599,6 @@ The following new features have been added to the datashader support in HoloViews, mainly focused on Datashader's new support for antialiasing lines as well as the new `rescale_discrete_levels` colormapping option. - - Add automatic categorical legend for datashaded plots ([#4806](https://github.com/holoviz/holoviews/pull/4806)) - Implement `line_width` support when rasterizing spatialpandas paths @@ -576,59 +622,59 @@ New features for the Bokeh plotting backend: - Add `legend_labels` option to allow overriding legend labels ([#5342](https://github.com/holoviz/holoviews/pull/5342)) - Updated sankey algorithm to `d3-sankey-v0.12.3` - ([#4707](https://github.com/holoviz/holoviews/pull/4707)) + ([#4707](https://github.com/holoviz/holoviews/pull/4707)) Other enhancements: - Optimize and clean up options system - ([#4954](https://github.com/holoviz/holoviews/pull/4954)) + ([#4954](https://github.com/holoviz/holoviews/pull/4954)) - Optimize lasso selection by applying box-select first - ([#5061](https://github.com/holoviz/holoviews/pull/5061)) - https://github.com/holoviz/holoviews/pull/5061 + ([#5061](https://github.com/holoviz/holoviews/pull/5061)) + https://github.com/holoviz/holoviews/pull/5061 - Support ibis-framework version 3 - ([#5292](https://github.com/holoviz/holoviews/pull/5292)) + ([#5292](https://github.com/holoviz/holoviews/pull/5292)) - Add `OpenTopoMap` as a tile source - ([#5052](https://github.com/holoviz/holoviews/pull/5052)) + ([#5052](https://github.com/holoviz/holoviews/pull/5052)) - Show all histograms of an `Overlay` -([#5031](https://github.com/holoviz/holoviews/pull/5031)) + ([#5031](https://github.com/holoviz/holoviews/pull/5031)) Bug fixes: - Fix batch watching and linking of parameters in Params stream - ([#4960](https://github.com/holoviz/holoviews/pull/4960), + ([#4960](https://github.com/holoviz/holoviews/pull/4960), [#4956](https://github.com/holoviz/holoviews/pull/4956)) - Ensure `Plot.refresh` is dispatched immediately if possible - ([#5348](https://github.com/holoviz/holoviews/pull/5348)) + ([#5348](https://github.com/holoviz/holoviews/pull/5348)) - Fix datashader empty overlay aggregation - ([#5334](https://github.com/holoviz/holoviews/pull/5334)) + ([#5334](https://github.com/holoviz/holoviews/pull/5334)) - Fixed missing handling of nodata for count aggregator with column - ([#4951](https://github.com/holoviz/holoviews/pull/4951)) + ([#4951](https://github.com/holoviz/holoviews/pull/4951)) - Handle `pd.NA` as missing data in dtype=object column - ([#5323](https://github.com/holoviz/holoviews/pull/5323)) + ([#5323](https://github.com/holoviz/holoviews/pull/5323)) - Forward `DynamicMap.hist` dimension parameter to histogram creation - ([#5037](https://github.com/holoviz/holoviews/pull/5037)) + ([#5037](https://github.com/holoviz/holoviews/pull/5037)) - Remove numpy pin from examples - ([#5285](https://github.com/holoviz/holoviews/pull/5285)) + ([#5285](https://github.com/holoviz/holoviews/pull/5285)) - Fix vmin/vmax deprecation on matplotlib HeatMapPlot - ([#5300](https://github.com/holoviz/holoviews/pull/5300)) + ([#5300](https://github.com/holoviz/holoviews/pull/5300)) - Don't skip each renderer's `load_nb call` when multiple extension - calls are made in a single cell - ([#5302](https://github.com/holoviz/holoviews/pull/5302)) + calls are made in a single cell + ([#5302](https://github.com/holoviz/holoviews/pull/5302)) - Set plotly range correctly for log axis - ([#5272](https://github.com/holoviz/holoviews/pull/5272)) + ([#5272](https://github.com/holoviz/holoviews/pull/5272)) - Sanitize uses of `contextlib.contextmanager` - ([#5018](https://github.com/holoviz/holoviews/pull/5018)) + ([#5018](https://github.com/holoviz/holoviews/pull/5018)) - Ensure `overlay_aggregate` is not applied for anti-aliased lines - ([#5266](https://github.com/holoviz/holoviews/pull/5266)) + ([#5266](https://github.com/holoviz/holoviews/pull/5266)) - Switch to using bokeh `rangesupdate` event for `Range` streams - ([#5265](https://github.com/holoviz/holoviews/pull/5265)) + ([#5265](https://github.com/holoviz/holoviews/pull/5265)) - Fixes for bokeh `Callbacks` - ([#5040](https://github.com/holoviz/holoviews/pull/5040)) + ([#5040](https://github.com/holoviz/holoviews/pull/5040)) - Fix for attribute error in matplotlib `CompositePlot` - ([#4969](https://github.com/holoviz/holoviews/pull/4969)) + ([#4969](https://github.com/holoviz/holoviews/pull/4969)) - Silenced inappropriate deprecation warnings and updated deprecation settings in options system - ([#5345](https://github.com/holoviz/holoviews/pull/5345), + ([#5345](https://github.com/holoviz/holoviews/pull/5345), [#5346](https://github.com/holoviz/holoviews/pull/5346)) Documentation: @@ -636,23 +682,23 @@ Documentation: The following improvements to the documentation have been made: - Fix `hv.help` when pattern is set - ([#5330](https://github.com/holoviz/holoviews/pull/5330)) + ([#5330](https://github.com/holoviz/holoviews/pull/5330)) - Added release dates to changelog and releases - ([#5027](https://github.com/holoviz/holoviews/pull/5027), + ([#5027](https://github.com/holoviz/holoviews/pull/5027), [#5035](https://github.com/holoviz/holoviews/pull/5035)) - Removed unneeded list from dynamic map example - ([#4953](https://github.com/holoviz/holoviews/pull/4953)) + ([#4953](https://github.com/holoviz/holoviews/pull/4953)) - Added FAQ about sharing only a single axis - ([#5278](https://github.com/holoviz/holoviews/pull/5278)) + ([#5278](https://github.com/holoviz/holoviews/pull/5278)) - Miscellaneous fixes to Heatmap reference notebook and Continuous Coordinates user guide - ([#5262](https://github.com/holoviz/holoviews/pull/5262)) + ([#5262](https://github.com/holoviz/holoviews/pull/5262)) - Added example of multiple RGB images as glyphs - ([#5172](https://github.com/holoviz/holoviews/pull/5172)) + ([#5172](https://github.com/holoviz/holoviews/pull/5172)) - Trim trailing whitespaces - ([#5019](https://github.com/holoviz/holoviews/pull/5019)) + ([#5019](https://github.com/holoviz/holoviews/pull/5019)) - Update outdated IOAM references - ([#4985](https://github.com/holoviz/holoviews/pull/4985)) + ([#4985](https://github.com/holoviz/holoviews/pull/4985)) Testing infrastructure: @@ -660,15 +706,14 @@ Many thanks to @maximlt for his work maintaining and fixing the testing infrastructure across too many PRs to list here. - Switch to pytest - ([#4949](https://github.com/holoviz/holoviews/pull/4949)) + ([#4949](https://github.com/holoviz/holoviews/pull/4949)) - Test suite clean up and fix for the pip build - ([#5326](https://github.com/holoviz/holoviews/pull/5326)) + ([#5326](https://github.com/holoviz/holoviews/pull/5326)) - Test updates following release of datashader 0.14.1 - ([#5344](https://github.com/holoviz/holoviews/pull/5344)) + ([#5344](https://github.com/holoviz/holoviews/pull/5344)) +# Version 1.14.9 -Version 1.14.9 -============== **May 6, 2022** This release contains a small number of important bug fixes as well as @@ -682,12 +727,12 @@ Enhancements: JupyterLab when no logo is used and a check to avoid loading unnecessary JavaScript. ([#5216](https://github.com/holoviz/holoviews/pull/5216), - [#5249](https://github.com/holoviz/holoviews/pull/5249)) + [#5249](https://github.com/holoviz/holoviews/pull/5249)) - Add support for setting antialiased line_width on datashader line aggregation as well as pixel_ratio setting ([#5264](https://github.com/holoviz/holoviews/pull/5264), [#5288](https://github.com/holoviz/holoviews/pull/5288)) -- Added options to customize hover line_(width|join|cap|dash) properties +- Added options to customize hover line\_(width|join|cap|dash) properties ([#5211](https://github.com/holoviz/holoviews/pull/5211)) - Restored Python 2 compatibility that lapsed due to lack of CI testing since 1.14.3. This is expected to be the last release with Python 2 support. @@ -715,9 +760,8 @@ Documentation: ([#5267](https://github.com/holoviz/holoviews/pull/5267), [#5290](https://github.com/holoviz/holoviews/pull/5290)) +# Version 1.14.8 -Version 1.14.8 -============== **February 15, 2022** This release contains a small number of important bug fixes as well as @@ -750,8 +794,8 @@ Bug fixes: [#5201](https://github.com/holoviz/holoviews/pull/5201), [#5206](https://github.com/holoviz/holoviews/pull/5206)) -Version 1.14.7 -============== +# Version 1.14.7 + **December 16, 2021** This release contains a small number of important bug fixes. Many thanks @@ -805,16 +849,16 @@ Bug fixes: - Fix for Contours consistent of empty and nonempty paths ([#5162](https://github.com/holoviz/holoviews/pull/5162)) - Fixed docs: - * Fix `fig_bounds` description in Plotting_with_Matplotlib.ipynb - ([#4983](https://github.com/holoviz/holoviews/pull/4983)) - * Fix broken link in Gridded user guide - ([#5098](https://github.com/holoviz/holoviews/pull/5098)) + - Fix `fig_bounds` description in Plotting_with_Matplotlib.ipynb + ([#4983](https://github.com/holoviz/holoviews/pull/4983)) + - Fix broken link in Gridded user guide + ([#5098](https://github.com/holoviz/holoviews/pull/5098)) - Improved docs: - * Switch to the Pydata Sphinx theme - ([#5163](https://github.com/holoviz/holoviews/pull/5163)) + - Switch to the Pydata Sphinx theme + ([#5163](https://github.com/holoviz/holoviews/pull/5163)) + +# Version 1.14.6 -Version 1.14.6 -============== **September 16, 2021** This is a hotfix release with a number of important bug fixes. Most @@ -836,7 +880,7 @@ Bug fixes: - Improvements to linked selections including support for linked selection lasso for cudf and improved warnings ([#5044](https://github.com/holoviz/holoviews/pull/5044), - [#5051](https://github.com/holoviz/holoviews/pull/5051)) + [#5051](https://github.com/holoviz/holoviews/pull/5051)) - Respect apply_ranges at range computation level ([#5081](https://github.com/holoviz/holoviews/pull/5081)) - Keep ordering of kdim when stacking Areas @@ -844,8 +888,8 @@ Bug fixes: - Apply hover postprocessor on updates ([#5039](https://github.com/holoviz/holoviews/pull/5039)) -Version 1.14.5 -============== +# Version 1.14.5 + **July 16, 2021** This is a hotfix release with a number of important bug fixes. Most @@ -863,9 +907,8 @@ Bug fixes: [#5001](https://github.com/holoviz/holoviews/pull/5001), [#5005](https://github.com/holoviz/holoviews/pull/5005)) +# Version 1.14.4 -Version 1.14.4 -============== **May 18, 2021** This release primarily focuses on a number of bug fixes. Many thanks to @@ -893,7 +936,7 @@ Bug fixes: ([#4911](https://github.com/holoviz/holoviews/pull/4911)) - Fix bug using dimensions with label on `Bars` ([#4929](https://github.com/holoviz/holoviews/pull/4929)) -- Do not reverse colormaps with '_r' suffix a second time +- Do not reverse colormaps with '\_r' suffix a second time ([#4931](https://github.com/holoviz/holoviews/pull/4931)) - Fix remapping of `Params` stream parameter names ([#4932](https://github.com/holoviz/holoviews/pull/4932)) @@ -922,8 +965,8 @@ unless `hv.config.raise_deprecated_tilesource_exception` is set to available. Attempting to use these tile sources will result in a deprecation warning. -Version 1.14.3 -============== +# Version 1.14.3 + **April 8, 2021** This release contains a small number of bug fixes, enhancements and @@ -953,8 +996,8 @@ Compatibility: - Support matplotlib versions >=3.4 ([#4878](https://github.com/holoviz/holoviews/pull/4878)) -Version 1.14.2 -============== +# Version 1.14.2 + **March 2, 2021** This release adds support for Bokeh 2.3, introduces a number of minor @@ -976,8 +1019,8 @@ Enhancements: [#4809](https://github.com/holoviz/holoviews/pull/4809)) - Supporting dictionary streams parameter in DynamicMaps and operations ([#4787](https://github.com/holoviz/holoviews/pull/4787), - [#4818](https://github.com/holoviz/holoviews/pull/4818), - [#4822](https://github.com/holoviz/holoviews/pull/4822)) + [#4818](https://github.com/holoviz/holoviews/pull/4818), + [#4822](https://github.com/holoviz/holoviews/pull/4822)) - Support spatialpandas DaskGeoDataFrame ([#4792](https://github.com/holoviz/holoviews/pull/4792)) - Disable zoom on axis for geographic plots @@ -1023,8 +1066,8 @@ Documentation: [#4844](https://github.com/holoviz/holoviews/pull/4844), [#4811](https://github.com/holoviz/holoviews/pull/4811)) -Version 1.14.1 -============== +# Version 1.14.1 + **December 28, 2020** This release contains a small number of bug fixes addressing @@ -1048,8 +1091,8 @@ Documentation: - Warn about disabled interactive features on website ([#4762](https://github.com/holoviz/holoviews/pull/4762)) -Version 1.14.0 -============== +# Version 1.14.0 + **December 1, 2020** This release brings a number of major features including a new @@ -1061,7 +1104,7 @@ suggestions. Specifically, we would like to thank @philippjfr, @jonmmease, and @tonyfast for their work on the IbisInterface and @jonmmease for improving Plotly support, as well as @kcpevey, @Hoxbro, @marckassay, @mcepl, and @ceball for various other enhancements, -improvements to documentation and testing infrastructure. In +improvements to documentation and testing infrastructure. In addition, thanks to the maintainers @jbednar, @jlstevens and @philippjfr for contributing to this release. This version includes a large number of new features, enhancements, and bug fixes. @@ -1154,8 +1197,8 @@ Compatibility: set to 'kbc_r' for consistency and can be set back to the old value of 'RdYlBu_r' via `hv.config.default_heatmap_cmap`. -Version 1.13.5 -============== +# Version 1.13.5 + **October 23, 2020** This version contains numerous bug fixes and a number of enhancements. @@ -1197,8 +1240,8 @@ Documentation: - Various documentation fixes ([#4628](https://github.com/holoviz/holoviews/pull/4628)) -Version 1.13.4 -============== +# Version 1.13.4 + **September 8, 2020** This version fixes a large number of bugs particularly relating to @@ -1269,8 +1312,8 @@ Enhancements: - Allow rendering to pgf in matplotlib ([#4577](https://github.com/holoviz/holoviews/pull/4577)) -Version 1.13.3 -============== +# Version 1.13.3 + **June 23, 2020** This version introduces a number of enhancements of existing @@ -1339,8 +1382,8 @@ Bug fixes: - Handle missing categories on split Violin plot ([#4482](https://github.com/holoviz/holoviews/pull/4482)) -Version 1.13.2 -============== +# Version 1.13.2 + **April 2, 2020** This is a minor patch release fixing a number of regressions @@ -1366,8 +1409,8 @@ Bug fixes: - Fix handling of document in server mode ([#4355](https://github.com/holoviz/holoviews/pull/4355)) -Version 1.13.1 -============== +# Version 1.13.1 + **March 25, 2020** This is a minor patch release to fix issues compatibility with the @@ -1412,8 +1455,8 @@ Documentation: - Update API reference manual ([#4316](https://github.com/holoviz/holoviews/pull/4316)) -Version 1.13.0 -============== +# Version 1.13.0 + **March 20, 2020** This release is packed full of features and includes a general @@ -1424,7 +1467,7 @@ suggestions. Specifically we would like to thank @poplarShift, @jonmease, @flothesof, @julioasotodv, @ltalirz, @DancingQuanta, @ahuang, @kcpevey, @Jacob-Barkhak, @nluetts, @harmbuisman, @ceball, @mgsnuno, @srp3003, @jsignell as well as the maintainers @jbednar, @jlstevens and -@philippjfr for contributing to this release. This version includes the +@philippjfr for contributing to this release. This version includes the addition of a large number of features, enhancements and bug fixes: Major features: @@ -1530,7 +1573,6 @@ Bug fixes: [#3027](https://github.com/holoviz/holoviews/pull/3027), [#3777](https://github.com/holoviz/holoviews/pull/3777)) - Library compatibility: - Better support for Pandas 1.0 @@ -1563,9 +1605,8 @@ Migration notes: - `hv.output` `filename` argument is deprecated; use `hv.save` instead ([#3985](https://github.com/holoviz/holoviews/pull/3985)) +# Version 1.12.7 -Version 1.12.7 -============== **November 22, 2019** This a very minor hotfix release fixing an important bug related to @@ -1583,9 +1624,8 @@ Bug fixes: - Fixed shared_axes/axiswise regression ([#4097](https://github.com/holoviz/holoviews/pull/4097)) +# Version 1.12.6 -Version 1.12.6 -============== **October 8, 2019** This is a minor release containing a large number of bug fixes thanks @@ -1601,7 +1641,7 @@ Enhancements: ([#3952](https://github.com/pyviz/holoviews/issues/3952)) - Add support for dependent functions in dynamic operations ([#3975](https://github.com/pyviz/holoviews/issues/3975), - [#3980](https://github.com/pyviz/holoviews/issues/3980)) + [#3980](https://github.com/pyviz/holoviews/issues/3980)) - Add support for fast QuadMesh rasterization with datashader >= 0.8 ([#4020](https://github.com/pyviz/holoviews/issues/4020)) - Allow passing Panel widgets as operation parameter @@ -1619,7 +1659,7 @@ Bug fixes: ([#3981](https://github.com/pyviz/holoviews/issues/3981)) - Ensure .apply work correctly on HoloMaps ([#3989](https://github.com/pyviz/holoviews/issues/3989), - [#4025](https://github.com/pyviz/holoviews/issues/4025)) + [#4025](https://github.com/pyviz/holoviews/issues/4025)) - Ensure Grid axes are always aligned in bokeh ([#3916](https://github.com/pyviz/holoviews/issues/3916)) - Fix hover tool on Image and Raster plots with inverted axis @@ -1650,8 +1690,8 @@ Compatibility: - Ensure compatibility with new legend options in bokeh 1.4.0 ([#4036](https://github.com/pyviz/holoviews/issues/4036)) -Version 1.12.5 -============== +# Version 1.12.5 + **August 14, 2019** This is a very minor bug fix release ensuring compatibility with recent @@ -1665,8 +1705,8 @@ Compatibility: - Fix for rendering Scatter3D with matplotlib 3.1 ([#3898](https://github.com/pyviz/holoviews/issues/3898)) -Version 1.12.4 -============== +# Version 1.12.4 + **August 4, 2019** This is a minor release with a number of bug and compatibility fixes @@ -1734,8 +1774,8 @@ Backwards incompatible changes: box-whisker plots was fixed resulting in different results going forward. -Version 1.12.3 -============== +# Version 1.12.3 + **May 20, 2019** This is a minor release primarily focused on a number of important bug @@ -1769,8 +1809,8 @@ Bug fixes: - Ensure that param streams handle subobjects ([#3728](https://github.com/pyviz/holoviews/pull/3728)) -Version 1.12.2 -============== +# Version 1.12.2 + **May 1, 2019** This is a minor release with a number of important bug fixes and a @@ -1807,7 +1847,7 @@ Bug fixes: ([#3564](https://github.com/pyviz/holoviews/pull/3564)) - Fixed handling of datetimes on Path plots ([#3464](https://github.com/pyviz/holoviews/pull/3464), - [#3662](https://github.com/pyviz/holoviews/pull/3662)) + [#3662](https://github.com/pyviz/holoviews/pull/3662)) - Ensure that resampling operations do not cause event loops ([#3614](https://github.com/pyviz/holoviews/issues/3614)) @@ -1816,8 +1856,8 @@ Backward compatibility: - Added color cycles on Violin and BoxWhisker elements due to earlier regression ([#3592](https://github.com/pyviz/holoviews/pull/3592)) -Version 1.12.1 -============== +# Version 1.12.1 + **April 10, 2019** This is a minor release that pins to the newly released Bokeh 1.1 and @@ -1828,8 +1868,8 @@ Enhancements: - Add support for passing in parameter instances as streams ([#3616](https://github.com/pyviz/holoviews/pull/3616)) -Version 1.12.0 -============== +# Version 1.12.0 + **April 2, 2019** This release provides a number of exciting new features as well as a set @@ -1870,19 +1910,18 @@ Bug fixes: ([#3572](https://github.com/pyviz/holoviews/pull/3572), [#3590](https://github.com/pyviz/holoviews/pull/3590)) - Other miscellaneous fixes -([#3530](https://github.com/pyviz/holoviews/pull/3530), -[#3536](https://github.com/pyviz/holoviews/pull/3536), -[#3546](https://github.com/pyviz/holoviews/pull/3546), -[#3560](https://github.com/pyviz/holoviews/pull/3560), -[#3571](https://github.com/pyviz/holoviews/pull/3571), -[#3580](https://github.com/pyviz/holoviews/pull/3580), -[#3584](https://github.com/pyviz/holoviews/pull/3584), -[#3585](https://github.com/pyviz/holoviews/pull/3585), -[#3594](https://github.com/pyviz/holoviews/pull/3594)) - - -Version 1.11.3 -============== + ([#3530](https://github.com/pyviz/holoviews/pull/3530), + [#3536](https://github.com/pyviz/holoviews/pull/3536), + [#3546](https://github.com/pyviz/holoviews/pull/3546), + [#3560](https://github.com/pyviz/holoviews/pull/3560), + [#3571](https://github.com/pyviz/holoviews/pull/3571), + [#3580](https://github.com/pyviz/holoviews/pull/3580), + [#3584](https://github.com/pyviz/holoviews/pull/3584), + [#3585](https://github.com/pyviz/holoviews/pull/3585), + [#3594](https://github.com/pyviz/holoviews/pull/3594)) + +# Version 1.11.3 + **February 25, 2019** This is the last micro-release in the 1.11 series providing a number @@ -1926,8 +1965,8 @@ Enhancements: - Added Tiles element from GeoViews ([#3515](https://github.com/pyviz/holoviews/pull/3515)) -Version 1.11.2 -============== +# Version 1.11.2 + **January 28, 2019** This is a minor bug fix release with a number of small but important @@ -1951,9 +1990,8 @@ Enhancements: - Improvements for handling graph attributes in Graph.from_networkx ([#3432](https://github.com/pyviz/holoviews/pull/3432)) +# Version 1.11.1 -Version 1.11.1 -============== **January 17, 2019** This is a minor bug fix release with a number of important bug fixes, @@ -1992,11 +2030,10 @@ Documentation: - Completed updates from .options to .opts API in the documentation ([#3364]((https://github.com/pyviz/holoviews/pull/3364), - [#3367]((https://github.com/pyviz/holoviews/pull/3367)) + [#3367](<(https://github.com/pyviz/holoviews/pull/3367)>) +# Version 1.11.0 -Version 1.11.0 -============== **December 24, 2018** This is a major release containing a large number of features and API @@ -2097,12 +2134,10 @@ Deprecations: marked for deprecation ([#3128](https://github.com/pyviz/holoviews/pull/3128)) +# Version 1.10.8 -Version 1.10.8 -============== **October 29, 2018** - This a likely the last hotfix release in the 1.10.x series containing fixes for compatibility with bokeh 1.0 and matplotlib 3.0. It also contains a wide array of fixes contributed and reported by users: @@ -2174,8 +2209,8 @@ Documentation: [#2959](https://github.com/pyviz/holoviews/pull/2959), [#3025](https://github.com/pyviz/holoviews/pull/3025)) -Version 1.10.7 -============== +# Version 1.10.7 + **July 8, 2018** This a very minor hotfix release mostly containing fixes for datashader @@ -2193,9 +2228,8 @@ Fixes: - Fixed ticks on log Colorbar if low value <= 0 ([#2865](https://github.com/pyviz/holoviews/pull/2865)) +# Version 1.10.6 -Version 1.10.6 -============== **June 29, 2018** This another minor bug fix release in the 1.10 series and likely the @@ -2226,9 +2260,8 @@ Fixes: zero range ([#2829](https://github.com/pyviz/holoviews/pull/2829), [#2842](https://github.com/pyviz/holoviews/pull/2842)) +# Version 1.10.5 -Version 1.10.5 -============== **June 5, 2018** This is a minor bug fix release containing a mixture of small @@ -2246,7 +2279,7 @@ Enhancements: ([#2719](https://github.com/pyviz/holoviews/pull/2719)) - Legends on NdOverlay containing overlays now supported ([#2755](https://github.com/pyviz/holoviews/pull/2755)) -- Dataframe indexes may now be referenced in ``.to`` conversion +- Dataframe indexes may now be referenced in `.to` conversion ([#2739](https://github.com/pyviz/holoviews/pull/2739)) - Reindexing a gridded Dataset without arguments now behaves consistently with NdMapping types and drops scalar dimensions making @@ -2272,9 +2305,8 @@ Compatibility: [#2725](https://github.com/pyviz/holoviews/pull/2725), [#2767](https://github.com/pyviz/holoviews/pull/2767)) +# Version 1.10.4 -Version 1.10.4 -============== **May 14, 2018** This is a minor bug fix release including a number of crucial fixes @@ -2294,8 +2326,8 @@ Fixes: - Fixed bug slicing xarray with tuples ([#2674](https://github.com/pyviz/holoviews/pull/2674)) -Version 1.10.3 -============== +# Version 1.10.3 + **May 8, 2018** This is a minor bug fix release including a number of crucial fixes @@ -2309,14 +2341,14 @@ Enhancement: Fixes: -- Fix for ``labelled`` plot option +- Fix for `labelled` plot option ([#2643](https://github.com/pyviz/holoviews/pull/2643)) - Optimized initialization of dynamic plots specifying a large parameter space ([#2646](https://github.com/pyviz/holoviews/pull/2646)) - Fixed unicode and reversed axis slicing issues in XArrayInterface ([#2658](https://github.com/pyviz/holoviews/issues/2658), - [#2653](https://github.com/pyviz/holoviews/pull/2653)) + [#2653](https://github.com/pyviz/holoviews/pull/2653)) - Fixed widget sorting issues when applying dynamic groupby ([#2641](https://github.com/pyviz/holoviews/issues/2641)) @@ -2329,8 +2361,8 @@ API: keys for consistency ([#2650](https://github.com/pyviz/holoviews/issues/2650)) -Version 1.10.2 -============== +# Version 1.10.2 + **April 30, 2018** This is a minor bug fix release with a number of small fixes for @@ -2358,13 +2390,12 @@ Fixes: Deprecations: -- BoxWhisker and Bars ``width`` bokeh style options and Arrow - matplotlib ``fontsize`` option are deprecated +- BoxWhisker and Bars `width` bokeh style options and Arrow + matplotlib `fontsize` option are deprecated ([#2411](https://github.com/pyviz/holoviews/issues/2411)) +# Version 1.10.1 -Version 1.10.1 -============== **April 20, 2018** This is a minor bug fix release with a number of fixes for regressions @@ -2381,9 +2412,8 @@ Fixes: - Fixed Selection1D stream on bokeh server after changes in bokeh 0.12.15 ([#2586](https://github.com/pyviz/holoviews/pull/2586)) +# Version 1.10.0 -Version 1.10.0 -============== **April 17, 2018** This is a major release with a large number of new features and bug @@ -2392,7 +2422,6 @@ numerous users who filed bug reports, tested development versions, and contributed a number of new features and bug fixes, including special thanks to @mansenfranzen, @ea42gh, @drs251 and @jakirkham. - JupyterLab support: - Full compatibility with JupyterLab when installing the @@ -2401,42 +2430,42 @@ JupyterLab support: New components: -- Added [``Sankey`` element](http://holoviews.org/reference/elements/bokeh/Sankey.html) +- Added [`Sankey` element](http://holoviews.org/reference/elements/bokeh/Sankey.html) to plot directed flow graphs ([#1123](https://github.com/pyviz/holoviews/issues/1123)) -- Added [``TriMesh`` element](http://holoviews.org/reference/elements/bokeh/TriMesh.html) +- Added [`TriMesh` element](http://holoviews.org/reference/elements/bokeh/TriMesh.html) and datashading operation to plot small and large irregular meshes ([#2143](https://github.com/pyviz/holoviews/issues/2143)) -- Added a [``Chord`` element](http://holoviews.org/reference/elements/bokeh/Chord.html) +- Added a [`Chord` element](http://holoviews.org/reference/elements/bokeh/Chord.html) to draw flow graphs between different nodes ([#2137](https://github.com/pyviz/holoviews/issues/2137), [#2143](https://github.com/pyviz/holoviews/pull/2143)) -- Added [``HexTiles`` element](http://holoviews.org/reference/elements/bokeh/HexTiles.html) +- Added [`HexTiles` element](http://holoviews.org/reference/elements/bokeh/HexTiles.html) to plot data binned into a hexagonal grid ([#1141](https://github.com/pyviz/holoviews/issues/1141)) -- Added [``Labels`` element](http://holoviews.org/reference/elements/bokeh/Labels.html) +- Added [`Labels` element](http://holoviews.org/reference/elements/bokeh/Labels.html) to plot a large number of text labels at once (as data rather than as annotations) ([#1837](https://github.com/pyviz/holoviews/issues/1837)) -- Added [``Div`` element](http://holoviews.org/reference/elements/bokeh/Div.html) +- Added [`Div` element](http://holoviews.org/reference/elements/bokeh/Div.html) to add arbitrary HTML elements to a Bokeh layout ([#2221](https://github.com/pyviz/holoviews/issues/2221)) - Added - [``PointDraw``](http://holoviews.org/reference/streams/bokeh/PointDraw.html), - [``PolyDraw``](http://holoviews.org/reference/streams/bokeh/PolyDraw.html), - [``BoxEdit``](http://holoviews.org/reference/streams/bokeh/BoxEdit.html), and - [``PolyEdit``](http://holoviews.org/reference/streams/bokeh/PolyEdit.html) + [`PointDraw`](http://holoviews.org/reference/streams/bokeh/PointDraw.html), + [`PolyDraw`](http://holoviews.org/reference/streams/bokeh/PolyDraw.html), + [`BoxEdit`](http://holoviews.org/reference/streams/bokeh/BoxEdit.html), and + [`PolyEdit`](http://holoviews.org/reference/streams/bokeh/PolyEdit.html) streams to allow drawing, editing, and annotating glyphs on a Bokeh plot, and syncing the resulting data to Python ([#2268](https://github.com/pyviz/holoviews/issues/2459)) Features: -- Added [radial ``HeatMap``](http://holoviews.org/reference/elements/bokeh/RadialHeatMap.html) +- Added [radial `HeatMap`](http://holoviews.org/reference/elements/bokeh/RadialHeatMap.html) option to allow plotting heatmaps with a cyclic x-axis ([#2139](https://github.com/pyviz/holoviews/pull/2139)) - All elements now support declaring bin edges as well as centers - allowing ``Histogram`` and ``QuadMesh`` to become first class - ``Dataset`` types + allowing `Histogram` and `QuadMesh` to become first class + `Dataset` types ([#547](https://github.com/pyviz/holoviews/issues/547)) - When using widgets, their initial or default value can now be set via the `Dimension.default` parameter @@ -2452,7 +2481,7 @@ Enhancements: - Improvements to exceptions ([#1127](https://github.com/pyviz/holoviews/issues/1127)) -- Toolbar position and merging (via a new ``merge_toolbar`` +- Toolbar position and merging (via a new `merge_toolbar` option) can now be controlled for Layout and Grid plots ([#1977](https://github.com/pyviz/holoviews/issues/1977)) - Bokeh themes can now be applied at the renderer level @@ -2460,8 +2489,8 @@ Enhancements: - Dataframe and Series index can now be referenced by name when constructing an element ([#2000](https://github.com/pyviz/holoviews/issues/2000)) -- Option-setting methods such as ``.opts``, ``.options`` and - ``hv.opts`` now allow specifying the backend instead of defaulting +- Option-setting methods such as `.opts`, `.options` and + `hv.opts` now allow specifying the backend instead of defaulting to the current backend ([#1801](https://github.com/pyviz/holoviews/issues/1801)) - Handled API changes in streamz 0.3.0 in Buffer stream @@ -2469,23 +2498,23 @@ Enhancements: - Supported GIF output on windows using new Matplotlib pillow animation support ([#385](https://github.com/pyviz/holoviews/issues/385)) -- Provided simplified interface to ``rasterize`` most element types +- Provided simplified interface to `rasterize` most element types using datashader ([#2465](https://github.com/pyviz/holoviews/pull/2465)) -- ``Bivariate`` element now support ``levels`` as a plot option +- `Bivariate` element now support `levels` as a plot option ([#2099](https://github.com/pyviz/holoviews/issues/2099)) -- ``NdLayout`` and ``GridSpace`` now consistently support ``*`` +- `NdLayout` and `GridSpace` now consistently support `*` overlay operation ([#2075](https://github.com/pyviz/holoviews/issues/2075)) - The Bokeh backend no longer has a hard dependency on Matplotlib ([#829](https://github.com/pyviz/holoviews/issues/829)) -- ``DynamicMap`` may now return (``Nd``)``Overlay`` with varying +- `DynamicMap` may now return (`Nd`)`Overlay` with varying number of elements ([#1388](https://github.com/pyviz/holoviews/issues/1388)) - In the notebook, deleting or re-executing a cell will now delete the plot and clean up any attached streams ([#2141](https://github.com/pyviz/holoviews/issues/2141)) -- Added ``color_levels`` plot option to set discrete number of levels +- Added `color_levels` plot option to set discrete number of levels during colormapping ([#2483](https://github.com/pyviz/holoviews/pull/2483)) - Expanded the [Large Data](http://holoviews.org/user_guide/Large_Data.html) @@ -2494,27 +2523,26 @@ Enhancements: Fixes: -- ``Layout`` and ``Overlay`` objects no longer create lower-case nodes +- `Layout` and `Overlay` objects no longer create lower-case nodes on attribute access ([#2331](https://github.com/pyviz/holoviews/pull/2331)) -- ``Dimension.step`` now correctly respects both integer and float +- `Dimension.step` now correctly respects both integer and float steps ([#1707](https://github.com/pyviz/holoviews/issues/1707)) - Fixed timezone issues when using linked streams on datetime axes ([#2459](https://github.com/pyviz/holoviews/issues/2459)) - Changes affecting backwards compatibility: - Image elements now expect and validate regular sampling ([#1869](https://github.com/pyviz/holoviews/issues/1869)); for genuinely irregularly sampled data QuadMesh should be used. -- Tabular elements will no longer default to use ``ArrayInterface``, +- Tabular elements will no longer default to use `ArrayInterface`, instead preferring pandas and dictionary data formats ([#1236](https://github.com/pyviz/holoviews/issues/1236)) -- ``Cycle``/``Palette`` values are no longer zipped together; instead +- `Cycle`/`Palette` values are no longer zipped together; instead they now cycle independently ([#2333](https://github.com/pyviz/holoviews/pull/2333)) -- The default color ``Cycle`` was expanded to provide more unique colors +- The default color `Cycle` was expanded to provide more unique colors ([#2483](https://github.com/pyviz/holoviews/pull/2483)) - Categorical colormapping was made consistent across backends, changing the behavior of categorical Matplotlib colormaps @@ -2523,9 +2551,8 @@ Changes affecting backwards compatibility: single column is supplied no integer index column is added automatically ([#2522](https://github.com/pyviz/holoviews/pull/2522)) +# Version 1.9.5 -Version 1.9.5 -============= **March 2, 2018** This release includes a very small number of minor bugfixes and a new @@ -2533,37 +2560,35 @@ feature to simplify setting options in python: Enhancements: -- Added .options method for simplified options setting. - ([\#2306](https://github.com/pyviz/holoviews/pull/2306)) +- Added .options method for simplified options setting. + ([\#2306](https://github.com/pyviz/holoviews/pull/2306)) Fixes: -- Allow plotting bytes datausing the Bokeh backend in python3 - ([\#2357](https://github.com/pyviz/holoviews/pull/2357)) -- Allow .range to work on data with heterogeneous types in Python 3 - ([\#2345](https://github.com/pyviz/holoviews/pull/2345)) -- Fixed bug streaming data containing datetimes using bokeh>=0.12.14 - ([\#2383](https://github.com/pyviz/holoviews/pull/2383)) +- Allow plotting bytes datausing the Bokeh backend in python3 + ([\#2357](https://github.com/pyviz/holoviews/pull/2357)) +- Allow .range to work on data with heterogeneous types in Python 3 + ([\#2345](https://github.com/pyviz/holoviews/pull/2345)) +- Fixed bug streaming data containing datetimes using bokeh>=0.12.14 + ([\#2383](https://github.com/pyviz/holoviews/pull/2383)) +# Version 1.9.4 -Version 1.9.4 -============= **February 16, 2018** This release contains a small number of important bug fixes: -- Compatibility with recent versions of Dask and pandas - ([\#2329](https://github.com/pyviz/holoviews/pull/2329)) -- Fixed bug referencing columns containing non-alphanumeric characters - in Bokeh Tables ([\#2336](https://github.com/pyviz/holoviews/pull/2336)) -- Fixed issue in regrid operation - ([2337](https://github.com/pyviz/holoviews/pull/2337)) -- Fixed issue when using datetimes with datashader when processing - ranges ([\#2344](https://github.com/pyviz/holoviews/pull/2344)) +- Compatibility with recent versions of Dask and pandas + ([\#2329](https://github.com/pyviz/holoviews/pull/2329)) +- Fixed bug referencing columns containing non-alphanumeric characters + in Bokeh Tables ([\#2336](https://github.com/pyviz/holoviews/pull/2336)) +- Fixed issue in regrid operation + ([2337](https://github.com/pyviz/holoviews/pull/2337)) +- Fixed issue when using datetimes with datashader when processing + ranges ([\#2344](https://github.com/pyviz/holoviews/pull/2344)) +# Version 1.9.3 -Version 1.9.3 -============= **February 11, 2018** This release contains a number of important bug fixes and minor @@ -2574,53 +2599,51 @@ number of fixes and improvements to the documentation. Enhancements: -- Optimized rendering of stream based OverlayPlots - ([\#2253](https://github.com/pyviz/holoviews/pull/2253)) -- Added ``merge_toolbars`` and ``toolbar`` options to control - toolbars on ``Layout`` and Grid plots - ([\#2289](https://github.com/pyviz/holoviews/pull/2289)) -- Optimized rendering of ``VectorField`` - ([\#2314](https://github.com/pyviz/holoviews/pull/2289)) -- Improvements to documentation - ([\#2198](https://github.com/pyviz/holoviews/pull/2198), - [\#2220](https://github.com/pyviz/holoviews/pull/2220), - [\#2233](https://github.com/pyviz/holoviews/pull/2233), - [\#2235](https://github.com/pyviz/holoviews/pull/2235), - [\#2316](https://github.com/pyviz/holoviews/pull/2316)) -- Improved Bokeh ``Table`` formatting - ([\#2267](https://github.com/pyviz/holoviews/pull/2267)) -- Added support for handling datetime.date types - ([\#2267](https://github.com/pyviz/holoviews/pull/2267)) -- Add support for pre- and post-process hooks on operations - ([\#2246](https://github.com/pyviz/holoviews/pull/2246), - [\#2334](https://github.com/pyviz/holoviews/pull/2334)) +- Optimized rendering of stream based OverlayPlots + ([\#2253](https://github.com/pyviz/holoviews/pull/2253)) +- Added `merge_toolbars` and `toolbar` options to control + toolbars on `Layout` and Grid plots + ([\#2289](https://github.com/pyviz/holoviews/pull/2289)) +- Optimized rendering of `VectorField` + ([\#2314](https://github.com/pyviz/holoviews/pull/2289)) +- Improvements to documentation + ([\#2198](https://github.com/pyviz/holoviews/pull/2198), + [\#2220](https://github.com/pyviz/holoviews/pull/2220), + [\#2233](https://github.com/pyviz/holoviews/pull/2233), + [\#2235](https://github.com/pyviz/holoviews/pull/2235), + [\#2316](https://github.com/pyviz/holoviews/pull/2316)) +- Improved Bokeh `Table` formatting + ([\#2267](https://github.com/pyviz/holoviews/pull/2267)) +- Added support for handling datetime.date types + ([\#2267](https://github.com/pyviz/holoviews/pull/2267)) +- Add support for pre- and post-process hooks on operations + ([\#2246](https://github.com/pyviz/holoviews/pull/2246), + [\#2334](https://github.com/pyviz/holoviews/pull/2334)) Fixes: -- Fix for Bokeh server widgets - ([\#2218](https://github.com/pyviz/holoviews/pull/2218)) -- Fix using event based streams on Bokeh server - ([\#2239](https://github.com/pyviz/holoviews/pull/2239), - [\#2256](https://github.com/pyviz/holoviews/pull/2256)) -- Switched to drawing ``Distribution``, ``Area`` and ``Spread`` - using patch glyphs in Bokeh fixing legends - ([\#2225](https://github.com/pyviz/holoviews/pull/2225)) -- Fixed categorical coloring of ``Polygons``/``Path`` elements in - Matplotlib ([\#2259](https://github.com/pyviz/holoviews/pull/2259)) -- Fixed bug computing categorical datashader aggregates - ([\#2295](https://github.com/pyviz/holoviews/pull/2295)) -- Allow using ``Empty`` object in ``AdjointLayout`` - ([\#2275](https://github.com/pyviz/holoviews/pull/2275)) - +- Fix for Bokeh server widgets + ([\#2218](https://github.com/pyviz/holoviews/pull/2218)) +- Fix using event based streams on Bokeh server + ([\#2239](https://github.com/pyviz/holoviews/pull/2239), + [\#2256](https://github.com/pyviz/holoviews/pull/2256)) +- Switched to drawing `Distribution`, `Area` and `Spread` + using patch glyphs in Bokeh fixing legends + ([\#2225](https://github.com/pyviz/holoviews/pull/2225)) +- Fixed categorical coloring of `Polygons`/`Path` elements in + Matplotlib ([\#2259](https://github.com/pyviz/holoviews/pull/2259)) +- Fixed bug computing categorical datashader aggregates + ([\#2295](https://github.com/pyviz/holoviews/pull/2295)) +- Allow using `Empty` object in `AdjointLayout` + ([\#2275](https://github.com/pyviz/holoviews/pull/2275)) API Changes: -- Renamed ``Trisurface`` to ``TriSurface`` for future consistency - ([\#2219](https://github.com/pyviz/holoviews/pull/2219)) +- Renamed `Trisurface` to `TriSurface` for future consistency + ([\#2219](https://github.com/pyviz/holoviews/pull/2219)) +# Version 1.9.2 -Version 1.9.2 -============= **December 11, 2017** This release is a minor bug fix release patching various issues @@ -2628,34 +2651,33 @@ which were found in the 1.9.1 release. Enhancements: -- Improved the Graph element, optimizing the constructor - and adding support for defining a `edge_color_index` - ([\#2145](https://github.com/pyviz/holoviews/pull/2145)) -- Added support for adding jitter to Bokeh Scatter and Points plots - ([e56208](https://github.com/pyviz/holoviews/commit/e56208e1eb6e1e4af67b6a3ffbb5a925bfc37e14)) +- Improved the Graph element, optimizing the constructor + and adding support for defining a `edge_color_index` + ([\#2145](https://github.com/pyviz/holoviews/pull/2145)) +- Added support for adding jitter to Bokeh Scatter and Points plots + ([e56208](https://github.com/pyviz/holoviews/commit/e56208e1eb6e1e4af67b6a3ffbb5a925bfc37e14)) Fixes: -- Ensure dimensions, group and label are inherited when casting - Image to QuadMesh - ([\#2144](https://github.com/pyviz/holoviews/pull/2144)) -- Handle compatibility for Bokeh version >= 0.12.11 - ([\#2159](https://github.com/pyviz/holoviews/pull/2159)) -- Fixed broken Bokeh ArrowPlot - ([\#2172](https://github.com/pyviz/holoviews/pull/2172)) -- Fixed Pointer based streams on datetime axes - ([\#2179](https://github.com/pyviz/holoviews/pull/2179)) -- Allow constructing and plotting of empty Distribution and - Bivariate elements - ([\#2190](https://github.com/pyviz/holoviews/pull/2190)) -- Added support for hover info on Bokeh BoxWhisker plots - ([\#2187](https://github.com/pyviz/holoviews/pull/2187)) -- Fixed bug attaching streams to (Nd)Overlay types - ([\#2194](https://github.com/pyviz/holoviews/pull/2194)) - - -Version 1.9.1 -============= +- Ensure dimensions, group and label are inherited when casting + Image to QuadMesh + ([\#2144](https://github.com/pyviz/holoviews/pull/2144)) +- Handle compatibility for Bokeh version >= 0.12.11 + ([\#2159](https://github.com/pyviz/holoviews/pull/2159)) +- Fixed broken Bokeh ArrowPlot + ([\#2172](https://github.com/pyviz/holoviews/pull/2172)) +- Fixed Pointer based streams on datetime axes + ([\#2179](https://github.com/pyviz/holoviews/pull/2179)) +- Allow constructing and plotting of empty Distribution and + Bivariate elements + ([\#2190](https://github.com/pyviz/holoviews/pull/2190)) +- Added support for hover info on Bokeh BoxWhisker plots + ([\#2187](https://github.com/pyviz/holoviews/pull/2187)) +- Fixed bug attaching streams to (Nd)Overlay types + ([\#2194](https://github.com/pyviz/holoviews/pull/2194)) + +# Version 1.9.1 + **November 13, 2017** This release is a minor bug fix release patching various issues @@ -2663,25 +2685,25 @@ which were found in the 1.9.0 release. Enhancements: -- Exposed min_alpha parameter on datashader shade and datashade - operations ([\#2109](https://github.com/pyviz/holoviews/pull/2109)) +- Exposed min_alpha parameter on datashader shade and datashade + operations ([\#2109](https://github.com/pyviz/holoviews/pull/2109)) Fixes: -- Fixed broken Bokeh server linked stream throttling - ([\#2112](https://github.com/pyviz/holoviews/pull/2112)) -- Fixed bug in Bokeh callbacks preventing linked streams using - Bokeh's on_event callbacks from working - ([\#2112](https://github.com/pyviz/holoviews/pull/2112)) -- Fixed insufficient validation issue for Image and bugs when - applying regrid operation to xarray based Images - ([\#2117](https://github.com/pyviz/holoviews/pull/2117)) -- Fixed handling of dimensions and empty elements in univariate_kde - and bivariate_kde operations - ([\#2103](https://github.com/pyviz/holoviews/pull/2103)) - -Version 1.9.0 -============= +- Fixed broken Bokeh server linked stream throttling + ([\#2112](https://github.com/pyviz/holoviews/pull/2112)) +- Fixed bug in Bokeh callbacks preventing linked streams using + Bokeh's on_event callbacks from working + ([\#2112](https://github.com/pyviz/holoviews/pull/2112)) +- Fixed insufficient validation issue for Image and bugs when + applying regrid operation to xarray based Images + ([\#2117](https://github.com/pyviz/holoviews/pull/2117)) +- Fixed handling of dimensions and empty elements in univariate_kde + and bivariate_kde operations + ([\#2103](https://github.com/pyviz/holoviews/pull/2103)) + +# Version 1.9.0 + **November 3, 2017** This release includes a large number of long awaited features, @@ -2694,81 +2716,80 @@ issues and submitted pull requests. Features: -- The kdim and vdim keyword arguments are now positional making the - declaration of elements less verbose (e.g. Scatter(data, 'x', - 'y')) ([\#1946](https://github.com/pyviz/holoviews/pull/1946)) -- Added Graph, Nodes, and EdgePaths elements adding support for - plotting network graphs - ([\#1829](https://github.com/pyviz/holoviews/pull/1829)) -- Added datashader based regrid operation for fast Image and RGB - regridding ([\#1773](https://github.com/pyviz/holoviews/pull/1773)) -- Added support for binary transport when plotting with Bokeh, - providing huge speedups for dynamic plots - ([\#1894](https://github.com/pyviz/holoviews/pull/1894), - [\#1896](https://github.com/pyviz/holoviews/pull/1896)) -- Added Pipe and Buffer streams for streaming data support - ([\#2011](https://github.com/pyviz/holoviews/pull/2011)) -- Add support for datetime axes on Image, RGB and when applying - datashading and regridding operations - ([\#2023](https://github.com/pyviz/holoviews/pull/2023)) -- Added Distribution and Bivariate as first class elements which can - be plotted with Matplotlib and Bokeh without depending on seaborn - ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) -- Completely overhauled support for plotting geometries with Path, - Contours and Polygons elements including support for coloring - individual segments and paths by value - ([\#1991](https://github.com/pyviz/holoviews/pull/1991)) +- The kdim and vdim keyword arguments are now positional making the + declaration of elements less verbose (e.g. Scatter(data, 'x', + 'y')) ([\#1946](https://github.com/pyviz/holoviews/pull/1946)) +- Added Graph, Nodes, and EdgePaths elements adding support for + plotting network graphs + ([\#1829](https://github.com/pyviz/holoviews/pull/1829)) +- Added datashader based regrid operation for fast Image and RGB + regridding ([\#1773](https://github.com/pyviz/holoviews/pull/1773)) +- Added support for binary transport when plotting with Bokeh, + providing huge speedups for dynamic plots + ([\#1894](https://github.com/pyviz/holoviews/pull/1894), + [\#1896](https://github.com/pyviz/holoviews/pull/1896)) +- Added Pipe and Buffer streams for streaming data support + ([\#2011](https://github.com/pyviz/holoviews/pull/2011)) +- Add support for datetime axes on Image, RGB and when applying + datashading and regridding operations + ([\#2023](https://github.com/pyviz/holoviews/pull/2023)) +- Added Distribution and Bivariate as first class elements which can + be plotted with Matplotlib and Bokeh without depending on seaborn + ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) +- Completely overhauled support for plotting geometries with Path, + Contours and Polygons elements including support for coloring + individual segments and paths by value + ([\#1991](https://github.com/pyviz/holoviews/pull/1991)) Enhancements: -- Add support for adjoining all elements on Matplotlib plots - ([\#1033](https://github.com/pyviz/holoviews/pull/1033)) -- Improved exception handling for data interfaces - ([\#2041](https://github.com/pyviz/holoviews/pull/2041)) -- Add groupby argument to histogram operation - ([\#1725](https://github.com/pyviz/holoviews/pull/1725)) -- Add support for reverse sort on Dataset elements - ([\#1843](https://github.com/pyviz/holoviews/pull/1843)) -- Added support for invert_x/yaxis on all elements - ([\#1872](https://github.com/pyviz/holoviews/pull/1872), - [\#1919](https://github.com/pyviz/holoviews/pull/1919)) +- Add support for adjoining all elements on Matplotlib plots + ([\#1033](https://github.com/pyviz/holoviews/pull/1033)) +- Improved exception handling for data interfaces + ([\#2041](https://github.com/pyviz/holoviews/pull/2041)) +- Add groupby argument to histogram operation + ([\#1725](https://github.com/pyviz/holoviews/pull/1725)) +- Add support for reverse sort on Dataset elements + ([\#1843](https://github.com/pyviz/holoviews/pull/1843)) +- Added support for invert_x/yaxis on all elements + ([\#1872](https://github.com/pyviz/holoviews/pull/1872), + [\#1919](https://github.com/pyviz/holoviews/pull/1919)) Fixes: -- Fixed a bug in Matplotlib causing the first frame in gif and mp4 - getting stuck - ([\#1922](https://github.com/pyviz/holoviews/pull/1922)) -- Fixed various issues with support for new nested categorical axes - in Bokeh ([\#1933](https://github.com/pyviz/holoviews/pull/1933)) -- A large range of other bug fixes too long to list here. +- Fixed a bug in Matplotlib causing the first frame in gif and mp4 + getting stuck + ([\#1922](https://github.com/pyviz/holoviews/pull/1922)) +- Fixed various issues with support for new nested categorical axes + in Bokeh ([\#1933](https://github.com/pyviz/holoviews/pull/1933)) +- A large range of other bug fixes too long to list here. Changes affecting backwards compatibility: -- The contours operation no longer overlays the contours on top of - the supplied Image by default and returns a single - Contours/Polygons rather than an NdOverlay of them - ([\#1991](https://github.com/pyviz/holoviews/pull/1991)) -- The values of the Distribution element should now be defined as a - key dimension - ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) -- The seaborn interface was removed in its entirety being replaced - by first class support for statistics elements such as - Distribution and Bivariate - ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) -- Since kdims and vdims can now be passed as positional arguments - the bounds argument on Image is no longer positional - ([\#1946](https://github.com/pyviz/holoviews/pull/1946)). -- The datashade and shade cmap was reverted back to blue due to issues - with the fire cmap against a white background. - ([\#2078](https://github.com/pyviz/holoviews/pull/2078)) -- Dropped all support for Bokeh versions older than 0.12.10 -- histogram operation now returns Histogram elements with less - generic value dimension and customizable label - ([\#1836](https://github.com/pyviz/holoviews/pull/1836)) - - -Version 1.8.4 -============= +- The contours operation no longer overlays the contours on top of + the supplied Image by default and returns a single + Contours/Polygons rather than an NdOverlay of them + ([\#1991](https://github.com/pyviz/holoviews/pull/1991)) +- The values of the Distribution element should now be defined as a + key dimension + ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) +- The seaborn interface was removed in its entirety being replaced + by first class support for statistics elements such as + Distribution and Bivariate + ([\#1985](https://github.com/pyviz/holoviews/pull/1985)) +- Since kdims and vdims can now be passed as positional arguments + the bounds argument on Image is no longer positional + ([\#1946](https://github.com/pyviz/holoviews/pull/1946)). +- The datashade and shade cmap was reverted back to blue due to issues + with the fire cmap against a white background. + ([\#2078](https://github.com/pyviz/holoviews/pull/2078)) +- Dropped all support for Bokeh versions older than 0.12.10 +- histogram operation now returns Histogram elements with less + generic value dimension and customizable label + ([\#1836](https://github.com/pyviz/holoviews/pull/1836)) + +# Version 1.8.4 + **September 13, 2017** This bugfix release includes a number of critical fixes for compatibility @@ -2777,25 +2798,24 @@ users for various detailed bug reports, feedback and contributions. Fixes: -- Fixes to register BoundsXY stream. - ([\#1826](https://github.com/pyviz/holoviews/pull/1826)) -- Fix for Bounds streams on Bokeh server. - ([\#1883](https://github.com/pyviz/holoviews/pull/1883)) -- Compatibility with Matplotlib 2.1 - ([\#1842](https://github.com/pyviz/holoviews/pull/1842)) -- Fixed bug in scrubber widget and support for scrubbing discrete - DynamicMaps ([\#1832](https://github.com/pyviz/holoviews/pull/1832)) -- Various fixes for compatibility with Bokeh 0.12.9 - ([\#1849](https://github.com/pyviz/holoviews/pull/1849), - [\#1866](https://github.com/pyviz/holoviews/pull/1886)) -- Fixes for setting QuadMesh ranges. - ([\#1876](https://github.com/pyviz/holoviews/pull/1876)) -- Fixes for inverting Image/RGB/Raster axes in Bokeh. - ([\#1872](https://github.com/pyviz/holoviews/pull/1872)) - - -Version 1.8.3 -============= +- Fixes to register BoundsXY stream. + ([\#1826](https://github.com/pyviz/holoviews/pull/1826)) +- Fix for Bounds streams on Bokeh server. + ([\#1883](https://github.com/pyviz/holoviews/pull/1883)) +- Compatibility with Matplotlib 2.1 + ([\#1842](https://github.com/pyviz/holoviews/pull/1842)) +- Fixed bug in scrubber widget and support for scrubbing discrete + DynamicMaps ([\#1832](https://github.com/pyviz/holoviews/pull/1832)) +- Various fixes for compatibility with Bokeh 0.12.9 + ([\#1849](https://github.com/pyviz/holoviews/pull/1849), + [\#1866](https://github.com/pyviz/holoviews/pull/1886)) +- Fixes for setting QuadMesh ranges. + ([\#1876](https://github.com/pyviz/holoviews/pull/1876)) +- Fixes for inverting Image/RGB/Raster axes in Bokeh. + ([\#1872](https://github.com/pyviz/holoviews/pull/1872)) + +# Version 1.8.3 + **August 21, 2017** This bugfix release fixes a number of minor issues identified since the @@ -2803,27 +2823,26 @@ last release: Features: -- Add support for setting the Bokeh sizing_mode as a plot option - ([\#1813](https://github.com/pyviz/holoviews/pull/1813)) +- Add support for setting the Bokeh sizing_mode as a plot option + ([\#1813](https://github.com/pyviz/holoviews/pull/1813)) Fixes: -- Handle StopIteration on DynamicMap correctly. - ([\#1792](https://github.com/pyviz/holoviews/pull/1792)) -- Fix bug with linked streams on empty source element - ([\#1725](https://github.com/pyviz/holoviews/pull/1806)) -- Compatibility with latest datashader 0.6.0 release - ([\#1773](https://github.com/pyviz/holoviews/pull/1773)) -- Fixed missing HTML closing tag in extension - ([\#1797](https://github.com/pyviz/holoviews/issues/1797), - [\#1809](https://github.com/pyviz/holoviews/pull/1809)) -- Various fixes and improvements for documentation - ([\#1664](https://github.com/pyviz/holoviews/pull/1664), - [\#1796](https://github.com/pyviz/holoviews/pull/1796)) - - -Version 1.8.2 -============= +- Handle StopIteration on DynamicMap correctly. + ([\#1792](https://github.com/pyviz/holoviews/pull/1792)) +- Fix bug with linked streams on empty source element + ([\#1725](https://github.com/pyviz/holoviews/pull/1806)) +- Compatibility with latest datashader 0.6.0 release + ([\#1773](https://github.com/pyviz/holoviews/pull/1773)) +- Fixed missing HTML closing tag in extension + ([\#1797](https://github.com/pyviz/holoviews/issues/1797), + [\#1809](https://github.com/pyviz/holoviews/pull/1809)) +- Various fixes and improvements for documentation + ([\#1664](https://github.com/pyviz/holoviews/pull/1664), + [\#1796](https://github.com/pyviz/holoviews/pull/1796)) + +# Version 1.8.2 + **August 4, 2017** This bugfix release addresses a number of minor issues identified since @@ -2831,26 +2850,26 @@ the 1.8.1 release: Feature: -- Added support for groupby to histogram operation. - ([\#1725](https://github.com/pyviz/holoviews/pull/1725)) +- Added support for groupby to histogram operation. + ([\#1725](https://github.com/pyviz/holoviews/pull/1725)) Fixes: -- Fixed problem with HTML export due to new extension logos. - ([\#1778](https://github.com/pyviz/holoviews/pull/1778)) -- Replaced deprecated ``__call__`` usage with opts method throughout codebase. - ([\#1759](https://github.com/pyviz/holoviews/pull/1759), - [\#1763](https://github.com/pyviz/holoviews/pull/1763), - [\#1779](https://github.com/pyviz/holoviews/pull/1779)) -- Fixed pip installation. - ([\#1782](https://github.com/pyviz/holoviews/pull/1782)) -- Fixed miscellaneous bugs - ([\#1724](https://github.com/pyviz/holoviews/pull/1724), - [\#1739](https://github.com/pyviz/holoviews/pull/1739), - [\#1711](https://github.com/pyviz/holoviews/pull/1711)) - -Version 1.8.1 -============= +- Fixed problem with HTML export due to new extension logos. + ([\#1778](https://github.com/pyviz/holoviews/pull/1778)) +- Replaced deprecated `__call__` usage with opts method throughout codebase. + ([\#1759](https://github.com/pyviz/holoviews/pull/1759), + [\#1763](https://github.com/pyviz/holoviews/pull/1763), + [\#1779](https://github.com/pyviz/holoviews/pull/1779)) +- Fixed pip installation. + ([\#1782](https://github.com/pyviz/holoviews/pull/1782)) +- Fixed miscellaneous bugs + ([\#1724](https://github.com/pyviz/holoviews/pull/1724), + [\#1739](https://github.com/pyviz/holoviews/pull/1739), + [\#1711](https://github.com/pyviz/holoviews/pull/1711)) + +# Version 1.8.1 + **July 7, 2017** This bugfix release addresses a number of minor issues identified since @@ -2858,40 +2877,40 @@ the 1.8 release: Feature: -- All enabled plotting extension logos now shown - ([\#1694](https://github.com/pyviz/holoviews/pull/1694)) +- All enabled plotting extension logos now shown + ([\#1694](https://github.com/pyviz/holoviews/pull/1694)) Fixes: -- Updated search ordering when looking for holoviews.rc - ([\#1700](https://github.com/pyviz/holoviews/pull/1700)) -- Fixed lower bound inclusivity bug when no upper bound supplied - ([\#1686](https://github.com/pyviz/holoviews/pull/1686)) -- Raise SkipRendering error when plotting nested layouts - ([\#1687](https://github.com/pyviz/holoviews/pull/1687)) -- Added safety margin for grid axis constraint issue - ([\#1695](https://github.com/pyviz/holoviews/pull/1685)) -- Fixed bug when using +framewise - ([\#1685](https://github.com/pyviz/holoviews/pull/1685)) -- Fixed handling of Spacer models in sparse grid - ([\#1682](https://github.com/pyviz/holoviews/pull/)) -- Renamed Bounds to BoundsXY for consistency - ([\#1672](https://github.com/pyviz/holoviews/pull/1672)) -- Fixed Bokeh log axes with axis lower bound <=0 - ([\#1691](https://github.com/pyviz/holoviews/pull/1691)) -- Set default datashader cmap to fire - ([\#1697](https://github.com/pyviz/holoviews/pull/1697)) -- Set SpikesPlot color index to None by default - ([\#1671](https://github.com/pyviz/holoviews/pull/1671)) -- Documentation fixes - ([\#1662](https://github.com/pyviz/holoviews/pull/1662), - [\#1665](https://github.com/pyviz/holoviews/pull/1665), - [\#1690](https://github.com/pyviz/holoviews/pull/1690), - [\#1692](https://github.com/pyviz/holoviews/pull/1692), - [\#1658](https://github.com/pyviz/holoviews/pull/1658)) - -Version 1.8.0 -============= +- Updated search ordering when looking for holoviews.rc + ([\#1700](https://github.com/pyviz/holoviews/pull/1700)) +- Fixed lower bound inclusivity bug when no upper bound supplied + ([\#1686](https://github.com/pyviz/holoviews/pull/1686)) +- Raise SkipRendering error when plotting nested layouts + ([\#1687](https://github.com/pyviz/holoviews/pull/1687)) +- Added safety margin for grid axis constraint issue + ([\#1695](https://github.com/pyviz/holoviews/pull/1685)) +- Fixed bug when using +framewise + ([\#1685](https://github.com/pyviz/holoviews/pull/1685)) +- Fixed handling of Spacer models in sparse grid + ([\#1682](https://github.com/pyviz/holoviews/pull/)) +- Renamed Bounds to BoundsXY for consistency + ([\#1672](https://github.com/pyviz/holoviews/pull/1672)) +- Fixed Bokeh log axes with axis lower bound <=0 + ([\#1691](https://github.com/pyviz/holoviews/pull/1691)) +- Set default datashader cmap to fire + ([\#1697](https://github.com/pyviz/holoviews/pull/1697)) +- Set SpikesPlot color index to None by default + ([\#1671](https://github.com/pyviz/holoviews/pull/1671)) +- Documentation fixes + ([\#1662](https://github.com/pyviz/holoviews/pull/1662), + [\#1665](https://github.com/pyviz/holoviews/pull/1665), + [\#1690](https://github.com/pyviz/holoviews/pull/1690), + [\#1692](https://github.com/pyviz/holoviews/pull/1692), + [\#1658](https://github.com/pyviz/holoviews/pull/1658)) + +# Version 1.8.0 + **June 29, 2017** This release includes a complete and long awaited overhaul of the @@ -2903,116 +2922,116 @@ new contributors for providing feedback, bug reports, and pull requests. Major features: -- Completely overhauled the documentation and website - ([\#1384](https://github.com/pyviz/holoviews/pull/1384), - [\#1473](https://github.com/pyviz/holoviews/pull/1473), - [\#1476](https://github.com/pyviz/holoviews/pull/1476), - [\#1473](https://github.com/pyviz/holoviews/pull/1473), - [\#1537](https://github.com/pyviz/holoviews/pull/1537), - [\#1585](https://github.com/pyviz/holoviews/pull/1585), - [\#1628](https://github.com/pyviz/holoviews/pull/1628), - [\#1636](https://github.com/pyviz/holoviews/pull/1636)) -- Replaced dependency on bkcharts with new Bokeh bar plot - ([\#1416](https://github.com/pyviz/holoviews/pull/1416)) and Bokeh - BoxWhisker plot - ([\#1604](https://github.com/pyviz/holoviews/pull/1604)) -- Added support for drawing the `Arrow` annotation in Bokeh - ([\#1608](https://github.com/pyviz/holoviews/pull/1608)) -- Added periodic method DynamicMap to schedule recurring events - ([\#1429](https://github.com/pyviz/holoviews/pull/1429)) -- Cleaned up the API for deploying to Bokeh server - ([\#1444](https://github.com/pyviz/holoviews/pull/1444), - [\#1469](https://github.com/pyviz/holoviews/pull/1469), - [\#1486](https://github.com/pyviz/holoviews/pull/1486)) -- Validation of invalid backend specific options - ([\#1465](https://github.com/pyviz/holoviews/pull/1465)) -- Added utilities and entry points to convert notebooks to scripts - including magics - ([\#1491](https://github.com/pyviz/holoviews/pull/1491)) -- Added support for rendering to png in Bokeh backend - ([\#1493](https://github.com/pyviz/holoviews/pull/1493)) -- Made Matplotlib and Bokeh styling more consistent and dropped custom - Matplotlib rc file - ([\#1518](https://github.com/pyviz/holoviews/pull/1518)) -- Added `iloc` and `ndloc` method to allow integer based indexing on - tabular and gridded datasets - ([\#1435](https://github.com/pyviz/holoviews/pull/1435)) -- Added option to restore case sensitive completion order by setting - `hv.extension.case_sensitive_completion=True` in python or via - holoviews.rc file - ([\#1613](https://github.com/pyviz/holoviews/pull/1613)) +- Completely overhauled the documentation and website + ([\#1384](https://github.com/pyviz/holoviews/pull/1384), + [\#1473](https://github.com/pyviz/holoviews/pull/1473), + [\#1476](https://github.com/pyviz/holoviews/pull/1476), + [\#1473](https://github.com/pyviz/holoviews/pull/1473), + [\#1537](https://github.com/pyviz/holoviews/pull/1537), + [\#1585](https://github.com/pyviz/holoviews/pull/1585), + [\#1628](https://github.com/pyviz/holoviews/pull/1628), + [\#1636](https://github.com/pyviz/holoviews/pull/1636)) +- Replaced dependency on bkcharts with new Bokeh bar plot + ([\#1416](https://github.com/pyviz/holoviews/pull/1416)) and Bokeh + BoxWhisker plot + ([\#1604](https://github.com/pyviz/holoviews/pull/1604)) +- Added support for drawing the `Arrow` annotation in Bokeh + ([\#1608](https://github.com/pyviz/holoviews/pull/1608)) +- Added periodic method DynamicMap to schedule recurring events + ([\#1429](https://github.com/pyviz/holoviews/pull/1429)) +- Cleaned up the API for deploying to Bokeh server + ([\#1444](https://github.com/pyviz/holoviews/pull/1444), + [\#1469](https://github.com/pyviz/holoviews/pull/1469), + [\#1486](https://github.com/pyviz/holoviews/pull/1486)) +- Validation of invalid backend specific options + ([\#1465](https://github.com/pyviz/holoviews/pull/1465)) +- Added utilities and entry points to convert notebooks to scripts + including magics + ([\#1491](https://github.com/pyviz/holoviews/pull/1491)) +- Added support for rendering to png in Bokeh backend + ([\#1493](https://github.com/pyviz/holoviews/pull/1493)) +- Made Matplotlib and Bokeh styling more consistent and dropped custom + Matplotlib rc file + ([\#1518](https://github.com/pyviz/holoviews/pull/1518)) +- Added `iloc` and `ndloc` method to allow integer based indexing on + tabular and gridded datasets + ([\#1435](https://github.com/pyviz/holoviews/pull/1435)) +- Added option to restore case sensitive completion order by setting + `hv.extension.case_sensitive_completion=True` in python or via + holoviews.rc file + ([\#1613](https://github.com/pyviz/holoviews/pull/1613)) Other new features and improvements: -- Optimized datashading of `NdOverlay` - ([\#1430](https://github.com/pyviz/holoviews/pull/1430)) -- Expose last `DynamicMap` args and kwargs on Callable - ([\#1453](https://github.com/pyviz/holoviews/pull/1453)) -- Allow colormapping `Contours` Element - ([\#1499](https://github.com/pyviz/holoviews/pull/1499)) -- Add support for fixed ticks with labels in Bokeh backend - ([\#1503](https://github.com/pyviz/holoviews/pull/1503)) -- Added a `clim` parameter to datashade controlling the color range - ([\#1508](https://github.com/pyviz/holoviews/pull/1508)) -- Add support for wrapping xarray DataArrays containing Dask arrays - ([\#1512](https://github.com/pyviz/holoviews/pull/1512)) -- Added support for aggregating to target `Image` dimensions in - datashader `aggregate` operation - ([\#1513](https://github.com/pyviz/holoviews/pull/1513)) -- Added top-level hv.extension and `hv.renderer` utilities - ([\#1517](https://github.com/pyviz/holoviews/pull/1517)) -- Added support for `Splines` defining multiple cubic splines in Bokeh - ([\#1529](https://github.com/pyviz/holoviews/pull/1529)) -- Add support for redim.label to quickly define dimension labels - ([\#1541](https://github.com/pyviz/holoviews/pull/1541)) -- Add `BoundsX` and `BoundsY` streams - ([\#1554](https://github.com/pyviz/holoviews/pull/1554)) -- Added support for adjoining empty plots - ([\#1561](https://github.com/pyviz/holoviews/pull/1561)) -- Handle zero-values correctly when using `logz` colormapping option - in Matplotlib - ([\#1576](https://github.com/pyviz/holoviews/pull/1576)) -- Define a number of `Cycle` and `Palette` defaults across backends - ([\#1605](https://github.com/pyviz/holoviews/pull/1605)) -- Many other small improvements and fixes - ([\#1399](https://github.com/pyviz/holoviews/pull/1399), - [\#1400](https://github.com/pyviz/holoviews/pull/1400), - [\#1405](https://github.com/pyviz/holoviews/pull/1405), - [\#1412](https://github.com/pyviz/holoviews/pull/1412), - [\#1413](https://github.com/pyviz/holoviews/pull/1413), - [\#1418](https://github.com/pyviz/holoviews/pull/1418), - [\#1439](https://github.com/pyviz/holoviews/pull/1439), - [\#1442](https://github.com/pyviz/holoviews/pull/1442), - [\#1443](https://github.com/pyviz/holoviews/pull/1443), - [\#1467](https://github.com/pyviz/holoviews/pull/1467), - [\#1485](https://github.com/pyviz/holoviews/pull/1485), - [\#1505](https://github.com/pyviz/holoviews/pull/1505), - [\#1493](https://github.com/pyviz/holoviews/pull/1493), - [\#1509](https://github.com/pyviz/holoviews/pull/1509), - [\#1524](https://github.com/pyviz/holoviews/pull/1524), - [\#1543](https://github.com/pyviz/holoviews/pull/1543), - [\#1547](https://github.com/pyviz/holoviews/pull/1547), - [\#1560](https://github.com/pyviz/holoviews/pull/1560), - [\#1603](https://github.com/pyviz/holoviews/pull/1603)) +- Optimized datashading of `NdOverlay` + ([\#1430](https://github.com/pyviz/holoviews/pull/1430)) +- Expose last `DynamicMap` args and kwargs on Callable + ([\#1453](https://github.com/pyviz/holoviews/pull/1453)) +- Allow colormapping `Contours` Element + ([\#1499](https://github.com/pyviz/holoviews/pull/1499)) +- Add support for fixed ticks with labels in Bokeh backend + ([\#1503](https://github.com/pyviz/holoviews/pull/1503)) +- Added a `clim` parameter to datashade controlling the color range + ([\#1508](https://github.com/pyviz/holoviews/pull/1508)) +- Add support for wrapping xarray DataArrays containing Dask arrays + ([\#1512](https://github.com/pyviz/holoviews/pull/1512)) +- Added support for aggregating to target `Image` dimensions in + datashader `aggregate` operation + ([\#1513](https://github.com/pyviz/holoviews/pull/1513)) +- Added top-level hv.extension and `hv.renderer` utilities + ([\#1517](https://github.com/pyviz/holoviews/pull/1517)) +- Added support for `Splines` defining multiple cubic splines in Bokeh + ([\#1529](https://github.com/pyviz/holoviews/pull/1529)) +- Add support for redim.label to quickly define dimension labels + ([\#1541](https://github.com/pyviz/holoviews/pull/1541)) +- Add `BoundsX` and `BoundsY` streams + ([\#1554](https://github.com/pyviz/holoviews/pull/1554)) +- Added support for adjoining empty plots + ([\#1561](https://github.com/pyviz/holoviews/pull/1561)) +- Handle zero-values correctly when using `logz` colormapping option + in Matplotlib + ([\#1576](https://github.com/pyviz/holoviews/pull/1576)) +- Define a number of `Cycle` and `Palette` defaults across backends + ([\#1605](https://github.com/pyviz/holoviews/pull/1605)) +- Many other small improvements and fixes + ([\#1399](https://github.com/pyviz/holoviews/pull/1399), + [\#1400](https://github.com/pyviz/holoviews/pull/1400), + [\#1405](https://github.com/pyviz/holoviews/pull/1405), + [\#1412](https://github.com/pyviz/holoviews/pull/1412), + [\#1413](https://github.com/pyviz/holoviews/pull/1413), + [\#1418](https://github.com/pyviz/holoviews/pull/1418), + [\#1439](https://github.com/pyviz/holoviews/pull/1439), + [\#1442](https://github.com/pyviz/holoviews/pull/1442), + [\#1443](https://github.com/pyviz/holoviews/pull/1443), + [\#1467](https://github.com/pyviz/holoviews/pull/1467), + [\#1485](https://github.com/pyviz/holoviews/pull/1485), + [\#1505](https://github.com/pyviz/holoviews/pull/1505), + [\#1493](https://github.com/pyviz/holoviews/pull/1493), + [\#1509](https://github.com/pyviz/holoviews/pull/1509), + [\#1524](https://github.com/pyviz/holoviews/pull/1524), + [\#1543](https://github.com/pyviz/holoviews/pull/1543), + [\#1547](https://github.com/pyviz/holoviews/pull/1547), + [\#1560](https://github.com/pyviz/holoviews/pull/1560), + [\#1603](https://github.com/pyviz/holoviews/pull/1603)) Changes affecting backwards compatibility: -- Renamed `ElementOperation` to `Operation` - ([\#1421](https://github.com/pyviz/holoviews/pull/1421)) -- Removed `stack_area` operation in favor of `Area.stack` classmethod - ([\#1515](https://github.com/pyviz/holoviews/pull/1515)) -- Removed all mpld3 support - ([\#1516](https://github.com/pyviz/holoviews/pull/1516)) -- Added `opts` method on all types, replacing the now-deprecated - `__call__` syntax to set options - ([\#1589](https://github.com/pyviz/holoviews/pull/1589)) -- Styling changes for both Matplotlib and Bokeh, which can be reverted - for a notebook with the `config` option of `hv.extension`. For - instance, `hv.extension('bokeh', config=dict(style_17=True))` - ([\#1518](https://github.com/pyviz/holoviews/pull/1518)) - -Version 1.7.0 -============= +- Renamed `ElementOperation` to `Operation` + ([\#1421](https://github.com/pyviz/holoviews/pull/1421)) +- Removed `stack_area` operation in favor of `Area.stack` classmethod + ([\#1515](https://github.com/pyviz/holoviews/pull/1515)) +- Removed all mpld3 support + ([\#1516](https://github.com/pyviz/holoviews/pull/1516)) +- Added `opts` method on all types, replacing the now-deprecated + `__call__` syntax to set options + ([\#1589](https://github.com/pyviz/holoviews/pull/1589)) +- Styling changes for both Matplotlib and Bokeh, which can be reverted + for a notebook with the `config` option of `hv.extension`. For + instance, `hv.extension('bokeh', config=dict(style_17=True))` + ([\#1518](https://github.com/pyviz/holoviews/pull/1518)) + +# Version 1.7.0 + **April 25, 2017** This version is a major new release incorporating seven months of work @@ -3028,421 +3047,421 @@ in the run-up to HoloViews 2.0. Major features and improvements: -- Interactive Streams API (PR - [\#832](https://github.com/pyviz/holoviews/pull/832), - [\#838](https://github.com/pyviz/holoviews/pull/838), - [\#842](https://github.com/pyviz/holoviews/pull/842), - [\#844](https://github.com/pyviz/holoviews/pull/844), - [\#845](https://github.com/pyviz/holoviews/pull/845), - [\#846](https://github.com/pyviz/holoviews/pull/846), - [\#858](https://github.com/pyviz/holoviews/pull/858), - [\#860](https://github.com/pyviz/holoviews/pull/860), - [\#889](https://github.com/pyviz/holoviews/pull/889), - [\#904](https://github.com/pyviz/holoviews/pull/904), - [\#913](https://github.com/pyviz/holoviews/pull/913), - [\#933](https://github.com/pyviz/holoviews/pull/933), - [\#962](https://github.com/pyviz/holoviews/pull/962), - [\#964](https://github.com/pyviz/holoviews/pull/964), - [\#1094](https://github.com/pyviz/holoviews/pull/1094), - [\#1256](https://github.com/pyviz/holoviews/pull/1256), - [\#1274](https://github.com/pyviz/holoviews/pull/1274), - [\#1297](https://github.com/pyviz/holoviews/pull/1297), - [\#1301](https://github.com/pyviz/holoviews/pull/1301), - [\#1303](https://github.com/pyviz/holoviews/pull/1303)). -- Dynamic Callable API (PR - [\#951](https://github.com/pyviz/holoviews/pull/951), - [\#1103](https://github.com/pyviz/holoviews/pull/1103), - [\#1029](https://github.com/pyviz/holoviews/pull/1029), - [\#968](https://github.com/pyviz/holoviews/pull/968), - [\#935](https://github.com/pyviz/holoviews/pull/935), - [\#1063](https://github.com/pyviz/holoviews/pull/1063), - [\#1260](https://github.com/pyviz/holoviews/pull/1260)). -- Simpler and more powerful DynamicMap (PR - [\#1238](https://github.com/pyviz/holoviews/pull/1238), - [\#1240](https://github.com/pyviz/holoviews/pull/1240), - [\#1243](https://github.com/pyviz/holoviews/pull/1243), - [\#1257](https://github.com/pyviz/holoviews/pull/1257), - [\#1267](https://github.com/pyviz/holoviews/pull/1267), - [\#1302](https://github.com/pyviz/holoviews/pull/1302), - [\#1304](https://github.com/pyviz/holoviews/pull/1304), - [\#1305](https://github.com/pyviz/holoviews/pull/1305)). -- Fully general support for Bokeh events (PR - [\#892](https://github.com/pyviz/holoviews/pull/892), - [\#1148](https://github.com/pyviz/holoviews/pull/1148), - [\#1235](https://github.com/pyviz/holoviews/pull/1235)). -- Datashader operations (PR - [\#894](https://github.com/pyviz/holoviews/pull/894), - [\#907](https://github.com/pyviz/holoviews/pull/907), - [\#963](https://github.com/pyviz/holoviews/pull/963), - [\#1125](https://github.com/pyviz/holoviews/pull/1125), - [\#1281](https://github.com/pyviz/holoviews/pull/1281), - [\#1306](https://github.com/pyviz/holoviews/pull/1306)). -- Support for Bokeh apps and Bokeh Server (PR - [\#959](https://github.com/pyviz/holoviews/pull/959), - [\#1283](https://github.com/pyviz/holoviews/pull/1283)). -- Working with renderers interactively outside the notebook (PR - [\#1214](https://github.com/pyviz/holoviews/pull/1214)). -- Support for Matplotlib 2.0 (PR - [\#867](https://github.com/pyviz/holoviews/pull/867), - [\#868](https://github.com/pyviz/holoviews/pull/868), - [\#1131](https://github.com/pyviz/holoviews/pull/1131), - [\#1264](https://github.com/pyviz/holoviews/pull/1264), - [\#1266](https://github.com/pyviz/holoviews/pull/1266)). -- Support for Bokeh 0.12.2, 0.12.3, 0.12.4, and 0.12.5 (PR - [\#899](https://github.com/pyviz/holoviews/pull/899), - [\#900](https://github.com/pyviz/holoviews/pull/900), - [\#1007](https://github.com/pyviz/holoviews/pull/1007), - [\#1036](https://github.com/pyviz/holoviews/pull/1036), - [\#1116](https://github.com/pyviz/holoviews/pull/1116)). -- Many new features for the Bokeh backend: widgets editable (PR - [\#1247](https://github.com/pyviz/holoviews/pull/1247)), selection - colors and interactive legends (PR - [\#1220](https://github.com/pyviz/holoviews/pull/1220)), GridSpace - axes (PR [\#1150](https://github.com/pyviz/holoviews/pull/1150)), - categorical axes and colormapping (PR - [\#1089](https://github.com/pyviz/holoviews/pull/1089), - [\#1137](https://github.com/pyviz/holoviews/pull/1137)), computing - plot size (PR - [\#1140](https://github.com/pyviz/holoviews/pull/1140)), GridSpaces - inside Layouts (PR - [\#1104](https://github.com/pyviz/holoviews/pull/1104)), Layout/Grid - titles (PR [\#1017](https://github.com/pyviz/holoviews/pull/1017)), - histogram with live colormapping (PR - [\#928](https://github.com/pyviz/holoviews/pull/928)), colorbars (PR - [\#861](https://github.com/pyviz/holoviews/pull/861)), - finalize\_hooks (PR - [\#1040](https://github.com/pyviz/holoviews/pull/1040)), labelled and - show\_frame options (PR - [\#863](https://github.com/pyviz/holoviews/pull/863), - [\#1013](https://github.com/pyviz/holoviews/pull/1013)), styling - hover glyphs (PR - [\#1286](https://github.com/pyviz/holoviews/pull/1286)), hiding - legends on BarPlot (PR - [\#837](https://github.com/pyviz/holoviews/pull/837)), VectorField - plot (PR [\#1196](https://github.com/pyviz/holoviews/pull/1196)), - Histograms now have same color cycle as mpl - ([\#1008](https://github.com/pyviz/holoviews/pull/1008)). -- Implemented convenience redim methods to easily set dimension - ranges, values etc. (PR - [\#1302](https://github.com/pyviz/holoviews/pull/1302)) -- Made methods on and operations applied to DynamicMap lazy - ([\#422](https://github.com/pyviz/holoviews/pull/422), - [\#588](https://github.com/pyviz/holoviews/pull/588), - [\#1188](https://github.com/pyviz/holoviews/pull/1188), - [\#1240](https://github.com/pyviz/holoviews/pull/1240), - [\#1227](https://github.com/pyviz/holoviews/pull/1227)) -- Improved documentation (PR - [\#936](https://github.com/pyviz/holoviews/pull/936), - [\#1070](https://github.com/pyviz/holoviews/pull/1070), - [\#1242](https://github.com/pyviz/holoviews/pull/1242), - [\#1273](https://github.com/pyviz/holoviews/pull/1273), - [\#1280](https://github.com/pyviz/holoviews/pull/1280)). -- Improved error handling (PR - [\#906](https://github.com/pyviz/holoviews/pull/906), - [\#932](https://github.com/pyviz/holoviews/pull/932), - [\#939](https://github.com/pyviz/holoviews/pull/939), - [\#949](https://github.com/pyviz/holoviews/pull/949), - [\#1011](https://github.com/pyviz/holoviews/pull/1011), - [\#1290](https://github.com/pyviz/holoviews/pull/1290), - [\#1262](https://github.com/pyviz/holoviews/pull/1262), - [\#1295](https://github.com/pyviz/holoviews/pull/1295)), including - re-enabling option system keyword validation (PR - [\#1277](https://github.com/pyviz/holoviews/pull/1277)). -- Improved testing (PR - [\#834](https://github.com/pyviz/holoviews/pull/834), - [\#871](https://github.com/pyviz/holoviews/pull/871), - [\#881](https://github.com/pyviz/holoviews/pull/881), - [\#941](https://github.com/pyviz/holoviews/pull/941), - [\#1117](https://github.com/pyviz/holoviews/pull/1117), - [\#1153](https://github.com/pyviz/holoviews/pull/1153), - [\#1171](https://github.com/pyviz/holoviews/pull/1171), - [\#1207](https://github.com/pyviz/holoviews/pull/1207), - [\#1246](https://github.com/pyviz/holoviews/pull/1246), - [\#1259](https://github.com/pyviz/holoviews/pull/1259), - [\#1287](https://github.com/pyviz/holoviews/pull/1287)). +- Interactive Streams API (PR + [\#832](https://github.com/pyviz/holoviews/pull/832), + [\#838](https://github.com/pyviz/holoviews/pull/838), + [\#842](https://github.com/pyviz/holoviews/pull/842), + [\#844](https://github.com/pyviz/holoviews/pull/844), + [\#845](https://github.com/pyviz/holoviews/pull/845), + [\#846](https://github.com/pyviz/holoviews/pull/846), + [\#858](https://github.com/pyviz/holoviews/pull/858), + [\#860](https://github.com/pyviz/holoviews/pull/860), + [\#889](https://github.com/pyviz/holoviews/pull/889), + [\#904](https://github.com/pyviz/holoviews/pull/904), + [\#913](https://github.com/pyviz/holoviews/pull/913), + [\#933](https://github.com/pyviz/holoviews/pull/933), + [\#962](https://github.com/pyviz/holoviews/pull/962), + [\#964](https://github.com/pyviz/holoviews/pull/964), + [\#1094](https://github.com/pyviz/holoviews/pull/1094), + [\#1256](https://github.com/pyviz/holoviews/pull/1256), + [\#1274](https://github.com/pyviz/holoviews/pull/1274), + [\#1297](https://github.com/pyviz/holoviews/pull/1297), + [\#1301](https://github.com/pyviz/holoviews/pull/1301), + [\#1303](https://github.com/pyviz/holoviews/pull/1303)). +- Dynamic Callable API (PR + [\#951](https://github.com/pyviz/holoviews/pull/951), + [\#1103](https://github.com/pyviz/holoviews/pull/1103), + [\#1029](https://github.com/pyviz/holoviews/pull/1029), + [\#968](https://github.com/pyviz/holoviews/pull/968), + [\#935](https://github.com/pyviz/holoviews/pull/935), + [\#1063](https://github.com/pyviz/holoviews/pull/1063), + [\#1260](https://github.com/pyviz/holoviews/pull/1260)). +- Simpler and more powerful DynamicMap (PR + [\#1238](https://github.com/pyviz/holoviews/pull/1238), + [\#1240](https://github.com/pyviz/holoviews/pull/1240), + [\#1243](https://github.com/pyviz/holoviews/pull/1243), + [\#1257](https://github.com/pyviz/holoviews/pull/1257), + [\#1267](https://github.com/pyviz/holoviews/pull/1267), + [\#1302](https://github.com/pyviz/holoviews/pull/1302), + [\#1304](https://github.com/pyviz/holoviews/pull/1304), + [\#1305](https://github.com/pyviz/holoviews/pull/1305)). +- Fully general support for Bokeh events (PR + [\#892](https://github.com/pyviz/holoviews/pull/892), + [\#1148](https://github.com/pyviz/holoviews/pull/1148), + [\#1235](https://github.com/pyviz/holoviews/pull/1235)). +- Datashader operations (PR + [\#894](https://github.com/pyviz/holoviews/pull/894), + [\#907](https://github.com/pyviz/holoviews/pull/907), + [\#963](https://github.com/pyviz/holoviews/pull/963), + [\#1125](https://github.com/pyviz/holoviews/pull/1125), + [\#1281](https://github.com/pyviz/holoviews/pull/1281), + [\#1306](https://github.com/pyviz/holoviews/pull/1306)). +- Support for Bokeh apps and Bokeh Server (PR + [\#959](https://github.com/pyviz/holoviews/pull/959), + [\#1283](https://github.com/pyviz/holoviews/pull/1283)). +- Working with renderers interactively outside the notebook (PR + [\#1214](https://github.com/pyviz/holoviews/pull/1214)). +- Support for Matplotlib 2.0 (PR + [\#867](https://github.com/pyviz/holoviews/pull/867), + [\#868](https://github.com/pyviz/holoviews/pull/868), + [\#1131](https://github.com/pyviz/holoviews/pull/1131), + [\#1264](https://github.com/pyviz/holoviews/pull/1264), + [\#1266](https://github.com/pyviz/holoviews/pull/1266)). +- Support for Bokeh 0.12.2, 0.12.3, 0.12.4, and 0.12.5 (PR + [\#899](https://github.com/pyviz/holoviews/pull/899), + [\#900](https://github.com/pyviz/holoviews/pull/900), + [\#1007](https://github.com/pyviz/holoviews/pull/1007), + [\#1036](https://github.com/pyviz/holoviews/pull/1036), + [\#1116](https://github.com/pyviz/holoviews/pull/1116)). +- Many new features for the Bokeh backend: widgets editable (PR + [\#1247](https://github.com/pyviz/holoviews/pull/1247)), selection + colors and interactive legends (PR + [\#1220](https://github.com/pyviz/holoviews/pull/1220)), GridSpace + axes (PR [\#1150](https://github.com/pyviz/holoviews/pull/1150)), + categorical axes and colormapping (PR + [\#1089](https://github.com/pyviz/holoviews/pull/1089), + [\#1137](https://github.com/pyviz/holoviews/pull/1137)), computing + plot size (PR + [\#1140](https://github.com/pyviz/holoviews/pull/1140)), GridSpaces + inside Layouts (PR + [\#1104](https://github.com/pyviz/holoviews/pull/1104)), Layout/Grid + titles (PR [\#1017](https://github.com/pyviz/holoviews/pull/1017)), + histogram with live colormapping (PR + [\#928](https://github.com/pyviz/holoviews/pull/928)), colorbars (PR + [\#861](https://github.com/pyviz/holoviews/pull/861)), + finalize_hooks (PR + [\#1040](https://github.com/pyviz/holoviews/pull/1040)), labelled and + show_frame options (PR + [\#863](https://github.com/pyviz/holoviews/pull/863), + [\#1013](https://github.com/pyviz/holoviews/pull/1013)), styling + hover glyphs (PR + [\#1286](https://github.com/pyviz/holoviews/pull/1286)), hiding + legends on BarPlot (PR + [\#837](https://github.com/pyviz/holoviews/pull/837)), VectorField + plot (PR [\#1196](https://github.com/pyviz/holoviews/pull/1196)), + Histograms now have same color cycle as mpl + ([\#1008](https://github.com/pyviz/holoviews/pull/1008)). +- Implemented convenience redim methods to easily set dimension + ranges, values etc. (PR + [\#1302](https://github.com/pyviz/holoviews/pull/1302)) +- Made methods on and operations applied to DynamicMap lazy + ([\#422](https://github.com/pyviz/holoviews/pull/422), + [\#588](https://github.com/pyviz/holoviews/pull/588), + [\#1188](https://github.com/pyviz/holoviews/pull/1188), + [\#1240](https://github.com/pyviz/holoviews/pull/1240), + [\#1227](https://github.com/pyviz/holoviews/pull/1227)) +- Improved documentation (PR + [\#936](https://github.com/pyviz/holoviews/pull/936), + [\#1070](https://github.com/pyviz/holoviews/pull/1070), + [\#1242](https://github.com/pyviz/holoviews/pull/1242), + [\#1273](https://github.com/pyviz/holoviews/pull/1273), + [\#1280](https://github.com/pyviz/holoviews/pull/1280)). +- Improved error handling (PR + [\#906](https://github.com/pyviz/holoviews/pull/906), + [\#932](https://github.com/pyviz/holoviews/pull/932), + [\#939](https://github.com/pyviz/holoviews/pull/939), + [\#949](https://github.com/pyviz/holoviews/pull/949), + [\#1011](https://github.com/pyviz/holoviews/pull/1011), + [\#1290](https://github.com/pyviz/holoviews/pull/1290), + [\#1262](https://github.com/pyviz/holoviews/pull/1262), + [\#1295](https://github.com/pyviz/holoviews/pull/1295)), including + re-enabling option system keyword validation (PR + [\#1277](https://github.com/pyviz/holoviews/pull/1277)). +- Improved testing (PR + [\#834](https://github.com/pyviz/holoviews/pull/834), + [\#871](https://github.com/pyviz/holoviews/pull/871), + [\#881](https://github.com/pyviz/holoviews/pull/881), + [\#941](https://github.com/pyviz/holoviews/pull/941), + [\#1117](https://github.com/pyviz/holoviews/pull/1117), + [\#1153](https://github.com/pyviz/holoviews/pull/1153), + [\#1171](https://github.com/pyviz/holoviews/pull/1171), + [\#1207](https://github.com/pyviz/holoviews/pull/1207), + [\#1246](https://github.com/pyviz/holoviews/pull/1246), + [\#1259](https://github.com/pyviz/holoviews/pull/1259), + [\#1287](https://github.com/pyviz/holoviews/pull/1287)). Other new features and improvements: -- Operations for timeseries (PR - [\#1172](https://github.com/pyviz/holoviews/pull/1172)), - downsample\_columns (PR - [\#903](https://github.com/pyviz/holoviews/pull/903)), - interpolate\_curve (PR - [\#1097](https://github.com/pyviz/holoviews/pull/1097)), and stacked - area (PR [\#1193](https://github.com/pyviz/holoviews/pull/1193)). -- Dataset types can be declared as empty by passing an empty list (PR - [\#1355](https://github.com/pyviz/holoviews/pull/1355)) -- Plot or style options for Curve interpolation (PR - [\#1097](https://github.com/pyviz/holoviews/pull/1097)), transposing - layouts (PR [\#1100](https://github.com/pyviz/holoviews/pull/1100)), - multiple paths (PR - [\#997](https://github.com/pyviz/holoviews/pull/997)), and norm for - ColorbarPlot (PR - [\#957](https://github.com/pyviz/holoviews/pull/957)). -- Improved options inheritance for more intuitive behavior (PR - [\#1275](https://github.com/pyviz/holoviews/pull/1275)). -- Image interface providing similar functionality for Image and - non-Image types (making GridImage obsolete) (PR - [\#994](https://github.com/pyviz/holoviews/pull/994)). -- Dask data interface (PR - [\#974](https://github.com/pyviz/holoviews/pull/974), - [\#991](https://github.com/pyviz/holoviews/pull/991)). -- xarray aggregate/reduce (PR - [\#1192](https://github.com/pyviz/holoviews/pull/1192)). -- Indicate color clipping and control clipping colors (PR - [\#686](https://github.com/pyviz/holoviews/pull/686)). -- Better datetime handling (PR - [\#1098](https://github.com/pyviz/holoviews/pull/1098)). -- Gridmatrix diagonal types (PR - [\#1194](https://github.com/pyviz/holoviews/pull/1194), - [\#1027](https://github.com/pyviz/holoviews/pull/1027)). -- log option for histogram operation (PR - [\#929](https://github.com/pyviz/holoviews/pull/929)). -- Perceptually uniform fire colormap (PR - [\#943](https://github.com/pyviz/holoviews/pull/943)). -- Support for adjoining overlays (PR - [\#1213](https://github.com/pyviz/holoviews/pull/1213)). -- coloring weighted average in SideHistogram (PR - [\#1087](https://github.com/pyviz/holoviews/pull/1087)). -- HeatMap allows displaying multiple values on hover (PR - [\#849](https://github.com/pyviz/holoviews/pull/849)). -- Allow casting Image to QuadMesh (PR - [\#1282](https://github.com/pyviz/holoviews/pull/1282)). -- Unused columns are now preserved in gridded groupby (PR - [\#1154](https://github.com/pyviz/holoviews/pull/1154)). -- Optimizations and fixes for constructing Layout/Overlay types (PR - [\#952](https://github.com/pyviz/holoviews/pull/952)). -- DynamicMap fixes (PR - [\#848](https://github.com/pyviz/holoviews/pull/848), - [\#883](https://github.com/pyviz/holoviews/pull/883), - [\#911](https://github.com/pyviz/holoviews/pull/911), - [\#922](https://github.com/pyviz/holoviews/pull/922), - [\#923](https://github.com/pyviz/holoviews/pull/923), - [\#927](https://github.com/pyviz/holoviews/pull/927), - [\#944](https://github.com/pyviz/holoviews/pull/944), - [\#1170](https://github.com/pyviz/holoviews/pull/1170), - [\#1227](https://github.com/pyviz/holoviews/pull/1227), - [\#1270](https://github.com/pyviz/holoviews/pull/1270)). -- Bokeh-backend fixes including handling of empty frames - ([\#835](https://github.com/pyviz/holoviews/pull/835)), faster - updates ([\#905](https://github.com/pyviz/holoviews/pull/905)), hover - tool fixes ([\#1004](https://github.com/pyviz/holoviews/pull/1004), - [\#1178](https://github.com/pyviz/holoviews/pull/1178), - [\#1092](https://github.com/pyviz/holoviews/pull/1092), - [\#1250](https://github.com/pyviz/holoviews/pull/1250)) and many more - (PR [\#537](https://github.com/pyviz/holoviews/pull/537), - [\#851](https://github.com/pyviz/holoviews/pull/851), - [\#852](https://github.com/pyviz/holoviews/pull/852), - [\#854](https://github.com/pyviz/holoviews/pull/854), - [\#880](https://github.com/pyviz/holoviews/pull/880), - [\#896](https://github.com/pyviz/holoviews/pull/896), - [\#898](https://github.com/pyviz/holoviews/pull/898), - [\#921](https://github.com/pyviz/holoviews/pull/921), - [\#934](https://github.com/pyviz/holoviews/pull/934), - [\#1004](https://github.com/pyviz/holoviews/pull/1004), - [\#1010](https://github.com/pyviz/holoviews/pull/1010), - [\#1014](https://github.com/pyviz/holoviews/pull/1014), - [\#1030](https://github.com/pyviz/holoviews/pull/1030), - [\#1069](https://github.com/pyviz/holoviews/pull/1069), - [\#1072](https://github.com/pyviz/holoviews/pull/1072), - [\#1085](https://github.com/pyviz/holoviews/pull/1085), - [\#1157](https://github.com/pyviz/holoviews/pull/1157), - [\#1086](https://github.com/pyviz/holoviews/pull/1086), - [\#1169](https://github.com/pyviz/holoviews/pull/1169), - [\#1195](https://github.com/pyviz/holoviews/pull/1195), - [\#1263](https://github.com/pyviz/holoviews/pull/1263)). -- Matplotlib-backend fixes and improvements (PR - [\#864](https://github.com/pyviz/holoviews/pull/864), - [\#873](https://github.com/pyviz/holoviews/pull/873), - [\#954](https://github.com/pyviz/holoviews/pull/954), - [\#1037](https://github.com/pyviz/holoviews/pull/1037), - [\#1068](https://github.com/pyviz/holoviews/pull/1068), - [\#1128](https://github.com/pyviz/holoviews/pull/1128), - [\#1132](https://github.com/pyviz/holoviews/pull/1132), - [\#1143](https://github.com/pyviz/holoviews/pull/1143), - [\#1163](https://github.com/pyviz/holoviews/pull/1163), - [\#1209](https://github.com/pyviz/holoviews/pull/1209), - [\#1211](https://github.com/pyviz/holoviews/pull/1211), - [\#1225](https://github.com/pyviz/holoviews/pull/1225), - [\#1269](https://github.com/pyviz/holoviews/pull/1269), - [\#1300](https://github.com/pyviz/holoviews/pull/1300)). -- Many other small improvements and fixes (PR - [\#830](https://github.com/pyviz/holoviews/pull/830), - [\#840](https://github.com/pyviz/holoviews/pull/840), - [\#841](https://github.com/pyviz/holoviews/pull/841), - [\#850](https://github.com/pyviz/holoviews/pull/850), - [\#855](https://github.com/pyviz/holoviews/pull/855), - [\#856](https://github.com/pyviz/holoviews/pull/856), - [\#859](https://github.com/pyviz/holoviews/pull/859), - [\#865](https://github.com/pyviz/holoviews/pull/865), - [\#893](https://github.com/pyviz/holoviews/pull/893), - [\#897](https://github.com/pyviz/holoviews/pull/897), - [\#902](https://github.com/pyviz/holoviews/pull/902), - [\#912](https://github.com/pyviz/holoviews/pull/912), - [\#916](https://github.com/pyviz/holoviews/pull/916), - [\#925](https://github.com/pyviz/holoviews/pull/925), - [\#938](https://github.com/pyviz/holoviews/pull/938), - [\#940](https://github.com/pyviz/holoviews/pull/940), - [\#948](https://github.com/pyviz/holoviews/pull/948), - [\#950](https://github.com/pyviz/holoviews/pull/950), - [\#955](https://github.com/pyviz/holoviews/pull/955), - [\#956](https://github.com/pyviz/holoviews/pull/956), - [\#967](https://github.com/pyviz/holoviews/pull/967), - [\#970](https://github.com/pyviz/holoviews/pull/970), - [\#972](https://github.com/pyviz/holoviews/pull/972), - [\#973](https://github.com/pyviz/holoviews/pull/973), - [\#981](https://github.com/pyviz/holoviews/pull/981), - [\#992](https://github.com/pyviz/holoviews/pull/992), - [\#998](https://github.com/pyviz/holoviews/pull/998), - [\#1009](https://github.com/pyviz/holoviews/pull/1009), - [\#1012](https://github.com/pyviz/holoviews/pull/1012), - [\#1016](https://github.com/pyviz/holoviews/pull/1016), - [\#1023](https://github.com/pyviz/holoviews/pull/1023), - [\#1034](https://github.com/pyviz/holoviews/pull/1034), - [\#1043](https://github.com/pyviz/holoviews/pull/1043), - [\#1045](https://github.com/pyviz/holoviews/pull/1045), - [\#1046](https://github.com/pyviz/holoviews/pull/1046), - [\#1048](https://github.com/pyviz/holoviews/pull/1048), - [\#1050](https://github.com/pyviz/holoviews/pull/1050), - [\#1051](https://github.com/pyviz/holoviews/pull/1051), - [\#1054](https://github.com/pyviz/holoviews/pull/1054), - [\#1060](https://github.com/pyviz/holoviews/pull/1060), - [\#1062](https://github.com/pyviz/holoviews/pull/1062), - [\#1074](https://github.com/pyviz/holoviews/pull/1074), - [\#1082](https://github.com/pyviz/holoviews/pull/1082), - [\#1084](https://github.com/pyviz/holoviews/pull/1084), - [\#1088](https://github.com/pyviz/holoviews/pull/1088), - [\#1093](https://github.com/pyviz/holoviews/pull/1093), - [\#1099](https://github.com/pyviz/holoviews/pull/1099), - [\#1115](https://github.com/pyviz/holoviews/pull/1115), - [\#1119](https://github.com/pyviz/holoviews/pull/1119), - [\#1121](https://github.com/pyviz/holoviews/pull/1121), - [\#1130](https://github.com/pyviz/holoviews/pull/1130), - [\#1133](https://github.com/pyviz/holoviews/pull/1133), - [\#1151](https://github.com/pyviz/holoviews/pull/1151), - [\#1152](https://github.com/pyviz/holoviews/pull/1152), - [\#1155](https://github.com/pyviz/holoviews/pull/1155), - [\#1156](https://github.com/pyviz/holoviews/pull/1156), - [\#1158](https://github.com/pyviz/holoviews/pull/1158), - [\#1162](https://github.com/pyviz/holoviews/pull/1162), - [\#1164](https://github.com/pyviz/holoviews/pull/1164), - [\#1174](https://github.com/pyviz/holoviews/pull/1174), - [\#1175](https://github.com/pyviz/holoviews/pull/1175), - [\#1180](https://github.com/pyviz/holoviews/pull/1180), - [\#1187](https://github.com/pyviz/holoviews/pull/1187), - [\#1197](https://github.com/pyviz/holoviews/pull/1197), - [\#1202](https://github.com/pyviz/holoviews/pull/1202), - [\#1205](https://github.com/pyviz/holoviews/pull/1205), - [\#1206](https://github.com/pyviz/holoviews/pull/1206), - [\#1210](https://github.com/pyviz/holoviews/pull/1210), - [\#1217](https://github.com/pyviz/holoviews/pull/1217), - [\#1219](https://github.com/pyviz/holoviews/pull/1219), - [\#1228](https://github.com/pyviz/holoviews/pull/1228), - [\#1232](https://github.com/pyviz/holoviews/pull/1232), - [\#1241](https://github.com/pyviz/holoviews/pull/1241), - [\#1244](https://github.com/pyviz/holoviews/pull/1244), - [\#1245](https://github.com/pyviz/holoviews/pull/1245), - [\#1249](https://github.com/pyviz/holoviews/pull/1249), - [\#1254](https://github.com/pyviz/holoviews/pull/1254), - [\#1255](https://github.com/pyviz/holoviews/pull/1255), - [\#1271](https://github.com/pyviz/holoviews/pull/1271), - [\#1276](https://github.com/pyviz/holoviews/pull/1276), - [\#1278](https://github.com/pyviz/holoviews/pull/1278), - [\#1285](https://github.com/pyviz/holoviews/pull/1285), - [\#1288](https://github.com/pyviz/holoviews/pull/1288), - [\#1289](https://github.com/pyviz/holoviews/pull/1289)). +- Operations for timeseries (PR + [\#1172](https://github.com/pyviz/holoviews/pull/1172)), + downsample_columns (PR + [\#903](https://github.com/pyviz/holoviews/pull/903)), + interpolate_curve (PR + [\#1097](https://github.com/pyviz/holoviews/pull/1097)), and stacked + area (PR [\#1193](https://github.com/pyviz/holoviews/pull/1193)). +- Dataset types can be declared as empty by passing an empty list (PR + [\#1355](https://github.com/pyviz/holoviews/pull/1355)) +- Plot or style options for Curve interpolation (PR + [\#1097](https://github.com/pyviz/holoviews/pull/1097)), transposing + layouts (PR [\#1100](https://github.com/pyviz/holoviews/pull/1100)), + multiple paths (PR + [\#997](https://github.com/pyviz/holoviews/pull/997)), and norm for + ColorbarPlot (PR + [\#957](https://github.com/pyviz/holoviews/pull/957)). +- Improved options inheritance for more intuitive behavior (PR + [\#1275](https://github.com/pyviz/holoviews/pull/1275)). +- Image interface providing similar functionality for Image and + non-Image types (making GridImage obsolete) (PR + [\#994](https://github.com/pyviz/holoviews/pull/994)). +- Dask data interface (PR + [\#974](https://github.com/pyviz/holoviews/pull/974), + [\#991](https://github.com/pyviz/holoviews/pull/991)). +- xarray aggregate/reduce (PR + [\#1192](https://github.com/pyviz/holoviews/pull/1192)). +- Indicate color clipping and control clipping colors (PR + [\#686](https://github.com/pyviz/holoviews/pull/686)). +- Better datetime handling (PR + [\#1098](https://github.com/pyviz/holoviews/pull/1098)). +- Gridmatrix diagonal types (PR + [\#1194](https://github.com/pyviz/holoviews/pull/1194), + [\#1027](https://github.com/pyviz/holoviews/pull/1027)). +- log option for histogram operation (PR + [\#929](https://github.com/pyviz/holoviews/pull/929)). +- Perceptually uniform fire colormap (PR + [\#943](https://github.com/pyviz/holoviews/pull/943)). +- Support for adjoining overlays (PR + [\#1213](https://github.com/pyviz/holoviews/pull/1213)). +- coloring weighted average in SideHistogram (PR + [\#1087](https://github.com/pyviz/holoviews/pull/1087)). +- HeatMap allows displaying multiple values on hover (PR + [\#849](https://github.com/pyviz/holoviews/pull/849)). +- Allow casting Image to QuadMesh (PR + [\#1282](https://github.com/pyviz/holoviews/pull/1282)). +- Unused columns are now preserved in gridded groupby (PR + [\#1154](https://github.com/pyviz/holoviews/pull/1154)). +- Optimizations and fixes for constructing Layout/Overlay types (PR + [\#952](https://github.com/pyviz/holoviews/pull/952)). +- DynamicMap fixes (PR + [\#848](https://github.com/pyviz/holoviews/pull/848), + [\#883](https://github.com/pyviz/holoviews/pull/883), + [\#911](https://github.com/pyviz/holoviews/pull/911), + [\#922](https://github.com/pyviz/holoviews/pull/922), + [\#923](https://github.com/pyviz/holoviews/pull/923), + [\#927](https://github.com/pyviz/holoviews/pull/927), + [\#944](https://github.com/pyviz/holoviews/pull/944), + [\#1170](https://github.com/pyviz/holoviews/pull/1170), + [\#1227](https://github.com/pyviz/holoviews/pull/1227), + [\#1270](https://github.com/pyviz/holoviews/pull/1270)). +- Bokeh-backend fixes including handling of empty frames + ([\#835](https://github.com/pyviz/holoviews/pull/835)), faster + updates ([\#905](https://github.com/pyviz/holoviews/pull/905)), hover + tool fixes ([\#1004](https://github.com/pyviz/holoviews/pull/1004), + [\#1178](https://github.com/pyviz/holoviews/pull/1178), + [\#1092](https://github.com/pyviz/holoviews/pull/1092), + [\#1250](https://github.com/pyviz/holoviews/pull/1250)) and many more + (PR [\#537](https://github.com/pyviz/holoviews/pull/537), + [\#851](https://github.com/pyviz/holoviews/pull/851), + [\#852](https://github.com/pyviz/holoviews/pull/852), + [\#854](https://github.com/pyviz/holoviews/pull/854), + [\#880](https://github.com/pyviz/holoviews/pull/880), + [\#896](https://github.com/pyviz/holoviews/pull/896), + [\#898](https://github.com/pyviz/holoviews/pull/898), + [\#921](https://github.com/pyviz/holoviews/pull/921), + [\#934](https://github.com/pyviz/holoviews/pull/934), + [\#1004](https://github.com/pyviz/holoviews/pull/1004), + [\#1010](https://github.com/pyviz/holoviews/pull/1010), + [\#1014](https://github.com/pyviz/holoviews/pull/1014), + [\#1030](https://github.com/pyviz/holoviews/pull/1030), + [\#1069](https://github.com/pyviz/holoviews/pull/1069), + [\#1072](https://github.com/pyviz/holoviews/pull/1072), + [\#1085](https://github.com/pyviz/holoviews/pull/1085), + [\#1157](https://github.com/pyviz/holoviews/pull/1157), + [\#1086](https://github.com/pyviz/holoviews/pull/1086), + [\#1169](https://github.com/pyviz/holoviews/pull/1169), + [\#1195](https://github.com/pyviz/holoviews/pull/1195), + [\#1263](https://github.com/pyviz/holoviews/pull/1263)). +- Matplotlib-backend fixes and improvements (PR + [\#864](https://github.com/pyviz/holoviews/pull/864), + [\#873](https://github.com/pyviz/holoviews/pull/873), + [\#954](https://github.com/pyviz/holoviews/pull/954), + [\#1037](https://github.com/pyviz/holoviews/pull/1037), + [\#1068](https://github.com/pyviz/holoviews/pull/1068), + [\#1128](https://github.com/pyviz/holoviews/pull/1128), + [\#1132](https://github.com/pyviz/holoviews/pull/1132), + [\#1143](https://github.com/pyviz/holoviews/pull/1143), + [\#1163](https://github.com/pyviz/holoviews/pull/1163), + [\#1209](https://github.com/pyviz/holoviews/pull/1209), + [\#1211](https://github.com/pyviz/holoviews/pull/1211), + [\#1225](https://github.com/pyviz/holoviews/pull/1225), + [\#1269](https://github.com/pyviz/holoviews/pull/1269), + [\#1300](https://github.com/pyviz/holoviews/pull/1300)). +- Many other small improvements and fixes (PR + [\#830](https://github.com/pyviz/holoviews/pull/830), + [\#840](https://github.com/pyviz/holoviews/pull/840), + [\#841](https://github.com/pyviz/holoviews/pull/841), + [\#850](https://github.com/pyviz/holoviews/pull/850), + [\#855](https://github.com/pyviz/holoviews/pull/855), + [\#856](https://github.com/pyviz/holoviews/pull/856), + [\#859](https://github.com/pyviz/holoviews/pull/859), + [\#865](https://github.com/pyviz/holoviews/pull/865), + [\#893](https://github.com/pyviz/holoviews/pull/893), + [\#897](https://github.com/pyviz/holoviews/pull/897), + [\#902](https://github.com/pyviz/holoviews/pull/902), + [\#912](https://github.com/pyviz/holoviews/pull/912), + [\#916](https://github.com/pyviz/holoviews/pull/916), + [\#925](https://github.com/pyviz/holoviews/pull/925), + [\#938](https://github.com/pyviz/holoviews/pull/938), + [\#940](https://github.com/pyviz/holoviews/pull/940), + [\#948](https://github.com/pyviz/holoviews/pull/948), + [\#950](https://github.com/pyviz/holoviews/pull/950), + [\#955](https://github.com/pyviz/holoviews/pull/955), + [\#956](https://github.com/pyviz/holoviews/pull/956), + [\#967](https://github.com/pyviz/holoviews/pull/967), + [\#970](https://github.com/pyviz/holoviews/pull/970), + [\#972](https://github.com/pyviz/holoviews/pull/972), + [\#973](https://github.com/pyviz/holoviews/pull/973), + [\#981](https://github.com/pyviz/holoviews/pull/981), + [\#992](https://github.com/pyviz/holoviews/pull/992), + [\#998](https://github.com/pyviz/holoviews/pull/998), + [\#1009](https://github.com/pyviz/holoviews/pull/1009), + [\#1012](https://github.com/pyviz/holoviews/pull/1012), + [\#1016](https://github.com/pyviz/holoviews/pull/1016), + [\#1023](https://github.com/pyviz/holoviews/pull/1023), + [\#1034](https://github.com/pyviz/holoviews/pull/1034), + [\#1043](https://github.com/pyviz/holoviews/pull/1043), + [\#1045](https://github.com/pyviz/holoviews/pull/1045), + [\#1046](https://github.com/pyviz/holoviews/pull/1046), + [\#1048](https://github.com/pyviz/holoviews/pull/1048), + [\#1050](https://github.com/pyviz/holoviews/pull/1050), + [\#1051](https://github.com/pyviz/holoviews/pull/1051), + [\#1054](https://github.com/pyviz/holoviews/pull/1054), + [\#1060](https://github.com/pyviz/holoviews/pull/1060), + [\#1062](https://github.com/pyviz/holoviews/pull/1062), + [\#1074](https://github.com/pyviz/holoviews/pull/1074), + [\#1082](https://github.com/pyviz/holoviews/pull/1082), + [\#1084](https://github.com/pyviz/holoviews/pull/1084), + [\#1088](https://github.com/pyviz/holoviews/pull/1088), + [\#1093](https://github.com/pyviz/holoviews/pull/1093), + [\#1099](https://github.com/pyviz/holoviews/pull/1099), + [\#1115](https://github.com/pyviz/holoviews/pull/1115), + [\#1119](https://github.com/pyviz/holoviews/pull/1119), + [\#1121](https://github.com/pyviz/holoviews/pull/1121), + [\#1130](https://github.com/pyviz/holoviews/pull/1130), + [\#1133](https://github.com/pyviz/holoviews/pull/1133), + [\#1151](https://github.com/pyviz/holoviews/pull/1151), + [\#1152](https://github.com/pyviz/holoviews/pull/1152), + [\#1155](https://github.com/pyviz/holoviews/pull/1155), + [\#1156](https://github.com/pyviz/holoviews/pull/1156), + [\#1158](https://github.com/pyviz/holoviews/pull/1158), + [\#1162](https://github.com/pyviz/holoviews/pull/1162), + [\#1164](https://github.com/pyviz/holoviews/pull/1164), + [\#1174](https://github.com/pyviz/holoviews/pull/1174), + [\#1175](https://github.com/pyviz/holoviews/pull/1175), + [\#1180](https://github.com/pyviz/holoviews/pull/1180), + [\#1187](https://github.com/pyviz/holoviews/pull/1187), + [\#1197](https://github.com/pyviz/holoviews/pull/1197), + [\#1202](https://github.com/pyviz/holoviews/pull/1202), + [\#1205](https://github.com/pyviz/holoviews/pull/1205), + [\#1206](https://github.com/pyviz/holoviews/pull/1206), + [\#1210](https://github.com/pyviz/holoviews/pull/1210), + [\#1217](https://github.com/pyviz/holoviews/pull/1217), + [\#1219](https://github.com/pyviz/holoviews/pull/1219), + [\#1228](https://github.com/pyviz/holoviews/pull/1228), + [\#1232](https://github.com/pyviz/holoviews/pull/1232), + [\#1241](https://github.com/pyviz/holoviews/pull/1241), + [\#1244](https://github.com/pyviz/holoviews/pull/1244), + [\#1245](https://github.com/pyviz/holoviews/pull/1245), + [\#1249](https://github.com/pyviz/holoviews/pull/1249), + [\#1254](https://github.com/pyviz/holoviews/pull/1254), + [\#1255](https://github.com/pyviz/holoviews/pull/1255), + [\#1271](https://github.com/pyviz/holoviews/pull/1271), + [\#1276](https://github.com/pyviz/holoviews/pull/1276), + [\#1278](https://github.com/pyviz/holoviews/pull/1278), + [\#1285](https://github.com/pyviz/holoviews/pull/1285), + [\#1288](https://github.com/pyviz/holoviews/pull/1288), + [\#1289](https://github.com/pyviz/holoviews/pull/1289)). Changes affecting backwards compatibility: -- Automatic coloring and sizing on Points now disabled (PR - [\#748](https://github.com/pyviz/holoviews/pull/748)). -- Deprecated max\_branches output magic option (PR - [\#1293](https://github.com/pyviz/holoviews/pull/1293)). -- Deprecated GridImage (PR - [\#1292](https://github.com/pyviz/holoviews/pull/1292), - [\#1223](https://github.com/pyviz/holoviews/pull/1223)). -- Deprecated NdElement (PR - [\#1191](https://github.com/pyviz/holoviews/pull/1191)). -- Deprecated DFrame conversion methods (PR - [\#1065](https://github.com/pyviz/holoviews/pull/1065)). -- Banner text removed from notebook\_extension() (PR - [\#1231](https://github.com/pyviz/holoviews/pull/1231), - [\#1291](https://github.com/pyviz/holoviews/pull/1291)). -- Bokeh's Matplotlib compatibility module removed (PR - [\#1239](https://github.com/pyviz/holoviews/pull/1239)). -- ls as Matplotlib linestyle alias dropped (PR - [\#1203](https://github.com/pyviz/holoviews/pull/1203)). -- mdims argument of conversion interface renamed to groupby (PR - [\#1066](https://github.com/pyviz/holoviews/pull/1066)). -- Replaced global alias state with Dimension.label - ([\#1083](https://github.com/pyviz/holoviews/pull/1083)). -- DynamicMap only update ranges when set to framewise -- Deprecated DynamicMap sampled, bounded, open and generator modes - ([\#969](https://github.com/pyviz/holoviews/pull/969), - [\#1305](https://github.com/pyviz/holoviews/pull/1305)) -- Layout.display method is now deprecated - ([\#1026](https://github.com/pyviz/holoviews/pull/1026)) -- Layout fix for Matplotlib figures with non-square aspects introduced - in 1.6.2 (PR [\#826](https://github.com/pyviz/holoviews/pull/826)), - now enabled by default. - -Version 1.6.2 -============= +- Automatic coloring and sizing on Points now disabled (PR + [\#748](https://github.com/pyviz/holoviews/pull/748)). +- Deprecated max_branches output magic option (PR + [\#1293](https://github.com/pyviz/holoviews/pull/1293)). +- Deprecated GridImage (PR + [\#1292](https://github.com/pyviz/holoviews/pull/1292), + [\#1223](https://github.com/pyviz/holoviews/pull/1223)). +- Deprecated NdElement (PR + [\#1191](https://github.com/pyviz/holoviews/pull/1191)). +- Deprecated DFrame conversion methods (PR + [\#1065](https://github.com/pyviz/holoviews/pull/1065)). +- Banner text removed from notebook_extension() (PR + [\#1231](https://github.com/pyviz/holoviews/pull/1231), + [\#1291](https://github.com/pyviz/holoviews/pull/1291)). +- Bokeh's Matplotlib compatibility module removed (PR + [\#1239](https://github.com/pyviz/holoviews/pull/1239)). +- ls as Matplotlib linestyle alias dropped (PR + [\#1203](https://github.com/pyviz/holoviews/pull/1203)). +- mdims argument of conversion interface renamed to groupby (PR + [\#1066](https://github.com/pyviz/holoviews/pull/1066)). +- Replaced global alias state with Dimension.label + ([\#1083](https://github.com/pyviz/holoviews/pull/1083)). +- DynamicMap only update ranges when set to framewise +- Deprecated DynamicMap sampled, bounded, open and generator modes + ([\#969](https://github.com/pyviz/holoviews/pull/969), + [\#1305](https://github.com/pyviz/holoviews/pull/1305)) +- Layout.display method is now deprecated + ([\#1026](https://github.com/pyviz/holoviews/pull/1026)) +- Layout fix for Matplotlib figures with non-square aspects introduced + in 1.6.2 (PR [\#826](https://github.com/pyviz/holoviews/pull/826)), + now enabled by default. + +# Version 1.6.2 + **August 23, 2016** Bug fix release with various fixes for gridded data backends and optimizations for Bokeh. -- Optimized Bokeh event messaging, reducing the average json payload - by 30-50% (PR [\#807](https://github.com/pyviz/holoviews/pull/807)). -- Fixes for correctly handling NdOverlay types returned by DynamicMaps - (PR [\#814](https://github.com/pyviz/holoviews/pull/814)). -- Added support for datetime64 handling in Matplotlib and support for - datetime formatters on Dimension.type\_formatters (PR - [\#816](https://github.com/pyviz/holoviews/pull/816)). -- Fixed handling of constant dimensions when slicing xarray datasets - (PR [\#817](https://github.com/pyviz/holoviews/pull/817)). -- Fixed support for passing custom dimensions to iris Datasets (PR - [\#818](https://github.com/pyviz/holoviews/pull/818)). -- Fixed support for add\_dimension on xarray interface (PR - [\#820](https://github.com/pyviz/holoviews/pull/820)). -- Improved extents computation on Matplotlib SpreadPlot (PR - [\#821](https://github.com/pyviz/holoviews/pull/821)). -- Bokeh backend avoids sending data for static frames and empty events - (PR [\#822](https://github.com/pyviz/holoviews/pull/822)). -- Added major layout fix for figures with non-square aspects, reducing - the amount of unnecessary whitespace (PR - [\#826](https://github.com/pyviz/holoviews/pull/826)). Disabled by - default until 1.7 release but can be enabled with: - -``` {.sourceCode .python} +- Optimized Bokeh event messaging, reducing the average json payload + by 30-50% (PR [\#807](https://github.com/pyviz/holoviews/pull/807)). +- Fixes for correctly handling NdOverlay types returned by DynamicMaps + (PR [\#814](https://github.com/pyviz/holoviews/pull/814)). +- Added support for datetime64 handling in Matplotlib and support for + datetime formatters on Dimension.type_formatters (PR + [\#816](https://github.com/pyviz/holoviews/pull/816)). +- Fixed handling of constant dimensions when slicing xarray datasets + (PR [\#817](https://github.com/pyviz/holoviews/pull/817)). +- Fixed support for passing custom dimensions to iris Datasets (PR + [\#818](https://github.com/pyviz/holoviews/pull/818)). +- Fixed support for add_dimension on xarray interface (PR + [\#820](https://github.com/pyviz/holoviews/pull/820)). +- Improved extents computation on Matplotlib SpreadPlot (PR + [\#821](https://github.com/pyviz/holoviews/pull/821)). +- Bokeh backend avoids sending data for static frames and empty events + (PR [\#822](https://github.com/pyviz/holoviews/pull/822)). +- Added major layout fix for figures with non-square aspects, reducing + the amount of unnecessary whitespace (PR + [\#826](https://github.com/pyviz/holoviews/pull/826)). Disabled by + default until 1.7 release but can be enabled with: + +```{.sourceCode .python} from holoviews.plotting.mpl import LayoutPlot LayoutPlot.v17_layout_format = True LayoutPlot.vspace = 0.3 ``` -Version 1.6.1 -============= +# Version 1.6.1 + **July 27, 2016** Bug fix release following the 1.6 major release with major bug fixes for the grid data interfaces and improvements to the options system. -- Ensured that style options incompatible with active backend are - ignored (PR [\#802](https://github.com/pyviz/holoviews/pull/802)). -- Added support for placing legends outside the plot area in Bokeh (PR - [\#801](https://github.com/pyviz/holoviews/pull/801)). -- Fix to ensure Bokeh backend does not depend on pandas (PR - [\#792](https://github.com/pyviz/holoviews/pull/792)). -- Fixed option system to ensure correct inheritance when redefining - options (PR [\#796](https://github.com/pyviz/holoviews/pull/796)). -- Major refactor and fixes for the grid based data backends (iris, - xarray and arrays with coordinates) ensuring the data is oriented - and transposed correctly (PR - [\#794](https://github.com/pyviz/holoviews/pull/794)). - -Version 1.6 -=========== +- Ensured that style options incompatible with active backend are + ignored (PR [\#802](https://github.com/pyviz/holoviews/pull/802)). +- Added support for placing legends outside the plot area in Bokeh (PR + [\#801](https://github.com/pyviz/holoviews/pull/801)). +- Fix to ensure Bokeh backend does not depend on pandas (PR + [\#792](https://github.com/pyviz/holoviews/pull/792)). +- Fixed option system to ensure correct inheritance when redefining + options (PR [\#796](https://github.com/pyviz/holoviews/pull/796)). +- Major refactor and fixes for the grid based data backends (iris, + xarray and arrays with coordinates) ensuring the data is oriented + and transposed correctly (PR + [\#794](https://github.com/pyviz/holoviews/pull/794)). + +# Version 1.6 + **July 14, 2016** A major release with an optional new data interface based on xarray, @@ -3451,30 +3470,30 @@ support for Bokeh 0.12 and various other fixes and improvements. Features and improvements: -- Made VectorFieldPlot more general with support for independent - coloring and scaling (PR - [\#701](https://github.com/pyviz/holoviews/pull/701)). -- Iris interface now allows tuple and dict formats in the constructor - (PR [\#709](https://github.com/pyviz/holoviews/pull/709). -- Added support for dynamic groupby on all data interfaces (PR - [\#711](https://github.com/pyviz/holoviews/pull/711)). -- Added an xarray data interface (PR - [\#713](https://github.com/pyviz/holoviews/pull/713)). -- Added the redim method to all Dimensioned objects making it easy to - quickly change dimension names and attributes on nested objects - [\#715](https://github.com/pyviz/holoviews/pull/715)). -- Added support for batching plots (PR - [\#715](https://github.com/pyviz/holoviews/pull/717)). -- Support for Bokeh 0.12 release (PR - [\#725](https://github.com/pyviz/holoviews/pull/725)). -- Added support for logz option on Bokeh Raster plots (PR - [\#729](https://github.com/pyviz/holoviews/pull/729)). -- Bokeh plots now support custom tick formatters specified via - Dimension value\_format (PR - [\#728](https://github.com/pyviz/holoviews/pull/728)). - -Version 1.5 -=========== +- Made VectorFieldPlot more general with support for independent + coloring and scaling (PR + [\#701](https://github.com/pyviz/holoviews/pull/701)). +- Iris interface now allows tuple and dict formats in the constructor + (PR [\#709](https://github.com/pyviz/holoviews/pull/709). +- Added support for dynamic groupby on all data interfaces (PR + [\#711](https://github.com/pyviz/holoviews/pull/711)). +- Added an xarray data interface (PR + [\#713](https://github.com/pyviz/holoviews/pull/713)). +- Added the redim method to all Dimensioned objects making it easy to + quickly change dimension names and attributes on nested objects + [\#715](https://github.com/pyviz/holoviews/pull/715)). +- Added support for batching plots (PR + [\#715](https://github.com/pyviz/holoviews/pull/717)). +- Support for Bokeh 0.12 release (PR + [\#725](https://github.com/pyviz/holoviews/pull/725)). +- Added support for logz option on Bokeh Raster plots (PR + [\#729](https://github.com/pyviz/holoviews/pull/729)). +- Bokeh plots now support custom tick formatters specified via + Dimension value_format (PR + [\#728](https://github.com/pyviz/holoviews/pull/728)). + +# Version 1.5 + **May 12, 2016** A major release with a large number of new features including new data @@ -3483,93 +3502,93 @@ large number of bug fixes. Features and improvements: -- Added a grid based data interface to explore n-dimensional gridded - data easily (PR - [\#562](https://github.com/pyviz/holoviews/pull/542)). -- Added data interface based on [iris - Cubes](http://scitools.org.uk/iris/docs/v1.9.2/index.html) (PR - [\#624](https://github.com/pyviz/holoviews/pull/624)). -- Added support for dynamic operations and overlaying of DynamicMaps - (PR [\#588](https://github.com/pyviz/holoviews/pull/588)). -- Added support for applying groupby operations to DynamicMaps (PR - [\#667](https://github.com/pyviz/holoviews/pull/667)). -- Added dimension value formatting in widgets (PR - [\#562](https://github.com/pyviz/holoviews/issues/562)). -- Added support for indexing and slicing with a function (PR - [\#619](https://github.com/pyviz/holoviews/pull/619)). -- Improved throttling behavior on widgets (PR - [\#596](https://github.com/pyviz/holoviews/pull/596)). -- Major refactor of Matplotlib plotting classes to simplify - implementing new Element plots (PR - [\#438](https://github.com/pyviz/holoviews/pull/438)). -- Added Renderer.last\_plot attribute to allow easily debugging or - modifying the last displayed plot (PR - [\#538](https://github.com/pyviz/holoviews/pull/538)). -- Added Bokeh QuadMeshPlot (PR - [\#661](https://github.com/pyviz/holoviews/pull/661)). +- Added a grid based data interface to explore n-dimensional gridded + data easily (PR + [\#562](https://github.com/pyviz/holoviews/pull/542)). +- Added data interface based on [iris + Cubes](http://scitools.org.uk/iris/docs/v1.9.2/index.html) (PR + [\#624](https://github.com/pyviz/holoviews/pull/624)). +- Added support for dynamic operations and overlaying of DynamicMaps + (PR [\#588](https://github.com/pyviz/holoviews/pull/588)). +- Added support for applying groupby operations to DynamicMaps (PR + [\#667](https://github.com/pyviz/holoviews/pull/667)). +- Added dimension value formatting in widgets (PR + [\#562](https://github.com/pyviz/holoviews/issues/562)). +- Added support for indexing and slicing with a function (PR + [\#619](https://github.com/pyviz/holoviews/pull/619)). +- Improved throttling behavior on widgets (PR + [\#596](https://github.com/pyviz/holoviews/pull/596)). +- Major refactor of Matplotlib plotting classes to simplify + implementing new Element plots (PR + [\#438](https://github.com/pyviz/holoviews/pull/438)). +- Added Renderer.last_plot attribute to allow easily debugging or + modifying the last displayed plot (PR + [\#538](https://github.com/pyviz/holoviews/pull/538)). +- Added Bokeh QuadMeshPlot (PR + [\#661](https://github.com/pyviz/holoviews/pull/661)). Bug fixes: -- Fixed overlaying of 3D Element types (PR - [\#504](https://github.com/pyviz/holoviews/pull/504)). -- Fix for Bokeh hovertools with dimensions with special characters (PR - [\#524](https://github.com/pyviz/holoviews/pull/524)). -- Fixed bugs in seaborn Distribution Element (PR - [\#630](https://github.com/pyviz/holoviews/pull/630)). -- Fix for inverted Raster.reduce method (PR - [\#672](https://github.com/pyviz/holoviews/pull/672)). -- Fixed Store.add\_style\_opts method (PR - [\#587](https://github.com/pyviz/holoviews/pull/587)). -- Fixed bug preventing simultaneous logx and logy plot options (PR - [\#554](https://github.com/pyviz/holoviews/pull/554)). +- Fixed overlaying of 3D Element types (PR + [\#504](https://github.com/pyviz/holoviews/pull/504)). +- Fix for Bokeh hovertools with dimensions with special characters (PR + [\#524](https://github.com/pyviz/holoviews/pull/524)). +- Fixed bugs in seaborn Distribution Element (PR + [\#630](https://github.com/pyviz/holoviews/pull/630)). +- Fix for inverted Raster.reduce method (PR + [\#672](https://github.com/pyviz/holoviews/pull/672)). +- Fixed Store.add_style_opts method (PR + [\#587](https://github.com/pyviz/holoviews/pull/587)). +- Fixed bug preventing simultaneous logx and logy plot options (PR + [\#554](https://github.com/pyviz/holoviews/pull/554)). Backwards compatibility: -- Renamed `Columns` type to `Dataset` (PR - [\#620](https://github.com/pyviz/holoviews/issues/620)). +- Renamed `Columns` type to `Dataset` (PR + [\#620](https://github.com/pyviz/holoviews/issues/620)). + +# Version 1.4.3 -Version 1.4.3 -============= **February 11, 2016** A minor bugfix release to patch a number of small but important issues. Fixes and improvements: -- Added a [DynamicMap - Tutorial](http://holoviews.org/Tutorials/Dynamic_Map.html) to - explain how to explore very large or continuous parameter spaces in - HoloViews ([PR - \#470](https://github.com/pyviz/holoviews/issues/470)). -- Various fixes and improvements for DynamicMaps including slicing - ([PR \#488](https://github.com/pyviz/holoviews/issues/488)) and - validation ([PR - \#483](https://github.com/pyviz/holoviews/issues/478)) and - serialization ([PR - \#483](https://github.com/pyviz/holoviews/issues/478)) -- Widgets containing Matplotlib plots now display the first frame from - cache providing at least the initial frame when exporting - DynamicMaps ([PR - \#486](https://github.com/pyviz/holoviews/issues/483)) -- Fixed plotting Bokeh plots using widgets in live mode, after changes - introduced in latest Bokeh version (commit - [1b87c91e9](https://github.com/pyviz/holoviews/commit/1b87c91e9e7cf35b267344ccd4a2fa91dd052890)). -- Fixed issue in coloring Point/Scatter objects by values ([Issue - \#467](https://github.com/pyviz/holoviews/issues/467)). +- Added a [DynamicMap + Tutorial](http://holoviews.org/Tutorials/Dynamic_Map.html) to + explain how to explore very large or continuous parameter spaces in + HoloViews ([PR + \#470](https://github.com/pyviz/holoviews/issues/470)). +- Various fixes and improvements for DynamicMaps including slicing + ([PR \#488](https://github.com/pyviz/holoviews/issues/488)) and + validation ([PR + \#483](https://github.com/pyviz/holoviews/issues/478)) and + serialization ([PR + \#483](https://github.com/pyviz/holoviews/issues/478)) +- Widgets containing Matplotlib plots now display the first frame from + cache providing at least the initial frame when exporting + DynamicMaps ([PR + \#486](https://github.com/pyviz/holoviews/issues/483)) +- Fixed plotting Bokeh plots using widgets in live mode, after changes + introduced in latest Bokeh version (commit + [1b87c91e9](https://github.com/pyviz/holoviews/commit/1b87c91e9e7cf35b267344ccd4a2fa91dd052890)). +- Fixed issue in coloring Point/Scatter objects by values ([Issue + \#467](https://github.com/pyviz/holoviews/issues/467)). Backwards compatibility: -- The behavior of the `scaling_factor` on Point and Scatter plots has - changed now simply multiplying `area` or `width` (as defined by the - `scaling_method`). To disable scaling points by a dimension set - `size_index=None`. -- Removed hooks to display 3D Elements using the `BokehMPLRawWrapper` - in Bokeh ([PR \#477](https://github.com/pyviz/holoviews/pull/477)) -- Renamed the DynamicMap mode `closed` to `bounded` ([PR - \#477](https://github.com/pyviz/holoviews/pull/485)) - -Version 1.4.2 -============= +- The behavior of the `scaling_factor` on Point and Scatter plots has + changed now simply multiplying `area` or `width` (as defined by the + `scaling_method`). To disable scaling points by a dimension set + `size_index=None`. +- Removed hooks to display 3D Elements using the `BokehMPLRawWrapper` + in Bokeh ([PR \#477](https://github.com/pyviz/holoviews/pull/477)) +- Renamed the DynamicMap mode `closed` to `bounded` ([PR + \#477](https://github.com/pyviz/holoviews/pull/485)) + +# Version 1.4.2 + **February 7, 2016** Over the past month since the 1.4.1 release, we have improved our @@ -3578,44 +3597,44 @@ made several additional usability improvements. Documentation changes: -- Major overhaul of website and notebook building making it much - easier to test user contributions ([Issue - \#180](https://github.com/pyviz/holoviews/issues/180), [PR - \#429](https://github.com/pyviz/holoviews/pull/429)) -- Major rewrite of the documentation ([PR - \#401](https://github.com/pyviz/holoviews/pull/401), [PR - \#411](https://github.com/pyviz/holoviews/pull/411)) -- Added Columnar Data Tutorial and removed most of Pandas Conversions - as it is now supported by the core. +- Major overhaul of website and notebook building making it much + easier to test user contributions ([Issue + \#180](https://github.com/pyviz/holoviews/issues/180), [PR + \#429](https://github.com/pyviz/holoviews/pull/429)) +- Major rewrite of the documentation ([PR + \#401](https://github.com/pyviz/holoviews/pull/401), [PR + \#411](https://github.com/pyviz/holoviews/pull/411)) +- Added Columnar Data Tutorial and removed most of Pandas Conversions + as it is now supported by the core. Fixes and improvements: -- Major improvement for grid based layouts with varying aspects ([PR - \#457](https://github.com/pyviz/holoviews/pull/457)) -- Fix for interleaving %matplotline inline and holoviews plots ([Issue - \#179](https://github.com/pyviz/holoviews/issues/179)) -- Matplotlib legend z-orders and updating fixed ([Issue - \#304](https://github.com/pyviz/holoviews/issues/304), [Issue - \#305](https://github.com/pyviz/holoviews/issues/305)) -- `color_index` and `size_index` plot options support specifying - dimension by name ([Issue - \#391](https://github.com/pyviz/holoviews/issues/391)) -- Added `Area` Element type for drawing area under or between Curves. - ([PR \#427](https://github.com/pyviz/holoviews/pull/427)) -- Fixed issues where slicing would remove styles applied to - an Element. ([Issue - \#423](https://github.com/pyviz/holoviews/issues/423), [PR - \#439](https://github.com/pyviz/holoviews/pull/439)) -- Updated the `title_format` plot option to support a `{dimensions}` - formatter ([PR \#436](https://github.com/pyviz/holoviews/pull/436)) -- Improvements to Renderer API to allow JS and CSS requirements for - exporting standalone widgets ([PR - \#426](https://github.com/pyviz/holoviews/pull/426)) -- Compatibility with the latest Bokeh 0.11 release ([PR - \#393](https://github.com/pyviz/holoviews/pull/393)) - -Version 1.4.1 -============= +- Major improvement for grid based layouts with varying aspects ([PR + \#457](https://github.com/pyviz/holoviews/pull/457)) +- Fix for interleaving %matplotline inline and holoviews plots ([Issue + \#179](https://github.com/pyviz/holoviews/issues/179)) +- Matplotlib legend z-orders and updating fixed ([Issue + \#304](https://github.com/pyviz/holoviews/issues/304), [Issue + \#305](https://github.com/pyviz/holoviews/issues/305)) +- `color_index` and `size_index` plot options support specifying + dimension by name ([Issue + \#391](https://github.com/pyviz/holoviews/issues/391)) +- Added `Area` Element type for drawing area under or between Curves. + ([PR \#427](https://github.com/pyviz/holoviews/pull/427)) +- Fixed issues where slicing would remove styles applied to + an Element. ([Issue + \#423](https://github.com/pyviz/holoviews/issues/423), [PR + \#439](https://github.com/pyviz/holoviews/pull/439)) +- Updated the `title_format` plot option to support a `{dimensions}` + formatter ([PR \#436](https://github.com/pyviz/holoviews/pull/436)) +- Improvements to Renderer API to allow JS and CSS requirements for + exporting standalone widgets ([PR + \#426](https://github.com/pyviz/holoviews/pull/426)) +- Compatibility with the latest Bokeh 0.11 release ([PR + \#393](https://github.com/pyviz/holoviews/pull/393)) + +# Version 1.4.1 + **December 22, 2015** Over the past two weeks since the 1.4 release, we have implemented @@ -3624,46 +3643,46 @@ improvements. New features: -- Improved help system. It is now possible to recursively list all the - applicable documentation for a composite object. In addition, the - documentation may now be filtered using a regular - expression pattern. ([PR - \#370](https://github.com/pyviz/holoviews/pull/370)) -- HoloViews now supports multiple active display hooks making it - easier to use nbconvert. For instance, PNG data will be embedded in - the notebook if the argument display\_formats=\['html','png'\] is - supplied to the notebook\_extension. ([PR - \#355](https://github.com/pyviz/holoviews/pull/355)) -- Improvements to the display of DynamicMaps as well as many new - improvements to the Bokeh backend including better VLines/HLines and - support for the Bars element. ([PR - \#367](https://github.com/pyviz/holoviews/pull/367) , [PR - \#362](https://github.com/pyviz/holoviews/pull/362), [PR - \#339](https://github.com/pyviz/holoviews/pull/339)). -- New Spikes and BoxWhisker elements suitable for representing - distributions as a sequence of lines or as a box-and-whisker plot. - ([PR \#346](https://github.com/pyviz/holoviews/pull/346), [PR - \#339](https://github.com/pyviz/holoviews/pull/339)) -- Improvements to the notebook\_extension. For instance, - executing hv.notebook\_extension('bokeh') will now load BokehJS and - automatically activate the Bokeh backend (if available). -- Significant performance improvements when using the groupby - operation on HoloMaps and when working with highly - nested datastructures. ([PR - \#349](https://github.com/pyviz/holoviews/pull/349), [PR - \#359](https://github.com/pyviz/holoviews/pull/359)) +- Improved help system. It is now possible to recursively list all the + applicable documentation for a composite object. In addition, the + documentation may now be filtered using a regular + expression pattern. ([PR + \#370](https://github.com/pyviz/holoviews/pull/370)) +- HoloViews now supports multiple active display hooks making it + easier to use nbconvert. For instance, PNG data will be embedded in + the notebook if the argument display_formats=\['html','png'\] is + supplied to the notebook_extension. ([PR + \#355](https://github.com/pyviz/holoviews/pull/355)) +- Improvements to the display of DynamicMaps as well as many new + improvements to the Bokeh backend including better VLines/HLines and + support for the Bars element. ([PR + \#367](https://github.com/pyviz/holoviews/pull/367) , [PR + \#362](https://github.com/pyviz/holoviews/pull/362), [PR + \#339](https://github.com/pyviz/holoviews/pull/339)). +- New Spikes and BoxWhisker elements suitable for representing + distributions as a sequence of lines or as a box-and-whisker plot. + ([PR \#346](https://github.com/pyviz/holoviews/pull/346), [PR + \#339](https://github.com/pyviz/holoviews/pull/339)) +- Improvements to the notebook_extension. For instance, + executing hv.notebook_extension('bokeh') will now load BokehJS and + automatically activate the Bokeh backend (if available). +- Significant performance improvements when using the groupby + operation on HoloMaps and when working with highly + nested datastructures. ([PR + \#349](https://github.com/pyviz/holoviews/pull/349), [PR + \#359](https://github.com/pyviz/holoviews/pull/359)) Notable bug fixes: -- DynamicMaps are now properly integrated into the style system and - can be customized in the same way as HoloMaps. ([PR - \#368](https://github.com/pyviz/holoviews/pull/368)) -- Widgets now work correctly when unicode is used in the dimension - labels and values ([PR - \#376](https://github.com/pyviz/holoviews/pull/376)). +- DynamicMaps are now properly integrated into the style system and + can be customized in the same way as HoloMaps. ([PR + \#368](https://github.com/pyviz/holoviews/pull/368)) +- Widgets now work correctly when unicode is used in the dimension + labels and values ([PR + \#376](https://github.com/pyviz/holoviews/pull/376)). + +# Version 1.4.0 -Version 1.4.0 -============= **December 4, 2015** Over the past few months we have added several major new features and @@ -3673,89 +3692,89 @@ commits. Major new features: -- Data API: The new data API brings an extensible system of to add new - data interfaces to column based Element types. These interfaces - allow applying powerful operations on the data independently of the - data format. The currently supported datatypes include NumPy, pandas - dataframes and a simple dictionary format. ([PR - \#284](https://github.com/pyviz/holoviews/pull/284)) -- Backend API: In this release we completely refactored the rendering, - plotting and IPython display system to make it easy to add new - plotting backends. Data may be styled and pickled for each backend - independently and renderers now support exporting all plotting data - including widgets as standalone HTML files or with separate - JSON data. -- Bokeh backend: The first new plotting backend added via the new - backend API. Bokeh plots allow for much faster plotting and - greater interactivity. Supports most Element types and layouts and - provides facilities for sharing axes across plots and linked - brushing across plots. ([PR - \#250](https://github.com/pyviz/holoviews/pull/250)) -- DynamicMap: The new DynamicMap class allows HoloMap data to be - generated on-the-fly while running a Jupyter IPython - notebook kernel. Allows visualization of unbounded data streams and - smooth exploration of large continuous parameter spaces. ([PR - \#278](https://github.com/pyviz/holoviews/pull/278)) +- Data API: The new data API brings an extensible system of to add new + data interfaces to column based Element types. These interfaces + allow applying powerful operations on the data independently of the + data format. The currently supported datatypes include NumPy, pandas + dataframes and a simple dictionary format. ([PR + \#284](https://github.com/pyviz/holoviews/pull/284)) +- Backend API: In this release we completely refactored the rendering, + plotting and IPython display system to make it easy to add new + plotting backends. Data may be styled and pickled for each backend + independently and renderers now support exporting all plotting data + including widgets as standalone HTML files or with separate + JSON data. +- Bokeh backend: The first new plotting backend added via the new + backend API. Bokeh plots allow for much faster plotting and + greater interactivity. Supports most Element types and layouts and + provides facilities for sharing axes across plots and linked + brushing across plots. ([PR + \#250](https://github.com/pyviz/holoviews/pull/250)) +- DynamicMap: The new DynamicMap class allows HoloMap data to be + generated on-the-fly while running a Jupyter IPython + notebook kernel. Allows visualization of unbounded data streams and + smooth exploration of large continuous parameter spaces. ([PR + \#278](https://github.com/pyviz/holoviews/pull/278)) Other features: -- Easy definition of custom aliases for group, label and Dimension - names, allowing easier use of LaTeX. -- New Trisurface and QuadMesh elements. -- Widgets now allow expressing hierarchical relationships - between dimensions. -- Added GridMatrix container for heterogeneous Elements and gridmatrix - operation to generate scatter matrix showing relationship - between dimensions. -- Filled contour regions can now be generated using the - contours operation. -- Consistent indexing semantics for all Elements and support for - boolean indexing for Columns and NdMapping types. -- New hv.notebook\_extension function offers a more flexible - alternative to %load\_ext, e.g. for loading other - extensions hv.notebook\_extension(bokeh=True). +- Easy definition of custom aliases for group, label and Dimension + names, allowing easier use of LaTeX. +- New Trisurface and QuadMesh elements. +- Widgets now allow expressing hierarchical relationships + between dimensions. +- Added GridMatrix container for heterogeneous Elements and gridmatrix + operation to generate scatter matrix showing relationship + between dimensions. +- Filled contour regions can now be generated using the + contours operation. +- Consistent indexing semantics for all Elements and support for + boolean indexing for Columns and NdMapping types. +- New hv.notebook_extension function offers a more flexible + alternative to %load_ext, e.g. for loading other + extensions hv.notebook_extension(bokeh=True). Experimental features: -- Bokeh callbacks allow adding interactivity by communicating between - BokehJS tools and the IPython kernel, e.g. allowing downsampling - based on the zoom level. +- Bokeh callbacks allow adding interactivity by communicating between + BokehJS tools and the IPython kernel, e.g. allowing downsampling + based on the zoom level. Notable bug fixes: -- Major speedup rendering large HoloMaps (\~ 2-3 times faster). -- Colorbars now consistent for all plot configurations. -- Style pickling now works correctly. +- Major speedup rendering large HoloMaps (\~ 2-3 times faster). +- Colorbars now consistent for all plot configurations. +- Style pickling now works correctly. API Changes: -- Dimension formatter parameter now deprecated in favor - of value\_format. -- Types of Chart and Table Element data now dependent on - selected interface. -- DFrame conversion interface deprecated in favor of Columns - pandas interface. +- Dimension formatter parameter now deprecated in favor + of value_format. +- Types of Chart and Table Element data now dependent on + selected interface. +- DFrame conversion interface deprecated in favor of Columns + pandas interface. + +# Version 1.3.2 -Version 1.3.2 -============= **July 6, 2015** Minor bugfix release to address a small number of issues: Features: -- Added support for colorbars on Surface Element (1cd5281). -- Added linewidth style option to SurfacePlot (9b6ccc5). +- Added support for colorbars on Surface Element (1cd5281). +- Added linewidth style option to SurfacePlot (9b6ccc5). Bug fixes: -- Fixed inversion inversion of y-range during sampling (6ff81bb). -- Fixed overlaying of 3D elements (787d511). -- Ensuring that underscore.js is loaded in widgets (f2f6378). -- Fixed Python3 issue in Overlay.get (8ceabe3). +- Fixed inversion inversion of y-range during sampling (6ff81bb). +- Fixed overlaying of 3D elements (787d511). +- Ensuring that underscore.js is loaded in widgets (f2f6378). +- Fixed Python3 issue in Overlay.get (8ceabe3). + +# Version 1.3.1 -Version 1.3.1 -============= **July 1, 2015** Minor bugfix release to address a number of issues that weren't caught @@ -3764,21 +3783,21 @@ features: Features: -- Introduced new `Spread` element to plot errors and confidence - intervals (30d3184). -- `ErrorBars` and `Spread` elements now allow most Chart constructor - types (f013deb). +- Introduced new `Spread` element to plot errors and confidence + intervals (30d3184). +- `ErrorBars` and `Spread` elements now allow most Chart constructor + types (f013deb). Bug fixes: -- Fixed unicode handling for dimension labels (061e9af). -- Handling of invalid dimension label characters in widgets (a101b9e). -- Fixed setting of fps option for MPLRenderer video output (c61b9df). -- Fix for multiple and animated colorbars (5e1e4b5). -- Fix to Chart slices starting or ending at zero (edd0039). +- Fixed unicode handling for dimension labels (061e9af). +- Handling of invalid dimension label characters in widgets (a101b9e). +- Fixed setting of fps option for MPLRenderer video output (c61b9df). +- Fix for multiple and animated colorbars (5e1e4b5). +- Fix to Chart slices starting or ending at zero (edd0039). + +# Version 1.3.0 -Version 1.3.0 -============= **June 27, 2015** Since the last release we closed over 34 issues and have made 380 @@ -3792,58 +3811,58 @@ number of important bugs. Highlights/Features: -- Allowed display of data structures which do not match the - recommended nesting hierarchy (67b28f3, fbd89c3). -- Dimensions now sanitized for `.select`, `.sample` and `.reduce` - calls (6685633, 00b5a66). -- Added `holoviews.ipython.display` function to render (and display) - any HoloViews object, useful for IPython interact widgets (0fa49cd). -- Table column widths now adapt to cell contents (be90a54). -- Defaulting to Matplotlib ticking behavior (62e1e58). -- Allowed specifying fixed figure sizes to Matplotlib via `fig_inches` - tuples using (width, None) and (None, height) formats (632facd). -- Constructors of `Chart`, `Path` and `Histogram` classes now support - additional data formats (2297375). -- `ScrubberWidget` now supports all figure formats (c317db4). -- Allowed customizing legend positions on `Bars` Elements (5a12882). -- Support for multiple colorbars on one axis (aac7b92). -- `.reindex` on `NdElement` types now support converting between key - and value dimensions allowing more powerful conversions. (03ac3ce) -- Improved support for casting between `Element` types (cdaab4e, - b2ad91b, ce7fe2d, 865b4d5). -- The `%%opts` cell magic may now be used multiple times in the same - cell (2a77fd0) -- Matplotlib rcParams can now be set correctly per figure (751210f). -- Improved `OptionTree` repr which now works with eval (2f824c1). -- Refactor of rendering system and IPython extension to allow easy - swapping of plotting backend (\#141) -- Large plotting optimization by computing tight `bbox_inches` - once (e34e339). -- Widgets now cache frames in the DOM, avoiding flickering in some - browsers and make use of jinja2 template inheritance. (fc7dd2b) -- Calling a HoloViews object without arguments now clears any - associated custom styles. (9e8c343) +- Allowed display of data structures which do not match the + recommended nesting hierarchy (67b28f3, fbd89c3). +- Dimensions now sanitized for `.select`, `.sample` and `.reduce` + calls (6685633, 00b5a66). +- Added `holoviews.ipython.display` function to render (and display) + any HoloViews object, useful for IPython interact widgets (0fa49cd). +- Table column widths now adapt to cell contents (be90a54). +- Defaulting to Matplotlib ticking behavior (62e1e58). +- Allowed specifying fixed figure sizes to Matplotlib via `fig_inches` + tuples using (width, None) and (None, height) formats (632facd). +- Constructors of `Chart`, `Path` and `Histogram` classes now support + additional data formats (2297375). +- `ScrubberWidget` now supports all figure formats (c317db4). +- Allowed customizing legend positions on `Bars` Elements (5a12882). +- Support for multiple colorbars on one axis (aac7b92). +- `.reindex` on `NdElement` types now support converting between key + and value dimensions allowing more powerful conversions. (03ac3ce) +- Improved support for casting between `Element` types (cdaab4e, + b2ad91b, ce7fe2d, 865b4d5). +- The `%%opts` cell magic may now be used multiple times in the same + cell (2a77fd0) +- Matplotlib rcParams can now be set correctly per figure (751210f). +- Improved `OptionTree` repr which now works with eval (2f824c1). +- Refactor of rendering system and IPython extension to allow easy + swapping of plotting backend (\#141) +- Large plotting optimization by computing tight `bbox_inches` + once (e34e339). +- Widgets now cache frames in the DOM, avoiding flickering in some + browsers and make use of jinja2 template inheritance. (fc7dd2b) +- Calling a HoloViews object without arguments now clears any + associated custom styles. (9e8c343) API Changes -- Renamed key\_dimensions and value\_dimensions to kdims and vdims - respectively, while providing backward compatibility for passing and - accessing the long names (8feb7d2). -- Combined x/y/zticker plot options into x/y/zticks parameters which - now accept an explicit number of ticks, an explicit list of tick - positions (and labels), and a Matplotlib tick locator. -- Changed backend options in %output magic, `nbagg` and `d3` are now - modes of the Matplotlib backend and can be selected with - `backend='matplotlib:nbagg'` and - `backend='matplotlib:mpld3'` respectively. The 'd3' and 'nbagg' - options remain supported but will be deprecated in future. -- Customizations should no longer be applied directly to - `Store.options`; the `Store.options(backend='matplotlib')` object - should be customized instead. There is no longer a need to call the - deprecated `Store.register_plots` method. - -Version 1.2.0 -============= +- Renamed key_dimensions and value_dimensions to kdims and vdims + respectively, while providing backward compatibility for passing and + accessing the long names (8feb7d2). +- Combined x/y/zticker plot options into x/y/zticks parameters which + now accept an explicit number of ticks, an explicit list of tick + positions (and labels), and a Matplotlib tick locator. +- Changed backend options in %output magic, `nbagg` and `d3` are now + modes of the Matplotlib backend and can be selected with + `backend='matplotlib:nbagg'` and + `backend='matplotlib:mpld3'` respectively. The 'd3' and 'nbagg' + options remain supported but will be deprecated in future. +- Customizations should no longer be applied directly to + `Store.options`; the `Store.options(backend='matplotlib')` object + should be customized instead. There is no longer a need to call the + deprecated `Store.register_plots` method. + +# Version 1.2.0 + **May 27, 2015** Since the last release we closed over 20 issues and have made 334 @@ -3856,104 +3875,105 @@ range of problems. Highlights/Features: -- Added new `ErrorBars` Element (f2b276b) -- Added `Empty` pseudo-Element to define empty placeholders in - Layouts (35bac9f1d) -- Added support for changing font sizes easily (0f54bea) -- Support for holoviews.rc file (79076c8) -- Many major speed optimizations for working with and plotting - HoloViews data structures (fe87b4c, 7578c51, 5876fe6, 8863333) -- Support for `GridSpace` with inner axes (93295c8) -- New `aspect_weight` and `tight` Layout plot options for more - customizability of Layout arrangements (4b1f03d, e6a76b7) -- Added `bgcolor` plot option to easily set axis background - color (92eb95c) -- Improved widget layout (f51af02) -- New `OutputMagic` css option to style html output (9d42dc2) -- Experimental support for PDF output (1e8a59b) -- Added support for 3D interactivity with nbagg (781bc25) -- Added ability to support deprecated plot options in %%opts magic. -- Added `DrawPlot` simplifying the implementation of custom - plots (38e9d44) +- Added new `ErrorBars` Element (f2b276b) +- Added `Empty` pseudo-Element to define empty placeholders in + Layouts (35bac9f1d) +- Added support for changing font sizes easily (0f54bea) +- Support for holoviews.rc file (79076c8) +- Many major speed optimizations for working with and plotting + HoloViews data structures (fe87b4c, 7578c51, 5876fe6, 8863333) +- Support for `GridSpace` with inner axes (93295c8) +- New `aspect_weight` and `tight` Layout plot options for more + customizability of Layout arrangements (4b1f03d, e6a76b7) +- Added `bgcolor` plot option to easily set axis background + color (92eb95c) +- Improved widget layout (f51af02) +- New `OutputMagic` css option to style html output (9d42dc2) +- Experimental support for PDF output (1e8a59b) +- Added support for 3D interactivity with nbagg (781bc25) +- Added ability to support deprecated plot options in %%opts magic. +- Added `DrawPlot` simplifying the implementation of custom + plots (38e9d44) API changes: -- `Path` and `Histogram` support new constructors (7138ef4, 03b5d38) -- New depth argument on the relabel method (f89b89f) -- Interface to Pandas improved (1a7cd3d) -- Removed `xlim`, `ylim` and `zlim` to eliminate redundancy. -- Renaming of various plot and style options including: +- `Path` and `Histogram` support new constructors (7138ef4, 03b5d38) +- New depth argument on the relabel method (f89b89f) +- Interface to Pandas improved (1a7cd3d) +- Removed `xlim`, `ylim` and `zlim` to eliminate redundancy. +- Renaming of various plot and style options including: + + - `figure_*` to `fig_*` + - `vertical_spacing` and `horizontal_spacing` to `vspace` and + `hspace` respectively - - `figure_*` to `fig_*` - - `vertical_spacing` and `horizontal_spacing` to `vspace` and - `hspace` respectively + \* Deprecation of confusing `origin` style option on RasterPlot - \* Deprecation of confusing `origin` style option on RasterPlot -- `Overlay.__getitem__` no longer supports integer indexing (use `get` - method instead) +- `Overlay.__getitem__` no longer supports integer indexing (use `get` + method instead) Important bug fixes: -- Important fixes to inheritance in the options system - (d34a931, 71c1f3a7) -- Fixes to the select method (df839bea5) -- Fixes to normalization system (c3ef40b) -- Fixes to `Raster` and `Image` extents, `__getitem__` and sampling. -- Fixed bug with disappearing adjoined plots (2360972) -- Fixed plot ordering of overlaid elements across a - `HoloMap` (c4f1685) - -Version 1.1.0 -============= +- Important fixes to inheritance in the options system + (d34a931, 71c1f3a7) +- Fixes to the select method (df839bea5) +- Fixes to normalization system (c3ef40b) +- Fixes to `Raster` and `Image` extents, `__getitem__` and sampling. +- Fixed bug with disappearing adjoined plots (2360972) +- Fixed plot ordering of overlaid elements across a + `HoloMap` (c4f1685) + +# Version 1.1.0 + **April 15, 2015** Highlights: -- Support for nbagg as a backend (09eab4f1) -- New .hvz file format for saving HoloViews objects (bfd5f7af) -- New `Polygon` element type (d1ec8ec8) -- Greatly improved Unicode support throughout, including support for - unicode characters in Python 3 attribute names (609a8454) -- Regular SelectionWidget now supports live rendering (eb5bf8b6) -- Supports a list of objects in Layout and Overlay - constructors (5ba1866e) -- Polar projections now supported (3801b76e) +- Support for nbagg as a backend (09eab4f1) +- New .hvz file format for saving HoloViews objects (bfd5f7af) +- New `Polygon` element type (d1ec8ec8) +- Greatly improved Unicode support throughout, including support for + unicode characters in Python 3 attribute names (609a8454) +- Regular SelectionWidget now supports live rendering (eb5bf8b6) +- Supports a list of objects in Layout and Overlay + constructors (5ba1866e) +- Polar projections now supported (3801b76e) API changes (not backward compatible): -- `xlim`, `ylim`, `zlim`, `xlabel`, `ylabel` and `zlabel` have been - deprecated (081d4123) -- Plotting options `show_xaxis` and `show_yaxis` renamed to `xaxis` - and `yaxis`, respectively (13393f2a). -- Deprecated IPySelectionWidget (f59c34c0) +- `xlim`, `ylim`, `zlim`, `xlabel`, `ylabel` and `zlabel` have been + deprecated (081d4123) +- Plotting options `show_xaxis` and `show_yaxis` renamed to `xaxis` + and `yaxis`, respectively (13393f2a). +- Deprecated IPySelectionWidget (f59c34c0) In addition to the above improvements, many miscellaneous bug fixes were made. -Version 1.0.1 -============= +# Version 1.0.1 + **March 26, 2015** Minor release addressing bugs and issues with 1.0.0. Highlights: -- New separate Pandas Tutorial (8455abc3) -- Silenced warnings when loading the IPython extension in IPython - 3 (aaa6861b) -- Added more useful installation options via `setup.py` (72ece4db) -- Improvements and bug-fixes for the `%%opts` magic - tab-completion (e0ad7108) -- `DFrame` now supports standard constructor for pandas - dataframes (983825c5) -- `Tables` are now correctly formatted using the appropriate - `Dimension` formatter (588bc2a3) -- Support for unlimited alphabetical subfigure labelling (e039d00b) -- Miscellaneous bug fixes, including Python 3 - compatibility improvements. - -Version 1.0.0 -============= +- New separate Pandas Tutorial (8455abc3) +- Silenced warnings when loading the IPython extension in IPython + 3 (aaa6861b) +- Added more useful installation options via `setup.py` (72ece4db) +- Improvements and bug-fixes for the `%%opts` magic + tab-completion (e0ad7108) +- `DFrame` now supports standard constructor for pandas + dataframes (983825c5) +- `Tables` are now correctly formatted using the appropriate + `Dimension` formatter (588bc2a3) +- Support for unlimited alphabetical subfigure labelling (e039d00b) +- Miscellaneous bug fixes, including Python 3 + compatibility improvements. + +# Version 1.0.0 + **March 16, 2015** First public release available on GitHub and PyPI. diff --git a/README.md b/README.md index b70ff28ccc..eaf2ec464e 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,11 @@ **Stop plotting your data - annotate your data and let it visualize itself.** + | | | | --- | --- | -| Build Status | [![Build Status](https://github.com/holoviz/holoviews/workflows/tests/badge.svg?query=branch:main)](https://github.com/holoviz/holoviews/actions/workflows/test.yaml?query=branch%3Amain) | +| Downloads | ![https://pypistats.org/packages/holoviews](https://img.shields.io/pypi/dm/holoviews?label=pypi) ![https://anaconda.org/pyviz/holoviews](https://pyviz.org/_static/cache/holoviews_conda_downloads_badge.svg) +| Build Status | [![Build Status](https://github.com/holoviz/holoviews/actions/workflows/test.yaml/badge.svg?branch=main)](https://github.com/holoviz/holoviews/actions/workflows/test.yaml?query=branch%3Amain) | | Coverage | [![codecov](https://codecov.io/gh/holoviz/holoviews/branch/main/graph/badge.svg)](https://codecov.io/gh/holoviz/holoviews) | | Latest dev release | [![Github tag](https://img.shields.io/github/tag/holoviz/holoviews.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/holoviews/tags) [![dev-site](https://img.shields.io/website-up-down-green-red/http/dev.holoviews.org.svg?label=dev%20website)](http://dev.holoviews.org) | | Latest release | [![Github release](https://img.shields.io/github/release/holoviz/holoviews.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/holoviews/releases) [![PyPI version](https://img.shields.io/pypi/v/holoviews.svg?colorB=cc77dd)](https://pypi.python.org/pypi/holoviews) [![holoviews version](https://img.shields.io/conda/v/pyviz/holoviews.svg?colorB=4488ff&style=flat)](https://anaconda.org/pyviz/holoviews) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/holoviews.svg?label=conda%7Cconda-forge&colorB=4488ff)](https://anaconda.org/conda-forge/holoviews) [![defaults version](https://img.shields.io/conda/v/anaconda/holoviews.svg?label=conda%7Cdefaults&style=flat&colorB=4488ff)](https://anaconda.org/anaconda/holoviews) | @@ -14,9 +16,7 @@ itself.** | Binder | [![Binder](https://img.shields.io/badge/Launch%20JupyterLab-v1.15.4-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gh/holoviz/holoviews/v1.15.4?urlpath=lab/tree/examples) | | Support | [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.holoviz.org)](https://discourse.holoviz.org/) | - -HoloViews is an -[open-source](https://github.com/holoviz/holoviews/blob/main/LICENSE.txt) +HoloViews is an [open-source](https://github.com/holoviz/holoviews/blob/main/LICENSE.txt) Python library designed to make data analysis and visualization seamless and simple. With HoloViews, you can usually express what you want to do in very few lines of code, letting you focus on what you are trying to @@ -54,21 +54,19 @@ Check out the [HoloViews web site](http://holoviews.org) for extensive examples - -Installation -============ +# Installation HoloViews works with -[Python 3](https://github.com/holoviz/holoviews/actions?query=workflow%3Apytest) +[Python](https://github.com/holoviz/holoviews/actions/workflows/test.yaml) on Linux, Windows, or Mac, and works seamlessly with [Jupyter Notebook and JupyterLab](https://jupyter.org). The recommended way to install HoloViews is using the [conda](https://docs.conda.io/projects/conda/en/latest/index.html) command provided by -[Anaconda](https://docs.anaconda.com/anaconda/install/) or +[Anaconda](https://docs.anaconda.com/free/anaconda/install/) or [Miniconda](https://docs.conda.io/en/latest/miniconda.html): - conda install -c pyviz holoviews bokeh + conda install holoviews This command will install the typical packages most useful with HoloViews, though HoloViews itself depends only on @@ -82,8 +80,7 @@ You can also clone holoviews directly from GitHub and install it with: cd holoviews pip install -e . -Usage ------ +## Usage Once you've installed HoloViews, you can get a copy of all the examples shown on this website: @@ -96,14 +93,9 @@ Now you can launch Jupyter Notebook or JupyterLab to explore them: jupyter lab -If you are working with a JupyterLab version <2.0 you will also need the PyViz JupyterLab -extension: - - jupyter labextension install @pyviz/jupyterlab_pyviz - For more details on setup and configuration see [our website](https://holoviews.org/user_guide/Installing_and_Configuring.html). -For general discussion, we have a [gitter channel](https://gitter.im/pyviz/pyviz). +For general discussion, we have a [discord channel](https://discord.gg/AXRHnJU6sP). If you find any bugs or have any feature suggestions please file a GitHub [issue](https://github.com/holoviz/holoviews/issues) or submit a [pull request](https://help.github.com/articles/about-pull-requests). diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 24f412d2a7..087efe849e 100644 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -32,6 +32,13 @@ requirements: - {{ dep }} {% endfor %} +test: + imports: + - {{ sdata['name'] }} + commands: + - pip check + requires: + - pip about: home: https://holoviews.org diff --git a/doc/conf.py b/doc/conf.py index 11ae7bf5b2..63fe74c028 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -51,7 +51,6 @@ "copyright", "last-updated", ], - "analytics": {"google_analytics_id": 'G-91EZMMHSF7'} } nbbuild_cell_timeout = 360 @@ -59,8 +58,13 @@ extensions += [ 'nbsite.gallery', 'sphinx_copybutton', + 'nbsite.analytics', ] +nbsite_analytics = { + 'goatcounter_holoviz': True, +} + nbsite_gallery_conf = { 'backends': ['bokeh', 'matplotlib', 'plotly'], 'galleries': {}, diff --git a/doc/releases.rst b/doc/releases.rst index 911d38faf0..216b89a563 100644 --- a/doc/releases.rst +++ b/doc/releases.rst @@ -4,6 +4,122 @@ Releases Version 1.18 ~~~~~~~~~~~~ +Version 1.18.3 +************** + +**February 12, 2024** + +This micro release includes bug fixes. + +Bug fixes: + +- Fix BoundsX and BoundsY regression + (`#6099 `__) +- Fix rasterize regression + (`#6102 `__) +- Fix link selection for empty Layout + (`#6110 `__) +- Don’t pin notebook in conda recipe for pyviz channel + (`#6108 `__) + + +Version 1.18.2 +************** + +**February 5, 2024** + +This micro release includes a number of bug fixes and documentation +updates, as well as compatibility updates for xarray 2023.12 and Pandas +2.2. Many thanks to the new contributors @junietoc, @JulianGiles, and +@magic-lantern, as well as the returning contributors @ianthomas23, +@maximlt, @TheoMathurin, @philippjfr, @ahuang11, and @Hoxbro. + +Enhancements: + +- Update contour line calculations to use ContourPy’s + ``LineType.ChunkCombinedNan`` + (`#5985 `__) +- Use sys.executable for ``check_output`` + (`#5983 `__) +- Updates to ``show_versions`` + (`#6072 `__, + `#6081 `__) + +Bug fixes: + +- Support ``color_key`` in ``datashade`` when intermediate step is an + ``ImageStack`` + (`#5994 `__) +- Fix hist on overlay + (`#5995 `__) +- Set proper context before triggering streams + (`#6000 `__) +- Support partial bound function + (`#6009 `__) +- Add ``norm`` in ``init_artists`` in holoviews/plotting/mpl/raster.py + (`#6029 `__) +- Fix linking elements that are transformed by a Compositor + (`#6003 `__) +- Add datetime hover information for selector + (`#6023 `__, + `#6039 `__) +- Only evaluate ``rx`` if it is a Reactive Expression + (`#6014 `__) +- Ensure partial methods can be used as dmap callables + (`#6063 `__) +- Del frame after stack level is found in ``deprecated`` + (`#6085 `__) + +Compatibility: + +- Compatibility updates with xarray 2023.12 + (`#6026 `__) +- Add extra check to detect if we are in jupyterlite + (`#6007 `__) +- Compatibility updates with Pandas 2.2 + (`#6074 `__, + `#6078 `__) +- Add Comm ``on_open`` handler to initialize the server comm + (`#6076 `__) + +Documentation: + +- Fix docs (`#5996 `__) +- Fix Param usage in the Plot and Renderers guide + (`#6001 `__) +- Fixing URLs to bokeh project + (`#6005 `__) +- Fix to broken urls in example gallery pages + (`#6038 `__) +- Replace Google Analytics with GoatCounter + (`#6048 `__) +- Add downloads badges + (`#6088 `__) + +Maintenance: + +- Change to pytest-rerunfailures + (`#5984 `__) +- Holoviews maintenance + (`#5987 `__) +- Add ``log_cli_level = "INFO"`` to pytest + (`#5989 `__) +- Add shell pre-commit hook + (`#5991 `__) +- Enable Bugbear 904 + (`#5992 `__) +- Part 1, modernize test suite + (`#5954 `__) +- Enforce labels + (`#5996 `__) +- Add lower pin to scipy + (`#6032 `__) +- Skip Deploying_Bokeh_Apps.ipynb on Windows + (`#6070 `__) +- Fix failing Windows tests + (`#6087 `__) + + Version 1.18.1 ************** diff --git a/examples/README.md b/examples/README.md index 3db37a2720..e4d1b36b69 100644 --- a/examples/README.md +++ b/examples/README.md @@ -5,20 +5,20 @@ This directory contains all the notebooks built as part of the ## Directory structure -* ``assets``: Files used by the examples. -* ``gallery``: Examples shown on the [gallery page](http://holoviews.org/gallery/index.html). -* ``getting_started``: Notebooks used in the [getting started](http://holoviews.org/getting_started/index.html) guide. -* `reference`: Notebooks shown in the website [reference gallery](http://holoviews.org/reference/index.html) -* ``topics``: Notebooks shown in the [showcase](http://holoviews.org/reference/showcase/index.html) -* ``user_guide``: Notebooks used in the [user guide](http://holoviews.org/user_guide/index.html). +- `assets`: Files used by the examples. +- `gallery`: Examples shown on the [gallery page](http://holoviews.org/gallery/index.html). +- `getting_started`: Notebooks used in the [getting started](http://holoviews.org/getting_started/index.html) guide. +- `reference`: Notebooks shown in the website [reference gallery](http://holoviews.org/reference/index.html) +- `topics`: Notebooks shown in the [showcase](http://holoviews.org/reference/showcase/index.html) +- `user_guide`: Notebooks used in the [user guide](http://holoviews.org/user_guide/index.html). ## Contributing to examples If you have improvements to suggest regarding the existing set of notebooks, please tell us on [gitter](https://gitter.im/pyviz/pyviz) or submit a pull request. We are happy to consider user submissions for -``/topics`` so if you have an interesting notebook using HoloViews that -isn't too long and about a domain not already in ``/topics``, please +`/topics` so if you have an interesting notebook using HoloViews that +isn't too long and about a domain not already in `/topics`, please consider submitting a PR. Lastly, if you find a particular notebook that does not seem to be diff --git a/examples/conftest.py b/examples/conftest.py index c02fc8d16c..22dced7136 100644 --- a/examples/conftest.py +++ b/examples/conftest.py @@ -1,3 +1,4 @@ +import os import platform import sys @@ -40,6 +41,11 @@ "user_guide/16-Streaming_Data.ipynb", ] +# 2024-01-15: See https://github.com/holoviz/holoviews/issues/6069 +if system == "Windows": + collect_ignore_glob += [ + "user_guide/Deploying_Bokeh_Apps.ipynb", + ] # First available in Bokeh 3.2.0 if Version(bokeh.__version__) < Version("3.2.0"): @@ -50,6 +56,12 @@ "reference/elements/bokeh/VSpans.ipynb", ] +# 2024-03-27: ffmpeg errors on Windows CI +if system == "Windows" and os.environ.get("GITHUB_RUN_ID"): + collect_ignore_glob += [ + "user_guide/Plotting_with_Matplotlib.ipynb", + ] + def pytest_runtest_makereport(item, call): """ diff --git a/examples/gallery/demos/bokeh/dot_example.ipynb b/examples/gallery/demos/bokeh/dot_example.ipynb index 8736404dbf..4949704edf 100644 --- a/examples/gallery/demos/bokeh/dot_example.ipynb +++ b/examples/gallery/demos/bokeh/dot_example.ipynb @@ -1,12 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/dot.html" - ] - }, { "cell_type": "code", "execution_count": null, @@ -69,5 +62,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/histogram_example.ipynb b/examples/gallery/demos/bokeh/histogram_example.ipynb index ac25be0303..461b6941ca 100644 --- a/examples/gallery/demos/bokeh/histogram_example.ipynb +++ b/examples/gallery/demos/bokeh/histogram_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/histogram.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/stats/histogram.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -133,5 +133,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/iris_example.ipynb b/examples/gallery/demos/bokeh/iris_example.ipynb index ce80c330b5..d63a4d19b0 100644 --- a/examples/gallery/demos/bokeh/iris_example.ipynb +++ b/examples/gallery/demos/bokeh/iris_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/iris.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/iris.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -63,5 +63,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/iris_splom_example.ipynb b/examples/gallery/demos/bokeh/iris_splom_example.ipynb index da491e2c6c..018dd19717 100644 --- a/examples/gallery/demos/bokeh/iris_splom_example.ipynb +++ b/examples/gallery/demos/bokeh/iris_splom_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/iris_splom.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/iris_splom.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -68,5 +68,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/legend_example.ipynb b/examples/gallery/demos/bokeh/legend_example.ipynb index 4366be9300..eb1f508f07 100644 --- a/examples/gallery/demos/bokeh/legend_example.ipynb +++ b/examples/gallery/demos/bokeh/legend_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/legend.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/basic/annotations/legend.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", diff --git a/examples/gallery/demos/bokeh/lesmis_example.ipynb b/examples/gallery/demos/bokeh/lesmis_example.ipynb index bfb7ac5f5c..5b6354634d 100644 --- a/examples/gallery/demos/bokeh/lesmis_example.ipynb +++ b/examples/gallery/demos/bokeh/lesmis_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/les_mis.html" + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/categorical/les_mis.html" ] }, { @@ -104,5 +104,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/lorenz_attractor_example.ipynb b/examples/gallery/demos/bokeh/lorenz_attractor_example.ipynb index 49fdb042c9..d209ac2a04 100644 --- a/examples/gallery/demos/bokeh/lorenz_attractor_example.ipynb +++ b/examples/gallery/demos/bokeh/lorenz_attractor_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/lorenz.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/basic/lines/lorenz.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -89,5 +89,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/nyc_airport_connections.ipynb b/examples/gallery/demos/bokeh/nyc_airport_connections.ipynb index 6c0f5a0462..8b4f4bb3ab 100644 --- a/examples/gallery/demos/bokeh/nyc_airport_connections.ipynb +++ b/examples/gallery/demos/bokeh/nyc_airport_connections.ipynb @@ -52,7 +52,7 @@ "# Lay out graph weighting and weight by the number of connections\n", "np.random.seed(14)\n", "graph = layout_nodes(nyc_graph, layout=nx.layout.fruchterman_reingold_layout, kwargs={'weight': 'connections'})\n", - "labels = hv.Labels(graph.nodes, ['x', 'y'], ['IATA', 'City'])\n" + "labels = hv.Labels(graph.nodes, ['x', 'y'], ['IATA', 'City'])" ] }, { diff --git a/examples/gallery/demos/bokeh/step_chart.ipynb b/examples/gallery/demos/bokeh/step_chart.ipynb index d901f7f34d..75b37c4b84 100644 --- a/examples/gallery/demos/bokeh/step_chart.ipynb +++ b/examples/gallery/demos/bokeh/step_chart.ipynb @@ -4,8 +4,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/step_chart.html\n", - "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", "* [Matplotlib - step_chart example](../bokeh/step_chart_example.ipynb)" @@ -61,7 +59,7 @@ "outputs": [], "source": [ "postage.opts(\n", - " opts.Curve(interpolation='steps-mid', width=400, height=400, \n", + " opts.Curve(interpolation='steps-mid', width=400, height=400,\n", " line_dash=hv.Cycle(values=['dashed', 'solid'])),\n", " opts.Overlay(legend_position='top_left'))" ] diff --git a/examples/gallery/demos/bokeh/stocks_example.ipynb b/examples/gallery/demos/bokeh/stocks_example.ipynb index 7c945e24c6..38d0dea161 100644 --- a/examples/gallery/demos/bokeh/stocks_example.ipynb +++ b/examples/gallery/demos/bokeh/stocks_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/stocks.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/stocks.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -87,5 +87,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/bokeh/texas_choropleth_example.ipynb b/examples/gallery/demos/bokeh/texas_choropleth_example.ipynb index 4c8964dd43..9fdaefe668 100644 --- a/examples/gallery/demos/bokeh/texas_choropleth_example.ipynb +++ b/examples/gallery/demos/bokeh/texas_choropleth_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/texas.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/geo/texas_hover_map.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", diff --git a/examples/gallery/demos/bokeh/us_unemployment.ipynb b/examples/gallery/demos/bokeh/us_unemployment.ipynb index 8c76682bf5..e7fd2c3cf1 100644 --- a/examples/gallery/demos/bokeh/us_unemployment.ipynb +++ b/examples/gallery/demos/bokeh/us_unemployment.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/unemployment.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/categorical/heatmap_unemployment.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -70,5 +70,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/histogram_example.ipynb b/examples/gallery/demos/matplotlib/histogram_example.ipynb index 9e7f3d7863..50f284718d 100644 --- a/examples/gallery/demos/matplotlib/histogram_example.ipynb +++ b/examples/gallery/demos/matplotlib/histogram_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/histogram.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/stats/histogram.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -134,5 +134,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/iris_example.ipynb b/examples/gallery/demos/matplotlib/iris_example.ipynb index 35bf5915b8..bfecbc944c 100644 --- a/examples/gallery/demos/matplotlib/iris_example.ipynb +++ b/examples/gallery/demos/matplotlib/iris_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/iris.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/iris.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -65,5 +65,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/iris_splom_example.ipynb b/examples/gallery/demos/matplotlib/iris_splom_example.ipynb index bc5394a480..f78eb8de04 100644 --- a/examples/gallery/demos/matplotlib/iris_splom_example.ipynb +++ b/examples/gallery/demos/matplotlib/iris_splom_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/iris_splom.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/iris_splom.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -69,5 +69,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/legend_example.ipynb b/examples/gallery/demos/matplotlib/legend_example.ipynb index d24be65353..df3e7b3e99 100644 --- a/examples/gallery/demos/matplotlib/legend_example.ipynb +++ b/examples/gallery/demos/matplotlib/legend_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/legend.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/basic/annotations/legend.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", diff --git a/examples/gallery/demos/matplotlib/lorenz_attractor_example.ipynb b/examples/gallery/demos/matplotlib/lorenz_attractor_example.ipynb index 6197a1772f..8bfe057c26 100644 --- a/examples/gallery/demos/matplotlib/lorenz_attractor_example.ipynb +++ b/examples/gallery/demos/matplotlib/lorenz_attractor_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/lorenz.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/basic/lines/lorenz.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -88,5 +88,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/nyc_airport_connections.ipynb b/examples/gallery/demos/matplotlib/nyc_airport_connections.ipynb index ae34495676..fc3acb1cd2 100644 --- a/examples/gallery/demos/matplotlib/nyc_airport_connections.ipynb +++ b/examples/gallery/demos/matplotlib/nyc_airport_connections.ipynb @@ -52,7 +52,7 @@ "# Lay out graph weighting and weight by the number of connections\n", "np.random.seed(14)\n", "graph = layout_nodes(nyc_graph, layout=nx.layout.fruchterman_reingold_layout, kwargs={'weight': 'connections'})\n", - "labels = hv.Labels(graph.nodes, ['x', 'y'], ['IATA', 'City'])\n" + "labels = hv.Labels(graph.nodes, ['x', 'y'], ['IATA', 'City'])" ] }, { diff --git a/examples/gallery/demos/matplotlib/step_chart.ipynb b/examples/gallery/demos/matplotlib/step_chart.ipynb index 12ad9e68fd..61d228323a 100644 --- a/examples/gallery/demos/matplotlib/step_chart.ipynb +++ b/examples/gallery/demos/matplotlib/step_chart.ipynb @@ -4,8 +4,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/step_chart.html\n", - "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", "* [Bokeh - step_chart example](../bokeh/step_chart.ipynb)" diff --git a/examples/gallery/demos/matplotlib/stocks_example.ipynb b/examples/gallery/demos/matplotlib/stocks_example.ipynb index 3b6f6cb7ef..adf74df2d3 100644 --- a/examples/gallery/demos/matplotlib/stocks_example.ipynb +++ b/examples/gallery/demos/matplotlib/stocks_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/stocks.html\n", + "URL: https://docs.bokeh.org/en/2.4.1/docs/gallery/stocks.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -94,5 +94,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/gallery/demos/matplotlib/texas_choropleth_example.ipynb b/examples/gallery/demos/matplotlib/texas_choropleth_example.ipynb index eb182b08d8..69db3b5bb5 100644 --- a/examples/gallery/demos/matplotlib/texas_choropleth_example.ipynb +++ b/examples/gallery/demos/matplotlib/texas_choropleth_example.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/texas.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/geo/texas_hover_map.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", diff --git a/examples/gallery/demos/matplotlib/us_unemployment.ipynb b/examples/gallery/demos/matplotlib/us_unemployment.ipynb index 1722631b6b..e971c59360 100644 --- a/examples/gallery/demos/matplotlib/us_unemployment.ipynb +++ b/examples/gallery/demos/matplotlib/us_unemployment.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "URL: http://bokeh.pydata.org/en/latest/docs/gallery/unemployment.html\n", + "URL: https://docs.bokeh.org/en/latest/docs/examples/topics/categorical/heatmap_unemployment.html\n", "\n", "Most examples work across multiple plotting backends, this example is also available for:\n", "\n", @@ -68,5 +68,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/examples/reference/streams/bokeh/Tap.ipynb b/examples/reference/streams/bokeh/Tap.ipynb index 542afe6cd9..31d8e106c3 100644 --- a/examples/reference/streams/bokeh/Tap.ipynb +++ b/examples/reference/streams/bokeh/Tap.ipynb @@ -137,7 +137,7 @@ " fontsize={'xticks': '6pt'}, height=500, logz=True,\n", " tools=['hover'], width=700, xrotation=90,\n", " )\n", - ")\n" + ")" ] }, { diff --git a/holoviews/__init__.py b/holoviews/__init__.py index c90aa18dcd..e3231dece9 100644 --- a/holoviews/__init__.py +++ b/holoviews/__init__.py @@ -113,10 +113,10 @@ if "IPython" in sys.modules: from .ipython import notebook_extension - extension = notebook_extension # noqa (name remapping) + extension = notebook_extension else: class notebook_extension(param.ParameterizedFunction): - def __call__(self, *args, **opts): # noqa (dummy signature) + def __call__(self, *args, **kwargs): raise Exception("Jupyter notebook not available: use hv.extension instead.") if '_pyodide' in sys.modules: @@ -173,6 +173,8 @@ def help(obj, visualization=True, ansi=True, backend=None, pydoc.help(obj) +del os, rcfile, warnings + def __getattr__(name): if name == "annotate": # Lazy loading Panel @@ -180,5 +182,13 @@ def __getattr__(name): return annotate raise AttributeError(f"module {__name__!r} has no attribute {name!r}") +__all__ = [k for k in locals() if not k.startswith('_')] +__all__ += ['annotate', '__version__'] -del os, rcfile, warnings +def __dir__(): + return __all__ + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .annotators import annotate diff --git a/holoviews/core/data/cudf.py b/holoviews/core/data/cudf.py index 36af1ac49e..455a177183 100644 --- a/holoviews/core/data/cudf.py +++ b/holoviews/core/data/cudf.py @@ -231,6 +231,18 @@ def select_mask(cls, dataset, selection): mask &= new_mask return mask + @classmethod + def _select_mask_neighbor(cls, dataset, selection): + """Runs select mask and expand the True values to include its neighbors + + Example + + select_mask = [False, False, True, True, False, False] + select_mask_neighbor = [False, True, True, True, True, False] + + """ + raise NotImplementedError + @classmethod def select(cls, dataset, selection_mask=None, **selection): df = dataset.data diff --git a/holoviews/core/data/dask.py b/holoviews/core/data/dask.py index 5b1160220b..ebffe3519d 100644 --- a/holoviews/core/data/dask.py +++ b/holoviews/core/data/dask.py @@ -154,6 +154,9 @@ def select_mask(cls, dataset, selection): def select(cls, dataset, selection_mask=None, **selection): df = dataset.data if selection_mask is not None: + import dask.array as da + if isinstance(selection_mask, da.Array): + return df.loc[selection_mask] return df[selection_mask] selection_mask = cls.select_mask(dataset, selection) indexed = cls.indexed(dataset, selection) @@ -162,6 +165,23 @@ def select(cls, dataset, selection_mask=None, **selection): return df[dataset.vdims[0].name].compute().iloc[0] return df + @classmethod + def _select_mask_neighbor(cls, dataset, selection): + """Runs select mask and expand the True values to include its neighbors + + Example + + select_mask = [False, False, True, True, False, False] + select_mask_neighbor = [False, True, True, True, True, False] + + """ + mask = cls.select_mask(dataset, selection) + mask = mask.to_dask_array().compute_chunk_sizes() + extra = mask[1:] ^ mask[:-1] + mask[1:] |= extra + mask[:-1] |= extra + return mask + @classmethod def groupby(cls, dataset, dimensions, container_type, group_type, **kwargs): index_dims = [dataset.get_dimension(d) for d in dimensions] diff --git a/holoviews/core/data/ibis.py b/holoviews/core/data/ibis.py index 691a55d26c..f904995d07 100644 --- a/holoviews/core/data/ibis.py +++ b/holoviews/core/data/ibis.py @@ -427,6 +427,18 @@ def select_mask(cls, dataset, selection): predicates.append(column == object) return predicates + @classmethod + def _select_mask_neighbor(cls, dataset, selection): + """Runs select mask and expand the True values to include its neighbors + + Example + + select_mask = [False, False, True, True, False, False] + select_mask_neighbor = [False, True, True, True, True, False] + + """ + raise NotImplementedError + @classmethod def sample(cls, dataset, samples=None): import ibis diff --git a/holoviews/core/data/interface.py b/holoviews/core/data/interface.py index 0a60552f9b..cdd3e151a2 100644 --- a/holoviews/core/data/interface.py +++ b/holoviews/core/data/interface.py @@ -377,6 +377,21 @@ def select_mask(cls, dataset, selection): mask &= index_mask return mask + @classmethod + def _select_mask_neighbor(cls, dataset, selection): + """Runs select mask and expand the True values to include its neighbors + + Example + + select_mask = [False, False, True, True, False, False] + select_mask_neighbor = [False, True, True, True, True, False] + + """ + mask = cls.select_mask(dataset, selection) + extra = mask[1:] ^ mask[:-1] + mask[1:] |= extra + mask[:-1] |= extra + return mask @classmethod def indexed(cls, dataset, selection): diff --git a/holoviews/core/data/xarray.py b/holoviews/core/data/xarray.py index 18259f3359..c1cad1a16e 100644 --- a/holoviews/core/data/xarray.py +++ b/holoviews/core/data/xarray.py @@ -178,12 +178,18 @@ def retrieve_unit_and_label(dim): arrays[vdim.name] = arr data = xr.Dataset(arrays) else: + # Started to warn in xarray 2023.12.0: + # The return type of `Dataset.dims` will be changed to return a + # set of dimension names in future, in order to be more consistent + # with `DataArray.dims`. To access a mapping from dimension names to + # lengths, please use `Dataset.sizes`. + data_info = data.sizes if hasattr(data, "sizes") else data.dims if not data.coords: - data = data.assign_coords(**{k: range(v) for k, v in data.dims.items()}) + data = data.assign_coords(**{k: range(v) for k, v in data_info.items()}) if vdims is None: vdims = list(data.data_vars) if kdims is None: - xrdims = list(data.dims) + xrdims = list(data_info) xrcoords = list(data.coords) kdims = [name for name in data.indexes.keys() if isinstance(data[name].data, np.ndarray)] @@ -337,7 +343,7 @@ def groupby(cls, dataset, dimensions, container_type, group_type, **kwargs): group_by = [d.name for d in index_dims] data = [] if len(dimensions) == 1: - for k, v in dataset.data.groupby(index_dims[0].name): + for k, v in dataset.data.groupby(index_dims[0].name, squeeze=False): if drop_dim: v = v.to_dataframe().reset_index() data.append((k, group_type(v, **group_kwargs))) @@ -636,7 +642,7 @@ def length(cls, dataset): def dframe(cls, dataset, dimensions): import xarray as xr if cls.packed(dataset): - bands = {vd.name: dataset.data[..., i].drop('band') + bands = {vd.name: dataset.data[..., i].drop_vars('band') for i, vd in enumerate(dataset.vdims)} data = xr.Dataset(bands) else: diff --git a/holoviews/core/dimension.py b/holoviews/core/dimension.py index 6ff601295c..59218185f9 100644 --- a/holoviews/core/dimension.py +++ b/holoviews/core/dimension.py @@ -109,10 +109,12 @@ def process_dimensions(kdims, vdims): elif isinstance(dims, (tuple, str, Dimension, dict)): dims = [dims] elif not isinstance(dims, list): - raise ValueError("{} argument expects a Dimension or list of dimensions, " - "specified as tuples, strings, dictionaries or Dimension " - "instances, not a {} type. Ensure you passed the data as the " - "first argument.".format(group, type(dims).__name__)) + raise ValueError( + f"{group} argument expects a Dimension or list of dimensions, " + "specified as tuples, strings, dictionaries or Dimension " + f"instances, not a {type(dims).__name__} type. " + "Ensure you passed the data as the first argument." + ) dimensions[group] = [asdim(d) for d in dims] return dimensions diff --git a/holoviews/core/io.py b/holoviews/core/io.py index 13ddd9b45e..774238ece4 100644 --- a/holoviews/core/io.py +++ b/holoviews/core/io.py @@ -370,8 +370,7 @@ def save(self_or_cls, obj, filename, key=None, info=None, **kwargs): components = list(obj.data.values()) entries = entries if len(entries) > 1 else [entries[0]+'(L)'] else: - entries = ['{}.{}'.format(group_sanitizer(obj.group, False), - label_sanitizer(obj.label, False))] + entries = [f'{group_sanitizer(obj.group, False)}.{label_sanitizer(obj.label, False)}'] components = [obj] for component, entry in zip(components, entries): diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py index 6653bdc86b..cd9cac8b39 100644 --- a/holoviews/core/spaces.py +++ b/holoviews/core/spaces.py @@ -546,9 +546,10 @@ def __call__(self, *args, **kwargs): # Nothing to do for callbacks that accept no arguments kwarg_hash = kwargs.pop('_memoization_hash_', ()) (self.args, self.kwargs) = (args, kwargs) - if hasattr(self.callable, 'rx'): + if util.param_version >= util.Version('2.0.0') and isinstance(self.callable, param.rx): return self.callable.rx.value - if not args and not kwargs and not any(kwarg_hash): return self.callable() + elif not args and not kwargs and not any(kwarg_hash): + return self.callable() inputs = [i for i in self.inputs if isinstance(i, DynamicMap)] streams = [] for stream in [s for i in inputs for s in get_nested_streams(i)]: diff --git a/holoviews/core/util.py b/holoviews/core/util.py index 8664d0bb50..b389c884e9 100644 --- a/holoviews/core/util.py +++ b/holoviews/core/util.py @@ -445,6 +445,8 @@ def argspec(callable_obj): arglen = len(callable_obj.args) spec = inspect.getfullargspec(callable_obj.func) args = [arg for arg in spec.args[arglen:] if arg not in callable_obj.keywords] + if inspect.ismethod(callable_obj.func): + args = args[1:] elif inspect.ismethod(callable_obj): # instance and class methods spec = inspect.getfullargspec(callable_obj) args = spec.args[1:] @@ -1312,7 +1314,7 @@ def dimension_sort(odict, kdims, vdims, key_index): def is_number(obj): if isinstance(obj, numbers.Number): return True elif isinstance(obj, np.str_): return False - elif np.__version__[0] < "2" and isinstance(obj, np.unicode_): return False + elif np.__version__[0] < "2" and isinstance(obj, np.unicode_): return False # noqa: NPY201 # The extra check is for classes that behave like numbers, such as those # found in numpy, gmpy, etc. elif (hasattr(obj, '__int__') and hasattr(obj, '__add__')): return True diff --git a/holoviews/element/graphs.py b/holoviews/element/graphs.py index 048d8b2103..e46fc14f42 100644 --- a/holoviews/element/graphs.py +++ b/holoviews/element/graphs.py @@ -269,7 +269,7 @@ def select(self, selection_expr=None, selection_specs=None, selection_mode='edge index_dim = self.nodes.kdims[2].name dimensions = self.kdims+self.vdims - node_selection = {index_dim: v for k, v in selection.items() + node_selection = {index_dim: v for k, v in selection.items() # noqa: RUF011 if k in self.kdims} if selection_expr: mask = selection_expr.apply(self.nodes, compute=False, keep_index=True) diff --git a/holoviews/element/raster.py b/holoviews/element/raster.py index 19cf97e28e..8075bfff3b 100644 --- a/holoviews/element/raster.py +++ b/holoviews/element/raster.py @@ -278,10 +278,12 @@ def __init__(self, data, kdims=None, vdims=None, bounds=None, extents=None, Dataset.__init__(self, data, kdims=kdims, vdims=vdims, extents=extents, **params) if not self.interface.gridded: - raise DataError("{} type expects gridded data, {} is columnar. " - "To display columnar data as gridded use the HeatMap " - "element or aggregate the data (e.g. using rasterize " - "or np.histogram2d).".format(type(self).__name__, self.interface.__name__)) + raise DataError( + f"{type(self).__name__} type expects gridded data, " + f"{self.interface.__name__} is columnar. " + "To display columnar data as gridded use the HeatMap " + "element or aggregate the data (e.g. using np.histogram2d)." + ) dim2, dim1 = self.interface.shape(self, gridded=True)[:2] if bounds is None: @@ -800,10 +802,12 @@ def __init__(self, data, kdims=None, vdims=None, **params): data = ([], [], np.zeros((0, 0))) super().__init__(data, kdims, vdims, **params) if not self.interface.gridded: - raise DataError("{} type expects gridded data, {} is columnar. " - "To display columnar data as gridded use the HeatMap " - "element or aggregate the data (e.g. using " - "np.histogram2d).".format(type(self).__name__, self.interface.__name__)) + raise DataError( + f"{type(self).__name__} type expects gridded data, " + f"{self.interface.__name__} is columnar. " + "To display columnar data as gridded use the HeatMap " + "element or aggregate the data (e.g. using np.histogram2d)." + ) def trimesh(self): """ diff --git a/holoviews/element/selection.py b/holoviews/element/selection.py index 21c4311960..25d448e127 100644 --- a/holoviews/element/selection.py +++ b/holoviews/element/selection.py @@ -4,6 +4,7 @@ """ import sys +from importlib.util import find_spec import numpy as np import pandas as pd @@ -79,7 +80,7 @@ def spatial_select_gridded(xvals, yvals, geometry): sel_mask = spatial_select_columnar(xvals.flatten(), yvals.flatten(), geometry) return sel_mask.reshape(xvals.shape) -def spatial_select_columnar(xvals, yvals, geometry): +def spatial_select_columnar(xvals, yvals, geometry, geom_method=None): if 'cudf' in sys.modules: import cudf if isinstance(xvals, cudf.Series): @@ -119,20 +120,16 @@ def spatial_select_columnar(xvals, yvals, geometry): sel_mask = (xvals>=x0) & (xvals<=x1) & (yvals>=y0) & (yvals<=y1) masked_xvals = xvals[sel_mask] masked_yvals = yvals[sel_mask] - try: - from spatialpandas.geometry import PointArray, Polygon - points = PointArray((masked_xvals.astype('float'), masked_yvals.astype('float'))) - poly = Polygon([np.concatenate([geometry, geometry[:1]]).flatten()]) - geom_mask = points.intersects(poly) - except ImportError: - try: - from shapely.geometry import Point, Polygon - points = (Point(x, y) for x, y in zip(masked_xvals, masked_yvals)) - poly = Polygon(geometry) - geom_mask = np.array([poly.contains(p) for p in points]) - except ImportError: - raise ImportError("Lasso selection on tabular data requires " - "either spatialpandas or shapely to be available.") from None + if geom_method is None: + if find_spec("spatialpandas") is not None: + geom_method = "spatialpandas" + elif find_spec("shapely") is not None: + geom_method = "shapely" + else: + msg = "Lasso selection on tabular data requires either spatialpandas or shapely to be available." + raise ImportError(msg) from None + geom_function = {"spatialpandas": _mask_spatialpandas, "shapely": _mask_shapely}[geom_method] + geom_mask = geom_function(masked_xvals, masked_yvals, geometry) if isinstance(xvals, pd.Series): sel_mask[sel_mask.index[np.where(sel_mask)[0]]] = geom_mask else: @@ -140,6 +137,20 @@ def spatial_select_columnar(xvals, yvals, geometry): return sel_mask +def _mask_spatialpandas(masked_xvals, masked_yvals, geometry): + from spatialpandas.geometry import PointArray, Polygon + points = PointArray((masked_xvals.astype('float'), masked_yvals.astype('float'))) + poly = Polygon([np.concatenate([geometry, geometry[:1]]).flatten()]) + return points.intersects(poly) + + +def _mask_shapely(masked_xvals, masked_yvals, geometry): + from shapely.geometry import Point, Polygon + points = (Point(x, y) for x, y in zip(masked_xvals, masked_yvals)) + poly = Polygon(geometry) + return np.array([poly.contains(p) for p in points], dtype=bool) + + def spatial_select(xvals, yvals, geometry): if xvals.ndim > 1: return spatial_select_gridded(xvals, yvals, geometry) diff --git a/holoviews/ipython/archive.py b/holoviews/ipython/archive.py index 5eefa4f873..e6acd4d67f 100644 --- a/holoviews/ipython/archive.py +++ b/holoviews/ipython/archive.py @@ -147,8 +147,7 @@ def export(self, timestamp=None): tstamp = time.strftime(self.timestamp_format, self._timestamp) export_name = self._format(self.export_name, {'timestamp':tstamp, 'notebook':self.notebook_name}) - print(('Export name: {!r}\nDirectory {!r}'.format(export_name, - os.path.join(os.path.abspath(self.root)))) + print((f'Export name: {export_name!r}\nDirectory {os.path.join(os.path.abspath(self.root))!r}') + '\n\nIf no output appears, please check holoviews.archive.last_export_status()') display(Javascript(cmd)) diff --git a/holoviews/operation/datashader.py b/holoviews/operation/datashader.py index 441a6d144f..cd7ac77a2a 100644 --- a/holoviews/operation/datashader.py +++ b/holoviews/operation/datashader.py @@ -194,9 +194,10 @@ def _get_agg_params(self, element, x, y, agg_fn, bounds): elif column: dims = [d for d in element.dimensions('ranges') if d == column] if not dims: - raise ValueError("Aggregation column '{}' not found on '{}' element. " - "Ensure the aggregator references an existing " - "dimension.".format(column,element)) + raise ValueError( + f"Aggregation column '{column}' not found on '{element}' element. " + "Ensure the aggregator references an existing dimension." + ) if isinstance(agg_fn, (ds.count, ds.count_cat)): if vdim_prefix: vdim_name = f'{vdim_prefix}{column} Count' @@ -405,7 +406,7 @@ def _process(self, element, key=None): eldata = agg if ds_version > Version('0.5.0') else (xs, ys, agg.data) return self.p.element_type(eldata, **params) else: - params['vdims'] = list(agg.coords[agg_fn.column].data) + params['vdims'] = list(map(str, agg.coords[agg_fn.column].data)) return ImageStack(agg, **params) def _apply_datashader(self, dfdata, cvs_fn, agg_fn, agg_kwargs, x, y): @@ -438,12 +439,26 @@ def _apply_datashader(self, dfdata, cvs_fn, agg_fn, agg_kwargs, x, y): val[neg1] = "-" elif val.dtype.kind == "O": val[neg1] = "-" + elif val.dtype.kind == "M": + val[neg1] = np.datetime64("NaT") else: val = val.astype(np.float64) val[neg1] = np.nan agg[col] = ((y.name, x.name), val) return agg +class curve_aggregate(aggregate): + """ + Optimized aggregation for Curve objects by setting the default + of the aggregator to self_intersect=False to be more consistent + with the appearance of non-aggregated curves. + """ + aggregator = param.ClassSelector(class_=(rd.Reduction, rd.summary, str), + default=rd.count(self_intersect=False), doc=""" + Datashader reduction function used for aggregating the data. + The aggregator may also define a column to aggregate; if + no column is defined the first value dimension of the element + will be used. May also be defined as a string.""") class overlay_aggregate(aggregate): """ @@ -1457,7 +1472,7 @@ class rasterize(AggregationOperation): (Graph, aggregate), (Scatter, aggregate), (Points, aggregate), - (Curve, aggregate), + (Curve, curve_aggregate), (Path, aggregate), (type(None), shade) # To handle parameters of datashade ] diff --git a/holoviews/operation/downsample.py b/holoviews/operation/downsample.py index f7b2e75c82..616434d386 100644 --- a/holoviews/operation/downsample.py +++ b/holoviews/operation/downsample.py @@ -41,6 +41,7 @@ def _argmax_area(prev_x, prev_y, avg_next_x, avg_next_y, x_bucket, y_bucket): """Vectorized triangular area argmax computation. + Parameters ---------- prev_x : float @@ -99,9 +100,11 @@ def _lttb_inner(x, y, n_out, sampled_x, offset): ) -def _lttb(x, y, n_out): +def _lttb(x, y, n_out, **kwargs): """ - Downsample the data using the LTTB algorithm (python implementation). + Downsample the data using the LTTB algorithm. + + Will use a Python/Numpy implementation if tsdownsample is not available. Args: x (np.ndarray): The x-values of the data. @@ -110,6 +113,14 @@ def _lttb(x, y, n_out): Returns: np.array: The indexes of the selected datapoints. """ + try: + from tsdownsample import LTTBDownsampler + return LTTBDownsampler().downsample(x, y, n_out=n_out, **kwargs) + except ModuleNotFoundError: + pass + except Exception as e: + raise e + # Bucket size. Leave room for start and end data points block_size = (y.shape[0] - 2) / (n_out - 2) # Note this 'astype' cast must take place after array creation (and not with the @@ -132,8 +143,7 @@ def _lttb(x, y, n_out): return sampled_x - -def _nth_point(x, y, n_out): +def _nth_point(x, y, n_out, **kwargs): """ Downsampling by selecting every n-th datapoint @@ -142,33 +152,91 @@ def _nth_point(x, y, n_out): y (np.ndarray): The y-values of the data. n_out (int): The number of output points. Returns: - np.array: The indexes of the selected datapoints. + slice: The slice of selected datapoints. """ n_samples = len(x) - return np.arange(0, n_samples, max(1, math.ceil(n_samples / n_out))) + return slice(0, n_samples, max(1, math.ceil(n_samples / n_out))) + +def _viewport(x, y, n_out, **kwargs): + return slice(len(x)) + +def _min_max(x, y, n_out, **kwargs): + try: + from tsdownsample import MinMaxDownsampler + except ModuleNotFoundError: + raise NotImplementedError( + 'The min-max downsampling algorithm requires the tsdownsampler ' + 'library to be installed.' + ) from None + return MinMaxDownsampler().downsample(x, y, n_out=n_out, **kwargs) + +def _min_max_lttb(x, y, n_out, **kwargs): + try: + from tsdownsample import MinMaxLTTBDownsampler + except ModuleNotFoundError: + raise NotImplementedError( + 'The minmax-lttb downsampling algorithm requires the tsdownsampler ' + 'library to be installed.' + ) from None + return MinMaxLTTBDownsampler().downsample(x, y, n_out=n_out, **kwargs) + +def _m4(x, y, n_out, **kwargs): + try: + from tsdownsample import M4Downsampler + except ModuleNotFoundError: + raise NotImplementedError( + 'The m4 downsampling algorithm requires the tsdownsampler ' + 'library to be installed.' + ) from None + return M4Downsampler().downsample(x, y, n_out=n_out, **kwargs) _ALGORITHMS = { 'lttb': _lttb, - 'nth': _nth_point + 'nth': _nth_point, + 'viewport': _viewport, + 'minmax': _min_max, + 'minmax-lttb': _min_max_lttb, + 'm4': _m4, } - class downsample1d(ResampleOperation1D): """ Implements downsampling of a regularly sampled 1D dataset. - Supports multiple algorithms: - - - `lttb`: Largest Triangle Three Buckets downsample algorithm - - `nth`: Selects every n-th point. + If available uses the `tsdownsampler` library to perform massively + accelerated downsampling. """ - algorithm = param.Selector(default='lttb', objects=['lttb', 'nth']) + algorithm = param.Selector(default='lttb', objects=list(_ALGORITHMS), doc=""" + The algorithm to use for downsampling: - def _process(self, element, key=None): + - `lttb`: Largest Triangle Three Buckets downsample algorithm. + - `nth`: Selects every n-th point. + - `viewport`: Selects all points in a given viewport. + - `minmax`: Selects the min and max value in each bin (requires tsdownsampler). + - `m4`: Selects the min, max, first and last value in each bin (requires tsdownsampler). + - `minmax-lttb`: First selects n_out * minmax_ratio min and max values, + then further reduces these to n_out values using the + Largest Triangle Three Buckets algorithm (requires tsdownsampler).""") + + parallel = param.Boolean(default=False, doc=""" + The number of threads to use (if tsdownsampler is available).""") + + minmax_ratio = param.Integer(default=4, bounds=(0, None), doc=""" + For the minmax-lttb algorithm determines the ratio of candidate + values to generate with the minmax algorithm before further + downsampling with LTTB.""") + + neighbor_points = param.Boolean(default=None, doc=""" + Whether to add the neighbor points to the range before downsampling. + By default this is only enabled for the viewport algorithm.""") + + def _process(self, element, key=None, shared_data=None): if isinstance(element, (Overlay, NdOverlay)): - _process = partial(self._process, key=key) + # Shared data is so we only slice the given data once + kwargs = {'key': key, 'shared_data': {}} + _process = partial(self._process, **kwargs) if isinstance(element, Overlay): elements = [v.map(_process) for v in element] else: @@ -176,16 +244,49 @@ def _process(self, element, key=None): return element.clone(elements) if self.p.x_range: - element = element[slice(*self.p.x_range)] + key = (id(element.data), str(element.kdims[0])) + if shared_data is not None and key in shared_data: + element = element.clone(shared_data[key]) + else: + mask = self._compute_mask(element) + element = element[mask] + if shared_data is not None: + shared_data[key] = element.data + if len(element) <= self.p.width: return element xs, ys = (element.dimension_values(i) for i in range(2)) if ys.dtype == np.bool_: ys = ys.astype(np.int8) downsample = _ALGORITHMS[self.p.algorithm] - if self.p.algorithm == "lttb" and isinstance(element, Area): + kwargs = {} + if "lttb" in self.p.algorithm and isinstance(element, Area): raise NotImplementedError( "LTTB algorithm is not implemented for hv.Area" ) - samples = downsample(xs, ys, self.p.width) + elif self.p.algorithm == "minmax-lttb": + kwargs['minmax_ratio'] = self.p.minmax_ratio + samples = downsample(xs, ys, self.p.width, parallel=self.p.parallel, **kwargs) return element.iloc[samples] + + def _compute_mask(self, element): + """ + Computes the mask to apply to the element before downsampling. + """ + neighbor_enabled = ( + self.p.neighbor_points + if self.p.neighbor_points is not None + else self.p.algorithm == "viewport" + ) + if not neighbor_enabled: + return slice(*self.p.x_range) + try: + mask = element.dataset.interface._select_mask_neighbor( + element.dataset, {element.kdims[0]: self.p.x_range} + ) + except NotImplementedError: + mask = slice(*self.p.x_range) + except Exception as e: + self.param.warning(f"Could not apply neighbor mask to downsample1d: {e}") + mask = slice(*self.p.x_range) + return mask diff --git a/holoviews/operation/element.py b/holoviews/operation/element.py index 0d8bc13246..131a14a08d 100644 --- a/holoviews/operation/element.py +++ b/holoviews/operation/element.py @@ -3,6 +3,7 @@ examples. """ import warnings +from functools import partial import numpy as np import param @@ -754,6 +755,9 @@ class histogram(Operation): groupby = param.ClassSelector(default=None, class_=(str, Dimension), doc=""" Defines a dimension to group the Histogram returning an NdOverlay of Histograms.""") + groupby_range = param.Selector(default="shared", objects=["shared", "separated"], doc=""" + Whether to group the histograms along the same range or separate them.""") + log = param.Boolean(default=False, doc=""" Whether to use base 10 logarithmic samples for the bin edges.""") @@ -781,15 +785,7 @@ class histogram(Operation): style_prefix = param.String(default=None, allow_None=None, doc=""" Used for setting a common style for histograms in a HoloMap or AdjointLayout.""") - def _process(self, element, key=None): - if self.p.groupby: - if not isinstance(element, Dataset): - raise ValueError('Cannot use histogram groupby on non-Dataset Element') - grouped = element.groupby(self.p.groupby, group_type=Dataset, container_type=NdOverlay) - self.p.groupby = None - return grouped.map(self._process, Dataset) - - normed = False if self.p.mean_weighted and self.p.weight_dimension else self.p.normed + def _get_dim_and_data(self, element): if self.p.dimension: selected_dim = self.p.dimension else: @@ -800,6 +796,21 @@ def _process(self, element, key=None): data = element.interface.values(element, selected_dim, compute=False) else: data = element.dimension_values(selected_dim) + return dim, data + + def _process(self, element, key=None, groupby=False): + if self.p.groupby: + if not isinstance(element, Dataset): + raise ValueError('Cannot use histogram groupby on non-Dataset Element') + grouped = element.groupby(self.p.groupby, group_type=Dataset, container_type=NdOverlay) + if self.p.groupby_range == 'shared' and not self.p.bin_range: + _, data = self._get_dim_and_data(element) + self.p.bin_range = (data.min(), data.max()) + self.p.groupby = None + return grouped.map(partial(self._process, groupby=True), Dataset) + + normed = False if self.p.mean_weighted and self.p.weight_dimension else self.p.normed + dim, data = self._get_dim_and_data(element) is_datetime = isdatetime(data) if is_datetime: @@ -859,7 +870,7 @@ def _process(self, element, key=None): if isdatetime(edges): edges = edges.astype('datetime64[ns]').astype('int64') else: - hist_range = self.p.bin_range or element.range(selected_dim) + hist_range = self.p.bin_range or element.range(dim) # Suppress a warning emitted by Numpy when datetime or timedelta scalars # are compared. See https://github.com/numpy/numpy/issues/10095 and # https://github.com/numpy/numpy/issues/9210. @@ -939,8 +950,9 @@ def _process(self, element, key=None): # Save off the computed bin edges so that if this operation instance # is used to compute another histogram, it will default to the same # bin edges. - self.bins = list(edges) - return Histogram((edges, hist), kdims=[element.get_dimension(selected_dim)], + if not groupby: + self.bins = list(edges) + return Histogram((edges, hist), kdims=[dim], label=element.label, **params) diff --git a/holoviews/plotting/bokeh/callbacks.py b/holoviews/plotting/bokeh/callbacks.py index 8cf7639e38..521970a0a3 100644 --- a/holoviews/plotting/bokeh/callbacks.py +++ b/holoviews/plotting/bokeh/callbacks.py @@ -404,6 +404,7 @@ def set_callback(self, handle): if self.on_changes: change_handler = lambda attr, old, new: ( asyncio.create_task(self.on_change(attr, old, new)) + if self.plot.document else None ) for change in self.on_changes: if change in ['patching', 'streaming']: @@ -645,6 +646,12 @@ class RangeXYCallback(Callback): 'y1': 'cb_obj.y1', } + def initialize(self, plot_id=None): + super().initialize(plot_id) + for stream in self.streams: + msg = self._process_msg({}) + stream.update(**msg) + def _process_msg(self, msg): if self.plot.state.x_range is not self.plot.handles['x_range']: x_range = self.plot.handles['x_range'] @@ -826,7 +833,7 @@ class BoundsXCallback(Callback): models = ['plot'] on_events = ['selectiongeometry'] - skip_events = [lambda event: event.geometry['type'] != 'quad', + skip_events = [lambda event: event.geometry['type'] != 'rect', lambda event: not event.final] def _process_msg(self, msg): @@ -849,7 +856,7 @@ class BoundsYCallback(Callback): models = ['plot'] on_events = ['selectiongeometry'] - skip_events = [lambda event: event.geometry['type'] != 'quad', + skip_events = [lambda event: event.geometry['type'] != 'rect', lambda event: not event.final] def _process_msg(self, msg): diff --git a/holoviews/plotting/bokeh/chart.py b/holoviews/plotting/bokeh/chart.py index 0f481f2940..db03780ef5 100644 --- a/holoviews/plotting/bokeh/chart.py +++ b/holoviews/plotting/bokeh/chart.py @@ -61,7 +61,7 @@ class PointPlot(LegendPlot, ColorbarPlot): selection_display = BokehOverlaySelectionDisplay() - style_opts = (['cmap', 'palette', 'marker', 'size', 'angle'] + + style_opts = (['cmap', 'palette', 'marker', 'size', 'angle', 'hit_dilation'] + base_properties + line_properties + fill_properties) _plot_methods = dict(single='scatter', batched='scatter') diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index 47950b8d5b..e96e6e4b00 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -6,7 +6,6 @@ import bokeh.plotting import numpy as np import param -from bokeh.core.properties import value from bokeh.document.events import ModelChangedEvent from bokeh.models import ( BinnedTicker, @@ -370,16 +369,32 @@ def _init_tools(self, element, callbacks=None): tool = tools.HoverTool( tooltips=tooltips, tags=['hv_created'], mode=tool, **hover_opts ) - elif bokeh32 and tool in ['wheel_zoom', 'xwheel_zoom', 'ywheel_zoom']: - if tool.startswith('x'): + elif bokeh32 and isinstance(tool, str) and tool.endswith( + ('wheel_zoom', 'zoom_in', 'zoom_out') + ): + zoom_kwargs = {} + tags = ['hv_created'] + if self.subcoordinate_y and not tool.startswith('x'): + zoom_dims = 'height' + zoom_kwargs['level'] = 1 + tags.append(tool) + elif tool.startswith('x'): zoom_dims = 'width' elif tool.startswith('y'): zoom_dims = 'height' else: zoom_dims = 'both' - tool = tools.WheelZoomTool( - zoom_together='none', dimensions=zoom_dims, tags=['hv_created'] - ) + zoom_kwargs['dimensions'] = zoom_dims + zoom_kwargs['tags'] = tags + if tool.endswith('wheel_zoom'): + # Setting `zoom_together` for multi-y axis support. + zoom_kwargs['zoom_together'] = 'none' + zoom_type = tools.WheelZoomTool + elif tool.endswith('zoom_in'): + zoom_type = tools.ZoomInTool + elif tool.endswith('zoom_out'): + zoom_type = tools.ZoomOutTool + tool = zoom_type(**zoom_kwargs) tool_list.append(tool) copied_tools = [] @@ -398,6 +413,15 @@ def _init_tools(self, element, callbacks=None): if hover: self.handles['hover'] = hover + if self.subcoordinate_y: + zoom_tools = {} + _zoom_types = (tools.WheelZoomTool, tools.ZoomInTool, tools.ZoomOutTool) + for t in copied_tools: + if isinstance(t, _zoom_types) and 'hv_created' in t.tags and len(t.tags) == 2: + zoom_tools[t.tags[1]] = t + if zoom_tools: + self.handles['zooms_subcoordy'] = zoom_tools + box_tools = [t for t in copied_tools if isinstance(t, tools.BoxSelectTool)] if box_tools: self.handles['box_select'] = box_tools[0] @@ -1600,14 +1624,12 @@ def _apply_transforms(self, element, data, ranges, style, group=None): if not util.isscalar(val): if k in self._nonvectorized_styles: element = type(element).__name__ - raise ValueError('Mapping a dimension to the "{style}" ' + raise ValueError(f'Mapping a dimension to the "{k}" ' 'style option is not supported by the ' - '{element} element using the {backend} ' - 'backend. To map the "{dim}" dimension ' - 'to the {style} use a groupby operation ' - 'to overlay your data along the dimension.'.format( - style=k, dim=v.dimension, element=element, - backend=self.renderer.backend)) + f'{element} element using the {self.renderer.backend} ' + f'backend. To map the "{v.dimension}" dimension ' + f'to the {k} use a groupby operation ' + 'to overlay your data along the dimension.') elif data and len(val) != len(next(iter(data.values()))): if isinstance(element, VectorField): val = np.tile(val, 3) @@ -1831,8 +1853,10 @@ def _postprocess_hover(self, renderer, source): if not isinstance(hover.tooltips, str) and 'hv_created' in hover.tags: for k, values in source.data.items(): key = '@{%s}' % k - if ((isinstance(value, np.ndarray) and value.dtype.kind == 'M') or - (len(values) and isinstance(values[0], util.datetime_types))): + if ( + (len(values) and isinstance(values[0], util.datetime_types)) or + (len(values) and isinstance(values[0], np.ndarray) and values[0].dtype.kind == 'M') + ): hover.tooltips = [(l, f+'{%F %T}' if f == key else f) for l, f in hover.tooltips] hover.formatters[key] = "datetime" @@ -1877,6 +1901,14 @@ def _init_glyphs(self, plot, element, ranges, source): if self.scalebar: self._draw_scalebar(plot) + zooms_subcoordy = self.handles.get('zooms_subcoordy') + if zooms_subcoordy is not None: + for zoom in zooms_subcoordy.values(): + # The default renderer is 'auto', instead we want to + # store the subplot renderer to aggregate them and set + # the final tool with a list of all the renderers. + zoom.renderers = [renderer] + # Update plot, source and glyph with abbreviated_exception(): self._update_glyph(renderer, properties, mapping, glyph, source, source.data) @@ -2861,6 +2893,8 @@ def _init_tools(self, element, callbacks=None): if callbacks is None: callbacks = [] hover_tools = {} + zooms_subcoordy = {} + _zoom_types = (tools.WheelZoomTool, tools.ZoomInTool, tools.ZoomOutTool) init_tools, tool_types = [], [] for key, subplot in self.subplots.items(): el = element.get(key) @@ -2877,6 +2911,15 @@ def _init_tools(self, element, callbacks=None): continue else: hover_tools[tooltips] = tool + elif ( + self.subcoordinate_y and isinstance(tool, _zoom_types) + and 'hv_created' in tool.tags and len(tool.tags) == 2 + ): + if tool.tags[1] in zooms_subcoordy: + continue + else: + zooms_subcoordy[tool.tags[1]] = tool + self.handles['zooms_subcoordy'] = zooms_subcoordy elif tool_type in tool_types: continue else: @@ -2906,6 +2949,13 @@ def _merge_tools(self, subplot): tool.renderers = list(util.unique_iterator(renderers)) if 'hover' not in self.handles: self.handles['hover'] = tool + if 'zooms_subcoordy' in subplot.handles and 'zooms_subcoordy' in self.handles: + for subplot_zoom, overlay_zoom in zip( + subplot.handles['zooms_subcoordy'].values(), + self.handles['zooms_subcoordy'].values(), + ): + renderers = list(util.unique_iterator(subplot_zoom.renderers + overlay_zoom.renderers)) + overlay_zoom.renderers = renderers def _get_dimension_factors(self, overlay, ranges, dimension): factors = [] diff --git a/holoviews/plotting/bokeh/plot.py b/holoviews/plotting/bokeh/plot.py index 7e3814df76..6a97643d63 100644 --- a/holoviews/plotting/bokeh/plot.py +++ b/holoviews/plotting/bokeh/plot.py @@ -173,9 +173,6 @@ def _update_datasource(self, source, data): """ Update datasource with data for a new frame. """ - if not self.document: - return - data = self._postprocess_data(data) empty = all(len(v) == 0 for v in data.values()) if (self.streaming and self.streaming[0].data is self.current_frame.data @@ -617,8 +614,7 @@ def initialize_plot(self, ranges=None, plots=None): sync_legends(plot) plot = self._make_axes(plot) if hasattr(plot, "toolbar") and self.merge_tools: - plot.toolbar = merge_tools(plots) - + plot.toolbar = merge_tools(plots, hide_toolbar=True) title = self._get_title_div(self.keys[-1]) if title: plot = Column(title, plot) diff --git a/holoviews/plotting/bokeh/raster.py b/holoviews/plotting/bokeh/raster.py index 463a9a4fb1..8f281cc12b 100644 --- a/holoviews/plotting/bokeh/raster.py +++ b/holoviews/plotting/bokeh/raster.py @@ -11,7 +11,7 @@ from .element import ColorbarPlot, LegendPlot from .selection import BokehOverlaySelectionDisplay from .styles import base_properties, fill_properties, line_properties, mpl_to_bokeh -from .util import bokeh33, colormesh +from .util import bokeh33, bokeh34, colormesh class RasterPlot(ColorbarPlot): @@ -43,7 +43,7 @@ def _hover_opts(self, element): tooltips.append((vdims[0].pprint_label, '@image')) for vdim in vdims[1:]: vname = dimension_sanitizer(vdim.name) - tooltips.append((vdim.pprint_label, f'@{vname}')) + tooltips.append((vdim.pprint_label, f'@{{{vname}}}')) return tooltips, {} def _postprocess_hover(self, renderer, source): @@ -52,8 +52,6 @@ def _postprocess_hover(self, renderer, source): if not (hover and isinstance(hover.tooltips, list)): return - element = self.current_frame - xdim, ydim = (dimension_sanitizer(kd.name) for kd in element.kdims) xaxis = self.handles['xaxis'] yaxis = self.handles['yaxis'] @@ -73,6 +71,21 @@ def _postprocess_hover(self, renderer, source): formatters['$y'] = yhover formatter += '{custom}' tooltips.append((name, formatter)) + + if not bokeh34: # https://github.com/bokeh/bokeh/issues/13598 + datetime_code = """ + if (value === -9223372036854776) { + return "NaN" + } else { + const date = new Date(value); + return date.toISOString().slice(0, 19).replace('T', ' ') + } + """ + for key in formatters: + formatter = formatters[key] + if isinstance(formatter, str) and formatter.lower() == "datetime": + formatters[key] = CustomJSHover(code=datetime_code) + hover.tooltips = tooltips hover.formatters = formatters @@ -245,13 +258,31 @@ def _get_cmapper_opts(self, low, high, factors, colors): def _get_colormapper(self, eldim, element, ranges, style, factors=None, colors=None, group=None, name='color_mapper'): + indices = None + vdims = element.vdims + if isinstance(style.get("cmap"), dict): + dict_cmap = style["cmap"] + missing = [vd.name for vd in vdims if vd.name not in dict_cmap] + if missing: + missing_str = "', '".join(sorted(missing)) + raise ValueError( + "The supplied cmap dictionary must have the same " + f"value dimensions as the element. Missing: '{missing_str}'" + ) + keys, values = zip(*dict_cmap.items()) + style["cmap"] = list(values) + indices = [keys.index(vd.name) for vd in vdims] + cmapper = super()._get_colormapper( eldim, element, ranges, style, factors=factors, colors=colors, group=group, name=name ) - num_elements = len(element.vdims) - step_size = len(cmapper.palette) // num_elements - indices = np.arange(num_elements) * step_size + + if indices is None: + num_elements = len(vdims) + step_size = len(cmapper.palette) // num_elements + indices = np.arange(num_elements) * step_size + cmapper.palette = np.array(cmapper.palette)[indices].tolist() return cmapper diff --git a/holoviews/plotting/bokeh/stats.py b/holoviews/plotting/bokeh/stats.py index 4251e4ddda..cc2adcccbb 100644 --- a/holoviews/plotting/bokeh/stats.py +++ b/holoviews/plotting/bokeh/stats.py @@ -72,6 +72,9 @@ class BoxWhiskerPlot(MultiDistributionMixin, CompositeElementPlot, ColorbarPlot, show_legend = param.Boolean(default=False, doc=""" Whether to show legend for the plot.""") + outlier_radius = param.Number(default=0.01, doc=""" + The radius of the circle marker for the outliers.""") + # Deprecated options color_index = param.ClassSelector(default=None, class_=(str, int), @@ -191,11 +194,11 @@ def get_data(self, element, ranges, style): if self.invert_axes: vbar_map = {'y': 'index', 'left': 'top', 'right': 'bottom', 'height': width} seg_map = {'y0': 'x0', 'y1': 'x1', 'x0': 'y0', 'x1': 'y1'} - out_map = {'y': 'index', 'x': vdim} + out_map = {'y': 'index', 'x': vdim, 'radius': self.outlier_radius} else: vbar_map = {'x': 'index', 'top': 'top', 'bottom': 'bottom', 'width': width} seg_map = {'x0': 'x0', 'x1': 'x1', 'y0': 'y0', 'y1': 'y1'} - out_map = {'x': 'index', 'y': vdim} + out_map = {'x': 'index', 'y': vdim, 'radius': self.outlier_radius} vbar2_map = dict(vbar_map) # Get color values @@ -206,7 +209,7 @@ def get_data(self, element, ranges, style): cdim, cidx = None, None factors = [] - vdim = element.vdims[0].name + vdim = dimension_sanitizer(element.vdims[0].name) for key, g in groups.items(): # Compute group label if element.kdims: diff --git a/holoviews/plotting/bokeh/util.py b/holoviews/plotting/bokeh/util.py index bd54472844..1bc7427fa2 100644 --- a/holoviews/plotting/bokeh/util.py +++ b/holoviews/plotting/bokeh/util.py @@ -60,9 +60,10 @@ from ...util.warnings import warn from ..util import dim_axis_label -bokeh_version = Version(bokeh.__version__) +bokeh_version = Version(Version(bokeh.__version__).base_version) bokeh32 = bokeh_version >= Version("3.2") bokeh33 = bokeh_version >= Version("3.3") +bokeh34 = bokeh_version >= Version("3.4") TOOL_TYPES = { 'pan': tools.PanTool, @@ -383,7 +384,7 @@ def compute_layout_properties( return aspect_info, dimension_info -def merge_tools(plot_grid, disambiguation_properties=None): +def merge_tools(plot_grid, *, disambiguation_properties=None, hide_toolbar=False): """ Merges tools defined on a grid of plots into a single toolbar. All tools of the same type are merged unless they define one @@ -396,6 +397,8 @@ def merge_tools(plot_grid, disambiguation_properties=None): if isinstance(item, LayoutDOM): for p in item.select(dict(type=Plot)): tools.extend(p.toolbar.tools) + if hide_toolbar and hasattr(item, 'toolbar_location'): + item.toolbar_location = None if isinstance(item, GridPlot): item.toolbar_location = None @@ -414,7 +417,7 @@ def merge(tool, group): if p not in disambiguation_properties: ignore.add(p) - return Toolbar(tools=group_tools(tools, merge=merge, ignore=ignore) if merge_tools else tools) + return Toolbar(tools=group_tools(tools, merge=merge, ignore=ignore)) if tools else Toolbar() def sync_legends(bokeh_layout): diff --git a/holoviews/plotting/mpl/element.py b/holoviews/plotting/mpl/element.py index f370dc8d97..7f797ff47e 100644 --- a/holoviews/plotting/mpl/element.py +++ b/holoviews/plotting/mpl/element.py @@ -592,8 +592,8 @@ def init_artists(self, ax, plot_args, plot_kwargs): plot_method = self._plot_methods.get('batched' if self.batched else 'single') plot_fn = getattr(ax, plot_method) if 'norm' in plot_kwargs: # vmin/vmax should now be exclusively in norm - plot_kwargs.pop('vmin', None) - plot_kwargs.pop('vmax', None) + plot_kwargs.pop('vmin', None) + plot_kwargs.pop('vmax', None) with warnings.catch_warnings(): # scatter have a default cmap and with an empty array will emit this warning warnings.filterwarnings('ignore', "No data for colormapping provided via 'c'") diff --git a/holoviews/plotting/mpl/raster.py b/holoviews/plotting/mpl/raster.py index 23b752f09a..890d41d7f5 100644 --- a/holoviews/plotting/mpl/raster.py +++ b/holoviews/plotting/mpl/raster.py @@ -190,6 +190,9 @@ def init_artists(self, ax, plot_args, plot_kwargs): locs = plot_kwargs.pop('locs', None) artist = ax.pcolormesh(*plot_args, **plot_kwargs) colorbar = self.handles.get('cbar') + if 'norm' in plot_kwargs: # vmin/vmax should now be exclusively in norm + plot_kwargs.pop('vmin', None) + plot_kwargs.pop('vmax', None) if colorbar and mpl_version < Version('3.1'): colorbar.set_norm(artist.norm) if hasattr(colorbar, 'set_array'): diff --git a/holoviews/plotting/plot.py b/holoviews/plotting/plot.py index c3ab171864..612091659c 100644 --- a/holoviews/plotting/plot.py +++ b/holoviews/plotting/plot.py @@ -859,7 +859,7 @@ def _compute_group_range(cls, group, elements, ranges, framewise, # Filter out ranges of updated elements and append new ranges merged = {} for g, drange in dranges['values'].items(): - filtered = [r for i, r in zip(ids, values[g]) if i not in prev_ids] + filtered = [r for i, r in zip(ids, values.get(g, [])) if i not in prev_ids] filtered += drange merged[g] = filtered prev_ranges[d] = cls._merge_group_ranges(merged) @@ -925,7 +925,7 @@ def lookup(x): for opt, v in opts.items(): if opt not in options[key]: options[key][opt] = v - return options if keyfn else options[None] + return options if keyfn else options.get(None, {}) def _get_projection(cls, obj): """ @@ -1828,8 +1828,9 @@ def _create_subplot(self, key, obj, streams, ranges): plottype = registry.get(vtype, None) if plottype is None: self.param.warning( - "No plotting class for {} type and {} backend " - "found. ".format(vtype.__name__, self.renderer.backend)) + f"No plotting class for {vtype.__name__} type " + f"and {self.renderer.backend} backend found. " + ) return None # Get zorder and style counter diff --git a/holoviews/plotting/plotly/element.py b/holoviews/plotting/plotly/element.py index 504c7dcdea..564f67139f 100644 --- a/holoviews/plotting/plotly/element.py +++ b/holoviews/plotting/plotly/element.py @@ -174,11 +174,8 @@ def generate_plot(self, key, ranges, element=None, is_geo=False): ] if unsupported_opts: raise ValueError( - "The following {typ} style options are not supported by the Plotly " - "backend when overlaid on Tiles:\n" - " {unsupported_opts}".format( - typ=type(element).__name__, unsupported_opts=unsupported_opts - ) + f"The following {type(element).__name__} style options are not supported by the Plotly " + f"backend when overlaid on Tiles:\n {unsupported_opts}" ) # Get data and options and merge them @@ -352,8 +349,8 @@ def _apply_transforms(self, element, ranges, style): continue elif (not v.applies(element) and v.dimension not in self.overlay_dims): new_style.pop(k) - self.param.warning('Specified {} dim transform {!r} could not be applied, as not all ' - 'dimensions could be resolved.'.format(k, v)) + self.param.warning(f'Specified {k} dim transform {v!r} could not be applied, as not all ' + 'dimensions could be resolved.') continue if len(v.ops) == 0 and v.dimension in self.overlay_dims: @@ -368,14 +365,12 @@ def _apply_transforms(self, element, ranges, style): if not util.isscalar(val): if k in self._nonvectorized_styles: element = type(element).__name__ - raise ValueError('Mapping a dimension to the "{style}" ' + raise ValueError(f'Mapping a dimension to the "{k}" ' 'style option is not supported by the ' - '{element} element using the {backend} ' - 'backend. To map the "{dim}" dimension ' - 'to the {style} use a groupby operation ' - 'to overlay your data along the dimension.'.format( - style=k, dim=v.dimension, element=element, - backend=self.renderer.backend)) + f'{element} element using the {self.renderer.backend} ' + f'backend. To map the "{v.dimension}" dimension ' + f'to the {k} use a groupby operation ' + 'to overlay your data along the dimension.') # If color is not valid colorspec add colormapper numeric = isinstance(val, np.ndarray) and val.dtype.kind in 'uifMm' diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py index 484be8b87d..04f86b5b48 100644 --- a/holoviews/plotting/renderer.py +++ b/holoviews/plotting/renderer.py @@ -408,7 +408,8 @@ def _render_panel(self, plot, embed=False, comm=True): client_comm = self.comm_manager.get_client_comm( on_msg=partial(plot._on_msg, ref, manager), on_error=partial(plot._on_error, ref), - on_stdout=partial(plot._on_stdout, ref) + on_stdout=partial(plot._on_stdout, ref), + on_open=lambda _: comm.init() ) manager.client_comm_id = client_comm.id return render_mimebundle(model, doc, comm, manager) diff --git a/holoviews/plotting/util.py b/holoviews/plotting/util.py index d9157deca5..3cc2947bae 100644 --- a/holoviews/plotting/util.py +++ b/holoviews/plotting/util.py @@ -83,12 +83,12 @@ def collate(obj): return obj.collate() if isinstance(obj, HoloMap): display_warning.param.warning( - "Nesting {0}s within a {1} makes it difficult to access " - "your data or control how it appears; we recommend " - "calling .collate() on the {1} in order to follow the " - "recommended nesting structure shown in the Composing " - "Data user guide (https://goo.gl/2YS8LJ)".format( - obj.type.__name__, type(obj).__name__)) + f"Nesting {obj.type.__name__}s within a {type(obj).__name__} " + "makes it difficult to access your data or control how it appears; " + f"we recommend calling .collate() on the {type(obj).__name__} " + "in order to follow the recommended nesting structure shown " + "in the Composing Data user guide (https://goo.gl/2YS8LJ)" + ) return obj.collate() elif isinstance(obj, (Layout, NdLayout)): try: @@ -1129,6 +1129,8 @@ def hex2rgb(hex): class apply_nodata(Operation): + link_inputs = param.Boolean(default=True) + nodata = param.Integer(default=None, doc=""" Optional missing-data value for integer data. If non-None, data with this value will be replaced with NaN so diff --git a/holoviews/pyodide.py b/holoviews/pyodide.py index dfb1b7b56b..493f0c19ee 100644 --- a/holoviews/pyodide.py +++ b/holoviews/pyodide.py @@ -77,7 +77,7 @@ def render_svg(element): def in_jupyterlite(): import js - return hasattr(js, "_JUPYTERLAB") + return hasattr(js, "_JUPYTERLAB") or hasattr(js, "webpackChunk_jupyterlite_pyodide_kernel_extension") or not hasattr(js, "document") #----------------------------------------------------------------------------- # Public API diff --git a/holoviews/streams.py b/holoviews/streams.py index 309b4ac153..7a61a00cdf 100644 --- a/holoviews/streams.py +++ b/holoviews/streams.py @@ -240,12 +240,13 @@ def _process_streams(cls, streams): if overlap: pname = type(s.parameterized).__name__ param.main.param.warning( - 'The {} parameter(s) on the {} object have ' + f'The {sorted([p.name for p in overlap])} parameter(s) ' + f'on the {pname} object have ' 'already been supplied in another stream. ' 'Ensure that the supplied streams only specify ' 'each parameter once, otherwise multiple ' - 'events will be triggered when the parameter ' - 'changes.'.format(sorted([p.name for p in overlap]), pname)) + 'events will be triggered when the parameter changes.' + ) parameterizeds[pid] |= set(s.parameters) valid.append(s) return valid, invalid @@ -1480,6 +1481,10 @@ class RangeX(LinkedStream): x_range = param.Tuple(default=None, length=2, constant=True, doc=""" Range of the x-axis of a plot in data coordinates""") + def _set_stream_parameters(self, **kwargs): + kwargs.pop("y_range", None) + super()._set_stream_parameters(**kwargs) + class RangeY(LinkedStream): """ @@ -1489,6 +1494,10 @@ class RangeY(LinkedStream): y_range = param.Tuple(default=None, length=2, constant=True, doc=""" Range of the y-axis of a plot in data coordinates""") + def _set_stream_parameters(self, **kwargs): + kwargs.pop("x_range", None) + super()._set_stream_parameters(**kwargs) + class BoundsXY(LinkedStream): """ diff --git a/holoviews/tests/conftest.py b/holoviews/tests/conftest.py index 899d834f92..7d79f2379b 100644 --- a/holoviews/tests/conftest.py +++ b/holoviews/tests/conftest.py @@ -1,13 +1,19 @@ import contextlib +import sys +from collections.abc import Callable +import panel as pn import pytest -from panel.tests.conftest import ( # noqa +from panel.tests.conftest import ( # noqa: F401 optional_markers, port, pytest_addoption, pytest_configure, server_cleanup, ) +from panel.tests.util import serve_and_wait + +import holoviews as hv def pytest_collection_modifyitems(config, items): @@ -30,14 +36,19 @@ def pytest_collection_modifyitems(config, items): with contextlib.suppress(ImportError): import matplotlib as mpl - mpl.use('agg') + + mpl.use("agg") with contextlib.suppress(Exception): - # From Dask 2023.7,1 they now automatic convert strings + # From Dask 2023.7.1 they now automatically convert strings # https://docs.dask.org/en/stable/changelog.html#v2023-7-1 + # From Dask 2024.3.0 they now use `dask_expr` by default + # https://github.com/dask/dask/issues/10995 import dask + dask.config.set({"dataframe.convert-string": False}) + dask.config.set({"dataframe.query-planning": False}) @pytest.fixture @@ -47,36 +58,60 @@ def ibis_sqlite_backend(): except ImportError: yield None else: - ibis.set_backend('sqlite') + ibis.set_backend("sqlite") yield ibis.set_backend(None) @pytest.fixture def bokeh_backend(): - import holoviews as hv - hv.renderer('bokeh') + hv.renderer("bokeh") prev_backend = hv.Store.current_backend - hv.Store.current_backend = 'bokeh' + hv.Store.current_backend = "bokeh" yield hv.Store.current_backend = prev_backend @pytest.fixture def mpl_backend(): - import holoviews as hv - hv.renderer('matplotlib') + hv.renderer("matplotlib") prev_backend = hv.Store.current_backend - hv.Store.current_backend = 'matplotlib' + hv.Store.current_backend = "matplotlib" yield hv.Store.current_backend = prev_backend @pytest.fixture def plotly_backend(): - import holoviews as hv - hv.renderer('plotly') + hv.renderer("plotly") prev_backend = hv.Store.current_backend - hv.Store.current_backend = 'plotly' + hv.Store.current_backend = "plotly" yield hv.Store.current_backend = prev_backend + + +@pytest.fixture +def unimport(monkeypatch: pytest.MonkeyPatch) -> Callable[[str], None]: + """ + Return a function for unimporting modules and preventing reimport. + + This will block any new modules from being imported. + """ + + def unimport_module(modname: str) -> None: + # Remove if already imported + monkeypatch.delitem(sys.modules, modname, raising=False) + # Prevent import: + monkeypatch.setattr(sys, "path", []) + + return unimport_module + + +@pytest.fixture +def serve_hv(page, port): # noqa: F811 + def serve_and_return_page(hv_obj): + serve_and_wait(pn.pane.HoloViews(hv_obj), port=port) + page.goto(f"http://localhost:{port}") + return page + + return serve_and_return_page diff --git a/holoviews/tests/core/data/base.py b/holoviews/tests/core/data/base.py index ed8121688e..34bd776c0f 100644 --- a/holoviews/tests/core/data/base.py +++ b/holoviews/tests/core/data/base.py @@ -858,6 +858,12 @@ def test_dataset_transform_add_ht(self): kdims=self.kdims, vdims=self.vdims+['combined']) self.assertEqual(transformed, expected) + def test_select_with_neighbor(self): + select = self.table.interface.select_mask(self.table.dataset, {"Weight": 18}) + select_neighbor = self.table.interface._select_mask_neighbor(self.table.dataset, dict(Weight=18)) + + np.testing.assert_almost_equal(select, [False, True, False]) + np.testing.assert_almost_equal(select_neighbor, [True, True, True]) class ScalarColumnTests: diff --git a/holoviews/tests/core/data/test_cudfinterface.py b/holoviews/tests/core/data/test_cudfinterface.py index cdb6c19014..87cb469190 100644 --- a/holoviews/tests/core/data/test_cudfinterface.py +++ b/holoviews/tests/core/data/test_cudfinterface.py @@ -104,3 +104,10 @@ def test_dataset_groupby_second_dim(self): def test_dataset_aggregate_string_types_size(self): raise SkipTest("cuDF does not support variance aggregation") + + def test_select_with_neighbor(self): + try: + # Not currently supported by CuDF + super().test_select_with_neighbor() + except NotImplementedError: + raise SkipTest("Not supported") diff --git a/holoviews/tests/core/data/test_ibisinterface.py b/holoviews/tests/core/data/test_ibisinterface.py index 3f0b4d1773..2b488ec7a6 100644 --- a/holoviews/tests/core/data/test_ibisinterface.py +++ b/holoviews/tests/core/data/test_ibisinterface.py @@ -256,6 +256,13 @@ def test_aggregation_operations(self): self.compare_dataset(expected, result, msg=str(agg)) + def test_select_with_neighbor(self): + try: + # Not currently supported by Ibis + super().test_select_with_neighbor() + except NotImplementedError: + raise SkipTest("Not supported") + if not IbisInterface.has_rowid(): def test_dataset_iloc_slice_rows_slice_cols(self): diff --git a/holoviews/tests/core/data/test_pandasinterface.py b/holoviews/tests/core/data/test_pandasinterface.py index 37b7c0ae28..415ec6acce 100644 --- a/holoviews/tests/core/data/test_pandasinterface.py +++ b/holoviews/tests/core/data/test_pandasinterface.py @@ -172,7 +172,7 @@ class PandasInterfaceTests(BasePandasInterfaceTests): __test__ = True def test_data_with_tz(self): - dates = pd.date_range("2018-01-01", periods=3, freq="H") + dates = pd.date_range("2018-01-01", periods=3, freq="h") dates_tz = dates.tz_localize("UTC") df = pd.DataFrame({"dates": dates_tz}) data = Dataset(df).dimension_values("dates") diff --git a/holoviews/tests/core/data/test_xarrayinterface.py b/holoviews/tests/core/data/test_xarrayinterface.py index b30013da4c..fb67f917ac 100644 --- a/holoviews/tests/core/data/test_xarrayinterface.py +++ b/holoviews/tests/core/data/test_xarrayinterface.py @@ -249,8 +249,16 @@ def test_select_dropped_dimensions_restoration(self): coords=dict(chain=range(d.shape[0]), value=range(d.shape[1]))) ds = Dataset(da) t = ds.select(chain=0) - self.assertEqual(t.data.dims , dict(chain=1,value=8)) - self.assertEqual(t.data.stuff.shape , (1,8)) + if hasattr(t.data, "sizes"): + # Started to warn in xarray 2023.12.0: + # The return type of `Dataset.dims` will be changed to return a + # set of dimension names in future, in order to be more consistent + # with `DataArray.dims`. To access a mapping from dimension names to + # lengths, please use `Dataset.sizes`. + assert t.data.sizes == dict(chain=1, value=8) + else: + assert t.data.dims == dict(chain=1, value=8) + assert t.data.stuff.shape == (1, 8) def test_mask_2d_array_transposed(self): array = np.random.rand(4, 3) diff --git a/holoviews/tests/core/test_apply.py b/holoviews/tests/core/test_apply.py index 974b5a10fa..6f38635187 100644 --- a/holoviews/tests/core/test_apply.py +++ b/holoviews/tests/core/test_apply.py @@ -11,6 +11,10 @@ from holoviews.streams import ParamMethod, Params +def makeDataFrame(): + data = np.random.default_rng(2).standard_normal((30, 4)) + return pd.DataFrame(data, columns=list('ABCD')) + class ParamClass(param.Parameterized): label = param.String(default='Test') @@ -280,7 +284,7 @@ def test_dmap_apply_dynamic_with_param_method(self): def test_nested_widgets(): - df = pd._testing.makeDataFrame() + df = makeDataFrame() column = RadioButtonGroup(value="A", options=list("ABC")) ds = Dataset(df) transform = util.transform.df_dim("*").groupby(["D", column]).mean() @@ -295,7 +299,7 @@ def test_nested_widgets(): def test_slice_iloc(): - df = pd._testing.makeDataFrame() + df = makeDataFrame() column = IntSlider(start=10, end=40) ds = Dataset(df) transform = util.transform.df_dim("*").iloc[:column].mean(axis=0) @@ -310,7 +314,7 @@ def test_slice_iloc(): def test_slice_loc(): - df = pd._testing.makeDataFrame() + df = makeDataFrame() df.index = np.arange(5, len(df) + 5) column = IntSlider(start=10, end=40) ds = Dataset(df) @@ -330,7 +334,7 @@ def test_slice_loc(): def test_int_iloc(): - df = pd._testing.makeDataFrame() + df = makeDataFrame() column = IntSlider(start=10, end=40) ds = Dataset(df) transform = util.transform.df_dim("*").iloc[column] @@ -345,7 +349,7 @@ def test_int_iloc(): def test_int_loc(): - df = pd._testing.makeDataFrame() + df = makeDataFrame() df.index = np.arange(5, len(df) + 5) column = IntSlider(start=10, end=40) ds = Dataset(df) diff --git a/holoviews/tests/core/test_callable.py b/holoviews/tests/core/test_callable.py index 1e01d1b0eb..713c984ee6 100644 --- a/holoviews/tests/core/test_callable.py +++ b/holoviews/tests/core/test_callable.py @@ -24,6 +24,9 @@ def somestaticmethod(): pass @classmethod def someclsmethod(cls): pass + def someinstancemethod(self, x, y): + return x + y + def __call__(self, *testargs): return sum(testargs) @@ -66,6 +69,9 @@ def test_callable_class_name(self): def test_callable_class_call_method(self): self.assertEqual(Callable(CallableClass().__call__).name, 'CallableClass') + def test_callable_instance_method(self): + assert Callable(CallableClass().someinstancemethod).name == 'CallableClass.someinstancemethod' + def test_classmethod_name(self): self.assertEqual(Callable(CallableClass().someclsmethod).name, 'CallableClass.someclsmethod') @@ -116,6 +122,12 @@ def test_callable_partial(self): def test_callable_class(self): self.assertEqual(Callable(CallableClass())(1,2,3,4), 10) + def test_callable_instance_method(self): + assert Callable(CallableClass().someinstancemethod)(1, 2) == 3 + + def test_callable_partial_instance_method(self): + assert Callable(partial(CallableClass().someinstancemethod, x=1))(2) == 3 + def test_callable_paramfunc(self): self.assertEqual(Callable(ParamFunc)(3,b=5), 15) @@ -143,6 +155,14 @@ def test_callable_class_argspec(self): self.assertEqual(Callable(CallableClass()).argspec.keywords, None) self.assertEqual(Callable(CallableClass()).argspec.varargs, 'testargs') + def test_callable_instance_method(self): + assert Callable(CallableClass().someinstancemethod).argspec.args == ['x', 'y'] + assert Callable(CallableClass().someinstancemethod).argspec.keywords is None + + def test_callable_partial_instance_method(self): + assert Callable(partial(CallableClass().someinstancemethod, x=1)).argspec.args == ['y'] + assert Callable(partial(CallableClass().someinstancemethod, x=1)).argspec.keywords is None + def test_callable_paramfunc_argspec(self): self.assertEqual(Callable(ParamFunc).argspec.args, ['a']) self.assertEqual(Callable(ParamFunc).argspec.keywords, 'params') @@ -170,6 +190,12 @@ def test_callable_lambda(self): def test_callable_partial(self): self.assertEqual(Callable(partial(lambda x,y: x+y,x=4))(y=5), 9) + def test_callable_instance_method(self): + assert Callable(CallableClass().someinstancemethod)(x=1, y=2) == 3 + + def test_callable_partial_instance_method(self): + assert Callable(partial(CallableClass().someinstancemethod, x=1))(y=2) == 3 + def test_callable_paramfunc(self): self.assertEqual(Callable(ParamFunc)(a=3,b=5), 15) diff --git a/holoviews/tests/core/test_dynamic.py b/holoviews/tests/core/test_dynamic.py index 0dd9dd7373..65646f6802 100644 --- a/holoviews/tests/core/test_dynamic.py +++ b/holoviews/tests/core/test_dynamic.py @@ -16,6 +16,7 @@ from holoviews.streams import ( Buffer, LinkedStream, + Params, PointerX, PointerXY, PointerY, @@ -846,6 +847,24 @@ def history_callback(x): self.assertEqual(dmap[()], Curve([1, 1, 1, 2, 2, 2])) +class DynamicMapRX(ComparisonTestCase): + + def test_dynamic_rx(self): + freq = param.rx(1) + rx_curve = param.rx(sine_array)(0, freq).rx.pipe(Curve) + dmap = DynamicMap(rx_curve) + assert len(dmap.streams) == 1 + pstream = dmap.streams[0] + assert isinstance(pstream, Params) + assert len(pstream.parameters) == 2 + fn_param, freq_param = pstream.parameters + assert getattr(fn_param.owner, fn_param.name) == sine_array + assert getattr(freq_param.owner, freq_param.name) == 1 + self.assertEqual(dmap[()], Curve(sine_array(0, 1))) + freq.rx.value = 2 + self.assertEqual(dmap[()], Curve(sine_array(0, 2))) + + class StreamSubscribersAddandClear(ComparisonTestCase): def setUp(self): diff --git a/holoviews/tests/element/test_selection.py b/holoviews/tests/element/test_selection.py index 05235b995d..4586371262 100644 --- a/holoviews/tests/element/test_selection.py +++ b/holoviews/tests/element/test_selection.py @@ -616,8 +616,10 @@ def test_poly_geom_selection_inverted(self): self.assertEqual(region, Rectangles([]) * Path([list(geom)+[(0.2, -0.15)]])) -@pytest.mark.skipif(shapely is None and spd is None, reason='Neither shapely nor spatialpandas are available') class TestSpatialSelectColumnar: + __test__ = False + method = None + geometry_encl = np.array([ [-1, 0.5], [ 1, 0.5], @@ -655,30 +657,47 @@ def pandas_df(self): -1,-1,-1] }, dtype=float) - @dd_available + @pytest.fixture(scope="function") def dask_df(self, pandas_df): return dd.from_pandas(pandas_df, npartitions=2) + @pytest.fixture(scope="function") + def _method(self): + return self.method + @pytest.mark.parametrize("geometry,pt_mask", [(geometry_encl, pt_mask_encl),(geometry_noencl, pt_mask_noencl)]) class TestSpatialSelectColumnarPtMask: - def test_pandas(self, geometry, pt_mask, pandas_df): - mask = spatial_select_columnar(pandas_df.x, pandas_df.y, geometry) + + def test_pandas(self, geometry, pt_mask, pandas_df, _method): + mask = spatial_select_columnar(pandas_df.x, pandas_df.y, geometry, _method) assert np.array_equal(mask, pt_mask) @dd_available - def test_dask(self, geometry, pt_mask, dask_df): - mask = spatial_select_columnar(dask_df.x, dask_df.y, geometry) + def test_dask(self, geometry, pt_mask, dask_df, _method): + mask = spatial_select_columnar(dask_df.x, dask_df.y, geometry, _method) assert np.array_equal(mask.compute(), pt_mask) - def test_numpy(self, geometry, pt_mask, pandas_df): - mask = spatial_select_columnar(pandas_df.x.to_numpy(copy=True), pandas_df.y.to_numpy(copy=True), geometry) + def test_numpy(self, geometry, pt_mask, pandas_df, _method): + mask = spatial_select_columnar(pandas_df.x.to_numpy(copy=True), pandas_df.y.to_numpy(copy=True), geometry, _method) assert np.array_equal(mask, pt_mask) @pytest.mark.parametrize("geometry", [geometry_encl, geometry_noencl]) class TestSpatialSelectColumnarDaskMeta: @dd_available - def test_meta_dtype(self, geometry, dask_df): - mask = spatial_select_columnar(dask_df.x, dask_df.y, geometry) + def test_meta_dtype(self, geometry, dask_df, _method): + mask = spatial_select_columnar(dask_df.x, dask_df.y, geometry, _method) assert mask._meta.dtype == np.bool_ + + +@pytest.mark.skipif(shapely is None, reason='Shapely not available') +class TestSpatialSelectColumnarShapely(TestSpatialSelectColumnar): + __test__ = True + method = 'shapely' + + +@pytest.mark.skipif(spd is None, reason='Spatialpandas not available') +class TestSpatialSelectColumnarSpatialpandas(TestSpatialSelectColumnar): + __test__ = True + method = 'spatialpandas' diff --git a/holoviews/tests/operation/test_datashader.py b/holoviews/tests/operation/test_datashader.py index 7ad78dfe27..531d869a09 100644 --- a/holoviews/tests/operation/test_datashader.py +++ b/holoviews/tests/operation/test_datashader.py @@ -221,7 +221,7 @@ def test_aggregate_curve_datetimes(self): def test_aggregate_curve_datetimes_dask(self): df = pd.DataFrame( data=np.arange(1000), columns=['a'], - index=pd.date_range('2019-01-01', freq='1T', periods=1000), + index=pd.date_range('2019-01-01', freq='1min', periods=1000), ) ddf = dd.from_pandas(df, npartitions=4) curve = Curve(ddf, kdims=['index'], vdims=['a']) @@ -270,7 +270,7 @@ def test_aggregate_ndoverlay_count_cat_datetimes_microsecond_timebase(self): self.assertEqual(imgs[1], expected2) def test_aggregate_dt_xaxis_constant_yaxis(self): - df = pd.DataFrame({'y': np.ones(100)}, index=pd.date_range('1980-01-01', periods=100, freq='1T')) + df = pd.DataFrame({'y': np.ones(100)}, index=pd.date_range('1980-01-01', periods=100, freq='1min')) img = rasterize(Curve(df), dynamic=False, width=3) xs = np.array(['1980-01-01T00:16:30.000000', '1980-01-01T00:49:30.000000', '1980-01-01T01:22:30.000000'], dtype='datetime64[us]') @@ -868,7 +868,7 @@ def test_shade_categorical_images_grid(self): self.assertEqual(shaded, expected) def test_shade_dt_xaxis_constant_yaxis(self): - df = pd.DataFrame({'y': np.ones(100)}, index=pd.date_range('1980-01-01', periods=100, freq='1T')) + df = pd.DataFrame({'y': np.ones(100)}, index=pd.date_range('1980-01-01', periods=100, freq='1min')) rgb = shade(rasterize(Curve(df), dynamic=False, width=3)) xs = np.array(['1980-01-01T00:16:30.000000', '1980-01-01T00:49:30.000000', '1980-01-01T01:22:30.000000'], dtype='datetime64[us]') @@ -1339,6 +1339,21 @@ def test_rasterize_selector(point_plot, sel_fn): np.testing.assert_array_equal(img["Count"], img_count["Count"]) +def test_rasterize_with_datetime_column(): + n = 4 + df = pd.DataFrame({ + "x": np.random.uniform(-180, 180, n), + "y": np.random.uniform(-90, 90, n), + "Timestamp": pd.date_range(start="2023-01-01", periods=n, freq="D"), + "Value": np.random.rand(n) * 100, + }) + point_plot = Points(df) + rast_input = dict(dynamic=False, x_range=(-1, 1), y_range=(-1, 1), width=2, height=2) + img_agg = rasterize(point_plot, selector=ds.first("Value"), **rast_input) + + assert img_agg["Timestamp"].dtype == np.dtype("datetime64[ns]") + + class DatashaderSpreadTests(ComparisonTestCase): @@ -1545,3 +1560,10 @@ def test_imagestack_datashader_color_key(): color_key=cc.glasbey_light, ) render(op) # should not error out + + +def test_imagestack_datashade_count_cat(): + # Test for https://github.com/holoviz/holoviews/issues/6154 + df = pd.DataFrame({"x": range(3), "y": range(3), "c": range(3)}) + op = datashade(Points(df), aggregator=ds.count_cat("c")) + render(op) # should not error out diff --git a/holoviews/tests/operation/test_downsample.py b/holoviews/tests/operation/test_downsample.py index d82813b1d0..066a0dd6b8 100644 --- a/holoviews/tests/operation/test_downsample.py +++ b/holoviews/tests/operation/test_downsample.py @@ -1,7 +1,17 @@ +import numpy as np +import pandas as pd import pytest import holoviews as hv -from holoviews.operation.downsample import downsample1d +from holoviews.operation.downsample import _ALGORITHMS, downsample1d + +try: + import tsdownsample +except ImportError: + tsdownsample = None + +algorithms = _ALGORITHMS.copy() +algorithms.pop("viewport", None) # viewport return slice(len(data)) no matter the width @pytest.mark.parametrize("plottype", ["overlay", "ndoverlay"]) @@ -18,3 +28,71 @@ def test_downsample1d_multi(plottype): for n in figure_values: for value in n.data.values(): assert value.size == downsample1d.width + + +def test_downsample1d_shared_data(): + runs = [0] + + class mocksample(downsample1d): + def _compute_mask(self, element): + # Use _compute_mask as this should only be called once + # and then it should be cloned. + runs[0] += 1 + return super()._compute_mask(element) + + N = 1000 + df = pd.DataFrame({c: range(N) for c in "xyz"}) + figure = hv.Overlay([hv.Curve(df, kdims="x", vdims=c) for c in "yz"]) + + # We set x_range to trigger _compute_mask + mocksample(figure, dynamic=False, x_range=(0, 500)) + assert runs[0] == 1 + + +# Should be fixed when https://github.com/holoviz/holoviews/pull/6061 is merged +@pytest.mark.xfail(reason="This will make a copy of the data") +def test_downsample1d_shared_data_index(): + runs = [0] + + class mocksample(downsample1d): + def _compute_mask(self, element): + # Use _compute_mask as this should only be called once + # and then it should be cloned. + runs[0] += 1 + return super()._compute_mask(element) + + N = 1000 + df = pd.DataFrame({c: range(N) for c in "xyz"}) + figure = hv.Overlay([hv.Curve(df, kdims="index", vdims=c) for c in "xyz"]) + + # We set x_range to trigger _compute_mask + mocksample(figure, dynamic=False, x_range=(0, 500)) + assert runs[0] == 1 + + +@pytest.mark.parametrize("algorithm", algorithms.values(), ids=algorithms) +def test_downsample_algorithm(algorithm, unimport): + unimport("tsdownsample") + x = np.arange(1000) + y = np.random.rand(1000) + width = 20 + try: + result = algorithm(x, y, width) + except NotImplementedError: + pytest.skip("not testing tsdownsample algorithms") + else: + if isinstance(result, slice): + result = x[result] + assert result.size == width + + +@pytest.mark.skipif(not tsdownsample, reason="tsdownsample not installed") +@pytest.mark.parametrize("algorithm", algorithms.values(), ids=algorithms) +def test_downsample_algorithm_with_tsdownsample(algorithm): + x = np.arange(1000) + y = np.random.rand(1000) + width = 20 + result = algorithm(x, y, width) + if isinstance(result, slice): + result = x[result] + assert result.size == width diff --git a/holoviews/tests/operation/test_operation.py b/holoviews/tests/operation/test_operation.py index 0746560418..763c5f81ad 100644 --- a/holoviews/tests/operation/test_operation.py +++ b/holoviews/tests/operation/test_operation.py @@ -331,6 +331,49 @@ def test_dataset_histogram_empty_explicit_bins(self): hist = Histogram(([0, 1, 2], [0, 0]), vdims=('x_count', 'Count')) self.assertEqual(op_hist, hist) + def test_dataset_histogram_groupby_range_shared(self): + x = np.arange(10) + y = np.arange(10) + 10 + xy = np.concatenate([x, y]) + label = ["x"] * 10 + ["y"] * 10 + + ds = Dataset(pd.DataFrame([xy, label], index=["xy", "label"]).T, vdims=["xy", "label"]) + hist = histogram(ds, groupby="label", groupby_range="shared") + exp = np.linspace(0, 19, 21) + for k, v in hist.items(): + np.testing.assert_equal(exp, v.data["xy"]) + sel = np.asarray(label) == k + assert sel.sum() == 10 + assert (v.data["xy_count"][sel] == 1).all() + assert (v.data["xy_count"][~sel] == 0).all() + + def test_dataset_histogram_groupby_range_separated(self): + x = np.arange(10) + y = np.arange(10) + 10 + xy = np.concatenate([x, y]) + label = ["x"] * 10 + ["y"] * 10 + + ds = Dataset(pd.DataFrame([xy, label], index=["xy", "label"]).T, vdims=["xy", "label"]) + hist = histogram(ds, groupby="label", groupby_range="separated") + + for idx, v in enumerate(hist): + exp = np.linspace(idx * 10, 10 * idx + 9, 21) + np.testing.assert_equal(exp, v.data["xy"]) + assert v.data["xy_count"].sum() == 10 + + def test_dataset_histogram_groupby_datetime(self): + x = pd.date_range("2020-01-01", periods=100) + y = pd.date_range("2020-01-01", periods=100) + xy = np.concatenate([x, y]) + label = ["x"] * 100 + ["y"] * 100 + ds = Dataset(pd.DataFrame([xy, label], index=["xy", "label"]).T, vdims=["xy", "label"]) + hist = histogram(ds, groupby="label") + + exp = pd.date_range("2020-01-01", '2020-04-09', periods=21) + for h in hist: + np.testing.assert_equal(exp, h.data["xy"]) + assert (h.data["xy_count"] == 5).all() + @da_skip def test_dataset_histogram_dask(self): import dask.array as da diff --git a/holoviews/tests/plotting/bokeh/test_annotationplot.py b/holoviews/tests/plotting/bokeh/test_annotationplot.py index ab955a8131..4a60a3e823 100644 --- a/holoviews/tests/plotting/bokeh/test_annotationplot.py +++ b/holoviews/tests/plotting/bokeh/test_annotationplot.py @@ -17,7 +17,7 @@ VSpan, VSpans, ) -from holoviews.plotting.bokeh.util import bokeh32, bokeh33 +from holoviews.plotting.bokeh.util import bokeh32, bokeh33, bokeh34 from .test_plot import TestBokehPlot, bokeh_renderer @@ -29,7 +29,9 @@ VStrip as BkVStrip, ) -if bokeh33: +if bokeh34: + from bokeh.models import Node +elif bokeh33: from bokeh.models.coordinates import Node diff --git a/holoviews/tests/plotting/bokeh/test_callbacks.py b/holoviews/tests/plotting/bokeh/test_callbacks.py index 85ed947659..889740757c 100644 --- a/holoviews/tests/plotting/bokeh/test_callbacks.py +++ b/holoviews/tests/plotting/bokeh/test_callbacks.py @@ -422,7 +422,12 @@ def test_cds_resolves(self): 'value': points.columns()}) def test_rangexy_datetime(self): - curve = Curve(pd._testing.makeTimeDataFrame(), 'index', 'C') + df = pd.DataFrame( + data = np.random.default_rng(2).standard_normal((30, 4)), + columns=list('ABCD'), + index=pd.date_range('2018-01-01', freq='D', periods=30), + ) + curve = Curve(df, 'index', 'C') stream = RangeXY(source=curve) plot = bokeh_server_renderer.get_plot(curve) callback = plot.callbacks[0] diff --git a/holoviews/tests/plotting/bokeh/test_links.py b/holoviews/tests/plotting/bokeh/test_links.py index cb6efa25ef..ed11ac9a46 100644 --- a/holoviews/tests/plotting/bokeh/test_links.py +++ b/holoviews/tests/plotting/bokeh/test_links.py @@ -1,6 +1,6 @@ import numpy as np import pytest -from bokeh.models import ColumnDataSource +from bokeh.models import ColumnDataSource, RangeTool from holoviews.core.spaces import DynamicMap from holoviews.element import Curve, Image, Path, Points, Polygons, Scatter, Table @@ -12,7 +12,6 @@ class TestLinkCallbacks(TestBokehPlot): def test_range_tool_link_callback_single_axis(self): - from bokeh.models import RangeTool array = np.random.rand(100, 2) src = Curve(array) target = Scatter(array) @@ -26,7 +25,6 @@ def test_range_tool_link_callback_single_axis(self): self.assertIs(range_tool.y_range, None) def test_range_tool_link_callback_single_axis_overlay_target(self): - from bokeh.models import RangeTool array = np.random.rand(100, 2) src = Curve(array) target = Scatter(array, label='a') * Scatter(array, label='b') @@ -40,7 +38,6 @@ def test_range_tool_link_callback_single_axis_overlay_target(self): self.assertIs(range_tool.y_range, None) def test_range_tool_link_callback_single_axis_overlay_target_image_source(self): - from bokeh.models import RangeTool data = np.random.rand(50, 50) target = Curve(data) * Curve(data) source = Image(np.random.rand(50, 50), bounds=(0, 0, 1, 1)) @@ -53,8 +50,40 @@ def test_range_tool_link_callback_single_axis_overlay_target_image_source(self): self.assertEqual(range_tool.x_range, tgt_plot.handles['x_range']) self.assertIs(range_tool.y_range, None) + def test_range_tool_link_callback_single_axis_curve_target_image_dmap_source(self): + # Choosing Image to exert the apply_nodata compositor + src = DynamicMap( + lambda a: Image(a*np.random.random((20, 20)), bounds=[0, 0, 9, 9]), + kdims=['a'] + ).redim.range(a=(0.1,1)) + target = Curve(np.arange(10)) + RangeToolLink(src, target) + layout = target + src + plot = bokeh_renderer.get_plot(layout) + tgt_plot = plot.subplots[(0, 0)].subplots['main'] + src_plot = plot.subplots[(0, 1)].subplots['main'] + range_tool = src_plot.state.select_one({'type': RangeTool}) + assert range_tool.x_range == tgt_plot.handles['x_range'] + assert range_tool.y_range is None + + def test_range_tool_link_callback_single_axis_overlay_target_image_dmap_source(self): + # Choosing Image to exert the apply_nodata compositor + src = DynamicMap( + lambda a: Image(a*np.random.random((20, 20)), bounds=[0, 0, 9, 9]), + kdims=['a'] + ).redim.range(a=(0.1,1)) + data = np.random.rand(50, 50) + target = Curve(data) * Curve(data) + RangeToolLink(src, target) + layout = target + src + plot = bokeh_renderer.get_plot(layout) + tgt_plot = plot.subplots[(0, 0)].subplots['main'] + src_plot = plot.subplots[(0, 1)].subplots['main'] + range_tool = src_plot.state.select_one({'type': RangeTool}) + assert range_tool.x_range == tgt_plot.handles['x_range'] + assert range_tool.y_range is None + def test_range_tool_link_callback_both_axes(self): - from bokeh.models import RangeTool array = np.random.rand(100, 2) src = Curve(array) target = Scatter(array) diff --git a/holoviews/tests/plotting/bokeh/test_rasterplot.py b/holoviews/tests/plotting/bokeh/test_rasterplot.py index c12f969126..c5c404f6f9 100644 --- a/holoviews/tests/plotting/bokeh/test_rasterplot.py +++ b/holoviews/tests/plotting/bokeh/test_rasterplot.py @@ -1,9 +1,13 @@ from unittest import SkipTest import numpy as np +import pandas as pd +import pytest +from bokeh.models import CustomJSHover, HoverTool from holoviews.element import RGB, Image, ImageStack, Raster from holoviews.plotting.bokeh.raster import ImageStackPlot +from holoviews.plotting.bokeh.util import bokeh34 from .test_plot import TestBokehPlot, bokeh_renderer @@ -129,6 +133,38 @@ def test_rgb_invert_yaxis(self): assert cdata["dw"] == [1.0] assert cdata["y"] == [-0.5] + def test_image_datetime_hover(self): + xr = pytest.importorskip("xarray") + ts = pd.Timestamp("2020-01-01") + data = xr.Dataset( + coords={"x": [-0.5, 0.5], "y": [-0.5, 0.5]}, + data_vars={ + "Count": (["y", "x"], [[0, 1], [2, 3]]), + "Timestamp": (["y", "x"], [[ts, pd.NaT], [ts, ts]]), + }, + ) + img = Image(data).opts(tools=["hover"]) + plot = bokeh_renderer.get_plot(img) + + hover = plot.handles["hover"] + assert hover.tooltips[-1] == ("Timestamp", "@{Timestamp}{%F %T}") + assert "@{Timestamp}" in hover.formatters + + if bokeh34: # https://github.com/bokeh/bokeh/issues/13598 + assert hover.formatters["@{Timestamp}"] == "datetime" + else: + assert isinstance(hover.formatters["@{Timestamp}"], CustomJSHover) + + def test_image_hover_with_custom_js(self): + # Regression for https://github.com/holoviz/holoviews/issues/6101 + hover_tool = HoverTool( + tooltips=[("x", "$x{custom}")], formatters={"x": CustomJSHover(code="return value + '2'")} + ) + img = Image(np.ones(100).reshape(10, 10)).opts(tools=[hover_tool]) + plot = bokeh_renderer.get_plot(img) + + hover = plot.handles["hover"] + assert hover.formatters == hover_tool.formatters class _ImageStackBase(TestRasterPlot): __test__ = False @@ -372,6 +408,34 @@ def test_image_stack_tuple_single_3darray(self): assert source.data["dh"][0] == self.ysize assert isinstance(plot, ImageStackPlot) + def test_image_stack_dict_cmap(self): + x = np.arange(0, 3) + y = np.arange(5, 8) + a = np.array([[np.nan, np.nan, 1], [np.nan] * 3, [np.nan] * 3]) + b = np.array([[np.nan] * 3, [1, 1, np.nan], [np.nan] * 3]) + c = np.array([[np.nan] * 3, [np.nan] * 3, [1, 1, 1]]) + + img_stack = ImageStack((x, y, a, b, c), kdims=["x", "y"], vdims=["b", "a", "c"]) + img_stack.opts(cmap={"c": "yellow", "a": "red", "b": "green"}) + plot = bokeh_renderer.get_plot(img_stack) + source = plot.handles["source"] + np.testing.assert_equal(source.data["image"][0][:, :, 0], a) + np.testing.assert_equal(source.data["image"][0][:, :, 1], b) + np.testing.assert_equal(source.data["image"][0][:, :, 2], c) + assert plot.handles["color_mapper"].palette == ["green", "red", "yellow"] + + def test_image_stack_dict_cmap_missing(self): + x = np.arange(0, 3) + y = np.arange(5, 8) + a = np.array([[np.nan, np.nan, 1], [np.nan] * 3, [np.nan] * 3]) + b = np.array([[np.nan] * 3, [1, 1, np.nan], [np.nan] * 3]) + c = np.array([[np.nan] * 3, [np.nan] * 3, [1, 1, 1]]) + + img_stack = ImageStack((x, y, a, b, c), kdims=["x", "y"], vdims=["b", "a", "c"]) + with pytest.raises(ValueError, match="must have the same value dimensions"): + img_stack.opts(cmap={"c": "yellow", "a": "red"}) + bokeh_renderer.get_plot(img_stack) + class TestImageStackEven(_ImageStackBase): __test__ = True diff --git a/holoviews/tests/plotting/bokeh/test_renderer.py b/holoviews/tests/plotting/bokeh/test_renderer.py index bf601f5c81..2e69a49906 100644 --- a/holoviews/tests/plotting/bokeh/test_renderer.py +++ b/holoviews/tests/plotting/bokeh/test_renderer.py @@ -4,6 +4,7 @@ import numpy as np import panel as pn import param +import pytest from bokeh.io import curdoc from bokeh.themes.theme import Theme from panel.widgets import DiscreteSlider, FloatSlider, Player @@ -154,6 +155,7 @@ def test_render_holomap_individual_widget_position(self): self.assertEqual(obj.widget_location, 'top') self.assertEqual(obj.widget_type, 'individual') + @pytest.mark.filterwarnings('ignore:Attempted to send message over Jupyter Comm') def test_render_dynamicmap_with_dims(self): dmap = DynamicMap(lambda y: Curve([1, 2, y]), kdims=['y']).redim.range(y=(0.1, 5)) obj, _ = self.renderer._validate(dmap, None) @@ -166,6 +168,7 @@ def test_render_dynamicmap_with_dims(self): slider.value = 3.1 self.assertEqual(cds.data['y'][2], 3.1) + @pytest.mark.filterwarnings('ignore:Attempted to send message over Jupyter Comm') def test_render_dynamicmap_with_stream(self): stream = Stream.define('Custom', y=2)() dmap = DynamicMap(lambda y: Curve([1, 2, y]), kdims=['y'], streams=[stream]) @@ -178,6 +181,7 @@ def test_render_dynamicmap_with_stream(self): stream.event(y=3) self.assertEqual(cds.data['y'][2], 3) + @pytest.mark.filterwarnings('ignore:Attempted to send message over Jupyter Comm') def test_render_dynamicmap_with_stream_dims(self): stream = Stream.define('Custom', y=2)() dmap = DynamicMap(lambda x, y: Curve([x, 1, y]), kdims=['x', 'y'], diff --git a/holoviews/tests/plotting/bokeh/test_server.py b/holoviews/tests/plotting/bokeh/test_server.py index 4f9f21cf8e..5686bfbff3 100644 --- a/holoviews/tests/plotting/bokeh/test_server.py +++ b/holoviews/tests/plotting/bokeh/test_server.py @@ -163,6 +163,9 @@ def test_server_dynamicmap_with_stream(self): cds = session.document.roots[0].select_one({'type': ColumnDataSource}) self.assertEqual(cds.data['y'][2], 2) + def loaded(): + state._schedule_on_load(doc, None) + doc.add_next_tick_callback(loaded) def run(): stream.event(y=3) doc.add_next_tick_callback(run) @@ -180,6 +183,9 @@ def test_server_dynamicmap_with_stream_dims(self): orig_cds = session.document.roots[0].select_one({'type': ColumnDataSource}) self.assertEqual(orig_cds.data['y'][2], 2) + def loaded(): + state._schedule_on_load(doc, None) + doc.add_next_tick_callback(loaded) def run(): stream.event(y=3) doc.add_next_tick_callback(run) diff --git a/holoviews/tests/plotting/bokeh/test_subcoordy.py b/holoviews/tests/plotting/bokeh/test_subcoordy.py index a6af6a4664..0009d00950 100644 --- a/holoviews/tests/plotting/bokeh/test_subcoordy.py +++ b/holoviews/tests/plotting/bokeh/test_subcoordy.py @@ -1,5 +1,6 @@ import numpy as np import pytest +from bokeh.models.tools import WheelZoomTool, ZoomInTool, ZoomOutTool from holoviews.core import Overlay from holoviews.element import Curve @@ -202,3 +203,50 @@ def test_same_label_error(self): match='Elements wrapped in a subcoordinate_y overlay must all have a unique label', ): bokeh_renderer.get_plot(overlay) + + def test_tools_default_wheel_zoom_configured(self): + overlay = Overlay([Curve(range(10), label=f'Data {i}').opts(subcoordinate_y=True) for i in range(2)]) + plot = bokeh_renderer.get_plot(overlay) + zoom_subcoordy = plot.handles['zooms_subcoordy']['wheel_zoom'] + assert len(zoom_subcoordy.renderers) == 2 + assert len(set(zoom_subcoordy.renderers)) == 2 + assert zoom_subcoordy.dimensions == 'height' + assert zoom_subcoordy.level == 1 + + def test_tools_string_zoom_in_out_configured(self): + for zoom in ['zoom_in', 'zoom_out', 'yzoom_in', 'yzoom_out', 'ywheel_zoom']: + overlay = Overlay([Curve(range(10), label=f'Data {i}').opts(subcoordinate_y=True, tools=[zoom]) for i in range(2)]) + plot = bokeh_renderer.get_plot(overlay) + zoom_subcoordy = plot.handles['zooms_subcoordy'][zoom] + assert len(zoom_subcoordy.renderers) == 2 + assert len(set(zoom_subcoordy.renderers)) == 2 + assert zoom_subcoordy.dimensions == 'height' + assert zoom_subcoordy.level == 1 + + def test_tools_string_x_zoom_untouched(self): + for zoom, zoom_type in [ + ('xzoom_in', ZoomInTool), + ('xzoom_out', ZoomOutTool), + ('xwheel_zoom', WheelZoomTool), + ]: + overlay = Overlay([Curve(range(10), label=f'Data {i}').opts(subcoordinate_y=True, tools=[zoom]) for i in range(2)]) + plot = bokeh_renderer.get_plot(overlay) + for tool in plot.state.tools: + if isinstance(tool, zoom_type) and tool.tags == ['hv_created']: + assert tool.level == 0 + assert tool.dimensions == 'width' + break + else: + raise AssertionError('Provided zoom not found.') + + def test_tools_instance_zoom_untouched(self): + for zoom in [WheelZoomTool(), ZoomInTool(), ZoomOutTool()]: + overlay = Overlay([Curve(range(10), label=f'Data {i}').opts(subcoordinate_y=True, tools=[zoom]) for i in range(2)]) + plot = bokeh_renderer.get_plot(overlay) + for tool in plot.state.tools: + if isinstance(tool, type(zoom)) and 'hv_created' not in tool.tags: + assert tool.level == 0 + assert tool.dimensions == 'both' + break + else: + raise AssertionError('Provided zoom not found.') diff --git a/holoviews/tests/plotting/matplotlib/test_renderer.py b/holoviews/tests/plotting/matplotlib/test_renderer.py index 07d7523ebf..0c8f55aa26 100644 --- a/holoviews/tests/plotting/matplotlib/test_renderer.py +++ b/holoviews/tests/plotting/matplotlib/test_renderer.py @@ -1,12 +1,15 @@ """ Test cases for rendering exporters """ +import os import subprocess +import sys from unittest import SkipTest import numpy as np import panel as pn import param +import pytest from matplotlib import style from panel.widgets import DiscreteSlider, FloatSlider, Player from pyviz_comms import CommManager @@ -80,6 +83,7 @@ def test_render_gif(self): data, metadata = self.renderer.components(self.map1, 'gif') self.assertIn(" 2, page) + + assert BOUND_COUNT[0] == 1 diff --git a/holoviews/tests/ui/bokeh/test_layout.py b/holoviews/tests/ui/bokeh/test_layout.py index d7d08e11dd..114ea37fa6 100644 --- a/holoviews/tests/ui/bokeh/test_layout.py +++ b/holoviews/tests/ui/bokeh/test_layout.py @@ -1,29 +1,24 @@ -import time - +import numpy as np import pytest -pytestmark = pytest.mark.ui - -from panel.io.server import serve -from panel.widgets import Button - +import holoviews as hv -def test_button_click(page, port): - button = Button(name='Click') +from .. import expect - events = [] - def cb(event): - events.append(event) - button.on_click(cb) - - serve(button, port=port, threaded=True, show=False) - - time.sleep(0.2) +pytestmark = pytest.mark.ui - page.goto(f"http://localhost:{port}") - page.click('.bk-btn') +@pytest.mark.usefixtures("bokeh_backend") +def test_gridspace_toolbar(serve_hv): + def sine_curve(phase, freq): + xvals = [0.1 * i for i in range(100)] + return hv.Curve((xvals, [np.sin(phase + freq * x) for x in xvals])) - time.sleep(0.1) + phases = [0, np.pi / 2, np.pi, 3 * np.pi / 2] + frequencies = [0.5, 0.75, 1.0, 1.25] + curve_dict_2D = {(p, f): sine_curve(p, f) for p in phases for f in frequencies} + gridspace = hv.GridSpace(curve_dict_2D, kdims=["phase", "frequency"]) - assert len(events) == 1 + page = serve_hv(gridspace) + bokeh_logo = page.locator(".bk-logo") + expect(bokeh_logo).to_have_count(1) diff --git a/holoviews/tests/utils.py b/holoviews/tests/utils.py index c763122272..35c5670886 100644 --- a/holoviews/tests/utils.py +++ b/holoviews/tests/utils.py @@ -59,8 +59,7 @@ def assertEndsWith(self, level, substring): msg='\n\n{method}: {last_line}\ndoes not end with:\n{substring}' last_line = self.tail(level, n=1) if len(last_line) == 0: - raise AssertionError('Missing {method} output: {substring}'.format( - method=self.param_methods[level], substring=repr(substring))) + raise AssertionError(f'Missing {self.param_methods[level]} output: {substring!r}') if not last_line[0].endswith(substring): raise AssertionError(msg.format(method=self.param_methods[level], last_line=repr(last_line[0]), @@ -77,8 +76,7 @@ def assertContains(self, level, substring): msg='\n\n{method}: {last_line}\ndoes not contain:\n{substring}' last_line = self.tail(level, n=1) if len(last_line) == 0: - raise AssertionError('Missing {method} output: {substring}'.format( - method=self.param_methods[level], substring=repr(substring))) + raise AssertionError(f'Missing {self.param_methods[level]} output: {substring!r}') if substring not in last_line[0]: raise AssertionError(msg.format(method=self.param_methods[level], last_line=repr(last_line[0]), diff --git a/holoviews/util/__init__.py b/holoviews/util/__init__.py index 962496927c..fd11c49441 100644 --- a/holoviews/util/__init__.py +++ b/holoviews/util/__init__.py @@ -139,9 +139,7 @@ def _group_kwargs_to_options(cls, obj, kwargs): # Not targets specified - add current object as target sanitized_group = util.group_sanitizer(obj.group) if obj.label: - identifier = ('{}.{}.{}'.format( - obj.__class__.__name__, sanitized_group, - util.label_sanitizer(obj.label))) + identifier = (f'{obj.__class__.__name__}.{sanitized_group}.{util.label_sanitizer(obj.label)}') elif sanitized_group != obj.__class__.__name__: identifier = f'{obj.__class__.__name__}.{sanitized_group}' else: @@ -333,10 +331,10 @@ def _expand_options(cls, options, backend=None): "holoviews.plotting before applying any " "options.") elif current_backend not in Store.renderers: - raise ValueError("Currently selected plotting extension {ext} " + raise ValueError(f"Currently selected plotting extension {current_backend!r} " "has not been loaded, ensure you load it " - "with hv.extension({ext}) before setting " - "options".format(ext=repr(current_backend))) + f"with hv.extension({current_backend!r}) before setting " + "options") try: backend_options = Store.options(backend=backend or current_backend) @@ -872,7 +870,7 @@ class Dynamic(param.ParameterizedFunction): link_inputs = param.Boolean(default=True, doc=""" If Dynamic is applied to another DynamicMap, determines whether - linked streams attached to its Callable inputs are + linked streams and links attached to its Callable inputs are transferred to the output of the utility. For example if the Dynamic utility is applied to a DynamicMap @@ -900,8 +898,12 @@ def __call__(self, map_obj, **params): callback = self._dynamic_operation(map_obj) streams = self._get_streams(map_obj, watch) if isinstance(map_obj, DynamicMap): - dmap = map_obj.clone(callback=callback, shared_data=self.p.shared_data, - streams=streams) + kwargs = dict( + shared_data=self.p.shared_data, callback=callback, streams=streams + ) + if self.p.link_inputs: + kwargs['plot_id'] = map_obj._plot_id + dmap = map_obj.clone(**kwargs) if self.p.shared_data: dmap.data = dict([(k, callback.callable(*k)) for k, v in dmap.data]) diff --git a/holoviews/util/_versions.py b/holoviews/util/_versions.py index 3ee6d299e7..731dff2217 100644 --- a/holoviews/util/_versions.py +++ b/holoviews/util/_versions.py @@ -1,5 +1,6 @@ import platform import sys +from importlib.metadata import version __all__ = ("show_versions",) @@ -7,7 +8,7 @@ # Data "cudf", "dask", - "ibis", + "ibis-framework", "networkx", "numpy", "pandas", @@ -17,8 +18,9 @@ "xarray", # Processing "numba", - "skimage", + "scikit-image", "scipy", + "tsdownsample", # Plotting "bokeh", "colorcet", @@ -26,7 +28,7 @@ "geoviews", "hvplot", "matplotlib", - "PIL", + "pillow", "plotly", # Jupyter "IPython", @@ -36,6 +38,7 @@ # Misc "panel", "param", + "pyviz_comms", ] @@ -52,8 +55,7 @@ def show_versions(): def _package_version(p): try: - __import__(p) - print(f"{p:20}: {sys.modules[p].__version__}") + print(f"{p:20}: {version(p)}") except ImportError: print(f"{p:20}: -") @@ -62,3 +64,7 @@ def _panel_comms(): import panel as pn print(f"{'Panel comms':20}: {pn.config.comms}") + + +if __name__ == "__main__": + show_versions() diff --git a/holoviews/util/warnings.py b/holoviews/util/warnings.py index 6136ee7814..2bf6366ebb 100644 --- a/holoviews/util/warnings.py +++ b/holoviews/util/warnings.py @@ -34,14 +34,18 @@ def find_stack_level(): param_dir = os.path.dirname(param.__file__) frame = inspect.currentframe() - stacklevel = 0 - while frame: - fname = inspect.getfile(frame) - if fname.startswith((pkg_dir, param_dir)) and not fname.startswith(test_dir): - frame = frame.f_back - stacklevel += 1 - else: - break + try: + stacklevel = 0 + while frame: + fname = inspect.getfile(frame) + if fname.startswith((pkg_dir, param_dir)) and not fname.startswith(test_dir): + frame = frame.f_back + stacklevel += 1 + else: + break + finally: + # See: https://docs.python.org/3/library/inspect.html#inspect.Traceback + del frame return stacklevel @@ -81,7 +85,3 @@ class HoloviewsUserWarning(UserWarning): """A Holoviews-specific ``UserWarning`` subclass. Used to selectively filter Holoviews warnings for unconditional display. """ - - -warnings.simplefilter("always", HoloviewsDeprecationWarning) -warnings.simplefilter("always", HoloviewsUserWarning) diff --git a/pyproject.toml b/pyproject.toml index cf88cf6cc1..4338a5e691 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,12 @@ filterwarnings = [ "ignore:datetime.datetime.utcfromtimestamp():DeprecationWarning:dateutil.tz.tz", # https://github.com/dateutil/dateutil/pull/1285 "ignore:datetime.datetime.utcfromtimestamp():DeprecationWarning:bokeh", # https://github.com/bokeh/bokeh/issues/13125 "ignore:datetime.datetime.utcnow():DeprecationWarning:bokeh", # https://github.com/bokeh/bokeh/issues/13125 + # 2024-01: Pandas 2.2 + "ignore:When grouping with a length-1 list::dask.dataframe.groupby", # https://github.com/dask/dask/issues/10572 + "ignore:\\s*Pyarrow will become a required dependency of pandas:DeprecationWarning", # Will go away by itself in Pandas 3.0 + "ignore:Passing a (SingleBlockManager|BlockManager) to (Series|GeoSeries|DataFrame|GeoDataFrame) is deprecated:DeprecationWarning", # https://github.com/holoviz/spatialpandas/issues/137 + # 2024-02 + "ignore:The current Dask DataFrame implementation is deprecated:DeprecationWarning", # https://github.com/dask/dask/issues/10917 ] [tool.coverage] diff --git a/scripts/build_conda.sh b/scripts/build_conda.sh index 50f97422b8..4b47650355 100755 --- a/scripts/build_conda.sh +++ b/scripts/build_conda.sh @@ -5,10 +5,10 @@ set -euxo pipefail git status export SETUPTOOLS_ENABLE_FEATURES="legacy-editable" -python -m build . +python -m build -w . git diff --exit-code VERSION=$(find dist -name "*.whl" -exec basename {} \; | cut -d- -f2) export VERSION -conda build conda.recipe/ --no-test --no-anaconda-upload --no-verify +conda build conda.recipe/ --no-anaconda-upload --no-verify diff --git a/scripts/check_latest_packages.py b/scripts/check_latest_packages.py index 9fcada6001..e99f485efd 100644 --- a/scripts/check_latest_packages.py +++ b/scripts/check_latest_packages.py @@ -1,29 +1,36 @@ +import os import sys from datetime import date, datetime, timedelta +from importlib.metadata import version import requests from packaging.version import Version +if sys.stdout.isatty() or os.environ.get("GITHUB_ACTIONS"): + GREEN, RED, RESET = "\033[92m", "\033[91m", "\033[0m" +else: + GREEN = RED = RESET = "" + def main(*packages): allowed_date = date.today() - timedelta(days=5) - GREEN, RED, RESET = "\033[92m", "\033[91m", "\033[0m" all_latest = True for package in sorted(packages): url = f"https://pypi.org/pypi/{package}/json" resp = requests.get(url, timeout=20).json() latest = resp["info"]["version"] - current = __import__(package).__version__ + current = version(package) + # Remove suffix because older Python versions does not support it latest_release_date = datetime.fromisoformat( - resp["releases"][latest][0]["upload_time_iso_8601"] + resp["releases"][latest][0]["upload_time_iso_8601"].removesuffix("Z") ).date() current_release_date = datetime.fromisoformat( - resp["releases"][current][0]["upload_time_iso_8601"] + resp["releases"][current][0]["upload_time_iso_8601"].removesuffix("Z") ).date() version_check = Version(current) >= Version(latest) - date_check = current_release_date >= allowed_date + date_check = latest_release_date >= allowed_date is_latest = version_check or date_check all_latest &= is_latest @@ -37,4 +44,4 @@ def main(*packages): if __name__ == "__main__": - main("numpy", "pandas") + main(*sys.argv[1:]) diff --git a/scripts/download_data.sh b/scripts/download_data.sh new file mode 100755 index 0000000000..16754fee73 --- /dev/null +++ b/scripts/download_data.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +bokeh sampledata + +python -c " +try: + import pooch + import scipy + import xarray as xr +except ImportError: + pass +else: + xr.tutorial.open_dataset('air_temperature') + xr.tutorial.open_dataset('rasm') +" diff --git a/setup.py b/setup.py index d951f6a232..d25e1c47ef 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ install_requires = [ "param >=1.12.0,<3.0", "numpy >=1.0", - "pyviz_comms >=0.7.4", + "pyviz_comms >=2.1", "panel >=1.0", "colorcet", "packaging", @@ -52,13 +52,17 @@ 'shapely', 'ffmpeg', 'cftime', - 'scipy', + 'scipy >=1.10', # Python 3.9 + Windows downloads 1.9 'selenium', 'spatialpandas', 'datashader >=0.11.1', 'dash >=1.16', ] +if os.name != "nt": + # Currently not available on Windows on conda-forge + extras_require['tests'] += ['tsdownsample'] + extras_require['tests_ci'] = [ 'codecov', "pytest-github-actions-annotate-failures", @@ -98,6 +102,7 @@ "pyarrow", "pooch", "datashader >=0.11.1", + "notebook >=7.0", ] @@ -107,7 +112,7 @@ extras_require["unit_tests"] = extras_require["examples"] + extras_require["tests"] + extras_require['lint'] extras_require['doc'] = extras_require['examples'] + [ - 'nbsite >=0.8.2,<0.9.0', + 'nbsite >=0.8.4,<0.9.0', 'myst-nb <1', 'graphviz', 'bokeh >=3.1',