Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support numpy 1.24 #1158

Closed
ianthomas23 opened this issue Jan 3, 2023 · 3 comments · Fixed by #1185
Closed

Support numpy 1.24 #1158

ianthomas23 opened this issue Jan 3, 2023 · 3 comments · Fixed by #1185
Labels
Milestone

Comments

@ianthomas23
Copy link
Member

Prior to numpy 1.24 creating an array from ragged nested sequences produced a VisibleDeprecationWarning. With 1.24 this is now a ValueError. This is OK currently as numba doesn't yet support numpy 1.24 but it needs to be fixed here before that happens, so it is quite urgent.

Thanks to @Hoxbro for identifying this (holoviz/geoviews#608).

@ianthomas23 ianthomas23 added the bug label Jan 3, 2023
@ianthomas23 ianthomas23 added this to the v0.14.x milestone Jan 3, 2023
@ianthomas23 ianthomas23 modified the milestones: v0.14.x, v0.14.4 Jan 19, 2023
@ianthomas23
Copy link
Member Author

The latest spatialpandas release included fixes for these (holoviz/spatialpandas#107). With that, running CI locally the only issues relating to ragged nested sequences occur in dask and pandas, which will be fixed in due course and are outside of our control. So I am closing this issue as no action is required in datashader.

@bnavigator
Copy link

Since you are implementing your own handling of 'Ragged[...]' types I don't think dask and pandas will ever handle the current CI failures.

Two most obvious incompatibilities for numpy 1.42 in your code are here:

datashader/datashader/core.py

Lines 1258 to 1259 in 21a8614

with np.warnings.catch_warnings():
np.warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')

Fixable by

diff -ur datashader-0.14.3.orig/datashader/core.py datashader-0.14.3/datashader/core.py
--- datashader-0.14.3.orig/datashader/core.py	2023-01-13 19:26:45.686618962 +0100
+++ datashader-0.14.3/datashader/core.py	2023-01-13 19:47:44.032324340 +0100
@@ -2,6 +2,7 @@
 
 from numbers import Number
 from math import log10
+import warnings
 
 import numpy as np
 import pandas as pd
@@ -422,7 +423,6 @@
 
         if (line_width > 0 and ((cudf and isinstance(source, cudf.DataFrame)) or
                                (dask_cudf and isinstance(source, dask_cudf.DataFrame)))):
-            import warnings
             warnings.warn(
                 "Antialiased lines are not supported for CUDA-backed sources, "
                 "so reverting to line_width=0")
@@ -1248,8 +1248,8 @@
     canvas.validate()
 
     # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
-    with np.warnings.catch_warnings():
-        np.warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')
+    with warnings.catch_warnings():
+        warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')
         return bypixel.pipeline(source, schema, canvas, glyph, agg, antialias=antialias)
 
 

(and similar here:

with np.warnings.catch_warnings():

)

And

'x': pd.array([[-4, -2, 0], [2, 4]]),
'y': pd.array([[0, -4, 0], [4, 0]])

fixable by

diff -ur datashader-0.14.3.orig/datashader/tests/test_dask.py datashader-0.14.3/datashader/tests/test_dask.py
--- datashader-0.14.3.orig/datashader/tests/test_dask.py	2023-01-13 19:26:45.718619814 +0100
+++ datashader-0.14.3/datashader/tests/test_dask.py	2023-01-13 19:35:03.835928881 +0100
@@ -956,8 +956,8 @@
 
     # axis1 ragged arrays
     (dict(data={
-        'x': pd.array([[-4, -2, 0], [2, 4]]),
-        'y': pd.array([[0, -4, 0], [4, 0]])
+        'x': pd.array([[-4, -2, 0], [2, 4]], dtype=object),
+        'y': pd.array([[0, -4, 0], [4, 0]], dtype=object)
     }, dtype='Ragged[float32]'), dict(x='x', y='y', axis=1))
 ])
 def test_area_to_zero_fixedrange(DataFrame, df_kwargs, cvs_kwargs):

But there is more and I don't think dask will fix it for you:

