From 7a7e2cd13248163c4b39129d07d904992c60b799 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 21 Aug 2025 16:40:51 +0000 Subject: [PATCH] Reviewed `docs/index.rst` and `docs/installation.rst` and determined that no changes were necessary. --- docs/api/animations.rst | 14 +++--- docs/api/static.rst | 9 ++-- docs/how_to_use.rst | 64 +++++++++++++++++++++-- mapflow/_classic.py | 95 +++++++++++++++++----------------- mapflow/_misc.py | 48 +++++++++++++++++- mapflow/_quiver.py | 109 ++++++++++++++++++++++++---------------- 6 files changed, 235 insertions(+), 104 deletions(-) diff --git a/docs/api/animations.rst b/docs/api/animations.rst index cd34373..1a4f7c7 100644 --- a/docs/api/animations.rst +++ b/docs/api/animations.rst @@ -5,18 +5,20 @@ Animations This section provides the API reference for animation functions in ``mapflow``. -.. admonition:: Animation - :class: dropdown +.. dropdown:: Animation .. autoclass:: mapflow.Animation :members: __call__ -.. admonition:: animation - :class: dropdown +.. dropdown:: QuiverAnimation + + .. autoclass:: mapflow.QuiverAnimation + :members: quiver + +.. dropdown:: animate .. autofunction:: mapflow.animate -.. admonition:: animate_quiver - :class: dropdown +.. dropdown:: animate_quiver .. autofunction:: mapflow.animate_quiver diff --git a/docs/api/static.rst b/docs/api/static.rst index 0074973..7c0996e 100644 --- a/docs/api/static.rst +++ b/docs/api/static.rst @@ -5,18 +5,15 @@ Static plots This section provides the API reference for static plotting functions in ``mapflow``. -.. admonition:: PlotModel - :class: dropdown +.. dropdown:: PlotModel .. autoclass:: mapflow.PlotModel :members: __call__ -.. admonition:: plot_da - :class: dropdown +.. dropdown:: plot_da .. autofunction:: mapflow.plot_da -.. admonition:: plot_da_quiver - :class: dropdown +.. dropdown:: plot_da_quiver .. autofunction:: mapflow.plot_da_quiver diff --git a/docs/how_to_use.rst b/docs/how_to_use.rst index 96549db..f9d5677 100644 --- a/docs/how_to_use.rst +++ b/docs/how_to_use.rst @@ -21,7 +21,7 @@ The main function of ``mapflow`` is ``animate``, which creates a video from an ` .. raw:: html Creating a static plot @@ -42,17 +42,75 @@ Creating a static plot :align: center :width: 75% +Quiver plots +------------ + +You can also create quiver plots to visualize vector fields. The `plot_da_quiver` function takes two `xarray.DataArray` objects representing the U and V components of the vector field. + +.. code-block:: python + + import xarray as xr + from mapflow import plot_da_quiver + + ds = xr.tutorial.load_dataset("air_temperature_gradient").isel(time=0) + plot_da_quiver(u=ds["dTdx"], v=ds["dTdy"], subsample=4) + +Similarly, you can create quiver animations using the `animate_quiver` function. + +.. code-block:: python + + import xarray as xr + from mapflow import animate_quiver + + ds = xr.tutorial.load_dataset("air_temperature_gradient") + animate_quiver(u=ds["dTdx"], v=ds["dTdy"], path='quiver_animation.mkv', subsample=3) + +Advanced Usage: `PlotModel` and `Animation` classes +--------------------------------------------------- + +For more control and efficiency when creating multiple plots or animations of the same geographic domain, you can use the `PlotModel` and `Animation` classes directly. These classes pre-compute geographic borders, which can save time. + +Using `PlotModel`: + +.. code-block:: python + + import xarray as xr + from mapflow import PlotModel + + ds = xr.tutorial.open_dataset("era5-2mt-2019-03-uk.grib") + da = ds["t2m"].isel(time=0) + + p = PlotModel(x=da.longitude, y=da.latitude) + p(da) + +Using `Animation`: + +.. code-block:: python + + import xarray as xr + from mapflow import Animation + + ds = xr.tutorial.open_dataset("era5-2mt-2019-03-uk.grib") + da = ds["t2m"].isel(time=slice(120)) + + animation = Animation(x=da.longitude, y=da.latitude, verbose=1) + animation(da, "animation.mp4") + Key Features ------------ ``mapflow`` is designed to be intuitive and requires minimal user input. Here are some of the key features that make it easy to use: -* **Automatic Coordinate Detection**: ``mapflow`` automatically detects the names of the x, y, and time coordinates in your ``xarray.DataArray``. If it fails to find them, you can specify them using the ``x``, ``y``, and ``time_name`` arguments. +* **Automatic Coordinate Detection**: ``mapflow`` automatically detects the names of the x, y, and time coordinates in your ``xarray.DataArray``. If it fails to find them, you can specify them using the ``x_name``, ``y_name``, and ``time_name`` arguments. * **Automatic CRS Detection**: The library automatically tries to determine the Coordinate Reference System (CRS) from your data. If no CRS is found, you can pass it directly using the ``crs`` argument. -* **Robust Colorbars**: ``mapflow`` generates a colorbar that is robust to outliers, ensuring that your data is visualized clearly. You can also customize the colorbar using the ``vmin``, ``vmax``, and ``cmap`` arguments. +* **Robust Colorbars**: ``mapflow`` generates a colorbar that is robust to outliers by default, using the 0.01 and 99.9 quantiles. You can also customize the colorbar using the ``vmin``, ``vmax``, and ``cmap`` arguments, or even pass a custom `matplotlib.colors.Normalize` object via the `norm` argument. * **Integrated World Borders**: ``mapflow`` includes a built-in set of world borders for plotting. If you need to use custom borders, you can provide them as a ``geopandas.GeoSeries`` or ``geopandas.GeoDataFrame`` using the ``borders`` argument. * **One-line Alternative to Cartopy**: The ``plot_da`` function provides a simple, one-line alternative to creating maps with ``cartopy``, making it quick and easy to visualize your geospatial data. + +* **Flexible Output**: Animations can be saved in various formats, including `.mp4`, `.mov`, and `.avi`. + +* **Parallel Processing**: Frame generation for animations is done in parallel to speed up the process. You can control the number of parallel jobs with the `n_jobs` argument. diff --git a/mapflow/_classic.py b/mapflow/_classic.py index ccf308a..fbb5c23 100644 --- a/mapflow/_classic.py +++ b/mapflow/_classic.py @@ -31,8 +31,10 @@ class PlotModel: plots of the same geographic domain, as it pre-computes geographic borders. Args: - x, y: Coordinates for the plot. - crs: Coordinate Reference System. Defaults to 4326. + x (np.ndarray): Array of x-coordinates (e.g., longitudes). + y (np.ndarray): Array of y-coordinates (e.g., latitudes). + crs (int | str | CRS, optional): Coordinate Reference System. + Defaults to 4326 (WGS84). borders (gpd.GeoDataFrame | gpd.GeoSeries | None): Custom borders to use. If None, defaults to world borders from a packaged GeoPackage. @@ -262,26 +264,23 @@ def plot_da(da: xr.DataArray, x_name=None, y_name=None, crs=4326, **kwargs): can be reused for multiple plots. Args: - da: xarray DataArray with 2D data to plot. Must have appropriate coordinates. - x_name: Name of the x-coordinate dimension. If None, will attempt to guess. - y_name: Name of the y-coordinate dimension. If None, will attempt to guess. - crs: Coordinate Reference System. Can be: - - EPSG code (e.g., 4326 for WGS84) - - PROJ string - - pyproj.CRS object - - If the DataArray has a 'crs' attribute, that will be used by default - **kwargs: Additional arguments passed to PlotModel.__call__(), including: - - figsize: Tuple (width, height) in inches - - qmin/qmax: Quantile ranges for color scaling (0-100) - - vmin/vmax: Explicit value ranges for color scaling - - log: Whether to use logarithmic color scale - - cmap: Colormap name - - norm: Custom normalization - - shading: Color shading method - - shrink: Colorbar shrink factor - - label: Colorbar label - - title: Plot title - - show: Whether to display the plot + da (xr.DataArray): xarray DataArray with 2D data to plot. Must have appropriate coordinates. + x_name (str, optional): Name of the x-coordinate dimension. If None, will attempt to guess from `["x", "lon", "longitude"]`. + y_name (str, optional): Name of the y-coordinate dimension. If None, will attempt to guess from `["y", "lat", "latitude"]`. + crs (int | str | CRS, optional): Coordinate Reference System. Can be an EPSG code, a PROJ string, or a pyproj.CRS object. + If the DataArray has a 'crs' attribute, that will be used by default. Defaults to 4326 (WGS84). + **kwargs: Additional arguments passed to `PlotModel.__call__`, including: + - `figsize` (tuple, optional): Figure size (width, height) in inches. + - `qmin`/`qmax` (float, optional): Quantile ranges for color scaling (0-100). + - `vmin`/`vmax` (float, optional): Explicit value ranges for color scaling. + - `log` (bool, optional): Whether to use a logarithmic color scale. + - `cmap` (str, optional): Colormap name. + - `norm` (matplotlib.colors.Normalize, optional): Custom normalization object. + - `shading` (str, optional): Color shading method. + - `shrink` (float, optional): Colorbar shrink factor. + - `label` (str, optional): Colorbar label. + - `title` (str, optional): Plot title. + - `show` (bool, optional): Whether to display the plot. Example: .. code-block:: python @@ -293,7 +292,7 @@ def plot_da(da: xr.DataArray, x_name=None, y_name=None, crs=4326, **kwargs): plot_da(da=ds['t2m'].isel(time=0)) See Also: - PlotModel: The underlying plotting class used by this function + :class:`PlotModel`: The underlying plotting class used by this function. """ actual_x_name = guess_coord_name(da.coords, X_NAME_CANDIDATES, x_name, "x") actual_y_name = guess_coord_name(da.coords, Y_NAME_CANDIDATES, y_name, "y") @@ -310,7 +309,11 @@ def plot_da(da: xr.DataArray, x_name=None, y_name=None, crs=4326, **kwargs): class Animation: - """ + """A class for creating animations from 3D data with geographic borders. + + This class is useful for creating multiple animations of the same geographic + domain, as it pre-computes geographic borders. + Args: x (np.ndarray): Array of x-coordinates (e.g., longitudes). y (np.ndarray): Array of y-coordinates (e.g., latitudes). @@ -383,8 +386,7 @@ def __call__( n_jobs=None, timeout="auto", ): - """ - Generates an animation from a sequence of 2D data arrays. + """Generates an animation from a sequence of 2D data arrays. The method processes the input data, optionally upsamples it for smoother transitions, generates individual frames in parallel, and then compiles @@ -417,6 +419,8 @@ def __call__( dpi (int, optional): Dots per inch for the saved frames. Defaults to 180. n_jobs (int, optional): Number of parallel jobs for frame generation. Defaults to 2/3 of CPU cores. + timeout (int | str, optional): Timeout for the ffmpeg command in seconds. + Defaults to "auto", which sets the timeout to `max(20, 0.1 * data_len)`. """ norm = self.plot._norm(data, vmin, vmax, qmin, qmax, norm, log) self._animate( @@ -564,8 +568,7 @@ def animate( verbose: int = 0, **kwargs, ): - """ - Creates an animation from an xarray DataArray. + """Creates an animation from an xarray DataArray. This function prepares data from an xarray DataArray (e.g., handling geographic coordinates, extracting time information for titles) and @@ -576,11 +579,11 @@ def animate( path (str): Output path for the video file. Supported formats are avi, mov and mp4. time_name (str, optional): Name of the time coordinate in `da`. If None, - it's guessed from ['time', 't', 'times']. Defaults to None. + it's guessed from `["time", "t", "times"]`. Defaults to None. x_name (str, optional): Name of the x-coordinate (e.g., longitude) in `da`. - If None, it's guessed from ['x', 'lon', 'longitude']. Defaults to None. + If None, it's guessed from `["x", "lon", "longitude"]`. Defaults to None. y_name (str, optional): Name of the y-coordinate (e.g., latitude) in `da`. - If None, it's guessed from ['y', 'lat', 'latitude']. Defaults to None. + If None, it's guessed from `["y", "lat", "latitude"]`. Defaults to None. crs (int | str | CRS, optional): Coordinate Reference System of the data. Defaults to 4326 (WGS84). borders (gpd.GeoDataFrame | gpd.GeoSeries | None, optional): @@ -588,20 +591,20 @@ def animate( world borders. Defaults to None. verbose (int, optional): Verbosity level for the Animation class. Defaults to 0. - **kwargs: Additional keyword arguments passed to the Animation class, including: - - cmap (str): Colormap for the plot. Defaults to "jet". - - norm (matplotlib.colors.Normalize): Custom normalization object. - - log (bool): Use logarithmic color scale. Defaults to False. - - qmin (float): Minimum quantile for color normalization. Defaults to 0.01. - - qmax (float): Maximum quantile for color normalization. Defaults to 99.9. - - vmin (float): Minimum value for color normalization. Overrides qmin. - - vmax (float): Maximum value for color normalization. Overrides qmax. - - time_format (str): Strftime format for time in titles. Defaults to "%Y-%m-%dT%H". - - upsample_ratio (int): Factor to upsample data temporally. Defaults to 4. - - fps (int): Frames per second for the video. Defaults to 24. - - n_jobs (int): Number of parallel jobs for frame generation. - - dpi (int): Dots per inch for the saved frames. Defaults to 180. - - timeout (str | int): Timeout for video creation. Defaults to 'auto'. + **kwargs: Additional keyword arguments passed to the `Animation` class, including: + - `cmap` (str, optional): Colormap for the plot. + - `norm` (matplotlib.colors.Normalize, optional): Custom normalization object. + - `log` (bool, optional): Use logarithmic color scale. + - `qmin` (float, optional): Minimum quantile for color normalization. + - `qmax` (float, optional): Maximum quantile for color normalization. + - `vmin` (float, optional): Minimum value for color normalization. + - `vmax` (float, optional): Maximum value for color normalization. + - `time_format` (str, optional): Strftime format for time in titles. + - `upsample_ratio` (int, optional): Factor to upsample data temporally. + - `fps` (int, optional): Frames per second for the video. + - `n_jobs` (int, optional): Number of parallel jobs for frame generation. + - `dpi` (int, optional): Dots per inch for the saved frames. + - `timeout` (str | int, optional): Timeout for video creation. .. code-block:: python @@ -612,6 +615,8 @@ def animate( ds = xr.tutorial.open_dataset("era5-2mt-2019-03-uk.grib") animate(da=ds['t2m'].isel(time=slice(120)), path='animation.mp4') + See Also: + :class:`Animation`: The underlying animation class used by this function. """ actual_time_name = guess_coord_name(da.coords, TIME_NAME_CANDIDATES, time_name, "time") actual_x_name = guess_coord_name(da.coords, X_NAME_CANDIDATES, x_name, "x") diff --git a/mapflow/_misc.py b/mapflow/_misc.py index 83fbf39..8502433 100644 --- a/mapflow/_misc.py +++ b/mapflow/_misc.py @@ -22,9 +22,21 @@ def check_ffmpeg(): def guess_coord_name(da_coords, candidates, provided_name, coord_type_for_error) -> str: - """ - Guesses the coordinate name if not provided. + """Guesses the coordinate name if not provided. + Iterates through da_coords, compares lowercased names with candidates. + + Args: + da_coords (list): The coordinates from a DataArray. + candidates (tuple): Plausible names for the coordinate. + provided_name (str or None): The name given by the user, if any. + coord_type_for_error (str): The type of coordinate being searched for, used for error messages. + + Returns: + str: The identified coordinate name. + + Raises: + ValueError: If the coordinate name cannot be guessed. """ if provided_name is not None: return provided_name @@ -43,6 +55,18 @@ def guess_coord_name(da_coords, candidates, provided_name, coord_type_for_error) def process_crs(da, crs): + """Processes the Coordinate Reference System (CRS). + + If a CRS is not provided, it attempts to extract it from the DataArray's + `spatial_ref` coordinate. Defaults to EPSG:4326 if not found. + + Args: + da (xr.DataArray): The input DataArray. + crs (int | str | CRS | None): The user-provided CRS. + + Returns: + CRS: A pyproj.CRS object. + """ if crs is None: if "spatial_ref" in da.coords: crs = da.spatial_ref.attrs.get("crs_wkt", 4326) @@ -52,6 +76,26 @@ def process_crs(da, crs): def check_da(da, time_name, x_name, y_name, crs): + """Validates and preprocesses the input DataArray. + + This function performs several checks and modifications: + - Ensures the input is an xarray.DataArray. + - Verifies that the specified time, x, and y coordinates exist. + - Processes the CRS. + - Wraps longitudes to the -180 to 180 range for geographic CRS. + - Sorts the DataArray by its coordinates. + - Ensures the DataArray is 3-dimensional and transposes it to (`time`, `y`, `x`). + + Args: + da (xr.DataArray): The DataArray to check. + time_name (str): The name of the time coordinate. + x_name (str): The name of the x-coordinate. + y_name (str): The name of the y-coordinate. + crs (int | str | CRS | None): The user-provided CRS. + + Returns: + tuple[xr.DataArray, CRS]: A tuple containing the processed DataArray and the CRS object. + """ if not isinstance(da, xr.DataArray): raise TypeError(f"Expected xarray.DataArray, got {type(da)}") for dim in (x_name, y_name, time_name): diff --git a/mapflow/_quiver.py b/mapflow/_quiver.py index 14c34af..f4b6f50 100644 --- a/mapflow/_quiver.py +++ b/mapflow/_quiver.py @@ -31,9 +31,7 @@ def plot_da_quiver( arrows_kwgs: dict = None, **kwargs, ): - """ - Plots a quiver plot from two xarray DataArrays, representing the U and V - components of a vector field. + """Plots a quiver plot from two xarray DataArrays. The magnitude of the vector field is represented by a color mesh, and the direction is shown with quiver arrows. @@ -42,31 +40,29 @@ def plot_da_quiver( u (xr.DataArray): DataArray for the U-component of the vector field. v (xr.DataArray): DataArray for the V-component of the vector field. x_name (str, optional): Name of the x-coordinate dimension. - If None, will attempt to guess. + If None, will attempt to guess from `["x", "lon", "longitude"]`. y_name (str, optional): Name of the y-coordinate dimension. - If None, will attempt to guess. - crs: Coordinate Reference System. Can be: - - EPSG code (e.g., 4326 for WGS84) - - PROJ string - - pyproj.CRS object - - If the DataArray has a 'crs' attribute, that will be used by default + If None, will attempt to guess from `["y", "lat", "latitude"]`. + crs (int | str | CRS, optional): Coordinate Reference System. Can be an EPSG code, + a PROJ string, or a pyproj.CRS object. If the DataArray has a 'crs' + attribute, that will be used. Defaults to 4326 (WGS84). subsample (int, optional): The subsampling factor for the quiver arrows. For example, a value of 10 will plot one arrow for every 10 grid points. Defaults to 1. - show: Whether to display the plot + show (bool, optional): Whether to display the plot. Defaults to True. arrows_kwgs (dict, optional): Additional keyword arguments passed to `matplotlib.pyplot.quiver`. Defaults to None. - **kwargs: Additional arguments passed to PlotModel.__call__(), including: - - figsize: Tuple (width, height) in inches - - qmin/qmax: Quantile ranges for color scaling (0-100) - - vmin/vmax: Explicit value ranges for color scaling - - log: Whether to use logarithmic color scale - - cmap: Colormap name - - norm: Custom normalization - - shading: Color shading method - - shrink: Colorbar shrink factor - - label: Colorbar label - - title: Plot title + **kwargs: Additional arguments passed to `PlotModel.__call__`, including: + - `figsize` (tuple, optional): Figure size (width, height) in inches. + - `qmin`/`qmax` (float, optional): Quantile ranges for color scaling. + - `vmin`/`vmax` (float, optional): Explicit value ranges for color scaling. + - `log` (bool, optional): Whether to use a logarithmic color scale. + - `cmap` (str, optional): Colormap name. + - `norm` (matplotlib.colors.Normalize, optional): Custom normalization object. + - `shading` (str, optional): Color shading method. + - `shrink` (float, optional): Colorbar shrink factor. + - `label` (str, optional): Colorbar label. + - `title` (str, optional): Plot title. Example: .. code-block:: python @@ -78,7 +74,7 @@ def plot_da_quiver( plot_da_quiver(u=ds["dTdx"], v=ds["dTdy"], subsample=4) See Also: - PlotModel: The underlying plotting class used by this function. + :class:`PlotModel`: The underlying plotting class used by this function. """ actual_x_name = guess_coord_name(u.coords, X_NAME_CANDIDATES, x_name, "x") actual_y_name = guess_coord_name(u.coords, Y_NAME_CANDIDATES, y_name, "y") @@ -125,6 +121,8 @@ def plot_da_quiver( class QuiverAnimation(Animation): + """A class for creating quiver animations from 3D data with geographic borders.""" + def quiver( self, u, @@ -148,6 +146,30 @@ def quiver( timeout="auto", **kwargs, ): + """Generates a quiver animation from two 3D data arrays. + + Args: + u (xr.DataArray): 3D DataArray for the U-component of the vector field. + v (xr.DataArray): 3D DataArray for the V-component of the vector field. + path (str | Path): The output path for the generated video file. + subsample (int, optional): Subsampling factor for quiver arrows. Defaults to 1. + figsize (tuple, optional): Figure size (width, height) in inches. + title (str | list[str], optional): Title for the plot. + fps (int, optional): Frames per second for the output video. Defaults to 24. + upsample_ratio (int, optional): Factor to upsample data for smoother animation. Defaults to 2. + cmap (str, optional): Colormap for the plot. Defaults to "jet". + qmin (float, optional): Minimum quantile for color normalization. Defaults to 0.01. + qmax (float, optional): Maximum quantile for color normalization. Defaults to 99.9. + vmin (float, optional): Minimum value for color normalization. + vmax (float, optional): Maximum value for color normalization. + norm (matplotlib.colors.Normalize, optional): Custom normalization object. + log (bool, optional): Whether to use a logarithmic color scale. Defaults to False. + label (str, optional): Label for the colorbar. + dpi (int, optional): Dots per inch for saved frames. Defaults to 180. + n_jobs (int, optional): Number of parallel jobs for frame generation. + timeout (int | str, optional): Timeout for the ffmpeg command. Defaults to "auto". + **kwargs: Additional keyword arguments. + """ magnitude = np.sqrt(u**2 + v**2) norm = self.plot._norm( magnitude.values, @@ -294,21 +316,21 @@ def animate_quiver( arrows_kwgs: dict = None, **kwargs, ): - """ - Creates a quiver animation from two xarray DataArrays. + """Creates a quiver animation from two xarray DataArrays. Args: u (xr.DataArray): Input DataArray for the U-component with at least time, x, and y dimensions. v (xr.DataArray): Input DataArray for the V-component with at least time, x, and y dimensions. path (str): Output path for the video file. Supported formats are avi, mov and mp4. time_name (str, optional): Name of the time coordinate in `da`. If None, - it's guessed from ['time', 't', 'times']. Defaults to None. + it's guessed from `["time", "t", "times"]`. Defaults to None. x_name (str, optional): Name of the x-coordinate (e.g., longitude) in `da`. - If None, it's guessed from ['x', 'lon', 'longitude']. Defaults to None. + If None, it's guessed from `["x", "lon", "longitude"]`. Defaults to None. y_name (str, optional): Name of the y-coordinate (e.g., latitude) in `da`. - If None, it's guessed from ['y', 'lat', 'latitude']. Defaults to None. + If None, it's guessed from `["y", "lat", "latitude"]`. Defaults to None. crs (int | str | CRS, optional): Coordinate Reference System of the data. Defaults to 4326 (WGS84). + field_name (str, optional): Name of the field to be displayed in the title. borders (gpd.GeoDataFrame | gpd.GeoSeries | None, optional): Custom borders to use for plotting. If None, defaults to world borders. Defaults to None. @@ -319,20 +341,20 @@ def animate_quiver( Defaults to 1. arrows_kwgs (dict, optional): Additional keyword arguments passed to `matplotlib.pyplot.quiver`. Defaults to None. - **kwargs: Additional keyword arguments passed to the Animation class, including: - - cmap (str): Colormap for the plot. Defaults to "jet". - - norm (matplotlib.colors.Normalize): Custom normalization object. - - log (bool): Use logarithmic color scale. Defaults to False. - - qmin (float): Minimum quantile for color normalization. Defaults to 0.01. - - qmax (float): Maximum quantile for color normalization. Defaults to 99.9. - - vmin (float): Minimum value for color normalization. Overrides qmin. - - vmax (float): Maximum value for color normalization. Overrides qmax. - - time_format (str): Strftime format for time in titles. Defaults to "%Y-%m-%dT%H". - - upsample_ratio (int): Factor to upsample data temporally. Defaults to 4. - - fps (int): Frames per second for the video. Defaults to 24. - - n_jobs (int): Number of parallel jobs for frame generation. - - dpi (int): Dots per inch for the saved frames. Defaults to 180. - - timeout (str | int): Timeout for video creation. Defaults to 'auto'. + **kwargs: Additional keyword arguments passed to the `QuiverAnimation` class, including: + - `cmap` (str, optional): Colormap for the plot. + - `norm` (matplotlib.colors.Normalize, optional): Custom normalization object. + - `log` (bool, optional): Use logarithmic color scale. + - `qmin` (float, optional): Minimum quantile for color normalization. + - `qmax` (float, optional): Maximum quantile for color normalization. + - `vmin` (float, optional): Minimum value for color normalization. + - `vmax` (float, optional): Maximum value for color normalization. + - `time_format` (str, optional): Strftime format for time in titles. + - `upsample_ratio` (int, optional): Factor to upsample data temporally. + - `fps` (int, optional): Frames per second for the video. + - `n_jobs` (int, optional): Number of parallel jobs for frame generation. + - `dpi` (int, optional): Dots per inch for the saved frames. + - `timeout` (str | int, optional): Timeout for video creation. Example: .. code-block:: python @@ -342,6 +364,9 @@ def animate_quiver( ds = xr.tutorial.load_dataset("air_temperature_gradient") animate_quiver(u=ds["dTdx"], v=ds["dTdy"], path='animation.mkv', subsample=3) + + See Also: + :class:`QuiverAnimation`: The underlying animation class used by this function. """ actual_time_name = guess_coord_name(u.coords, TIME_NAME_CANDIDATES, time_name, "time") actual_x_name = guess_coord_name(u.coords, X_NAME_CANDIDATES, x_name, "x")