diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 723904c9..3a7d4fdc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ exclude: (\.min\.js$|\.svg$|\.html$) default_stages: [commit] repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: end-of-file-fixer - id: trailing-whitespace @@ -20,16 +20,16 @@ repos: - id: check-json - id: detect-private-key - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.5 + rev: v0.4.9 hooks: - id: ruff files: geoviews/ - repo: https://github.com/hoxbro/clean_notebook - rev: v0.1.14 + rev: v0.1.15 hooks: - id: clean-notebook - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: v2.3.0 hooks: - id: codespell additional_dependencies: diff --git a/geoviews/__init__.py b/geoviews/__init__.py index b846ca89..96151cf4 100644 --- a/geoviews/__init__.py +++ b/geoviews/__init__.py @@ -1,35 +1,142 @@ -import param +from functools import partial -from holoviews import (extension, help, opts, output, renderer, Store, # noqa (API import) - Cycle, Palette, Overlay, Layout, NdOverlay, NdLayout, - HoloMap, DynamicMap, GridSpace, Dimension, dim) +import param +from holoviews import ( + Cycle, + Dimension, + DynamicMap, + GridSpace, + HoloMap, + Layout, + NdLayout, + NdOverlay, + Overlay, + Palette, + Store, + dim, + extension, + help, + opts, + output, + render, + renderer, + save, +) -from holoviews import render, save # noqa (API import) +from . import ( + data, + feature, + plotting, + tile_sources, +) +from ._warnings import GeoviewsDeprecationWarning, GeoviewsUserWarning +from .element import ( + RGB, + WMTS, + Contours, + Dataset, + EdgePaths, + Feature, + FilledContours, + Graph, + HexTiles, + Image, + ImageStack, + Labels, + LineContours, + Nodes, + Path, + Points, + Polygons, + QuadMesh, + Rectangles, + Segments, + Shape, + Text, + Tiles, + TriMesh, + VectorField, + WindBarbs, +) +from .util import from_xarray -from .element import ( # noqa (API import) - _Element, Feature, Tiles, WMTS, LineContours, FilledContours, - Text, Image, ImageStack, Points, Path, Polygons, Shape, Dataset, RGB, - Contours, Graph, TriMesh, Nodes, EdgePaths, QuadMesh, VectorField, - HexTiles, Labels, Rectangles, Segments, WindBarbs +__version__ = str( + param.version.Version( + fpath=__file__, archive_commit="$Format:%h$", reponame="geoviews" + ) ) -from .util import from_xarray # noqa (API import) -from ._warnings import GeoviewsDeprecationWarning, GeoviewsUserWarning # noqa: F401 -from . import data # noqa (API import) -from . import plotting # noqa (API import) -from . import feature # noqa (API import) -from . import tile_sources # noqa (API import) -__version__ = str(param.version.Version(fpath=__file__, archive_commit="$Format:%h$", - reponame="geoviews")) +__all__ = ( + "Contours", + "Cycle", + "Dataset", + "Dimension", + "DynamicMap", + "EdgePaths", + "Feature", + "FilledContours", + "GeoviewsDeprecationWarning", + "GeoviewsUserWarning", + "Graph", + "GridSpace", + "HexTiles", + "HoloMap", + "Image", + "ImageStack", + "Labels", + "Layout", + "LineContours", + "NdLayout", + "NdOverlay", + "Nodes", + "Overlay", + "Palette", + "Path", + "Points", + "Polygons", + "QuadMesh", + "RGB", + "Rectangles", + "Segments", + "Shape", + "Store", + "Text", + "Tiles", + "TriMesh", + "VectorField", + "WMTS", + "WindBarbs", + "__version__", + "data", + "dim", + "extension", + "feature", + "from_xarray", + "help", + "opts", + "output", + "plotting", + "render", + "renderer", + "save", + "tile_sources", + # Lazy modules + "annotate", + "project", + "operation", +) # Ensure opts utility is initialized with GeoViews elements if Store._options: Store.set_current_backend(Store.current_backend) # make pyct's example/data commands available if possible -from functools import partial try: - from pyct.cmd import copy_examples as _copy, fetch_data as _fetch, examples as _examples + from pyct.cmd import ( + copy_examples as _copy, + examples as _examples, + fetch_data as _fetch, + ) copy_examples = partial(_copy, 'geoviews') fetch_data = partial(_fetch, 'geoviews') examples = partial(_examples, 'geoviews') @@ -54,8 +161,6 @@ def __getattr__(attr): return operation raise AttributeError(f"module {__name__} has no attribute {attr!r}") -__all__ = [k for k in locals() if not k.startswith('_')] -__all__ += ['annotate', 'project', 'operation', '__version__'] def __dir__(): return __all__ @@ -63,6 +168,6 @@ def __dir__(): from typing import TYPE_CHECKING if TYPE_CHECKING: + from . import operation from .annotators import annotate from .operation import project - from . import operation diff --git a/geoviews/__main__.py b/geoviews/__main__.py index d8a126f0..92205c60 100644 --- a/geoviews/__main__.py +++ b/geoviews/__main__.py @@ -3,6 +3,7 @@ def main(args=None): import pyct.cmd except ImportError: import sys + from . import _missing_cmd print(_missing_cmd()) sys.exit(1) diff --git a/geoviews/_warnings.py b/geoviews/_warnings.py index 53abc911..bd194790 100644 --- a/geoviews/_warnings.py +++ b/geoviews/_warnings.py @@ -4,7 +4,6 @@ import holoviews as hv import param - from packaging.version import Version __all__ = ( diff --git a/geoviews/annotators.py b/geoviews/annotators.py index bc61dd6f..a82d8e0b 100644 --- a/geoviews/annotators.py +++ b/geoviews/annotators.py @@ -1,17 +1,24 @@ -import param - import cartopy.crs as ccrs - +import param from holoviews.annotators import ( - annotate, Annotator, PathAnnotator, PolyAnnotator, PointAnnotator, - RectangleAnnotator + Annotator, + PathAnnotator, + PointAnnotator, + PolyAnnotator, + RectangleAnnotator, + annotate, ) from holoviews.plotting.links import DataLink, VertexTableLink as hvVertexTableLink from panel.util import param_name from .element import Path -from .models.custom_tools import CheckpointTool, RestoreTool, ClearTool -from .links import VertexTableLink, PointTableLink, HvRectanglesTableLink, RectanglesTableLink +from .links import ( + HvRectanglesTableLink, + PointTableLink, + RectanglesTableLink, + VertexTableLink, +) +from .models.custom_tools import CheckpointTool, ClearTool, RestoreTool from .operation import project from .streams import PolyVertexDraw, PolyVertexEdit @@ -74,12 +81,12 @@ def _init_stream(self): style_kwargs = dict(node_style=self.node_style, feature_style=self.feature_style) self._stream = PolyVertexDraw( source=self.plot, data={}, num_objects=self.num_objects, - show_vertices=self.show_vertices, tooltip='%s Tool' % name, + show_vertices=self.show_vertices, tooltip=f'{name} Tool', **style_kwargs ) if self.edit_vertices: self._vertex_stream = PolyVertexEdit( - source=self.plot, tooltip='%s Edit Tool' % name, + source=self.plot, tooltip=f'{name} Edit Tool', **style_kwargs ) diff --git a/geoviews/data/__init__.py b/geoviews/data/__init__.py index 5c82b307..493188a8 100644 --- a/geoviews/data/__init__.py +++ b/geoviews/data/__init__.py @@ -1,3 +1,5 @@ -from .geom_dict import GeomDictInterface # noqa (API import) -from .geopandas import GeoPandasInterface # noqa (API import) -from .iris import CubeInterface # noqa (API import) +from .geom_dict import GeomDictInterface +from .geopandas import GeoPandasInterface +from .iris import CubeInterface + +__all__ = ("GeomDictInterface", "GeoPandasInterface", "CubeInterface") diff --git a/geoviews/data/geom_dict.py b/geoviews/data/geom_dict.py index 6b325b9b..c3b43202 100644 --- a/geoviews/data/geom_dict.py +++ b/geoviews/data/geom_dict.py @@ -2,13 +2,13 @@ from collections import OrderedDict import numpy as np -from holoviews.core.data import Interface, DictInterface, MultiInterface +from holoviews.core.data import DictInterface, Interface, MultiInterface from holoviews.core.data.interface import DataError from holoviews.core.data.spatialpandas import to_geom_dict from holoviews.core.dimension import dimension_name from holoviews.core.util import isscalar -from ..util import asarray, geom_types, geom_to_array, geom_length +from ..util import asarray, geom_length, geom_to_array, geom_types class GeomDictInterface(DictInterface): @@ -37,8 +37,13 @@ def init(cls, eltype, data, kdims, vdims): elif not isinstance(data, dict) or 'geometry' not in data: xdim, ydim = kdims[:2] from shapely.geometry import ( - Point, LineString, Polygon, MultiPoint, MultiPolygon, - MultiLineString, LinearRing + LinearRing, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, ) data = to_geom_dict(eltype, data, kdims, vdims, GeomDictInterface) geom = data.get('geom_type') or MultiInterface.geom_type(eltype) @@ -102,9 +107,9 @@ def validate(cls, dataset, validate_vdims): elif 'geometry' not in dataset.data: raise DataError("Could not find a 'geometry' column in the data.") elif not isinstance(dataset.data['geometry'], BaseGeometry): + data_type = type(dataset.data['geometry']).__name__ raise DataError("The 'geometry' column should be a shapely" - "geometry type, found %s type instead." % - type(dataset.data['geometry']).__name__) + f"geometry type, found {data_type} type instead.") @classmethod def shape(cls, dataset): @@ -113,7 +118,11 @@ def shape(cls, dataset): @classmethod def geom_type(cls, dataset): from shapely.geometry import ( - Polygon, MultiPolygon, LineString, MultiLineString, LinearRing + LinearRing, + LineString, + MultiLineString, + MultiPolygon, + Polygon, ) geom = dataset.data['geometry'] if isinstance(geom, (Polygon, MultiPolygon)): @@ -131,7 +140,7 @@ def geo_column(cls, dataset): @classmethod def has_holes(cls, dataset): - from shapely.geometry import Polygon, MultiPolygon + from shapely.geometry import MultiPolygon, Polygon geom = dataset.data['geometry'] if isinstance(geom, Polygon) and geom.interiors: return True @@ -143,7 +152,7 @@ def has_holes(cls, dataset): @classmethod def holes(cls, dataset): - from shapely.geometry import Polygon, MultiPolygon + from shapely.geometry import MultiPolygon, Polygon geom = dataset.data['geometry'] if isinstance(geom, Polygon): return [[[geom_to_array(h) for h in geom.interiors]]] @@ -301,7 +310,12 @@ def concat(cls, datasets, dimensions, vdims): def geom_from_dict(geom, xdim, ydim, single_type, multi_type): from shapely.geometry import ( - Point, LineString, Polygon, MultiPoint, MultiPolygon, MultiLineString + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, ) if (xdim, ydim) in geom: xs, ys = asarray(geom.pop((xdim, ydim))).T diff --git a/geoviews/data/geopandas.py b/geoviews/data/geopandas.py index 7ddf88f8..26fc8321 100644 --- a/geoviews/data/geopandas.py +++ b/geoviews/data/geopandas.py @@ -1,20 +1,23 @@ import sys import warnings - from collections import defaultdict import numpy as np import pandas as pd - -from holoviews.core.util import isscalar, unique_iterator, unique_array -from holoviews.core.data import Dataset, Interface, MultiInterface, PandasAPI +from holoviews.core.data import ( + Dataset, + Interface, + MultiInterface, + PandasAPI, + PandasInterface, +) from holoviews.core.data.interface import DataError -from holoviews.core.data import PandasInterface from holoviews.core.data.spatialpandas import get_value_array from holoviews.core.dimension import dimension_name +from holoviews.core.util import isscalar, unique_array, unique_iterator from holoviews.element import Path -from ..util import asarray, geom_to_array, geom_types, geom_length +from ..util import asarray, geom_length, geom_to_array, geom_types from .geom_dict import geom_from_dict @@ -69,7 +72,7 @@ def init(cls, eltype, data, kdims, vdims): data = from_multi(eltype, data, kdims, vdims) elif not isinstance(data, GeoDataFrame): raise ValueError("GeoPandasInterface only support geopandas " - "DataFrames not %s." % type(data)) + f"DataFrames not {type(data)}.") elif 'geometry' not in data: cls.geo_column(data) @@ -95,7 +98,7 @@ def init(cls, eltype, data, kdims, vdims): shp_types = [] if len(shp_types) > 1: raise DataError('The GeopandasInterface can only read dataframes which ' - 'share a common geometry type, found %s types.' % shp_types, + f'share a common geometry type, found {shp_types} types.', cls) return data, {'kdims': kdims, 'vdims': vdims}, {} @@ -115,7 +118,7 @@ def validate(cls, dataset, vdims=True): if not_found: raise DataError("Supplied data does not contain specified " "dimensions, the following dimensions were " - "not found: %s" % repr(not_found), cls) + f"not found: {not_found!r}", cls) @classmethod def dtype(cls, dataset, dimension): @@ -126,7 +129,7 @@ def dtype(cls, dataset, dimension): @classmethod def has_holes(cls, dataset): - from shapely.geometry import Polygon, MultiPolygon + from shapely.geometry import MultiPolygon, Polygon col = cls.geo_column(dataset.data) for geom in dataset.data[col]: if isinstance(geom, Polygon) and geom.interiors: @@ -139,7 +142,7 @@ def has_holes(cls, dataset): @classmethod def holes(cls, dataset): - from shapely.geometry import Polygon, MultiPolygon + from shapely.geometry import MultiPolygon, Polygon holes = [] col = cls.geo_column(dataset.data) for geom in dataset.data[col]: @@ -521,7 +524,7 @@ def split(cls, dataset, start, end, datatype, **kwargs): elif datatype is None: obj = ds.clone() else: - raise ValueError("%s datatype not support" % datatype) + raise ValueError(f"{datatype} datatype not support") objs.append(obj) return objs @@ -536,7 +539,13 @@ def get_geom_type(geom): A string representing type of the geometry. """ from shapely.geometry import ( - Point, LineString, Polygon, Ring, MultiPoint, MultiPolygon, MultiLineString + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, + Ring, ) if isinstance(geom, (Point, MultiPoint)): return 'Point' @@ -562,7 +571,12 @@ def to_geopandas(data, xdim, ydim, columns=None, geom='point'): """ from geopandas import GeoDataFrame from shapely.geometry import ( - Point, LineString, Polygon, MultiPoint, MultiPolygon, MultiLineString + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, ) if columns is None: columns = [] diff --git a/geoviews/data/iris.py b/geoviews/data/iris.py index 9322fcaa..d3bf86a2 100644 --- a/geoviews/data/iris.py +++ b/geoviews/data/iris.py @@ -1,17 +1,16 @@ -import sys import datetime +import sys from itertools import product import numpy as np - +from holoviews.core import util from holoviews.core.data import Dataset -from holoviews.core.data.interface import Interface, DataError from holoviews.core.data.grid import GridInterface +from holoviews.core.data.interface import DataError, Interface from holoviews.core.dimension import Dimension, asdim from holoviews.core.element import Element -from holoviews.core.ndmapping import (NdMapping, item_check, sorted_context) +from holoviews.core.ndmapping import NdMapping, item_check, sorted_context from holoviews.core.spaces import HoloMap -from holoviews.core import util def get_date_format(coord): @@ -124,8 +123,8 @@ def init(cls, eltype, data, kdims, vdims): for kd in kdims: coord = data.coords(kd.name) if len(coord) == 0: - raise ValueError('Key dimension %s not found in ' - 'Iris cube.' % kd) + raise ValueError(f'Key dimension {kd} not found in ' + 'Iris cube.') coords.append(kd if isinstance(kd, Dimension) else coord[0]) else: coords = data.dim_coords diff --git a/geoviews/element/__init__.py b/geoviews/element/__init__.py index ad8e47a8..b608b540 100644 --- a/geoviews/element/__init__.py +++ b/geoviews/element/__init__.py @@ -1,13 +1,71 @@ from holoviews.element import ( - ElementConversion, Points as HvPoints, Polygons as HvPolygons, - Path as HvPath + ElementConversion, + Path as HvPath, + Points as HvPoints, + Polygons as HvPolygons, ) -from .geo import (_Element, Feature, Tiles, is_geographic, # noqa (API import) - WMTS, Points, Image, ImageStack, Text, LineContours, RGB, - FilledContours, Path, Polygons, Shape, Dataset, - Contours, TriMesh, Graph, Nodes, EdgePaths, QuadMesh, - VectorField, Labels, HexTiles, Rectangles, Segments, WindBarbs) +from .geo import ( + RGB, + WMTS, + Contours, + Dataset, + EdgePaths, + Feature, + FilledContours, + Graph, + HexTiles, + Image, + ImageStack, + Labels, + LineContours, + Nodes, + Path, + Points, + Polygons, + QuadMesh, + Rectangles, + Segments, + Shape, + Text, + Tiles, + TriMesh, + VectorField, + WindBarbs, + _Element, + is_geographic, +) + +__all__ = ( + "Contours", + "Dataset", + "EdgePaths", + "Feature", + "FilledContours", + "GeoConversion", + "Graph", + "HexTiles", + "Image", + "ImageStack", + "Labels", + "LineContours", + "Nodes", + "Path", + "Points", + "Polygons", + "QuadMesh", + "RGB", + "Rectangles", + "Segments", + "Shape", + "Text", + "Tiles", + "TriMesh", + "VectorField", + "WMTS", + "WindBarbs", + "is_geographic", +) class GeoConversion(ElementConversion): diff --git a/geoviews/element/comparison.py b/geoviews/element/comparison.py index a245b830..a7b5f376 100644 --- a/geoviews/element/comparison.py +++ b/geoviews/element/comparison.py @@ -2,7 +2,8 @@ from holoviews.element.comparison import Comparison as HvComparison -from .geo import Image, ImageStack, Points, LineContours, FilledContours, WindBarbs +from .geo import FilledContours, Image, ImageStack, LineContours, Points, WindBarbs + class Comparison(HvComparison): diff --git a/geoviews/element/geo.py b/geoviews/element/geo.py index a6b4deb4..29158a7b 100644 --- a/geoviews/element/geo.py +++ b/geoviews/element/geo.py @@ -1,31 +1,51 @@ -import param import numpy as np - +import param from bokeh.models import MercatorTileSource from cartopy import crs as ccrs from cartopy.feature import Feature as cFeature from cartopy.io.img_tiles import GoogleTiles from cartopy.io.shapereader import Reader -from holoviews.core import Element2D, Dimension, Dataset as HvDataset, NdOverlay, Overlay -from holoviews.core import util +from holoviews.core import ( + Dataset as HvDataset, + Dimension, + Element2D, + NdOverlay, + Overlay, + util, +) from holoviews.element import ( - Contours as HvContours, Graph as HvGraph, Image as HvImage, - Nodes as HvNodes, Path as HvPath, Polygons as HvPolygons, - RGB as HvRGB, Text as HvText, TriMesh as HvTriMesh, - QuadMesh as HvQuadMesh, Points as HvPoints, - VectorField as HvVectorField, HexTiles as HvHexTiles, - Labels as HvLabels, Rectangles as HvRectangles, - Segments as HvSegments, Geometry as HvGeometry, + RGB as HvRGB, + Contours as HvContours, + Geometry as HvGeometry, + Graph as HvGraph, + HexTiles as HvHexTiles, + Image as HvImage, + Labels as HvLabels, + Nodes as HvNodes, + Path as HvPath, + Points as HvPoints, + Polygons as HvPolygons, + QuadMesh as HvQuadMesh, + Rectangles as HvRectangles, + Segments as HvSegments, + Text as HvText, + TriMesh as HvTriMesh, + VectorField as HvVectorField, ) from holoviews.element.selection import Selection2DExpr - -from shapely.geometry.base import BaseGeometry from shapely.geometry import ( - box, GeometryCollection, MultiPolygon, LineString, MultiLineString, - Point, MultiPoint + GeometryCollection, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + box, ) +from shapely.geometry.base import BaseGeometry from shapely.ops import unary_union + def _get_iris_cube(): try: from iris.cube import Cube @@ -50,8 +70,12 @@ class HvImageStack: ... _IMAGESTACK_AVAILABLE = False from ..util import ( - path_to_geom_dicts, polygons_to_geom_dicts, from_xarray, - poly_types, expand_geoms, transform_shapely + expand_geoms, + from_xarray, + path_to_geom_dicts, + poly_types, + polygons_to_geom_dicts, + transform_shapely, ) geographic_types = (GoogleTiles, cFeature, BaseGeometry) @@ -152,8 +176,7 @@ class Feature(_GeoFeature): def __init__(self, data, kdims=None, vdims=None, **params): if not isinstance(data, cFeature): - raise TypeError('%s data has to be an cartopy Feature type' - % type(data).__name__) + raise TypeError(f'{type(data).__name__} data has to be an cartopy Feature type') super().__init__(data, kdims=kdims, vdims=vdims, **params) def __call__(self, *args, **kwargs): @@ -889,10 +912,12 @@ def __init__(self, data, kdims=None, vdims=None, **params): if params.get('level') is not None: if vdims is None: vdims = [Dimension('Level')] - self.param.warning('Supplying a level to a Shape is deprecated ' - 'provide the value as part of a dictionary of ' - 'the form {\'geometry\': , ' - '\'level\': %s} instead' % params['level']) + self.param.warning( + "Supplying a level to a Shape is deprecated " + "provide the value as part of a dictionary of " + "the form {{'geometry': , " + f"'level': {params['level']}}} instead" + ) super().__init__(data, kdims=kdims, vdims=vdims, **params) diff --git a/geoviews/links.py b/geoviews/links.py index dfa66906..e794671b 100644 --- a/geoviews/links.py +++ b/geoviews/links.py @@ -1,10 +1,10 @@ import param - -from holoviews.plotting.links import Link, RectanglesTableLink as HvRectanglesTableLink +from holoviews.core.util import dimension_sanitizer from holoviews.plotting.bokeh.links import ( - LinkCallback, RectanglesTableLinkCallback as HvRectanglesTableLinkCallback + LinkCallback, + RectanglesTableLinkCallback as HvRectanglesTableLinkCallback, ) -from holoviews.core.util import dimension_sanitizer +from holoviews.plotting.links import Link, RectanglesTableLink as HvRectanglesTableLink class PointTableLink(Link): diff --git a/geoviews/models/__init__.py b/geoviews/models/__init__.py index e4e9e469..137dcbd8 100644 --- a/geoviews/models/__init__.py +++ b/geoviews/models/__init__.py @@ -1,4 +1,15 @@ -from .custom_tools import ( # noqa - CheckpointTool, ClearTool, PolyVertexDrawTool, PolyVertexEditTool, - RestoreTool +from .custom_tools import ( + CheckpointTool, + ClearTool, + PolyVertexDrawTool, + PolyVertexEditTool, + RestoreTool, +) + +__all__ = ( + "CheckpointTool", + "ClearTool", + "PolyVertexDrawTool", + "PolyVertexEditTool", + "RestoreTool", ) diff --git a/geoviews/models/custom_tools.py b/geoviews/models/custom_tools.py index 36e3e74c..0ad46dd5 100644 --- a/geoviews/models/custom_tools.py +++ b/geoviews/models/custom_tools.py @@ -1,5 +1,5 @@ -from bokeh.core.properties import Instance, List, Dict, String, Any -from bokeh.models import Tool, ColumnDataSource, PolyEditTool, PolyDrawTool +from bokeh.core.properties import Any, Dict, Instance, List, String +from bokeh.models import ColumnDataSource, PolyDrawTool, PolyEditTool, Tool class CheckpointTool(Tool): diff --git a/geoviews/operation/__init__.py b/geoviews/operation/__init__.py index 8a5184a3..6d2bce6e 100644 --- a/geoviews/operation/__init__.py +++ b/geoviews/operation/__init__.py @@ -4,15 +4,23 @@ from .. import element as gv_element from ..element import _Element -from .projection import ( # noqa (API import) - project_image, project_path, project_shape, project_points, - project_graph, project_quadmesh, project_geom, - project_vectorfield, project_windbarbs, project) -from .resample import resample_geometry # noqa (API import) +from .projection import ( # noqa: F401 + project, + project_geom, + project_graph, + project_image, + project_path, + project_points, + project_quadmesh, + project_shape, + project_vectorfield, + project_windbarbs, +) +from .resample import resample_geometry # noqa: F401 geo_ops = [contours, bivariate_kde] try: - from holoviews.operation.datashader import shade, stack, dynspread + from holoviews.operation.datashader import dynspread, shade, stack from holoviews.operation.resample import ResampleOperation2D geo_ops += [ResampleOperation2D, shade, stack, dynspread] except ImportError: @@ -41,9 +49,8 @@ def find_crs(op, element): return {} crs = crss[0] if any(crs != ocrs for ocrs in crss[1:]): - raise ValueError('Cannot %s Elements in different ' - 'coordinate reference systems.' - % type(op).__name__) + raise ValueError(f'Cannot {type(op).__name__} Elements in different ' + 'coordinate reference systems.') return {'crs': crs} diff --git a/geoviews/operation/projection.py b/geoviews/operation/projection.py index fbb5c194..f3b04dad 100644 --- a/geoviews/operation/projection.py +++ b/geoviews/operation/projection.py @@ -1,24 +1,41 @@ import logging import sys -import param import numpy as np import pandas as pd - +import param from cartopy import crs as ccrs from holoviews.core.data import MultiInterface from holoviews.core.util import cartesian_product, get_param_values from holoviews.operation import Operation -from shapely.geometry import Polygon, MultiPolygon +from shapely.geometry import MultiPolygon, Polygon from shapely.geometry.collection import GeometryCollection from ..data import GeoPandasInterface -from ..element import (Image, Shape, Polygons, Path, Points, Contours, - RGB, Graph, Nodes, EdgePaths, QuadMesh, VectorField, - HexTiles, Labels, Rectangles, Segments, WindBarbs) +from ..element import ( + RGB, + Contours, + EdgePaths, + Graph, + HexTiles, + Image, + Labels, + Nodes, + Path, + Points, + Polygons, + QuadMesh, + Rectangles, + Segments, + Shape, + VectorField, + WindBarbs, +) from ..util import ( - project_extents, path_to_geom_dicts, polygons_to_geom_dicts, - geom_dict_to_array_dict + geom_dict_to_array_dict, + path_to_geom_dicts, + polygons_to_geom_dicts, + project_extents, ) diff --git a/geoviews/operation/regrid.py b/geoviews/operation/regrid.py index c2512219..2bc11e74 100644 --- a/geoviews/operation/regrid.py +++ b/geoviews/operation/regrid.py @@ -1,11 +1,10 @@ import os -import param import numpy as np +import param import xarray as xr - -from holoviews.core.util import get_param_values from holoviews.core.data import XArrayInterface +from holoviews.core.util import get_param_values from holoviews.element import Image as HvImage, QuadMesh as HvQuadMesh from holoviews.operation.datashader import regrid @@ -88,8 +87,8 @@ def _get_regridder(self, element): ds = xr.Dataset(arrays) ds = ds.rename({x.name: 'lon', y.name: 'lat'}) - x_range = str(tuple('%.3f' % r for r in x_range)).replace("'", '') - y_range = str(tuple('%.3f' % r for r in y_range)).replace("'", '') + x_range = str(tuple(f'{r:.3f}' for r in x_range)).replace("'", '') + y_range = str(tuple(f'{r:.3f}' for r in y_range)).replace("'", '') filename = self.p.file_pattern.format( method=self.p.interpolation, width=width, height=height, x_range=x_range, y_range=y_range diff --git a/geoviews/operation/resample.py b/geoviews/operation/resample.py index 53fe14fb..e50a1569 100644 --- a/geoviews/operation/resample.py +++ b/geoviews/operation/resample.py @@ -1,14 +1,11 @@ -import param import numpy as np - -from holoviews import Polygons, Path +import param +from holoviews import Operation, Path, Polygons from holoviews.streams import RangeXY -from holoviews import Operation from shapely.geometry import Polygon from shapely.strtree import STRtree -from ..util import polygons_to_geom_dicts, path_to_geom_dicts, shapely_v2 - +from ..util import path_to_geom_dicts, polygons_to_geom_dicts, shapely_v2 def find_geom(geom, geoms): diff --git a/geoviews/plotting/__init__.py b/geoviews/plotting/__init__.py index e884f22b..1a1e10a2 100644 --- a/geoviews/plotting/__init__.py +++ b/geoviews/plotting/__init__.py @@ -5,30 +5,20 @@ from ..element import Contours, Polygons -if hasattr(extension, 'register_backend_callback'): - def _load_bokeh(): - from . import bokeh # noqa - extension.register_backend_callback('bokeh', _load_bokeh) +def _load_bokeh(): + from geoviews.plotting import bokeh # noqa: F401 - def _load_mpl(): - from . import mpl # noqa - extension.register_backend_callback('matplotlib', _load_mpl) +extension.register_backend_callback('bokeh', _load_bokeh) - backends = Store.loaded_backends() - if 'bokeh' in backends: - _load_bokeh() - if 'matplotlib' in backends: - _load_mpl() -else: - try: - from . import mpl # noqa - except ImportError: - pass +def _load_mpl(): + from geoviews.plotting import mpl # noqa: F401 +extension.register_backend_callback('matplotlib', _load_mpl) - try: - from . import bokeh # noqa - except ImportError: - pass +backends = Store.loaded_backends() +if 'bokeh' in backends: + _load_bokeh() +if 'matplotlib' in backends: + _load_mpl() Compositor.register(Compositor("LineContours", contours, None, 'data', transfer_options=True, diff --git a/geoviews/plotting/bokeh/__init__.py b/geoviews/plotting/bokeh/__init__.py index 3b916f04..6a2c16cb 100644 --- a/geoviews/plotting/bokeh/__init__.py +++ b/geoviews/plotting/bokeh/__init__.py @@ -1,33 +1,59 @@ import copy -import param import numpy as np +import param +from bokeh.models import BBoxTileSource, QUADKEYTileSource, SaveTool, WMTSTileSource from cartopy.crs import GOOGLE_MERCATOR -from bokeh.models import WMTSTileSource, BBoxTileSource, QUADKEYTileSource, SaveTool - -from holoviews import Store, Overlay, NdOverlay +from holoviews import NdOverlay, Overlay, Store from holoviews.core import util -from holoviews.core.options import SkipRendering, Options, Compositor -from holoviews.plotting.bokeh.annotation import TextPlot, LabelsPlot +from holoviews.core.options import Compositor, Options, SkipRendering +from holoviews.plotting.bokeh.annotation import LabelsPlot, TextPlot from holoviews.plotting.bokeh.chart import PointPlot, VectorFieldPlot from holoviews.plotting.bokeh.geometry import RectanglesPlot, SegmentPlot -from holoviews.plotting.bokeh.graphs import TriMeshPlot, GraphPlot -from holoviews.plotting.bokeh.hex_tiles import hex_binning, HexTilesPlot -from holoviews.plotting.bokeh.path import PolygonPlot, PathPlot, ContourPlot -from holoviews.plotting.bokeh.raster import RasterPlot, RGBPlot, QuadMeshPlot +from holoviews.plotting.bokeh.graphs import GraphPlot, TriMeshPlot +from holoviews.plotting.bokeh.hex_tiles import HexTilesPlot, hex_binning +from holoviews.plotting.bokeh.path import ContourPlot, PathPlot, PolygonPlot +from holoviews.plotting.bokeh.raster import QuadMeshPlot, RasterPlot, RGBPlot + from ...element import ( - WMTS, Points, Polygons, Path, Contours, Shape, Image, ImageStack, Feature, - Text, RGB, Nodes, EdgePaths, Graph, TriMesh, QuadMesh, VectorField, - Labels, HexTiles, LineContours, FilledContours, Rectangles, Segments + RGB, + WMTS, + Contours, + EdgePaths, + Feature, + FilledContours, + Graph, + HexTiles, + Image, + ImageStack, + Labels, + LineContours, + Nodes, + Path, + Points, + Polygons, + QuadMesh, + Rectangles, + Segments, + Shape, + Text, + TriMesh, + VectorField, ) from ...operation import ( - project_image, project_points, project_path, project_graph, - project_quadmesh, project_geom, project_vectorfield + project_geom, + project_graph, + project_image, + project_path, + project_points, + project_quadmesh, + project_vectorfield, ) from ...tile_sources import _ATTRIBUTIONS -from ...util import poly_types, line_types -from .plot import GeoPlot, GeoOverlayPlot -from . import callbacks # noqa +from ...util import line_types, poly_types +from . import callbacks # noqa +from .plot import GeoOverlayPlot, GeoPlot + try: from holoviews.plotting.bokeh.raster import ImageStackPlot except ImportError: @@ -53,7 +79,7 @@ def get_extents(self, element, ranges, range_type='combined', **kwargs): def get_data(self, element, ranges, style): if not isinstance(element.data, (str, dict)): SkipRendering("WMTS element data must be a URL string, " - "bokeh cannot render %r" % element.data) + f"bokeh cannot render {element.data!r}") if isinstance(element.data, dict): # xyzservices tile provider diff --git a/geoviews/plotting/bokeh/callbacks.py b/geoviews/plotting/bokeh/callbacks.py index 41414550..a1bdab56 100644 --- a/geoviews/plotting/bokeh/callbacks.py +++ b/geoviews/plotting/bokeh/callbacks.py @@ -1,28 +1,60 @@ -import numpy as np from pathlib import Path -from bokeh.models import CustomJS, CustomAction, PolyEditTool +import numpy as np +from bokeh.models import CustomAction, CustomJS, PolyEditTool from holoviews.core.ndmapping import UniformNdMapping from holoviews.plotting.bokeh.callbacks import ( - RangeXYCallback, BoundsCallback, BoundsXCallback, BoundsYCallback, - PointerXYCallback, PointerXCallback, PointerYCallback, TapCallback, - SingleTapCallback, DoubleTapCallback, MouseEnterCallback, - MouseLeaveCallback, RangeXCallback, RangeYCallback, PolyDrawCallback, - PointDrawCallback, BoxEditCallback, PolyEditCallback, CDSCallback, - FreehandDrawCallback, SelectionXYCallback + BoundsCallback, + BoundsXCallback, + BoundsYCallback, + BoxEditCallback, + CDSCallback, + DoubleTapCallback, + FreehandDrawCallback, + MouseEnterCallback, + MouseLeaveCallback, + PointDrawCallback, + PointerXCallback, + PointerXYCallback, + PointerYCallback, + PolyDrawCallback, + PolyEditCallback, + RangeXCallback, + RangeXYCallback, + RangeYCallback, + SelectionXYCallback, + SingleTapCallback, + TapCallback, ) from holoviews.streams import ( - Stream, PointerXY, RangeXY, RangeX, RangeY, PointerX, PointerY, - BoundsX, BoundsY, Tap, SingleTap, DoubleTap, MouseEnter, MouseLeave, - BoundsXY, PolyDraw, PolyEdit, PointDraw, BoxEdit, FreehandDraw, - SelectionXY + BoundsX, + BoundsXY, + BoundsY, + BoxEdit, + DoubleTap, + FreehandDraw, + MouseEnter, + MouseLeave, + PointDraw, + PointerX, + PointerXY, + PointerY, + PolyDraw, + PolyEdit, + RangeX, + RangeXY, + RangeY, + SelectionXY, + SingleTap, + Stream, + Tap, ) -from ...element.geo import _Element, Shape -from ...util import project_extents +from ...element.geo import Shape, _Element from ...models import PolyVertexDrawTool, PolyVertexEditTool from ...operation import project -from ...streams import PolyVertexEdit, PolyVertexDraw +from ...streams import PolyVertexDraw, PolyVertexEdit +from ...util import project_extents from .plot import GeoOverlayPlot @@ -360,7 +392,7 @@ def initialize(self, plot_id=None): if vertex_tool is None: vertex_style = dict({'size': 10, 'alpha': 0.8}, **stream.vertex_style) r1 = plot.state.scatter([], [], **vertex_style) - tooltip = '%s Edit Tool' % type(element).__name__ + tooltip = f'{type(element).__name__} Edit Tool' vertex_tool = PolyVertexEditTool( vertex_renderer=r1, description=tooltip, node_style=stream.node_style, @@ -389,7 +421,7 @@ def initialize(self, plot_id=None): r1 = plot.state.scatter([], [], **vertex_style) kwargs['vertex_renderer'] = r1 renderer = plot.handles['glyph_renderer'] - tooltip = '%s Draw Tool' % type(element).__name__ + tooltip = f'{type(element).__name__} Draw Tool' if stream.empty_value is not None: kwargs['empty_value'] = stream.empty_value poly_tool = PolyVertexDrawTool( diff --git a/geoviews/plotting/bokeh/plot.py b/geoviews/plotting/bokeh/plot.py index 5c59212b..a9fa785e 100644 --- a/geoviews/plotting/bokeh/plot.py +++ b/geoviews/plotting/bokeh/plot.py @@ -2,15 +2,14 @@ Module for geographic bokeh plot baseclasses. """ import param - -from cartopy.crs import GOOGLE_MERCATOR, PlateCarree, Mercator, _CylindricalProjection +from bokeh.models import CustomJSHover, MercatorTicker, MercatorTickFormatter from bokeh.models.tools import BoxZoomTool, WheelZoomTool -from bokeh.models import MercatorTickFormatter, MercatorTicker, CustomJSHover +from cartopy.crs import GOOGLE_MERCATOR, Mercator, PlateCarree, _CylindricalProjection from holoviews.core.dimension import Dimension from holoviews.core.util import dimension_sanitizer from holoviews.plotting.bokeh.element import ElementPlot, OverlayPlot as HvOverlayPlot -from ...element import is_geographic, _Element, Shape +from ...element import Shape, _Element, is_geographic from ..plot import ProjectionPlot @@ -143,11 +142,11 @@ def _postprocess_hover(self, renderer, source): yhover = CustomJSHover(code=self._hover_code % 1) for name, formatter in hover.tooltips: customjs = None - if formatter in ('@{%s}' % xdim, '$x'): + if formatter in (f'@{{{xdim}}}', '$x'): dim = xdim formatter = '$x' customjs = xhover - elif formatter in ('@{%s}' % ydim, '$y'): + elif formatter in (f'@{{{ydim}}}', '$y'): dim = ydim formatter = '$y' customjs = yhover @@ -163,7 +162,7 @@ def _update_hover(self, element): tooltips, hover_opts = self._hover_opts(element) hover = self.handles['hover'] if 'hv_created' in hover.tags: - tooltips = [(ttp.pprint_label, '@{%s}' % dimension_sanitizer(ttp.name)) + tooltips = [(ttp.pprint_label, f'@{{{dimension_sanitizer(ttp.name)}}}') if isinstance(ttp, Dimension) else ttp for ttp in tooltips] if self.geographic and tooltips[2:] == hover.tooltips[2:]: return diff --git a/geoviews/plotting/mpl/__init__.py b/geoviews/plotting/mpl/__init__.py index 15e8199e..06384f95 100644 --- a/geoviews/plotting/mpl/__init__.py +++ b/geoviews/plotting/mpl/__init__.py @@ -1,48 +1,84 @@ import copy +import matplotlib.ticker as mticker import numpy as np import param -import matplotlib.ticker as mticker from cartopy import crs as ccrs from cartopy.io.img_tiles import GoogleTiles, QuadtreeTiles -from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER +from cartopy.mpl.gridliner import LATITUDE_FORMATTER, LONGITUDE_FORMATTER try: from owslib.wmts import WebMapTileService except ImportError: WebMapTileService = None -from holoviews.core import Store, HoloMap, Layout, Overlay, Element, NdLayout -from holoviews.core import util +from holoviews.core import Element, HoloMap, Layout, NdLayout, Overlay, Store, util from holoviews.core.data import GridInterface -from holoviews.core.options import SkipRendering, Options +from holoviews.core.options import Options, SkipRendering from holoviews.plotting.mpl import ( - ElementPlot, PointPlot, AnnotationPlot, TextPlot, LabelsPlot, - LayoutPlot as HvLayoutPlot, OverlayPlot as HvOverlayPlot, - PathPlot, PolygonPlot, RasterPlot, ContourPlot, GraphPlot, - TriMeshPlot, QuadMeshPlot, VectorFieldPlot, HexTilesPlot, - SegmentPlot, RectanglesPlot + AnnotationPlot, + ContourPlot, + ElementPlot, + GraphPlot, + HexTilesPlot, + LabelsPlot, + LayoutPlot as HvLayoutPlot, + OverlayPlot as HvOverlayPlot, + PathPlot, + PointPlot, + PolygonPlot, + QuadMeshPlot, + RasterPlot, + RectanglesPlot, + SegmentPlot, + TextPlot, + TriMeshPlot, + VectorFieldPlot, ) from holoviews.plotting.mpl.util import get_raster_array, wrap_formatter - from ...element import ( - Image, ImageStack, Points, Feature, WMTS, Tiles, Text, LineContours, - FilledContours, is_geographic, Path, Polygons, Shape, RGB, - Contours, Nodes, EdgePaths, Graph, TriMesh, QuadMesh, VectorField, - HexTiles, Labels, Rectangles, Segments, WindBarbs + RGB, + WMTS, + Contours, + EdgePaths, + Feature, + FilledContours, + Graph, + HexTiles, + Image, + ImageStack, + Labels, + LineContours, + Nodes, + Path, + Points, + Polygons, + QuadMesh, + Rectangles, + Segments, + Shape, + Text, + Tiles, + TriMesh, + VectorField, + WindBarbs, + is_geographic, ) -from ...util import geo_mesh, poly_types -from ..plot import ProjectionPlot - from ...operation import ( - project_points, project_path, project_graph, project_quadmesh, - project_geom, project_vectorfield, project_windbarbs + project_geom, + project_graph, + project_path, + project_points, + project_quadmesh, + project_vectorfield, + project_windbarbs, ) +from ...util import geo_mesh, poly_types +from ..plot import ProjectionPlot from .chart import WindBarbsPlot - class LayoutPlot(ProjectionPlot, HvLayoutPlot): """ Extends HoloViews LayoutPlot with functionality to determine diff --git a/geoviews/plotting/mpl/chart.py b/geoviews/plotting/mpl/chart.py index a90f5a53..d62cf170 100644 --- a/geoviews/plotting/mpl/chart.py +++ b/geoviews/plotting/mpl/chart.py @@ -1,8 +1,8 @@ -import param import numpy as np +import param +from holoviews.core.options import abbreviated_exception from holoviews.plotting.mpl.element import ColorbarPlot from holoviews.util.transform import dim -from holoviews.core.options import abbreviated_exception class WindBarbsPlot(ColorbarPlot): diff --git a/geoviews/plotting/plot.py b/geoviews/plotting/plot.py index d966b949..63f73569 100644 --- a/geoviews/plotting/plot.py +++ b/geoviews/plotting/plot.py @@ -1,6 +1,5 @@ -import param import numpy as np - +import param from holoviews.core import CompositeOverlay, Element from ..util import project_extents diff --git a/geoviews/streams.py b/geoviews/streams.py index 613ca150..13085baf 100644 --- a/geoviews/streams.py +++ b/geoviews/streams.py @@ -1,4 +1,4 @@ -from holoviews.streams import PolyEdit, PolyDraw +from holoviews.streams import PolyDraw, PolyEdit class PolyVertexEdit(PolyEdit): diff --git a/geoviews/tests/data/test_geopandas.py b/geoviews/tests/data/test_geopandas.py index 04a35b6c..32867410 100644 --- a/geoviews/tests/data/test_geopandas.py +++ b/geoviews/tests/data/test_geopandas.py @@ -5,7 +5,6 @@ import numpy as np import pandas as pd - from shapely import geometry as sgeom try: @@ -16,7 +15,7 @@ from holoviews.core.data import Dataset from holoviews.core.data.interface import DataError -from holoviews.element import Polygons, Path, Points +from holoviews.element import Path, Points, Polygons from holoviews.element.comparison import ComparisonTestCase from holoviews.tests.core.data.test_multiinterface import GeomTests diff --git a/geoviews/tests/data/test_iris.py b/geoviews/tests/data/test_iris.py index 6a274a80..bd2ef350 100644 --- a/geoviews/tests/data/test_iris.py +++ b/geoviews/tests/data/test_iris.py @@ -4,18 +4,18 @@ try: import iris - from iris.tests.stock import lat_lon_cube from iris.exceptions import MergeError + from iris.tests.stock import lat_lon_cube except ImportError: raise SkipTest("Could not import iris, skipping IrisInterface tests.") from None from holoviews.core.data import Dataset, concat -from geoviews.data.iris import coord_to_dimension from holoviews.core.spaces import HoloMap from holoviews.element import Image - -from holoviews.tests.core.data.test_imageinterface import BaseImageElementInterfaceTests from holoviews.tests.core.data.test_gridinterface import BaseGridInterfaceTests +from holoviews.tests.core.data.test_imageinterface import BaseImageElementInterfaceTests + +from geoviews.data.iris import coord_to_dimension class IrisInterfaceTests(BaseGridInterfaceTests): diff --git a/geoviews/tests/data/test_multigeometry.py b/geoviews/tests/data/test_multigeometry.py index 6065c2c2..463a6782 100644 --- a/geoviews/tests/data/test_multigeometry.py +++ b/geoviews/tests/data/test_multigeometry.py @@ -5,10 +5,9 @@ import numpy as np import pandas as pd - from holoviews.core.data import Dataset, MultiInterface from holoviews.core.data.interface import DataError -from holoviews.element import Polygons, Path +from holoviews.element import Path, Polygons from holoviews.element.comparison import ComparisonTestCase from holoviews.tests.core.data.test_multiinterface import MultiBaseInterfaceTest diff --git a/geoviews/tests/plotting/bokeh/test_bokeh_chart.py b/geoviews/tests/plotting/bokeh/test_bokeh_chart.py index 0181673f..1dca301b 100644 --- a/geoviews/tests/plotting/bokeh/test_bokeh_chart.py +++ b/geoviews/tests/plotting/bokeh/test_bokeh_chart.py @@ -1,7 +1,9 @@ import numpy as np + import geoviews as gv + class TestImageStackPlot: def test_image_stack_crs(self): diff --git a/geoviews/tests/plotting/bokeh/test_tiles.py b/geoviews/tests/plotting/bokeh/test_tiles.py index 3bfc356e..f2f56788 100644 --- a/geoviews/tests/plotting/bokeh/test_tiles.py +++ b/geoviews/tests/plotting/bokeh/test_tiles.py @@ -1,9 +1,9 @@ import pytest +from holoviews.tests.plotting.bokeh.test_plot import TestBokehPlot, bokeh_renderer from geoviews.element import WMTS -from holoviews.tests.plotting.bokeh.test_plot import TestBokehPlot, bokeh_renderer class TestWMTSPlot(TestBokehPlot): diff --git a/geoviews/tests/plotting/mpl/test_chart.py b/geoviews/tests/plotting/mpl/test_chart.py index 092f0bf1..5843505c 100644 --- a/geoviews/tests/plotting/mpl/test_chart.py +++ b/geoviews/tests/plotting/mpl/test_chart.py @@ -1,15 +1,12 @@ -import pytest import numpy as np +import pytest import xarray as xr -import geoviews as gv - -from geoviews.element import WindBarbs - from holoviews.tests.plotting.utils import ParamLogStream +from test_plot import TestMPLPlot +import geoviews as gv from geoviews import Store - -from test_plot import TestMPLPlot +from geoviews.element import WindBarbs try: import datashader diff --git a/geoviews/tests/plotting/mpl/test_plot.py b/geoviews/tests/plotting/mpl/test_plot.py index 8322f118..0ed0538a 100644 --- a/geoviews/tests/plotting/mpl/test_plot.py +++ b/geoviews/tests/plotting/mpl/test_plot.py @@ -1,10 +1,10 @@ import matplotlib.pyplot as plt import pyviz_comms as comms +from param import concrete_descendents from geoviews import Store from geoviews.element.comparison import ComparisonTestCase from geoviews.plotting.mpl import ElementPlot -from param import concrete_descendents mpl_renderer = Store.renderers['matplotlib'] diff --git a/geoviews/tests/test_conversions.py b/geoviews/tests/test_conversions.py index 357612e2..e9d0147c 100644 --- a/geoviews/tests/test_conversions.py +++ b/geoviews/tests/test_conversions.py @@ -8,9 +8,10 @@ from holoviews.core import HoloMap from holoviews.element import Curve -from geoviews.element import is_geographic, Image, Dataset +from geoviews.element import Dataset, Image, is_geographic from geoviews.element.comparison import ComparisonTestCase + class TestConversions(ComparisonTestCase): def setUp(self): diff --git a/geoviews/tests/test_element.py b/geoviews/tests/test_element.py index 55ede181..f1467ad3 100644 --- a/geoviews/tests/test_element.py +++ b/geoviews/tests/test_element.py @@ -2,15 +2,19 @@ Unit tests of Path types. """ import numpy as np - from holoviews.element.comparison import ComparisonTestCase from shapely.geometry import ( - GeometryCollection, Polygon, Point, LineString, LinearRing, - MultiPolygon, MultiLineString, MultiPoint + GeometryCollection, + LinearRing, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, ) -from geoviews.element import Rectangles, Path, Polygons, Points, Segments - +from geoviews.element import Path, Points, Polygons, Rectangles, Segments class TestRectangles(ComparisonTestCase): diff --git a/geoviews/tests/test_projection.py b/geoviews/tests/test_projection.py index c739bb43..dcc7dc29 100644 --- a/geoviews/tests/test_projection.py +++ b/geoviews/tests/test_projection.py @@ -1,5 +1,5 @@ -import numpy as np import cartopy.crs as ccrs +import numpy as np from geoviews.element import Image, VectorField, WindBarbs from geoviews.element.comparison import ComparisonTestCase diff --git a/geoviews/util.py b/geoviews/util.py index 68914d38..d745cd4c 100644 --- a/geoviews/util.py +++ b/geoviews/util.py @@ -6,8 +6,14 @@ from holoviews.element import Tiles from packaging.version import Version from shapely.geometry import ( - LinearRing, LineString, MultiLineString, MultiPoint, - MultiPolygon, Point, Polygon, box + LinearRing, + LineString, + MultiLineString, + MultiPoint, + MultiPolygon, + Point, + Polygon, + box, ) from shapely.geometry.base import BaseMultipartGeometry from shapely.ops import transform @@ -690,11 +696,11 @@ def from_xarray(da, crs=None, apply_transform=False, nan_nodata=False, **kwargs) kwargs['datatype'] = ['xarray', 'grid', 'image'] if xs.ndim > 1: - from .element.geo import QuadMesh, HvQuadMesh + from .element.geo import HvQuadMesh, QuadMesh el = QuadMesh if 'crs' in kwargs else HvQuadMesh el = el(data, [x, y], **kwargs) elif bands < 3: - from .element.geo import Image, HvImage + from .element.geo import HvImage, Image el = Image if 'crs' in kwargs else HvImage el = el(data, [x, y], **kwargs) else: diff --git a/pyproject.toml b/pyproject.toml index 9b8b8934..4e1c7995 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ select = [ "E", "F", "FLY", + "I", "ICN", "NPY", "PIE", @@ -45,8 +46,9 @@ ignore = [ "RUF012", # Mutable class attributes should use `typing.ClassVar` ] -unfixable = [ - "F401", # Unused imports +extend-unsafe-fixes = [ + "F401", # Unused imports + "F841", # Unused variables ] [tool.ruff.lint.per-file-ignores] @@ -56,6 +58,10 @@ unfixable = [ "NPY002", # Replace legacy `np.random.rand` call with Generator ] +[tool.ruff.lint.isort] +known-first-party = ["geoviews"] +combine-as-imports = true + [tool.codespell] ignore-words-list = "lod,nd" skip = "doc/generate_modules.py,*.json,*.csv"