[  285s] =================================== FAILURES ===================================
[  285s] ________ test_line_manual_range[df_kwargs5-cvs_kwargs5-dask_DataFrame] _________
[  285s] 
[  285s] DataFrame = <function dask_DataFrame at 0x7f509c75d160>
[  285s] df_kwargs = {'data': {'x': [[4, 0, -4], [-4, 0, 4, 4, 0, -4]], 'y': [[0, -4, 0], [0, 4, 0, 0, 0, 0]]}, 'dtype': 'Ragged[int64]'}
[  285s] cvs_kwargs = {'axis': 1, 'x': 'x', 'y': 'y'}
[  285s] 
[  285s]     @pytest.mark.parametrize('DataFrame', DataFrames)
[  285s]     @pytest.mark.parametrize('df_kwargs,cvs_kwargs', line_manual_range_params)
[  285s]     def test_line_manual_range(DataFrame, df_kwargs, cvs_kwargs):
[  285s]         if DataFrame is dask_cudf_DataFrame:
[  285s]             dtype = df_kwargs.get('dtype', '')
[  285s]             if dtype.startswith('Ragged') or dtype.startswith('Line'):
[  285s]                 pytest.skip("Ragged array not supported with cudf")
[  285s]     
[  285s]         axis = ds.core.LinearAxis()
[  285s]         lincoords = axis.compute_index(axis.compute_scale_and_translate((-3., 3.), 7), 7)
[  285s]     
[  285s] >       ddf = DataFrame(geo='geometry' in cvs_kwargs, **df_kwargs)
[  285s] 
[  285s] datashader/tests/test_dask.py:739: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = ()
[  285s] kwargs = {'data': {'x': [[4, 0, -4], [-4, 0, 4, 4, 0, -4]], 'y': [[0, -4, 0], [0, 4, 0, 0, 0, 0]]}, 'dtype': 'Ragged[int64]'}
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504eab0e20>
[  285s] 
[  285s]     def dask_DataFrame(*args, **kwargs):
[  285s]         if kwargs.pop("geo", False):
[  285s]             df = sp.GeoDataFrame(*args, **kwargs)
[  285s]         else:
[  285s]             df = pd.DataFrame(*args, **kwargs)
[  285s] >       return dd.from_pandas(df, npartitions=2)
[  285s] 
[  285s] datashader/tests/test_dask.py:55: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504eab0e20>
[  285s] npartitions = 2, chunksize = None, sort = True, name = None
[  285s] 
[  285s]     def from_pandas(
[  285s]         data: pd.DataFrame | pd.Series,
[  285s]         npartitions: int | None = None,
[  285s]         chunksize: int | None = None,
[  285s]         sort: bool = True,
[  285s]         name: str | None = None,
[  285s]     ) -> DataFrame | Series:
[  285s]         """
[  285s]         Construct a Dask DataFrame from a Pandas DataFrame
[  285s]     
[  285s]         This splits an in-memory Pandas dataframe into several parts and constructs
[  285s]         a dask.dataframe from those parts on which Dask.dataframe can operate in
[  285s]         parallel.  By default, the input dataframe will be sorted by the index to
[  285s]         produce cleanly-divided partitions (with known divisions).  To preserve the
[  285s]         input ordering, make sure the input index is monotonically-increasing. The
[  285s]         ``sort=False`` option will also avoid reordering, but will not result in
[  285s]         known divisions.
[  285s]     
[  285s]         Note that, despite parallelism, Dask.dataframe may not always be faster
[  285s]         than Pandas.  We recommend that you stay with Pandas for as long as
[  285s]         possible before switching to Dask.dataframe.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         data : pandas.DataFrame or pandas.Series
[  285s]             The DataFrame/Series with which to construct a Dask DataFrame/Series
[  285s]         npartitions : int, optional
[  285s]             The number of partitions of the index to create. Note that if there
[  285s]             are duplicate values or insufficient elements in ``data.index``, the
[  285s]             output may have fewer partitions than requested.
[  285s]         chunksize : int, optional
[  285s]             The desired number of rows per index partition to use. Note that
[  285s]             depending on the size and index of the dataframe, actual partition
[  285s]             sizes may vary.
[  285s]         sort: bool
[  285s]             Sort the input by index first to obtain cleanly divided partitions
[  285s]             (with known divisions).  If False, the input will not be sorted, and
[  285s]             all divisions will be set to None. Default is True.
[  285s]         name: string, optional
[  285s]             An optional keyname for the dataframe.  Defaults to hashing the input
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         dask.DataFrame or dask.Series
[  285s]             A dask DataFrame/Series partitioned along the index
[  285s]     
[  285s]         Examples
[  285s]         --------
[  285s]         >>> from dask.dataframe import from_pandas
[  285s]         >>> df = pd.DataFrame(dict(a=list('aabbcc'), b=list(range(6))),
[  285s]         ...                   index=pd.date_range(start='20100101', periods=6))
[  285s]         >>> ddf = from_pandas(df, npartitions=3)
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]         >>> ddf = from_pandas(df.a, npartitions=3)  # Works with Series too!
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]     
[  285s]         Raises
[  285s]         ------
[  285s]         TypeError
[  285s]             If something other than a ``pandas.DataFrame`` or ``pandas.Series`` is
[  285s]             passed in.
[  285s]     
[  285s]         See Also
[  285s]         --------
[  285s]         from_array : Construct a dask.DataFrame from an array that has record dtype
[  285s]         read_csv : Construct a dask.DataFrame from a CSV file
[  285s]         """
[  285s]         if isinstance(getattr(data, "index", None), pd.MultiIndex):
[  285s]             raise NotImplementedError("Dask does not support MultiIndex Dataframes.")
[  285s]     
[  285s]         if not has_parallel_type(data):
[  285s]             raise TypeError("Input must be a pandas DataFrame or Series.")
[  285s]     
[  285s]         if (npartitions is None) == (chunksize is None):
[  285s]             raise ValueError("Exactly one of npartitions and chunksize must be specified.")
[  285s]     
[  285s]         nrows = len(data)
[  285s]     
[  285s]         if chunksize is None:
[  285s]             if not isinstance(npartitions, int):
[  285s]                 raise TypeError(
[  285s]                     "Please provide npartitions as an int, or possibly as None if you specify chunksize."
[  285s]                 )
[  285s]         elif not isinstance(chunksize, int):
[  285s]             raise TypeError(
[  285s]                 "Please provide chunksize as an int, or possibly as None if you specify npartitions."
[  285s]             )
[  285s]     
[  285s] >       name = name or ("from_pandas-" + tokenize(data, chunksize, npartitions))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/dataframe/io/io.py:276: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = (<[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504eab0e20>, None, 2)
[  285s] kwargs = {}
[  285s] 
[  285s]     def tokenize(*args, **kwargs):
[  285s]         """Deterministic token
[  285s]     
[  285s]         >>> tokenize([1, 2, '3'])
[  285s]         '7d6a880cd9ec03506eee6973ff551339'
[  285s]     
[  285s]         >>> tokenize('Hello') == tokenize('Hello')
[  285s]         True
[  285s]         """
[  285s] >       hasher = _md5(str(tuple(map(normalize_token, args))).encode())
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:931: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504eab0e20>
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_dataframe at 0x7f50518ddf70>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504eab0e20>
[  285s] 
[  285s]     @normalize_token.register(pd.DataFrame)
[  285s]     def normalize_dataframe(df):
[  285s]         mgr = df._data
[  285s]     
[  285s]         if PANDAS_GT_130:
[  285s]             # for compat with ArrayManager, pandas 1.3.0 introduced a `.arrays`
[  285s]             # attribute that returns the column arrays/block arrays for both
[  285s]             # BlockManager and ArrayManager
[  285s]             data = list(mgr.arrays)
[  285s]         else:
[  285s]             data = [block.values for block in mgr.blocks]
[  285s]         data.extend([df.columns, df.index])
[  285s] >       return list(map(normalize_token, data))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1157: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <RaggedArray>
[  285s] [array([ 4,  0, -4]), array([-4,  0,  4,  4,  0, -4])]
[  285s] Length: 2, dtype: Ragged[int64]
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_extension_array at 0x7f5051912040>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] arr = <RaggedArray>
[  285s] [array([ 4,  0, -4]), array([-4,  0,  4,  4,  0, -4])]
[  285s] Length: 2, dtype: Ragged[int64]
[  285s] 
[  285s]     @normalize_token.register(pd.api.extensions.ExtensionArray)
[  285s]     def normalize_extension_array(arr):
[  285s]         import numpy as np
[  285s]     
[  285s] >       return normalize_token(np.asarray(arr))
[  285s] E       ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1163: ValueError
[  285s] _____ test_area_to_zero_fixedrange[df_kwargs3-cvs_kwargs3-dask_DataFrame] ______
[  285s] 
[  285s] DataFrame = <function dask_DataFrame at 0x7f509c75d160>
[  285s] df_kwargs = {'data': {'x': <PandasArray>
[  285s] [[-4, -2, 0], [2, 4]]
[  285s] Length: 2, dtype: object, 'y': <PandasArray>
[  285s] [[0, -4, 0], [4, 0]]
[  285s] Length: 2, dtype: object}, 'dtype': 'Ragged[float32]'}
[  285s] cvs_kwargs = {'axis': 1, 'x': 'x', 'y': 'y'}
[  285s] 
[  285s]     @pytest.mark.parametrize('DataFrame', DataFrames)
[  285s]     @pytest.mark.parametrize('df_kwargs,cvs_kwargs', [
[  285s]         # axis1 none constant
[  285s]         (dict(data={
[  285s]             'x0': [-4, np.nan],
[  285s]             'x1': [-2, 2],
[  285s]             'x2': [0, 4],
[  285s]             'y0': [0, np.nan],
[  285s]             'y1': [-4, 4],
[  285s]             'y2': [0, 0]
[  285s]         }, dtype='float32'), dict(x=['x0', 'x1', 'x2'], y=['y0', 'y1', 'y2'], axis=1)),
[  285s]     
[  285s]         # axis0 single
[  285s]         (dict(data={
[  285s]             'x': [-4, -2, 0, np.nan, 2, 4],
[  285s]             'y': [0, -4, 0, np.nan, 4, 0],
[  285s]         }), dict(x='x', y='y', axis=0)),
[  285s]     
[  285s]         # axis0 multi
[  285s]         (dict(data={
[  285s]             'x0': [-4, -2, 0],
[  285s]             'x1': [np.nan, 2, 4],
[  285s]             'y0': [0, -4, 0],
[  285s]             'y1': [np.nan, 4, 0],
[  285s]         }, dtype='float32'),  dict(x=['x0', 'x1'], y=['y0', 'y1'], axis=0)),
[  285s]     
[  285s]         # axis1 ragged arrays
[  285s]         (dict(data={
[  285s]             'x': pd.array([[-4, -2, 0], [2, 4]], dtype=object),
[  285s]             'y': pd.array([[0, -4, 0], [4, 0]], dtype=object)
[  285s]         }, dtype='Ragged[float32]'), dict(x='x', y='y', axis=1))
[  285s]     ])
[  285s]     def test_area_to_zero_fixedrange(DataFrame, df_kwargs, cvs_kwargs):
[  285s]         if DataFrame is dask_cudf_DataFrame:
[  285s]             if df_kwargs.get('dtype', '').startswith('Ragged'):
[  285s]                 pytest.skip("Ragged array not supported with cudf")
[  285s]     
[  285s]         axis = ds.core.LinearAxis()
[  285s]         lincoords_y = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-2.25, 2.25), 5), 5)
[  285s]     
[  285s]         lincoords_x = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-3.75, 3.75), 9), 9)
[  285s]     
[  285s]         cvs = ds.Canvas(plot_width=9, plot_height=5,
[  285s]                         x_range=[-3.75, 3.75], y_range=[-2.25, 2.25])
[  285s]     
[  285s] >       ddf = DataFrame(**df_kwargs)
[  285s] 
[  285s] datashader/tests/test_dask.py:1021: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = ()
[  285s] kwargs = {'data': {'x': <PandasArray>
[  285s] [[-4, -2, 0], [2, 4]]
[  285s] Length: 2, dtype: object, 'y': <PandasArray>
[  285s] [[0, -4, 0], [4, 0]]
[  285s] Length: 2, dtype: object}, 'dtype': 'Ragged[float32]'}
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c1220d0>
[  285s] 
[  285s]     def dask_DataFrame(*args, **kwargs):
[  285s]         if kwargs.pop("geo", False):
[  285s]             df = sp.GeoDataFrame(*args, **kwargs)
[  285s]         else:
[  285s]             df = pd.DataFrame(*args, **kwargs)
[  285s] >       return dd.from_pandas(df, npartitions=2)
[  285s] 
[  285s] datashader/tests/test_dask.py:55: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c1220d0>
[  285s] npartitions = 2, chunksize = None, sort = True, name = None
[  285s] 
[  285s]     def from_pandas(
[  285s]         data: pd.DataFrame | pd.Series,
[  285s]         npartitions: int | None = None,
[  285s]         chunksize: int | None = None,
[  285s]         sort: bool = True,
[  285s]         name: str | None = None,
[  285s]     ) -> DataFrame | Series:
[  285s]         """
[  285s]         Construct a Dask DataFrame from a Pandas DataFrame
[  285s]     
[  285s]         This splits an in-memory Pandas dataframe into several parts and constructs
[  285s]         a dask.dataframe from those parts on which Dask.dataframe can operate in
[  285s]         parallel.  By default, the input dataframe will be sorted by the index to
[  285s]         produce cleanly-divided partitions (with known divisions).  To preserve the
[  285s]         input ordering, make sure the input index is monotonically-increasing. The
[  285s]         ``sort=False`` option will also avoid reordering, but will not result in
[  285s]         known divisions.
[  285s]     
[  285s]         Note that, despite parallelism, Dask.dataframe may not always be faster
[  285s]         than Pandas.  We recommend that you stay with Pandas for as long as
[  285s]         possible before switching to Dask.dataframe.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         data : pandas.DataFrame or pandas.Series
[  285s]             The DataFrame/Series with which to construct a Dask DataFrame/Series
[  285s]         npartitions : int, optional
[  285s]             The number of partitions of the index to create. Note that if there
[  285s]             are duplicate values or insufficient elements in ``data.index``, the
[  285s]             output may have fewer partitions than requested.
[  285s]         chunksize : int, optional
[  285s]             The desired number of rows per index partition to use. Note that
[  285s]             depending on the size and index of the dataframe, actual partition
[  285s]             sizes may vary.
[  285s]         sort: bool
[  285s]             Sort the input by index first to obtain cleanly divided partitions
[  285s]             (with known divisions).  If False, the input will not be sorted, and
[  285s]             all divisions will be set to None. Default is True.
[  285s]         name: string, optional
[  285s]             An optional keyname for the dataframe.  Defaults to hashing the input
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         dask.DataFrame or dask.Series
[  285s]             A dask DataFrame/Series partitioned along the index
[  285s]     
[  285s]         Examples
[  285s]         --------
[  285s]         >>> from dask.dataframe import from_pandas
[  285s]         >>> df = pd.DataFrame(dict(a=list('aabbcc'), b=list(range(6))),
[  285s]         ...                   index=pd.date_range(start='20100101', periods=6))
[  285s]         >>> ddf = from_pandas(df, npartitions=3)
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]         >>> ddf = from_pandas(df.a, npartitions=3)  # Works with Series too!
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]     
[  285s]         Raises
[  285s]         ------
[  285s]         TypeError
[  285s]             If something other than a ``pandas.DataFrame`` or ``pandas.Series`` is
[  285s]             passed in.
[  285s]     
[  285s]         See Also
[  285s]         --------
[  285s]         from_array : Construct a dask.DataFrame from an array that has record dtype
[  285s]         read_csv : Construct a dask.DataFrame from a CSV file
[  285s]         """
[  285s]         if isinstance(getattr(data, "index", None), pd.MultiIndex):
[  285s]             raise NotImplementedError("Dask does not support MultiIndex Dataframes.")
[  285s]     
[  285s]         if not has_parallel_type(data):
[  285s]             raise TypeError("Input must be a pandas DataFrame or Series.")
[  285s]     
[  285s]         if (npartitions is None) == (chunksize is None):
[  285s]             raise ValueError("Exactly one of npartitions and chunksize must be specified.")
[  285s]     
[  285s]         nrows = len(data)
[  285s]     
[  285s]         if chunksize is None:
[  285s]             if not isinstance(npartitions, int):
[  285s]                 raise TypeError(
[  285s]                     "Please provide npartitions as an int, or possibly as None if you specify chunksize."
[  285s]                 )
[  285s]         elif not isinstance(chunksize, int):
[  285s]             raise TypeError(
[  285s]                 "Please provide chunksize as an int, or possibly as None if you specify npartitions."
[  285s]             )
[  285s]     
[  285s] >       name = name or ("from_pandas-" + tokenize(data, chunksize, npartitions))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/dataframe/io/io.py:276: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = (<[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c1220d0>, None, 2)
[  285s] kwargs = {}
[  285s] 
[  285s]     def tokenize(*args, **kwargs):
[  285s]         """Deterministic token
[  285s]     
[  285s]         >>> tokenize([1, 2, '3'])
[  285s]         '7d6a880cd9ec03506eee6973ff551339'
[  285s]     
[  285s]         >>> tokenize('Hello') == tokenize('Hello')
[  285s]         True
[  285s]         """
[  285s] >       hasher = _md5(str(tuple(map(normalize_token, args))).encode())
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:931: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c1220d0>
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_dataframe at 0x7f50518ddf70>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c1220d0>
[  285s] 
[  285s]     @normalize_token.register(pd.DataFrame)
[  285s]     def normalize_dataframe(df):
[  285s]         mgr = df._data
[  285s]     
[  285s]         if PANDAS_GT_130:
[  285s]             # for compat with ArrayManager, pandas 1.3.0 introduced a `.arrays`
[  285s]             # attribute that returns the column arrays/block arrays for both
[  285s]             # BlockManager and ArrayManager
[  285s]             data = list(mgr.arrays)
[  285s]         else:
[  285s]             data = [block.values for block in mgr.blocks]
[  285s]         data.extend([df.columns, df.index])
[  285s] >       return list(map(normalize_token, data))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1157: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_extension_array at 0x7f5051912040>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] arr = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] 
[  285s]     @normalize_token.register(pd.api.extensions.ExtensionArray)
[  285s]     def normalize_extension_array(arr):
[  285s]         import numpy as np
[  285s]     
[  285s] >       return normalize_token(np.asarray(arr))
[  285s] E       ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1163: ValueError
[  285s] ____ test_area_to_zero_autorange_gap[df_kwargs3-cvs_kwargs3-dask_DataFrame] ____
[  285s] 
[  285s] DataFrame = <function dask_DataFrame at 0x7f509c75d160>
[  285s] df_kwargs = {'data': {'x': [[-4, -2, 0], [2, 4]], 'y': [[0, -4, 0], [4, 0]]}, 'dtype': 'Ragged[float32]'}
[  285s] cvs_kwargs = {'axis': 1, 'x': 'x', 'y': 'y'}
[  285s] 
[  285s]     @pytest.mark.parametrize('DataFrame', DataFrames)
[  285s]     @pytest.mark.parametrize('df_kwargs,cvs_kwargs', [
[  285s]         # axis1 none constant
[  285s]         (dict(data={
[  285s]             'x0': [-4, np.nan],
[  285s]             'x1': [-2, 2],
[  285s]             'x2': [0, 4],
[  285s]             'y0': [0, np.nan],
[  285s]             'y1': [-4, 4],
[  285s]             'y2': [0, 0]
[  285s]         }, dtype='float32'), dict(x=['x0', 'x1', 'x2'], y=['y0', 'y1', 'y2'], axis=1)),
[  285s]     
[  285s]         # axis0 single
[  285s]         (dict(data={
[  285s]             'x': [-4, -2, 0, np.nan, 2, 4],
[  285s]             'y': [0, -4, 0, np.nan, 4, 0],
[  285s]         }), dict(x='x', y='y', axis=0)),
[  285s]     
[  285s]         # axis0 multi
[  285s]         (dict(data={
[  285s]             'x0': [-4, -2, 0],
[  285s]             'x1': [np.nan, 2, 4],
[  285s]             'y0': [0, -4, 0],
[  285s]             'y1': [np.nan, 4, 0],
[  285s]         }, dtype='float32'), dict(x=['x0', 'x1'], y=['y0', 'y1'], axis=0)),
[  285s]     
[  285s]         # axis1 ragged arrays
[  285s]         (dict(data={
[  285s]             'x': [[-4, -2, 0], [2, 4]],
[  285s]             'y': [[0, -4, 0], [4, 0]],
[  285s]         }, dtype='Ragged[float32]'), dict(x='x', y='y', axis=1))
[  285s]     ])
[  285s]     def test_area_to_zero_autorange_gap(DataFrame, df_kwargs, cvs_kwargs):
[  285s]         if DataFrame is dask_cudf_DataFrame:
[  285s]             if df_kwargs.get('dtype', '').startswith('Ragged'):
[  285s]                 pytest.skip("Ragged array not supported with cudf")
[  285s]     
[  285s]         axis = ds.core.LinearAxis()
[  285s]         lincoords_y = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-4., 4.), 7), 7)
[  285s]         lincoords_x = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-4., 4.), 13), 13)
[  285s]     
[  285s]         cvs = ds.Canvas(plot_width=13, plot_height=7)
[  285s]     
[  285s] >       ddf = DataFrame(**df_kwargs)
[  285s] 
[  285s] datashader/tests/test_dask.py:1186: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = ()
[  285s] kwargs = {'data': {'x': [[-4, -2, 0], [2, 4]], 'y': [[0, -4, 0], [4, 0]]}, 'dtype': 'Ragged[float32]'}
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c679c10>
[  285s] 
[  285s]     def dask_DataFrame(*args, **kwargs):
[  285s]         if kwargs.pop("geo", False):
[  285s]             df = sp.GeoDataFrame(*args, **kwargs)
[  285s]         else:
[  285s]             df = pd.DataFrame(*args, **kwargs)
[  285s] >       return dd.from_pandas(df, npartitions=2)
[  285s] 
[  285s] datashader/tests/test_dask.py:55: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c679c10>
[  285s] npartitions = 2, chunksize = None, sort = True, name = None
[  285s] 
[  285s]     def from_pandas(
[  285s]         data: pd.DataFrame | pd.Series,
[  285s]         npartitions: int | None = None,
[  285s]         chunksize: int | None = None,
[  285s]         sort: bool = True,
[  285s]         name: str | None = None,
[  285s]     ) -> DataFrame | Series:
[  285s]         """
[  285s]         Construct a Dask DataFrame from a Pandas DataFrame
[  285s]     
[  285s]         This splits an in-memory Pandas dataframe into several parts and constructs
[  285s]         a dask.dataframe from those parts on which Dask.dataframe can operate in
[  285s]         parallel.  By default, the input dataframe will be sorted by the index to
[  285s]         produce cleanly-divided partitions (with known divisions).  To preserve the
[  285s]         input ordering, make sure the input index is monotonically-increasing. The
[  285s]         ``sort=False`` option will also avoid reordering, but will not result in
[  285s]         known divisions.
[  285s]     
[  285s]         Note that, despite parallelism, Dask.dataframe may not always be faster
[  285s]         than Pandas.  We recommend that you stay with Pandas for as long as
[  285s]         possible before switching to Dask.dataframe.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         data : pandas.DataFrame or pandas.Series
[  285s]             The DataFrame/Series with which to construct a Dask DataFrame/Series
[  285s]         npartitions : int, optional
[  285s]             The number of partitions of the index to create. Note that if there
[  285s]             are duplicate values or insufficient elements in ``data.index``, the
[  285s]             output may have fewer partitions than requested.
[  285s]         chunksize : int, optional
[  285s]             The desired number of rows per index partition to use. Note that
[  285s]             depending on the size and index of the dataframe, actual partition
[  285s]             sizes may vary.
[  285s]         sort: bool
[  285s]             Sort the input by index first to obtain cleanly divided partitions
[  285s]             (with known divisions).  If False, the input will not be sorted, and
[  285s]             all divisions will be set to None. Default is True.
[  285s]         name: string, optional
[  285s]             An optional keyname for the dataframe.  Defaults to hashing the input
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         dask.DataFrame or dask.Series
[  285s]             A dask DataFrame/Series partitioned along the index
[  285s]     
[  285s]         Examples
[  285s]         --------
[  285s]         >>> from dask.dataframe import from_pandas
[  285s]         >>> df = pd.DataFrame(dict(a=list('aabbcc'), b=list(range(6))),
[  285s]         ...                   index=pd.date_range(start='20100101', periods=6))
[  285s]         >>> ddf = from_pandas(df, npartitions=3)
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]         >>> ddf = from_pandas(df.a, npartitions=3)  # Works with Series too!
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]     
[  285s]         Raises
[  285s]         ------
[  285s]         TypeError
[  285s]             If something other than a ``pandas.DataFrame`` or ``pandas.Series`` is
[  285s]             passed in.
[  285s]     
[  285s]         See Also
[  285s]         --------
[  285s]         from_array : Construct a dask.DataFrame from an array that has record dtype
[  285s]         read_csv : Construct a dask.DataFrame from a CSV file
[  285s]         """
[  285s]         if isinstance(getattr(data, "index", None), pd.MultiIndex):
[  285s]             raise NotImplementedError("Dask does not support MultiIndex Dataframes.")
[  285s]     
[  285s]         if not has_parallel_type(data):
[  285s]             raise TypeError("Input must be a pandas DataFrame or Series.")
[  285s]     
[  285s]         if (npartitions is None) == (chunksize is None):
[  285s]             raise ValueError("Exactly one of npartitions and chunksize must be specified.")
[  285s]     
[  285s]         nrows = len(data)
[  285s]     
[  285s]         if chunksize is None:
[  285s]             if not isinstance(npartitions, int):
[  285s]                 raise TypeError(
[  285s]                     "Please provide npartitions as an int, or possibly as None if you specify chunksize."
[  285s]                 )
[  285s]         elif not isinstance(chunksize, int):
[  285s]             raise TypeError(
[  285s]                 "Please provide chunksize as an int, or possibly as None if you specify npartitions."
[  285s]             )
[  285s]     
[  285s] >       name = name or ("from_pandas-" + tokenize(data, chunksize, npartitions))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/dataframe/io/io.py:276: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = (<[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c679c10>, None, 2)
[  285s] kwargs = {}
[  285s] 
[  285s]     def tokenize(*args, **kwargs):
[  285s]         """Deterministic token
[  285s]     
[  285s]         >>> tokenize([1, 2, '3'])
[  285s]         '7d6a880cd9ec03506eee6973ff551339'
[  285s]     
[  285s]         >>> tokenize('Hello') == tokenize('Hello')
[  285s]         True
[  285s]         """
[  285s] >       hasher = _md5(str(tuple(map(normalize_token, args))).encode())
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:931: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c679c10>
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_dataframe at 0x7f50518ddf70>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504c679c10>
[  285s] 
[  285s]     @normalize_token.register(pd.DataFrame)
[  285s]     def normalize_dataframe(df):
[  285s]         mgr = df._data
[  285s]     
[  285s]         if PANDAS_GT_130:
[  285s]             # for compat with ArrayManager, pandas 1.3.0 introduced a `.arrays`
[  285s]             # attribute that returns the column arrays/block arrays for both
[  285s]             # BlockManager and ArrayManager
[  285s]             data = list(mgr.arrays)
[  285s]         else:
[  285s]             data = [block.values for block in mgr.blocks]
[  285s]         data.extend([df.columns, df.index])
[  285s] >       return list(map(normalize_token, data))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1157: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_extension_array at 0x7f5051912040>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] arr = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] 
[  285s]     @normalize_token.register(pd.api.extensions.ExtensionArray)
[  285s]     def normalize_extension_array(arr):
[  285s]         import numpy as np
[  285s]     
[  285s] >       return normalize_token(np.asarray(arr))
[  285s] E       ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1163: ValueError
[  285s] ____ test_area_to_line_autorange_gap[df_kwargs3-cvs_kwargs3-dask_DataFrame] ____
[  285s] 
[  285s] DataFrame = <function dask_DataFrame at 0x7f509c75d160>
[  285s] df_kwargs = {'data': {'x': [[-4, -2, 0], [2, 4]], 'y': [[0, -4, 0], [4, 0]], 'y_stack': [[0, 0, 0], [0, 0]]}, 'dtype': 'Ragged[float32]'}
[  285s] cvs_kwargs = {'axis': 1, 'x': 'x', 'y': 'y', 'y_stack': 'y_stack'}
[  285s] 
[  285s]     @pytest.mark.parametrize('DataFrame', DataFrames)
[  285s]     @pytest.mark.parametrize('df_kwargs,cvs_kwargs', [
[  285s]         # axis1 none constant
[  285s]         (dict(data={
[  285s]             'x0': [-4, np.nan],
[  285s]             'x1': [-2, 2],
[  285s]             'x2': [0, 4],
[  285s]             'y0': [0, np.nan],
[  285s]             'y1': [-4, 4],
[  285s]             'y2': [0, 0],
[  285s]             'y4': [0, 0],
[  285s]             'y5': [0, 0],
[  285s]             'y6': [0, 0]
[  285s]         }, dtype='float32'),
[  285s]          dict(x=['x0', 'x1', 'x2'], y=['y0', 'y1', 'y2'],
[  285s]               y_stack=['y4', 'y5', 'y6'], axis=1)),
[  285s]     
[  285s]         # axis0 single
[  285s]         (dict(data={
[  285s]             'x': [-4, -2, 0, np.nan, 2, 4],
[  285s]             'y': [0, -4, 0, np.nan, 4, 0],
[  285s]             'y_stack': [0, 0, 0, 0, 0, 0],
[  285s]         }), dict(x='x', y='y', y_stack='y_stack', axis=0)),
[  285s]     
[  285s]         # axis0 multi
[  285s]         (dict(data={
[  285s]             'x0': [-4, -2, 0],
[  285s]             'x1': [np.nan, 2, 4],
[  285s]             'y0': [0, -4, 0],
[  285s]             'y1': [np.nan, 4, 0],
[  285s]             'y2': [0, 0, 0],
[  285s]             'y3': [0, 0, 0],
[  285s]         }, dtype='float32'),
[  285s]          dict(x=['x0', 'x1'], y=['y0', 'y1'], y_stack=['y2', 'y3'], axis=0)),
[  285s]     
[  285s]         # axis1 ragged arrays
[  285s]         (dict(data={
[  285s]             'x': [[-4, -2, 0], [2, 4]],
[  285s]             'y': [[0, -4, 0], [4, 0]],
[  285s]             'y_stack': [[0, 0, 0], [0, 0]],
[  285s]         }, dtype='Ragged[float32]'), dict(x='x', y='y', y_stack='y_stack', axis=1))
[  285s]     ])
[  285s]     def test_area_to_line_autorange_gap(DataFrame, df_kwargs, cvs_kwargs):
[  285s]         if DataFrame is dask_cudf_DataFrame:
[  285s]             if df_kwargs.get('dtype', '').startswith('Ragged'):
[  285s]                 pytest.skip("Ragged array not supported with cudf")
[  285s]     
[  285s]         axis = ds.core.LinearAxis()
[  285s]         lincoords_y = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-4., 4.), 7), 7)
[  285s]         lincoords_x = axis.compute_index(
[  285s]             axis.compute_scale_and_translate((-4., 4.), 13), 13)
[  285s]     
[  285s]         cvs = ds.Canvas(plot_width=13, plot_height=7)
[  285s]     
[  285s] >       ddf = DataFrame(**df_kwargs)
[  285s] 
[  285s] datashader/tests/test_dask.py:1376: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = ()
[  285s] kwargs = {'data': {'x': [[-4, -2, 0], [2, 4]], 'y': [[0, -4, 0], [4, 0]], 'y_stack': [[0, 0, 0], [0, 0]]}, 'dtype': 'Ragged[float32]'}
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504d11caf0>
[  285s] 
[  285s]     def dask_DataFrame(*args, **kwargs):
[  285s]         if kwargs.pop("geo", False):
[  285s]             df = sp.GeoDataFrame(*args, **kwargs)
[  285s]         else:
[  285s]             df = pd.DataFrame(*args, **kwargs)
[  285s] >       return dd.from_pandas(df, npartitions=2)
[  285s] 
[  285s] datashader/tests/test_dask.py:55: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504d11caf0>
[  285s] npartitions = 2, chunksize = None, sort = True, name = None
[  285s] 
[  285s]     def from_pandas(
[  285s]         data: pd.DataFrame | pd.Series,
[  285s]         npartitions: int | None = None,
[  285s]         chunksize: int | None = None,
[  285s]         sort: bool = True,
[  285s]         name: str | None = None,
[  285s]     ) -> DataFrame | Series:
[  285s]         """
[  285s]         Construct a Dask DataFrame from a Pandas DataFrame
[  285s]     
[  285s]         This splits an in-memory Pandas dataframe into several parts and constructs
[  285s]         a dask.dataframe from those parts on which Dask.dataframe can operate in
[  285s]         parallel.  By default, the input dataframe will be sorted by the index to
[  285s]         produce cleanly-divided partitions (with known divisions).  To preserve the
[  285s]         input ordering, make sure the input index is monotonically-increasing. The
[  285s]         ``sort=False`` option will also avoid reordering, but will not result in
[  285s]         known divisions.
[  285s]     
[  285s]         Note that, despite parallelism, Dask.dataframe may not always be faster
[  285s]         than Pandas.  We recommend that you stay with Pandas for as long as
[  285s]         possible before switching to Dask.dataframe.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         data : pandas.DataFrame or pandas.Series
[  285s]             The DataFrame/Series with which to construct a Dask DataFrame/Series
[  285s]         npartitions : int, optional
[  285s]             The number of partitions of the index to create. Note that if there
[  285s]             are duplicate values or insufficient elements in ``data.index``, the
[  285s]             output may have fewer partitions than requested.
[  285s]         chunksize : int, optional
[  285s]             The desired number of rows per index partition to use. Note that
[  285s]             depending on the size and index of the dataframe, actual partition
[  285s]             sizes may vary.
[  285s]         sort: bool
[  285s]             Sort the input by index first to obtain cleanly divided partitions
[  285s]             (with known divisions).  If False, the input will not be sorted, and
[  285s]             all divisions will be set to None. Default is True.
[  285s]         name: string, optional
[  285s]             An optional keyname for the dataframe.  Defaults to hashing the input
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         dask.DataFrame or dask.Series
[  285s]             A dask DataFrame/Series partitioned along the index
[  285s]     
[  285s]         Examples
[  285s]         --------
[  285s]         >>> from dask.dataframe import from_pandas
[  285s]         >>> df = pd.DataFrame(dict(a=list('aabbcc'), b=list(range(6))),
[  285s]         ...                   index=pd.date_range(start='20100101', periods=6))
[  285s]         >>> ddf = from_pandas(df, npartitions=3)
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]         >>> ddf = from_pandas(df.a, npartitions=3)  # Works with Series too!
[  285s]         >>> ddf.divisions  # doctest: +NORMALIZE_WHITESPACE
[  285s]         (Timestamp('2010-01-01 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-03 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-05 00:00:00', freq='D'),
[  285s]          Timestamp('2010-01-06 00:00:00', freq='D'))
[  285s]     
[  285s]         Raises
[  285s]         ------
[  285s]         TypeError
[  285s]             If something other than a ``pandas.DataFrame`` or ``pandas.Series`` is
[  285s]             passed in.
[  285s]     
[  285s]         See Also
[  285s]         --------
[  285s]         from_array : Construct a dask.DataFrame from an array that has record dtype
[  285s]         read_csv : Construct a dask.DataFrame from a CSV file
[  285s]         """
[  285s]         if isinstance(getattr(data, "index", None), pd.MultiIndex):
[  285s]             raise NotImplementedError("Dask does not support MultiIndex Dataframes.")
[  285s]     
[  285s]         if not has_parallel_type(data):
[  285s]             raise TypeError("Input must be a pandas DataFrame or Series.")
[  285s]     
[  285s]         if (npartitions is None) == (chunksize is None):
[  285s]             raise ValueError("Exactly one of npartitions and chunksize must be specified.")
[  285s]     
[  285s]         nrows = len(data)
[  285s]     
[  285s]         if chunksize is None:
[  285s]             if not isinstance(npartitions, int):
[  285s]                 raise TypeError(
[  285s]                     "Please provide npartitions as an int, or possibly as None if you specify chunksize."
[  285s]                 )
[  285s]         elif not isinstance(chunksize, int):
[  285s]             raise TypeError(
[  285s]                 "Please provide chunksize as an int, or possibly as None if you specify npartitions."
[  285s]             )
[  285s]     
[  285s] >       name = name or ("from_pandas-" + tokenize(data, chunksize, npartitions))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/dataframe/io/io.py:276: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] args = (<[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504d11caf0>, None, 2)
[  285s] kwargs = {}
[  285s] 
[  285s]     def tokenize(*args, **kwargs):
[  285s]         """Deterministic token
[  285s]     
[  285s]         >>> tokenize([1, 2, '3'])
[  285s]         '7d6a880cd9ec03506eee6973ff551339'
[  285s]     
[  285s]         >>> tokenize('Hello') == tokenize('Hello')
[  285s]         True
[  285s]         """
[  285s] >       hasher = _md5(str(tuple(map(normalize_token, args))).encode())
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:931: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504d11caf0>
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_dataframe at 0x7f50518ddf70>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] df = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f504d11caf0>
[  285s] 
[  285s]     @normalize_token.register(pd.DataFrame)
[  285s]     def normalize_dataframe(df):
[  285s]         mgr = df._data
[  285s]     
[  285s]         if PANDAS_GT_130:
[  285s]             # for compat with ArrayManager, pandas 1.3.0 introduced a `.arrays`
[  285s]             # attribute that returns the column arrays/block arrays for both
[  285s]             # BlockManager and ArrayManager
[  285s]             data = list(mgr.arrays)
[  285s]         else:
[  285s]             data = [block.values for block in mgr.blocks]
[  285s]         data.extend([df.columns, df.index])
[  285s] >       return list(map(normalize_token, data))
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1157: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <dask.utils.Dispatch object at 0x7f50b9beab20>
[  285s] arg = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] args = (), kwargs = {}
[  285s] meth = <function register_pandas.<locals>.normalize_extension_array at 0x7f5051912040>
[  285s] 
[  285s]     def __call__(self, arg, *args, **kwargs):
[  285s]         """
[  285s]         Call the corresponding method based on type of argument.
[  285s]         """
[  285s]         meth = self.dispatch(type(arg))
[  285s] >       return meth(arg, *args, **kwargs)
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/utils.py:640: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] arr = <RaggedArray>
[  285s] [array([-4., -2.,  0.], dtype=float32), array([2., 4.], dtype=float32)]
[  285s] Length: 2, dtype: Ragged[float32]
[  285s] 
[  285s]     @normalize_token.register(pd.api.extensions.ExtensionArray)
[  285s]     def normalize_extension_array(arr):
[  285s]         import numpy as np
[  285s]     
[  285s] >       return normalize_token(np.asarray(arr))
[  285s] E       ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib/python3.8/site-packages/dask/base.py:1163: ValueError
[  285s] _____________________ TestRaggedPrinting.test_series_repr ______________________
[  285s] 
[  285s] self = <datashader.tests.test_datatypes.TestRaggedPrinting object at 0x7f509cb53550>
[  285s] data = <RaggedArray>
[  285s] [        array([0., 1.]), array([1., 2., 3., 4.]),                     nan,
[  285s]        array([-1., -2.]),   ..., 4.]),                     nan,       array([-1., -2.]),
[  285s]                      nan]
[  285s] Length: 100, dtype: Ragged[float64]
[  285s] 
[  285s]     def test_series_repr(self, data):
[  285s]         ser = pd.Series(data)
[  285s] >       assert data.dtype.name in repr(ser)
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/tests/extension/base/printing.py:32: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.') raised in repr()] Series object at 0x7f502ba4ac10>
[  285s] 
[  285s]     def __repr__(self) -> str:
[  285s]         """
[  285s]         Return a string representation for a particular Series.
[  285s]         """
[  285s]         repr_params = fmt.get_series_repr_params()
[  285s] >       return self.to_string(**repr_params)
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/core/series.py:1594: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.') raised in repr()] Series object at 0x7f502ba4ac10>
[  285s] buf = None, na_rep = 'NaN', float_format = None, header = True, index = True
[  285s] length = 'truncate', dtype = True, name = True, max_rows = 60, min_rows = 10
[  285s] 
[  285s]     def to_string(
[  285s]         self,
[  285s]         buf: FilePath | WriteBuffer[str] | None = None,
[  285s]         na_rep: str = "NaN",
[  285s]         float_format: str | None = None,
[  285s]         header: bool = True,
[  285s]         index: bool = True,
[  285s]         length=False,
[  285s]         dtype=False,
[  285s]         name=False,
[  285s]         max_rows: int | None = None,
[  285s]         min_rows: int | None = None,
[  285s]     ) -> str | None:
[  285s]         """
[  285s]         Render a string representation of the Series.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         buf : StringIO-like, optional
[  285s]             Buffer to write to.
[  285s]         na_rep : str, optional
[  285s]             String representation of NaN to use, default 'NaN'.
[  285s]         float_format : one-parameter function, optional
[  285s]             Formatter function to apply to columns' elements if they are
[  285s]             floats, default None.
[  285s]         header : bool, default True
[  285s]             Add the Series header (index name).
[  285s]         index : bool, optional
[  285s]             Add index (row) labels, default True.
[  285s]         length : bool, default False
[  285s]             Add the Series length.
[  285s]         dtype : bool, default False
[  285s]             Add the Series dtype.
[  285s]         name : bool, default False
[  285s]             Add the Series name if not None.
[  285s]         max_rows : int, optional
[  285s]             Maximum number of rows to show before truncating. If None, show
[  285s]             all.
[  285s]         min_rows : int, optional
[  285s]             The number of rows to display in a truncated repr (when number
[  285s]             of rows is above `max_rows`).
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         str or None
[  285s]             String representation of Series if ``buf=None``, otherwise None.
[  285s]         """
[  285s]         formatter = fmt.SeriesFormatter(
[  285s]             self,
[  285s]             name=name,
[  285s]             length=length,
[  285s]             header=header,
[  285s]             index=index,
[  285s]             dtype=dtype,
[  285s]             na_rep=na_rep,
[  285s]             float_format=float_format,
[  285s]             min_rows=min_rows,
[  285s]             max_rows=max_rows,
[  285s]         )
[  285s] >       result = formatter.to_string()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/core/series.py:1687: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.SeriesFormatter object at 0x7f502ba4ac70>
[  285s] 
[  285s]     def to_string(self) -> str:
[  285s]         series = self.tr_series
[  285s]         footer = self._get_footer()
[  285s]     
[  285s]         if len(series) == 0:
[  285s]             return f"{type(self.series).__name__}([], {footer})"
[  285s]     
[  285s]         fmt_index, have_header = self._get_formatted_index()
[  285s] >       fmt_values = self._get_formatted_values()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:397: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.SeriesFormatter object at 0x7f502ba4ac70>
[  285s] 
[  285s]     def _get_formatted_values(self) -> list[str]:
[  285s] >       return format_array(
[  285s]             self.tr_series._values,
[  285s]             None,
[  285s]             float_format=self.float_format,
[  285s]             na_rep=self.na_rep,
[  285s]             leading_space=self.index,
[  285s]         )
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:381: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] values = <RaggedArray>
[  285s] [        array([0., 1.]), array([1., 2., 3., 4.]),                     nan,
[  285s]        array([-1., -2.]),   ...., 4.]),                     nan,       array([-1., -2.]),
[  285s]                      nan]
[  285s] Length: 10, dtype: Ragged[float64]
[  285s] formatter = None, float_format = None, na_rep = 'NaN', digits = 6, space = 12
[  285s] justify = 'right', decimal = '.', leading_space = True, quoting = None
[  285s] 
[  285s]     def format_array(
[  285s]         values: Any,
[  285s]         formatter: Callable | None,
[  285s]         float_format: FloatFormatType | None = None,
[  285s]         na_rep: str = "NaN",
[  285s]         digits: int | None = None,
[  285s]         space: str | int | None = None,
[  285s]         justify: str = "right",
[  285s]         decimal: str = ".",
[  285s]         leading_space: bool | None = True,
[  285s]         quoting: int | None = None,
[  285s]     ) -> list[str]:
[  285s]         """
[  285s]         Format an array for printing.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         values
[  285s]         formatter
[  285s]         float_format
[  285s]         na_rep
[  285s]         digits
[  285s]         space
[  285s]         justify
[  285s]         decimal
[  285s]         leading_space : bool, optional, default True
[  285s]             Whether the array should be formatted with a leading space.
[  285s]             When an array as a column of a Series or DataFrame, we do want
[  285s]             the leading space to pad between columns.
[  285s]     
[  285s]             When formatting an Index subclass
[  285s]             (e.g. IntervalIndex._format_native_types), we don't want the
[  285s]             leading space since it should be left-aligned.
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         List[str]
[  285s]         """
[  285s]         fmt_klass: type[GenericArrayFormatter]
[  285s]         if is_datetime64_dtype(values.dtype):
[  285s]             fmt_klass = Datetime64Formatter
[  285s]         elif isinstance(values.dtype, DatetimeTZDtype):
[  285s]             fmt_klass = Datetime64TZFormatter
[  285s]         elif is_timedelta64_dtype(values.dtype):
[  285s]             fmt_klass = Timedelta64Formatter
[  285s]         elif is_extension_array_dtype(values.dtype):
[  285s]             fmt_klass = ExtensionArrayFormatter
[  285s]         elif is_float_dtype(values.dtype) or is_complex_dtype(values.dtype):
[  285s]             fmt_klass = FloatArrayFormatter
[  285s]         elif is_integer_dtype(values.dtype):
[  285s]             fmt_klass = IntArrayFormatter
[  285s]         else:
[  285s]             fmt_klass = GenericArrayFormatter
[  285s]     
[  285s]         if space is None:
[  285s]             space = 12
[  285s]     
[  285s]         if float_format is None:
[  285s]             float_format = get_option("display.float_format")
[  285s]     
[  285s]         if digits is None:
[  285s]             digits = get_option("display.precision")
[  285s]     
[  285s]         fmt_obj = fmt_klass(
[  285s]             values,
[  285s]             digits=digits,
[  285s]             na_rep=na_rep,
[  285s]             float_format=float_format,
[  285s]             formatter=formatter,
[  285s]             space=space,
[  285s]             justify=justify,
[  285s]             decimal=decimal,
[  285s]             leading_space=leading_space,
[  285s]             quoting=quoting,
[  285s]         )
[  285s]     
[  285s] >       return fmt_obj.get_result()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1328: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.ExtensionArrayFormatter object at 0x7f502ba4a220>
[  285s] 
[  285s]     def get_result(self) -> list[str]:
[  285s] >       fmt_values = self._format_strings()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1359: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.ExtensionArrayFormatter object at 0x7f502ba4a220>
[  285s] 
[  285s]     def _format_strings(self) -> list[str]:
[  285s]         values = extract_array(self.values, extract_numpy=True)
[  285s]     
[  285s]         formatter = self.formatter
[  285s]         if formatter is None:
[  285s]             formatter = values._formatter(boxed=True)
[  285s]     
[  285s]         if isinstance(values, Categorical):
[  285s]             # Categorical is special for now, so that we can preserve tzinfo
[  285s]             array = values._internal_get_values()
[  285s]         else:
[  285s] >           array = np.asarray(values)
[  285s] E           ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1660: ValueError
[  285s] ____________________ TestRaggedPrinting.test_dataframe_repr ____________________
[  285s] 
[  285s] self = <datashader.tests.test_datatypes.TestRaggedPrinting object at 0x7f509cb533a0>
[  285s] data = <RaggedArray>
[  285s] [        array([0., 1.]), array([1., 2., 3., 4.]),                     nan,
[  285s]        array([-1., -2.]),   ..., 4.]),                     nan,       array([-1., -2.]),
[  285s]                      nan]
[  285s] Length: 100, dtype: Ragged[float64]
[  285s] 
[  285s]     def test_dataframe_repr(self, data):
[  285s]         df = pd.DataFrame({"A": data})
[  285s] >       repr(df)
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/tests/extension/base/printing.py:36: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f502a8d5130>
[  285s] 
[  285s]     def __repr__(self) -> str:
[  285s]         """
[  285s]         Return a string representation for a particular DataFrame.
[  285s]         """
[  285s]         if self._info_repr():
[  285s]             buf = StringIO()
[  285s]             self.info(buf=buf)
[  285s]             return buf.getvalue()
[  285s]     
[  285s]         repr_params = fmt.get_dataframe_repr_params()
[  285s] >       return self.to_string(**repr_params)
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/core/frame.py:1063: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <[ValueError('setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.') raised in repr()] DataFrame object at 0x7f502a8d5130>
[  285s] buf = None, columns = None, col_space = None, header = True, index = True
[  285s] na_rep = 'NaN', formatters = None, float_format = None, sparsify = None
[  285s] index_names = True, justify = None, max_rows = 60, max_cols = 0
[  285s] show_dimensions = 'truncate', decimal = '.', line_width = 80, min_rows = 10
[  285s] max_colwidth = 50, encoding = None
[  285s] 
[  285s]     @Substitution(
[  285s]         header_type="bool or sequence of str",
[  285s]         header="Write out the column names. If a list of strings "
[  285s]         "is given, it is assumed to be aliases for the "
[  285s]         "column names",
[  285s]         col_space_type="int, list or dict of int",
[  285s]         col_space="The minimum width of each column. If a list of ints is given "
[  285s]         "every integers corresponds with one column. If a dict is given, the key "
[  285s]         "references the column, while the value defines the space to use.",
[  285s]     )
[  285s]     @Substitution(shared_params=fmt.common_docstring, returns=fmt.return_docstring)
[  285s]     def to_string(
[  285s]         self,
[  285s]         buf: FilePath | WriteBuffer[str] | None = None,
[  285s]         columns: Sequence[str] | None = None,
[  285s]         col_space: int | list[int] | dict[Hashable, int] | None = None,
[  285s]         header: bool | Sequence[str] = True,
[  285s]         index: bool = True,
[  285s]         na_rep: str = "NaN",
[  285s]         formatters: fmt.FormattersType | None = None,
[  285s]         float_format: fmt.FloatFormatType | None = None,
[  285s]         sparsify: bool | None = None,
[  285s]         index_names: bool = True,
[  285s]         justify: str | None = None,
[  285s]         max_rows: int | None = None,
[  285s]         max_cols: int | None = None,
[  285s]         show_dimensions: bool = False,
[  285s]         decimal: str = ".",
[  285s]         line_width: int | None = None,
[  285s]         min_rows: int | None = None,
[  285s]         max_colwidth: int | None = None,
[  285s]         encoding: str | None = None,
[  285s]     ) -> str | None:
[  285s]         """
[  285s]         Render a DataFrame to a console-friendly tabular output.
[  285s]         %(shared_params)s
[  285s]         line_width : int, optional
[  285s]             Width to wrap a line in characters.
[  285s]         min_rows : int, optional
[  285s]             The number of rows to display in the console in a truncated repr
[  285s]             (when number of rows is above `max_rows`).
[  285s]         max_colwidth : int, optional
[  285s]             Max width to truncate each column in characters. By default, no limit.
[  285s]     
[  285s]             .. versionadded:: 1.0.0
[  285s]         encoding : str, default "utf-8"
[  285s]             Set character encoding.
[  285s]     
[  285s]             .. versionadded:: 1.0
[  285s]         %(returns)s
[  285s]         See Also
[  285s]         --------
[  285s]         to_html : Convert DataFrame to HTML.
[  285s]     
[  285s]         Examples
[  285s]         --------
[  285s]         >>> d = {'col1': [1, 2, 3], 'col2': [4, 5, 6]}
[  285s]         >>> df = pd.DataFrame(d)
[  285s]         >>> print(df.to_string())
[  285s]            col1  col2
[  285s]         0     1     4
[  285s]         1     2     5
[  285s]         2     3     6
[  285s]         """
[  285s]         from pandas import option_context
[  285s]     
[  285s]         with option_context("display.max_colwidth", max_colwidth):
[  285s]             formatter = fmt.DataFrameFormatter(
[  285s]                 self,
[  285s]                 columns=columns,
[  285s]                 col_space=col_space,
[  285s]                 na_rep=na_rep,
[  285s]                 formatters=formatters,
[  285s]                 float_format=float_format,
[  285s]                 sparsify=sparsify,
[  285s]                 justify=justify,
[  285s]                 index_names=index_names,
[  285s]                 header=header,
[  285s]                 index=index,
[  285s]                 min_rows=min_rows,
[  285s]                 max_rows=max_rows,
[  285s]                 max_cols=max_cols,
[  285s]                 show_dimensions=show_dimensions,
[  285s]                 decimal=decimal,
[  285s]             )
[  285s] >           return fmt.DataFrameRenderer(formatter).to_string(
[  285s]                 buf=buf,
[  285s]                 encoding=encoding,
[  285s]                 line_width=line_width,
[  285s]             )
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/core/frame.py:1244: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.DataFrameRenderer object at 0x7f502a8d5ee0>
[  285s] buf = None, encoding = None, line_width = 80
[  285s] 
[  285s]     def to_string(
[  285s]         self,
[  285s]         buf: FilePath | WriteBuffer[str] | None = None,
[  285s]         encoding: str | None = None,
[  285s]         line_width: int | None = None,
[  285s]     ) -> str | None:
[  285s]         """
[  285s]         Render a DataFrame to a console-friendly tabular output.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         buf : str, path object, file-like object, or None, default None
[  285s]             String, path object (implementing ``os.PathLike[str]``), or file-like
[  285s]             object implementing a string ``write()`` function. If None, the result is
[  285s]             returned as a string.
[  285s]         encoding: str, default “utf-8”
[  285s]             Set character encoding.
[  285s]         line_width : int, optional
[  285s]             Width to wrap a line in characters.
[  285s]         """
[  285s]         from pandas.io.formats.string import StringFormatter
[  285s]     
[  285s]         string_formatter = StringFormatter(self.fmt, line_width=line_width)
[  285s] >       string = string_formatter.to_string()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1136: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.string.StringFormatter object at 0x7f502a8d5ac0>
[  285s] 
[  285s]     def to_string(self) -> str:
[  285s] >       text = self._get_string_representation()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/string.py:30: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.string.StringFormatter object at 0x7f502a8d5ac0>
[  285s] 
[  285s]     def _get_string_representation(self) -> str:
[  285s]         if self.fmt.frame.empty:
[  285s]             return self._empty_info_line
[  285s]     
[  285s] >       strcols = self._get_strcols()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/string.py:45: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.string.StringFormatter object at 0x7f502a8d5ac0>
[  285s] 
[  285s]     def _get_strcols(self) -> list[list[str]]:
[  285s] >       strcols = self.fmt.get_strcols()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/string.py:36: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.DataFrameFormatter object at 0x7f502a8d5be0>
[  285s] 
[  285s]     def get_strcols(self) -> list[list[str]]:
[  285s]         """
[  285s]         Render a DataFrame to a list of columns (as lists of strings).
[  285s]         """
[  285s] >       strcols = self._get_strcols_without_index()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:617: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.DataFrameFormatter object at 0x7f502a8d5be0>
[  285s] 
[  285s]     def _get_strcols_without_index(self) -> list[list[str]]:
[  285s]         strcols: list[list[str]] = []
[  285s]     
[  285s]         if not is_list_like(self.header) and not self.header:
[  285s]             for i, c in enumerate(self.tr_frame):
[  285s]                 fmt_values = self.format_col(i)
[  285s]                 fmt_values = _make_fixed_width(
[  285s]                     strings=fmt_values,
[  285s]                     justify=self.justify,
[  285s]                     minimum=int(self.col_space.get(c, 0)),
[  285s]                     adj=self.adj,
[  285s]                 )
[  285s]                 strcols.append(fmt_values)
[  285s]             return strcols
[  285s]     
[  285s]         if is_list_like(self.header):
[  285s]             # cast here since can't be bool if is_list_like
[  285s]             self.header = cast(List[str], self.header)
[  285s]             if len(self.header) != len(self.columns):
[  285s]                 raise ValueError(
[  285s]                     f"Writing {len(self.columns)} cols "
[  285s]                     f"but got {len(self.header)} aliases"
[  285s]                 )
[  285s]             str_columns = [[label] for label in self.header]
[  285s]         else:
[  285s]             str_columns = self._get_formatted_column_labels(self.tr_frame)
[  285s]     
[  285s]         if self.show_row_idx_names:
[  285s]             for x in str_columns:
[  285s]                 x.append("")
[  285s]     
[  285s]         for i, c in enumerate(self.tr_frame):
[  285s]             cheader = str_columns[i]
[  285s]             header_colwidth = max(
[  285s]                 int(self.col_space.get(c, 0)), *(self.adj.len(x) for x in cheader)
[  285s]             )
[  285s] >           fmt_values = self.format_col(i)
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:883: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.DataFrameFormatter object at 0x7f502a8d5be0>
[  285s] i = 0
[  285s] 
[  285s]     def format_col(self, i: int) -> list[str]:
[  285s]         frame = self.tr_frame
[  285s]         formatter = self._get_formatter(i)
[  285s] >       return format_array(
[  285s]             frame.iloc[:, i]._values,
[  285s]             formatter,
[  285s]             float_format=self.float_format,
[  285s]             na_rep=self.na_rep,
[  285s]             space=self.col_space.get(frame.columns[i]),
[  285s]             decimal=self.decimal,
[  285s]             leading_space=self.index,
[  285s]         )
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:897: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] values = <RaggedArray>
[  285s] [        array([0., 1.]), array([1., 2., 3., 4.]),                     nan,
[  285s]        array([-1., -2.]),   ...., 4.]),                     nan,       array([-1., -2.]),
[  285s]                      nan]
[  285s] Length: 10, dtype: Ragged[float64]
[  285s] formatter = None, float_format = None, na_rep = 'NaN', digits = 6, space = 12
[  285s] justify = 'right', decimal = '.', leading_space = True, quoting = None
[  285s] 
[  285s]     def format_array(
[  285s]         values: Any,
[  285s]         formatter: Callable | None,
[  285s]         float_format: FloatFormatType | None = None,
[  285s]         na_rep: str = "NaN",
[  285s]         digits: int | None = None,
[  285s]         space: str | int | None = None,
[  285s]         justify: str = "right",
[  285s]         decimal: str = ".",
[  285s]         leading_space: bool | None = True,
[  285s]         quoting: int | None = None,
[  285s]     ) -> list[str]:
[  285s]         """
[  285s]         Format an array for printing.
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         values
[  285s]         formatter
[  285s]         float_format
[  285s]         na_rep
[  285s]         digits
[  285s]         space
[  285s]         justify
[  285s]         decimal
[  285s]         leading_space : bool, optional, default True
[  285s]             Whether the array should be formatted with a leading space.
[  285s]             When an array as a column of a Series or DataFrame, we do want
[  285s]             the leading space to pad between columns.
[  285s]     
[  285s]             When formatting an Index subclass
[  285s]             (e.g. IntervalIndex._format_native_types), we don't want the
[  285s]             leading space since it should be left-aligned.
[  285s]     
[  285s]         Returns
[  285s]         -------
[  285s]         List[str]
[  285s]         """
[  285s]         fmt_klass: type[GenericArrayFormatter]
[  285s]         if is_datetime64_dtype(values.dtype):
[  285s]             fmt_klass = Datetime64Formatter
[  285s]         elif isinstance(values.dtype, DatetimeTZDtype):
[  285s]             fmt_klass = Datetime64TZFormatter
[  285s]         elif is_timedelta64_dtype(values.dtype):
[  285s]             fmt_klass = Timedelta64Formatter
[  285s]         elif is_extension_array_dtype(values.dtype):
[  285s]             fmt_klass = ExtensionArrayFormatter
[  285s]         elif is_float_dtype(values.dtype) or is_complex_dtype(values.dtype):
[  285s]             fmt_klass = FloatArrayFormatter
[  285s]         elif is_integer_dtype(values.dtype):
[  285s]             fmt_klass = IntArrayFormatter
[  285s]         else:
[  285s]             fmt_klass = GenericArrayFormatter
[  285s]     
[  285s]         if space is None:
[  285s]             space = 12
[  285s]     
[  285s]         if float_format is None:
[  285s]             float_format = get_option("display.float_format")
[  285s]     
[  285s]         if digits is None:
[  285s]             digits = get_option("display.precision")
[  285s]     
[  285s]         fmt_obj = fmt_klass(
[  285s]             values,
[  285s]             digits=digits,
[  285s]             na_rep=na_rep,
[  285s]             float_format=float_format,
[  285s]             formatter=formatter,
[  285s]             space=space,
[  285s]             justify=justify,
[  285s]             decimal=decimal,
[  285s]             leading_space=leading_space,
[  285s]             quoting=quoting,
[  285s]         )
[  285s]     
[  285s] >       return fmt_obj.get_result()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1328: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.ExtensionArrayFormatter object at 0x7f502a8d5070>
[  285s] 
[  285s]     def get_result(self) -> list[str]:
[  285s] >       fmt_values = self._format_strings()
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1359: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] self = <pandas.io.formats.format.ExtensionArrayFormatter object at 0x7f502a8d5070>
[  285s] 
[  285s]     def _format_strings(self) -> list[str]:
[  285s]         values = extract_array(self.values, extract_numpy=True)
[  285s]     
[  285s]         formatter = self.formatter
[  285s]         if formatter is None:
[  285s]             formatter = values._formatter(boxed=True)
[  285s]     
[  285s]         if isinstance(values, Categorical):
[  285s]             # Categorical is special for now, so that we can preserve tzinfo
[  285s]             array = values._internal_get_values()
[  285s]         else:
[  285s] >           array = np.asarray(values)
[  285s] E           ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (10,) + inhomogeneous part.
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/pandas/io/formats/format.py:1660: ValueError
[  285s] __________________________ test_shade_category[array] __________________________
[  285s] 
[  285s] array = <built-in function array>
[  285s] 
[  285s]     @pytest.mark.parametrize('array', arrays)
[  285s]     def test_shade_category(array):
[  285s]         coords = [np.array([0, 1]), np.array([2, 5])]
[  285s]         cat_agg = tf.Image(array([[(0, 12, 0), (3, 0, 3)], [(12, 12, 12), (24, 0, 0)]], dtype='u4'),
[  285s]                            coords=(coords + [['a', 'b', 'c']]),
[  285s]                            dims=(dims + ['cats']))
[  285s]     
[  285s]         colors = [(255, 0, 0), '#0000FF', 'orange']
[  285s]     
[  285s] >       img = tf.shade(cat_agg, color_key=colors, how='log', min_alpha=20)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:304: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image (y_axis: 2, x_axis: 2, cats: 3)>
[  285s] array([[[ 0, 12,  0],
[  285s]         [ 3,  0,  3]],
[  285s] 
[  285s]        [[12, 12, 12],
[  285s]    ...int32)
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] cmap = ['lightblue', 'darkblue'], color_key = [(255, 0, 0), '#0000FF', 'orange']
[  285s] how = 'log', alpha = 255, min_alpha = 20, span = None, name = None
[  285s] color_baseline = None, rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image (y_axis: 2, x_axis: 2, cats: 3)>
[  285s] array([[[ 0, 12,  0],
[  285s]         [ 3,  0,  3]],
[  285s] 
[  285s]        [[12, 12, 12],
[  285s]    ...int32)
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] color_key = {'a': (255, 0, 0), 'b': '#0000FF', 'c': 'orange'}, how = 'log'
[  285s] alpha = 255, span = None, min_alpha = 20, name = None, color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[ 0, 12,  0],
[  285s]         [ 3,  0,  3]],
[  285s] 
[  285s]        [[12, 12, 12],
[  285s]         [24,  0,  0]]], dtype=uint32)
[  285s] total = array([[12,  6],
[  285s]        [36, 24]], dtype=uint64)
[  285s] mask = array([[False, False],
[  285s]        [False, False]]), how = 'log', alpha = 255
[  285s] span = None, min_alpha = 20, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] __________________ test_shade_category[create_dask_array_np] ___________________
[  285s] 
[  285s] array = <function create_dask_array_np at 0x7f508c0af5e0>
[  285s] 
[  285s]     @pytest.mark.parametrize('array', arrays)
[  285s]     def test_shade_category(array):
[  285s]         coords = [np.array([0, 1]), np.array([2, 5])]
[  285s]         cat_agg = tf.Image(array([[(0, 12, 0), (3, 0, 3)], [(12, 12, 12), (24, 0, 0)]], dtype='u4'),
[  285s]                            coords=(coords + [['a', 'b', 'c']]),
[  285s]                            dims=(dims + ['cats']))
[  285s]     
[  285s]         colors = [(255, 0, 0), '#0000FF', 'orange']
[  285s]     
[  285s] >       img = tf.shade(cat_agg, color_key=colors, how='log', min_alpha=20)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:304: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image 'array-d969c56674cdea5c004543a1ecb0ce69' (y_axis: 2, x_axis: 2,
[  285s]                                         ...array>
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] cmap = ['lightblue', 'darkblue'], color_key = [(255, 0, 0), '#0000FF', 'orange']
[  285s] how = 'log', alpha = 255, min_alpha = 20, span = None
[  285s] name = 'array-d969c56674cdea5c004543a1ecb0ce69', color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image 'array-d969c56674cdea5c004543a1ecb0ce69' (y_axis: 2, x_axis: 2,
[  285s]                                         ...array>
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] color_key = {'a': (255, 0, 0), 'b': '#0000FF', 'c': 'orange'}, how = 'log'
[  285s] alpha = 255, span = None, min_alpha = 20
[  285s] name = 'array-d969c56674cdea5c004543a1ecb0ce69', color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[ 0, 12,  0],
[  285s]         [ 3,  0,  3]],
[  285s] 
[  285s]        [[12, 12, 12],
[  285s]         [24,  0,  0]]], dtype=uint32)
[  285s] total = array([[12,  6],
[  285s]        [36, 24]], dtype=uint64)
[  285s] mask = array([[False, False],
[  285s]        [False, False]]), how = 'log', alpha = 255
[  285s] span = None, min_alpha = 20, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] ___________________________ test_shade_zeros[array] ____________________________
[  285s] 
[  285s] array = <built-in function array>
[  285s] 
[  285s]     @pytest.mark.parametrize('array', arrays)
[  285s]     def test_shade_zeros(array):
[  285s]         coords = [np.array([0, 1]), np.array([2, 5])]
[  285s]         cat_agg = tf.Image(array([[(0, 0, 0), (0, 0, 0)],
[  285s]                                   [(0, 0, 0), (0, 0, 0)]], dtype='u4'),
[  285s]                                coords=(coords + [['a', 'b', 'c']]),
[  285s]                                dims=(dims + ['cats']))
[  285s]     
[  285s]         colors = [(255, 0, 0), '#0000FF', 'orange']
[  285s]     
[  285s] >       img = tf.shade(cat_agg, color_key=colors, how='linear', min_alpha=0)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:492: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image (y_axis: 2, x_axis: 2, cats: 3)>
[  285s] array([[[0, 0, 0],
[  285s]         [0, 0, 0]],
[  285s] 
[  285s]        [[0, 0, 0],
[  285s]         [0, ...int32)
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] cmap = ['lightblue', 'darkblue'], color_key = [(255, 0, 0), '#0000FF', 'orange']
[  285s] how = 'linear', alpha = 255, min_alpha = 0, span = None, name = None
[  285s] color_baseline = None, rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image (y_axis: 2, x_axis: 2, cats: 3)>
[  285s] array([[[0, 0, 0],
[  285s]         [0, 0, 0]],
[  285s] 
[  285s]        [[0, 0, 0],
[  285s]         [0, ...int32)
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] color_key = {'a': (255, 0, 0), 'b': '#0000FF', 'c': 'orange'}, how = 'linear'
[  285s] alpha = 255, span = None, min_alpha = 0, name = None, color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[0, 0, 0],
[  285s]         [0, 0, 0]],
[  285s] 
[  285s]        [[0, 0, 0],
[  285s]         [0, 0, 0]]], dtype=uint32)
[  285s] total = array([[nan, nan],
[  285s]        [nan, nan]])
[  285s] mask = array([[ True,  True],
[  285s]        [ True,  True]]), how = 'linear'
[  285s] alpha = 255, span = None, min_alpha = 0, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] ____________________ test_shade_zeros[create_dask_array_np] ____________________
[  285s] 
[  285s] array = <function create_dask_array_np at 0x7f508c0af5e0>
[  285s] 
[  285s]     @pytest.mark.parametrize('array', arrays)
[  285s]     def test_shade_zeros(array):
[  285s]         coords = [np.array([0, 1]), np.array([2, 5])]
[  285s]         cat_agg = tf.Image(array([[(0, 0, 0), (0, 0, 0)],
[  285s]                                   [(0, 0, 0), (0, 0, 0)]], dtype='u4'),
[  285s]                                coords=(coords + [['a', 'b', 'c']]),
[  285s]                                dims=(dims + ['cats']))
[  285s]     
[  285s]         colors = [(255, 0, 0), '#0000FF', 'orange']
[  285s]     
[  285s] >       img = tf.shade(cat_agg, color_key=colors, how='linear', min_alpha=0)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:492: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image 'array-1f2122f8c2fb79e32b73175599767c4a' (y_axis: 2, x_axis: 2,
[  285s]                                         ...array>
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] cmap = ['lightblue', 'darkblue'], color_key = [(255, 0, 0), '#0000FF', 'orange']
[  285s] how = 'linear', alpha = 255, min_alpha = 0, span = None
[  285s] name = 'array-1f2122f8c2fb79e32b73175599767c4a', color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.Image 'array-1f2122f8c2fb79e32b73175599767c4a' (y_axis: 2, x_axis: 2,
[  285s]                                         ...array>
[  285s] Coordinates:
[  285s]   * y_axis   (y_axis) int64 0 1
[  285s]   * x_axis   (x_axis) int64 2 5
[  285s]   * cats     (cats) <U1 'a' 'b' 'c'
[  285s] color_key = {'a': (255, 0, 0), 'b': '#0000FF', 'c': 'orange'}, how = 'linear'
[  285s] alpha = 255, span = None, min_alpha = 0
[  285s] name = 'array-1f2122f8c2fb79e32b73175599767c4a', color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[0, 0, 0],
[  285s]         [0, 0, 0]],
[  285s] 
[  285s]        [[0, 0, 0],
[  285s]         [0, 0, 0]]], dtype=uint32)
[  285s] total = array([[nan, nan],
[  285s]        [nan, nan]])
[  285s] mask = array([[ True,  True],
[  285s]        [ True,  True]]), how = 'linear'
[  285s] alpha = 255, span = None, min_alpha = 0, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] _____________________ test_shade_all_masked[empty_array0] ______________________
[  285s] 
[  285s] empty_array = array([[[0, 0],
[  285s]         [0, 0]],
[  285s] 
[  285s]        [[0, 0],
[  285s]         [0, 0]]], dtype=uint32)
[  285s] 
[  285s]     @pytest.mark.parametrize('empty_array', empty_arrays)
[  285s]     def test_shade_all_masked(empty_array):
[  285s]         # Issue #1166, return early with array of all nans if all of data is masked out.
[  285s]         # Before the fix this test results in:
[  285s]         #   IndexError: index -1 is out of bounds for axis 0 with size 0
[  285s]         agg = xr.DataArray(
[  285s]             data=empty_array,
[  285s]             coords=dict(y=[0, 1], x=[0, 1], cat=['a', 'b']),
[  285s]         )
[  285s] >       im = tf.shade(agg, how='eq_hist', cmap=["white", "white"])
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:536: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.DataArray (y: 2, x: 2, cat: 2)>
[  285s] array([[[0, 0],
[  285s]         [0, 0]],
[  285s] 
[  285s]        [[0, 0],
[  285s]         [0, 0]]], dtype=uint32)
[  285s] Coordinates:
[  285s]   * y        (y) int64 0 1
[  285s]   * x        (x) int64 0 1
[  285s]   * cat      (cat) <U1 'a' 'b'
[  285s] cmap = ['white', 'white']
[  285s] color_key = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', ...]
[  285s] how = 'eq_hist', alpha = 255, min_alpha = 40, span = None, name = None
[  285s] color_baseline = None, rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.DataArray (y: 2, x: 2, cat: 2)>
[  285s] array([[[0, 0],
[  285s]         [0, 0]],
[  285s] 
[  285s]        [[0, 0],
[  285s]         [0, 0]]], dtype=uint32)
[  285s] Coordinates:
[  285s]   * y        (y) int64 0 1
[  285s]   * x        (x) int64 0 1
[  285s]   * cat      (cat) <U1 'a' 'b'
[  285s] color_key = {'a': '#e41a1c', 'b': '#377eb8'}, how = 'eq_hist', alpha = 255
[  285s] span = None, min_alpha = 40, name = None, color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[0, 0],
[  285s]         [0, 0]],
[  285s] 
[  285s]        [[0, 0],
[  285s]         [0, 0]]], dtype=uint32)
[  285s] total = array([[nan, nan],
[  285s]        [nan, nan]])
[  285s] mask = array([[ True,  True],
[  285s]        [ True,  True]]), how = 'eq_hist'
[  285s] alpha = 255, span = None, min_alpha = 40, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] _____________________ test_shade_all_masked[empty_array1] ______________________
[  285s] 
[  285s] empty_array = array([[[nan, nan],
[  285s]         [nan, nan]],
[  285s] 
[  285s]        [[nan, nan],
[  285s]         [nan, nan]]])
[  285s] 
[  285s]     @pytest.mark.parametrize('empty_array', empty_arrays)
[  285s]     def test_shade_all_masked(empty_array):
[  285s]         # Issue #1166, return early with array of all nans if all of data is masked out.
[  285s]         # Before the fix this test results in:
[  285s]         #   IndexError: index -1 is out of bounds for axis 0 with size 0
[  285s]         agg = xr.DataArray(
[  285s]             data=empty_array,
[  285s]             coords=dict(y=[0, 1], x=[0, 1], cat=['a', 'b']),
[  285s]         )
[  285s] >       im = tf.shade(agg, how='eq_hist', cmap=["white", "white"])
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:536: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.DataArray (y: 2, x: 2, cat: 2)>
[  285s] array([[[nan, nan],
[  285s]         [nan, nan]],
[  285s] 
[  285s]        [[nan, nan],
[  285s]         [nan, nan]]])
[  285s] Coordinates:
[  285s]   * y        (y) int64 0 1
[  285s]   * x        (x) int64 0 1
[  285s]   * cat      (cat) <U1 'a' 'b'
[  285s] cmap = ['white', 'white']
[  285s] color_key = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', ...]
[  285s] how = 'eq_hist', alpha = 255, min_alpha = 40, span = None, name = None
[  285s] color_baseline = None, rescale_discrete_levels = False
[  285s] 
[  285s]     def shade(agg, cmap=["lightblue", "darkblue"], color_key=Sets1to3,
[  285s]               how='eq_hist', alpha=255, min_alpha=40, span=None, name=None,
[  285s]               color_baseline=None, rescale_discrete_levels=False):
[  285s]         """Convert a DataArray to an image by choosing an RGBA pixel color for each value.
[  285s]     
[  285s]         Requires a DataArray with a single data dimension, here called the
[  285s]         "value", indexed using either 2D or 3D coordinates.
[  285s]     
[  285s]         For a DataArray with 2D coordinates, the RGB channels are computed
[  285s]         from the values by interpolated lookup into the given colormap
[  285s]         ``cmap``.  The A channel is then set to the given fixed ``alpha``
[  285s]         value for all non-zero values, and to zero for all zero values.
[  285s]         A dictionary ``color_key`` that specifies categories (values in ``agg``)
[  285s]         and corresponding colors can be provided to support discrete coloring
[  285s]         2D aggregates, i.e aggregates with a single category per pixel,
[  285s]         with no mixing. The A channel is set the given ``alpha`` value for all
[  285s]         pixels in the categories specified in ``color_key``, and to zero otherwise.
[  285s]     
[  285s]         DataArrays with 3D coordinates are expected to contain values
[  285s]         distributed over different categories that are indexed by the
[  285s]         additional coordinate. Such an array would reduce to the
[  285s]         2D-coordinate case if collapsed across the categories (e.g. if one
[  285s]         did ``aggc.sum(dim='cat')`` for a categorical dimension ``cat``).
[  285s]         The RGB channels for the uncollapsed, 3D case are mixed from separate
[  285s]         values over all categories. They are computed by averaging the colors
[  285s]         in the provided ``color_key`` (with one color per category),
[  285s]         weighted by the array's value for that category.
[  285s]         The A channel is then computed from the array's total value
[  285s]         collapsed across all categories at that location, ranging from the
[  285s]         specified ``min_alpha`` to the maximum alpha value (255).
[  285s]     
[  285s]         Parameters
[  285s]         ----------
[  285s]         agg : DataArray
[  285s]         cmap : list of colors or matplotlib.colors.Colormap, optional
[  285s]             The colormap to use for 2D agg arrays. Can be either a list of
[  285s]             colors (specified either by name, RGBA hexcode, or as a tuple
[  285s]             of ``(red, green, blue)`` values.), or a matplotlib colormap
[  285s]             object.  Default is ``["lightblue", "darkblue"]``.
[  285s]         color_key : dict or iterable
[  285s]             The colors to use for a categorical agg array. In 3D case, it can be
[  285s]             either a ``dict`` mapping from field name to colors, or an
[  285s]             iterable of colors in the same order as the record fields,
[  285s]             and including at least that many distinct colors. In 2D case,
[  285s]             ``color_key`` must be a ``dict`` where all keys are categories,
[  285s]             and values are corresponding colors. Number of categories does not
[  285s]             necessarily equal to the number of unique values in the agg DataArray.
[  285s]         how : str or callable, optional
[  285s]             The interpolation method to use, for the ``cmap`` of a 2D
[  285s]             DataArray or the alpha channel of a 3D DataArray. Valid
[  285s]             strings are 'eq_hist' [default], 'cbrt' (cube root), 'log'
[  285s]             (logarithmic), and 'linear'. Callables take 2 arguments - a
[  285s]             2-dimensional array of magnitudes at each pixel, and a boolean
[  285s]             mask array indicating missingness. They should return a numeric
[  285s]             array of the same shape, with ``NaN`` values where the mask was
[  285s]             True.
[  285s]         alpha : int, optional
[  285s]             Value between 0 - 255 representing the alpha value to use for
[  285s]             colormapped pixels that contain data (i.e. non-NaN values).
[  285s]             Also used as the maximum alpha value when alpha is indicating
[  285s]             data value, such as for single colors or categorical plots.
[  285s]             Regardless of this value, ``NaN`` values are set to be fully
[  285s]             transparent when doing colormapping.
[  285s]         min_alpha : float, optional
[  285s]             The minimum alpha value to use for non-empty pixels when
[  285s]             alpha is indicating data value, in [0, 255].  Use a higher value
[  285s]             to avoid undersaturation, i.e. poorly visible low-value datapoints,
[  285s]             at the expense of the overall dynamic range. Note that ``min_alpha``
[  285s]             will not take any effect when doing discrete categorical coloring
[  285s]             for 2D case as the aggregate can have only a single value to denote
[  285s]             the category.
[  285s]         span : list of min-max range, optional
[  285s]             Min and max data values to use for 2D colormapping,
[  285s]             and 3D alpha interpolation, when wishing to override autoranging.
[  285s]         name : string name, optional
[  285s]             Optional string name to give to the Image object to return,
[  285s]             to label results for display.
[  285s]         color_baseline : float or None
[  285s]             Baseline for calculating how categorical data mixes to
[  285s]             determine the color of a pixel. The color for each category is
[  285s]             weighted by how far that category's value is above this
[  285s]             baseline value, out of the total sum across all categories'
[  285s]             values. A value of zero is appropriate for counts and for
[  285s]             other physical quantities for which zero is a meaningful
[  285s]             reference; each category then contributes to the final color
[  285s]             in proportion to how much each category contributes to the
[  285s]             final sum.  However, if values can be negative or if they are
[  285s]             on an interval scale where values e.g. twice as far from zero
[  285s]             are not twice as high (such as temperature in Farenheit), then
[  285s]             you will need to provide a suitable baseline value for use in
[  285s]             calculating color mixing.  A value of None (the default) means
[  285s]             to take the minimum across the entire aggregate array, which
[  285s]             is safe but may not weight the colors as you expect; any
[  285s]             categories with values near this baseline will contribute
[  285s]             almost nothing to the final color. As a special case, if the
[  285s]             only data present in a pixel is at the baseline level, the
[  285s]             color will be an evenly weighted average of all such
[  285s]             categories with data (to avoid the color being undefined in
[  285s]             this case).
[  285s]         rescale_discrete_levels : boolean, optional
[  285s]             If ``how='eq_hist`` and there are only a few discrete values,
[  285s]             then ``rescale_discrete_levels=True`` decreases the lower
[  285s]             limit of the autoranged span so that the values are rendering
[  285s]             towards the (more visible) top of the ``cmap`` range, thus
[  285s]             avoiding washout of the lower values.  Has no effect if
[  285s]             ``how!=`eq_hist``. Default is False.
[  285s]         """
[  285s]         if not isinstance(agg, xr.DataArray):
[  285s]             raise TypeError("agg must be instance of DataArray")
[  285s]         name = agg.name if name is None else name
[  285s]     
[  285s]         if not ((0 <= min_alpha <= 255) and (0 <= alpha <= 255)):
[  285s]             raise ValueError("min_alpha ({}) and alpha ({}) must be between 0 and 255".format(min_alpha,alpha))
[  285s]     
[  285s]         if rescale_discrete_levels and how != 'eq_hist':
[  285s]             rescale_discrete_levels = False
[  285s]     
[  285s]         if agg.ndim == 2:
[  285s]             if color_key is not None and isinstance(color_key, dict):
[  285s]                 return _apply_discrete_colorkey(
[  285s]                     agg, color_key, alpha, name, color_baseline
[  285s]                 )
[  285s]             else:
[  285s]                 return _interpolate(agg, cmap, how, alpha, span, min_alpha, name, rescale_discrete_levels)
[  285s]         elif agg.ndim == 3:
[  285s] >           return _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:701: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] agg = <xarray.DataArray (y: 2, x: 2, cat: 2)>
[  285s] array([[[nan, nan],
[  285s]         [nan, nan]],
[  285s] 
[  285s]        [[nan, nan],
[  285s]         [nan, nan]]])
[  285s] Coordinates:
[  285s]   * y        (y) int64 0 1
[  285s]   * x        (x) int64 0 1
[  285s]   * cat      (cat) <U1 'a' 'b'
[  285s] color_key = {'a': '#e41a1c', 'b': '#377eb8'}, how = 'eq_hist', alpha = 255
[  285s] span = None, min_alpha = 40, name = None, color_baseline = None
[  285s] rescale_discrete_levels = False
[  285s] 
[  285s]     def _colorize(agg, color_key, how, alpha, span, min_alpha, name, color_baseline, rescale_discrete_levels):
[  285s]         if cupy and isinstance(agg.data, cupy.ndarray):
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             array = np.array
[  285s]     
[  285s]         if not agg.ndim == 3:
[  285s]             raise ValueError("agg must be 3D")
[  285s]     
[  285s]         cats = agg.indexes[agg.dims[-1]]
[  285s]         if not len(cats): # No categories and therefore no data; return an empty image
[  285s]             return Image(np.zeros(agg.shape[0:2], dtype=np.uint32), dims=agg.dims[:-1],
[  285s]                          coords=OrderedDict([
[  285s]                              (agg.dims[1], agg.coords[agg.dims[1]]),
[  285s]                              (agg.dims[0], agg.coords[agg.dims[0]]) ]), name=name)
[  285s]     
[  285s]         if color_key is None:
[  285s]             raise ValueError("Color key must be provided, with at least as many " +
[  285s]                              "colors as there are categorical fields")
[  285s]         if not isinstance(color_key, dict):
[  285s]             color_key = dict(zip(cats, color_key))
[  285s]         if len(color_key) < len(cats):
[  285s]             raise ValueError("Insufficient colors provided ({}) for the categorical fields available ({})"
[  285s]                              .format(len(color_key), len(cats)))
[  285s]     
[  285s]         colors = [rgb(color_key[c]) for c in cats]
[  285s]         rs, gs, bs = map(array, zip(*colors))
[  285s]     
[  285s]         # Reorient array (transposing the category dimension first)
[  285s]         agg_t = agg.transpose(*((agg.dims[-1],)+agg.dims[:2]))
[  285s]         data = agg_t.data.transpose([1, 2, 0])
[  285s]         if isinstance(data, da.Array):
[  285s]             data = data.compute()
[  285s]         color_data = data.copy()
[  285s]     
[  285s]         # subtract color_baseline if needed
[  285s]         baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s]         with np.errstate(invalid='ignore'):
[  285s]             if baseline > 0:
[  285s]                 color_data -= baseline
[  285s]             elif baseline < 0:
[  285s]                 color_data += -baseline
[  285s]             if color_data.dtype.kind != 'u' and color_baseline is not None:
[  285s]                 color_data[color_data<0]=0
[  285s]     
[  285s]         color_total = nansum_missing(color_data, axis=2)
[  285s]         # dot does not handle nans, so replace with zeros
[  285s]         color_data[np.isnan(data)] = 0
[  285s]     
[  285s]         # zero-count pixels will be 0/0, but it's safe to ignore that when dividing
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r = (color_data.dot(rs)/color_total).astype(np.uint8)
[  285s]             g = (color_data.dot(gs)/color_total).astype(np.uint8)
[  285s]             b = (color_data.dot(bs)/color_total).astype(np.uint8)
[  285s]     
[  285s]         # special case -- to give an appropriate color when min_alpha != 0 and data=0,
[  285s]         # take avg color of all non-nan categories
[  285s]         color_mask = ~np.isnan(data)
[  285s]         cmask_sum = np.sum(color_mask, axis=2)
[  285s]     
[  285s]         with np.errstate(divide='ignore', invalid='ignore'):
[  285s]             r2 = (color_mask.dot(rs)/cmask_sum).astype(np.uint8)
[  285s]             g2 = (color_mask.dot(gs)/cmask_sum).astype(np.uint8)
[  285s]             b2 = (color_mask.dot(bs)/cmask_sum).astype(np.uint8)
[  285s]     
[  285s]         missing_colors = np.sum(color_data, axis=2) == 0
[  285s]         r = np.where(missing_colors, r2, r)
[  285s]         g = np.where(missing_colors, g2, g)
[  285s]         b = np.where(missing_colors, b2, b)
[  285s]     
[  285s]         total = nansum_missing(data, axis=2)
[  285s]         mask = np.isnan(total)
[  285s] >       a = _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels)
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:416: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[[nan, nan],
[  285s]         [nan, nan]],
[  285s] 
[  285s]        [[nan, nan],
[  285s]         [nan, nan]]])
[  285s] total = array([[nan, nan],
[  285s]        [nan, nan]])
[  285s] mask = array([[ True,  True],
[  285s]        [ True,  True]]), how = 'eq_hist'
[  285s] alpha = 255, span = None, min_alpha = 40, rescale_discrete_levels = False
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] _________________ test_interpolate_alpha_discrete_levels_None __________________
[  285s] 
[  285s]     def test_interpolate_alpha_discrete_levels_None():
[  285s]         data = np.array([[0.0, 1.0], [1.0, 0.0]])
[  285s]         # Issue #1084: this raises a ValueError.
[  285s] >       tf._interpolate_alpha(data, data, None, "eq_hist", 0.5, None, 0.4, True)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py:1166: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] data = array([[0., 1.],
[  285s]        [1., 0.]])
[  285s] total = array([[0., 1.],
[  285s]        [1., 0.]]), mask = None, how = 'eq_hist'
[  285s] alpha = 0.5, span = None, min_alpha = 0.4, rescale_discrete_levels = True
[  285s] 
[  285s]     def _interpolate_alpha(data, total, mask, how, alpha, span, min_alpha, rescale_discrete_levels):
[  285s]     
[  285s]         if cupy and isinstance(data, cupy.ndarray):
[  285s]             from ._cuda_utils import interp, masked_clip_2d
[  285s]             array = cupy.array
[  285s]         else:
[  285s]             from ._cpu_utils import masked_clip_2d
[  285s]             interp = np.interp
[  285s]             array = np.array
[  285s]     
[  285s]         # if span is provided, use it, otherwise produce a span based off the
[  285s]         # min/max of the data
[  285s]         if span is None:
[  285s]             offset = np.nanmin(total)
[  285s]             if total.dtype.kind == 'u' and offset == 0:
[  285s]                 mask = mask | (total == 0)
[  285s]                 # If at least one element is not masked, use the minimum as the offset
[  285s]                 # otherwise the offset remains at zero
[  285s]                 if not np.all(mask):
[  285s]                     offset = total[total > 0].min()
[  285s]                 total = np.where(~mask, total, np.nan)
[  285s]     
[  285s]             a_scaled = _normalize_interpolate_how(how)(total - offset, mask)
[  285s]             discrete_levels = None
[  285s]             if isinstance(a_scaled, (list, tuple)):
[  285s]                 a_scaled, discrete_levels = a_scaled
[  285s]     
[  285s]             # All-NaN objects (e.g. chunks of arrays with no data) are valid in Datashader
[  285s] >           with np.warnings.catch_warnings():
[  285s] 
[  285s] datashader/transfer_functions/__init__.py:460: 
[  285s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  285s] 
[  285s] attr = 'warnings'
[  285s] 
[  285s]     def __getattr__(attr):
[  285s]         # Warn for expired attributes, and return a dummy function
[  285s]         # that always raises an exception.
[  285s]         import warnings
[  285s]         try:
[  285s]             msg = __expired_functions__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]     
[  285s]             def _expired(*args, **kwds):
[  285s]                 raise RuntimeError(msg)
[  285s]     
[  285s]             return _expired
[  285s]     
[  285s]         # Emit warnings for deprecated attributes
[  285s]         try:
[  285s]             val, msg = __deprecated_attrs__[attr]
[  285s]         except KeyError:
[  285s]             pass
[  285s]         else:
[  285s]             warnings.warn(msg, DeprecationWarning, stacklevel=2)
[  285s]             return val
[  285s]     
[  285s]         if attr in __future_scalars__:
[  285s]             # And future warnings for those that will change, but also give
[  285s]             # the AttributeError
[  285s]             warnings.warn(
[  285s]                 f"In the future `np.{attr}` will be defined as the "
[  285s]                 "corresponding NumPy scalar.  (This may have returned Python "
[  285s]                 "scalars in past versions.", FutureWarning, stacklevel=2)
[  285s]     
[  285s]         # Importing Tester requires importing all of UnitTest which is not a
[  285s]         # cheap import Since it is mainly used in test suits, we lazy import it
[  285s]         # here to save on the order of 10 ms of import time for most users
[  285s]         #
[  285s]         # The previous way Tester was imported also had a side effect of adding
[  285s]         # the full `numpy.testing` namespace
[  285s]         if attr == 'testing':
[  285s]             import numpy.testing as testing
[  285s]             return testing
[  285s]         elif attr == 'Tester':
[  285s]             from .testing import Tester
[  285s]             return Tester
[  285s]     
[  285s] >       raise AttributeError("module {!r} has no attribute "
[  285s]                              "{!r}".format(__name__, attr))
[  285s] E       AttributeError: module 'numpy' has no attribute 'warnings'
[  285s] 
[  285s] /usr/lib64/python3.8/site-packages/numpy/__init__.py:284: AttributeError
[  285s] =============================== warnings summary ===============================
[  285s] datashader/tests/test_dask.py: 361 warnings
[  285s] datashader/tests/test_xarray.py: 48 warnings
[  285s]   /usr/lib64/python3.8/pickle.py:329: DeprecationWarning: Please use `append` from the `scipy.optimize` namespace, the `scipy.optimize.slsqp` namespace is deprecated.
[  285s]     obj = getattr(obj, subpath)
[  285s] 
[  285s] datashader/tests/test_dask.py: 361 warnings
[  285s] datashader/tests/test_xarray.py: 48 warnings
[  285s]   /usr/lib64/python3.8/pickle.py:329: DeprecationWarning: Please use `append` from the `scipy.signal` namespace, the `scipy.signal.filter_design` namespace is deprecated.
[  285s]     obj = getattr(obj, subpath)
[  285s] 
[  285s] datashader/tests/test_dask.py: 10 warnings
[  285s] datashader/tests/test_pandas.py: 12 warnings
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/reductions.py:192: RuntimeWarning: invalid value encountered in cast
[  285s]     index = ((values - self.bin0) / self.binsize).astype(int)
[  285s] 
[  285s] datashader/tests/test_datatypes.py::TestRaggedDtype::test_is_not_string_type
[  285s]   /usr/lib/python3.8/site-packages/_pytest/python.py:199: PytestReturnNotNoneWarning: Expected None, but datashader/tests/test_datatypes.py::TestRaggedDtype::test_is_not_string_type returned False, which will be an error in a future version of pytest.  Did you mean to use `assert` instead of `return`?
[  285s]     warnings.warn(
[  285s] 
[  285s] datashader/tests/test_datatypes.py::TestRaggedDtype::test_is_not_object_type
[  285s]   /usr/lib/python3.8/site-packages/_pytest/python.py:199: PytestReturnNotNoneWarning: Expected None, but datashader/tests/test_datatypes.py::TestRaggedDtype::test_is_not_object_type returned True, which will be an error in a future version of pytest.  Did you mean to use `assert` instead of `return`?
[  285s]     warnings.warn(
[  285s] 
[  285s] datashader/tests/test_datatypes.py::TestRaggedGetitem::test_get
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/tests/test_datatypes.py:653: FutureWarning: The behavior of `series[i:j]` with an integer-dtype index is deprecated. In a future version, this will be treated as *label-based* indexing, consistent with e.g. `series[i]` lookups. To retain the old behavior, use `series.iloc[i:j]`. To get the future behavior, use `series.loc[i:j]`.
[  285s]     result = s.get(slice(2))
[  285s] 
[  285s] datashader/tests/test_raster.py: 1 warning
[  285s] datashader/tests/test_tiles.py: 2 warnings
[  285s] datashader/tests/test_transfer_functions.py: 306 warnings
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:308: RuntimeWarning: invalid value encountered in cast
[  285s]     r = interp(data, span, rspan, left=255).astype(np.uint8)
[  285s] 
[  285s] datashader/tests/test_raster.py: 1 warning
[  285s] datashader/tests/test_tiles.py: 2 warnings
[  285s] datashader/tests/test_transfer_functions.py: 306 warnings
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:309: RuntimeWarning: invalid value encountered in cast
[  285s]     g = interp(data, span, gspan, left=255).astype(np.uint8)
[  285s] 
[  285s] datashader/tests/test_raster.py: 1 warning
[  285s] datashader/tests/test_tiles.py: 2 warnings
[  285s] datashader/tests/test_transfer_functions.py: 306 warnings
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:310: RuntimeWarning: invalid value encountered in cast
[  285s]     b = interp(data, span, bspan, left=255).astype(np.uint8)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py: 42 warnings
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:320: RuntimeWarning: invalid value encountered in cast
[  285s]     a = interp(data, span, aspan, left=0, right=255).astype(np.uint8)
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py::test_shade_all_masked[empty_array1]
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:380: RuntimeWarning: All-NaN slice encountered
[  285s]     baseline = np.nanmin(color_data) if color_baseline is None else color_baseline
[  285s] 
[  285s] datashader/tests/test_transfer_functions.py::test_shade_all_masked[empty_array1]
[  285s]   /home/abuild/rpmbuild/BUILD/datashader-0.14.4/datashader/transfer_functions/__init__.py:445: RuntimeWarning: All-NaN slice encountered
[  285s]     offset = np.nanmin(total)
[  285s] 
[  285s] -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
[  285s] =========================== short test summary info ============================
[  285s] FAILED datashader/tests/test_dask.py::test_line_manual_range[df_kwargs5-cvs_kwargs5-dask_DataFrame]
[  285s] FAILED datashader/tests/test_dask.py::test_area_to_zero_fixedrange[df_kwargs3-cvs_kwargs3-dask_DataFrame]
[  285s] FAILED datashader/tests/test_dask.py::test_area_to_zero_autorange_gap[df_kwargs3-cvs_kwargs3-dask_DataFrame]
[  285s] FAILED datashader/tests/test_dask.py::test_area_to_line_autorange_gap[df_kwargs3-cvs_kwargs3-dask_DataFrame]
[  285s] FAILED datashader/tests/test_datatypes.py::TestRaggedPrinting::test_series_repr
[  285s] FAILED datashader/tests/test_datatypes.py::TestRaggedPrinting::test_dataframe_repr
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_category[array]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_category[create_dask_array_np]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_zeros[array]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_zeros[create_dask_array_np]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_all_masked[empty_array0]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_shade_all_masked[empty_array1]
[  285s] FAILED datashader/tests/test_transfer_functions.py::test_interpolate_alpha_discrete_levels_None
[  285s] = 13 failed, 794 passed, 69 skipped, 2 xfailed, 1814 warnings in 277.58s (0:04:37) =
[  289s] error: Bad exit status from /var/tmp/rpm-tmp.J7ABT2 (%check)

@ianthomas23
Copy link
Member Author

@bnavigator Yes, you are right. I will deal with this.

pmav99 added a commit to pmav99/Thalassa that referenced this issue May 5, 2023
`datashader` up to 1.14.4 was using `numpy.warnings` which got removed in 1.24.
They have fixed this on master, but they have not released a new version yet.
Adding this pin forces us to make a new thalassa release as soon as 1.14.5 gets released,
because if we don't we won't be able to use thalassa with up to date numpy versions.

holoviz/datashader#1158
pmav99 added a commit to pmav99/Thalassa that referenced this issue May 5, 2023
`datashader` up to 1.14.4 was using `numpy.warnings` which got removed in 1.24.
They have fixed this on master, but they have not released a new version yet.
Adding this pin forces us to make a new thalassa release as soon as 1.14.5 gets released,
because if we don't we won't be able to use thalassa with up to date numpy versions.

holoviz/datashader#1158
pmav99 added a commit to pmav99/Thalassa that referenced this issue May 5, 2023
`datashader` up to 1.14.4 was using `numpy.warnings` which got removed in 1.24.
They have fixed this on master, but they have not released a new version yet.
Adding this pin forces us to make a new thalassa release as soon as 1.14.5 gets released,
because if we don't we won't be able to use thalassa with up to date numpy versions.

holoviz/datashader#1158
pmav99 added a commit to pmav99/Thalassa that referenced this issue May 5, 2023
`datashader` up to 1.14.4 was using `numpy.warnings` which got removed in 1.24.
They have fixed this on master, but they have not released a new version yet.
Adding this pin forces us to make a new thalassa release as soon as 1.14.5 gets released,
because if we don't we won't be able to use thalassa with up to date numpy versions.

holoviz/datashader#1158
pmav99 added a commit to pmav99/Thalassa that referenced this issue May 5, 2023
`datashader` up to 1.14.4 was using `numpy.warnings` which got removed in 1.24.
They have fixed this on master, but they have not released a new version yet.
Adding this pin forces us to make a new thalassa release as soon as 1.14.5 gets released,
because if we don't we won't be able to use thalassa with up to date numpy versions.

holoviz/datashader#1158
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants