Hvplot.points (bokeh) returns "failed to validate CategoricalColorMapper" error

I’m trying to figure out what triggers the following error:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/mamba/envs/viz/lib/python3.10/site-packages/bokeh/application/handlers/code_runner.py”, line 229, in run
exec(self._code, module.dict)
File “…/6-MODEL_ARGO_GUI_test_geomap.py”, line 669, in
).servable()
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/template/base.py”, line 517, in servable
return super().servable(title, location, area, target)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/viewable.py”, line 392, in servable
self.server_doc(title=title, location=location) # type: ignore
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/template/base.py”, line 480, in server_doc
return self._init_doc(doc, title=title, location=location)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/template/base.py”, line 726, in _init_doc
document = super()._init_doc(doc, comm, title, notebook, location)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/template/base.py”, line 217, in _init_doc
model = obj.get_root(document, comm, preprocess=False)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 306, in get_root
root = super().get_root(doc, comm, preprocess)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/viewable.py”, line 666, in get_root
root = self._get_model(doc, comm=comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 174, in _get_model
objects, _ = self._get_objects(model, , doc, root, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 156, in _get_objects
child = pane._get_model(doc, root, model, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 174, in _get_model
objects, _ = self._get_objects(model, , doc, root, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 156, in _get_objects
child = pane._get_model(doc, root, model, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/param.py”, line 936, in _get_model
return super()._get_model(doc, root, parent, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/pane/base.py”, line 578, in _get_model
model = self._inner_layout._get_model(doc, root, parent, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 174, in _get_model
objects, _ = self._get_objects(model, , doc, root, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/layout/base.py”, line 156, in _get_objects
child = pane._get_model(doc, root, model, comm)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/pane/holoviews.py”, line 411, in _get_model
plot = self._render(doc, comm, root)
File “/mamba/envs/viz/lib/python3.10/site-packages/panel/pane/holoviews.py”, line 506, in _render
return renderer.get_plot(self.object, **kwargs)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/bokeh/renderer.py”, line 70, in get_plot
plot = super().get_plot(obj, doc, renderer, **kwargs)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/renderer.py”, line 241, in get_plot
plot.update(init_key)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/plot.py”, line 943, in update
return self.initialize_plot()
File “/mamba/envs/viz/lib/python3.10/site-packages/geoviews/plotting/bokeh/plot.py”, line 106, in initialize_plot
fig = super().initialize_plot(ranges, plot, plots, **opts)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/bokeh/element.py”, line 2773, in initialize_plot
child = subplot.initialize_plot(ranges, plot, plots)
File “/mamba/envs/viz/lib/python3.10/site-packages/geoviews/plotting/bokeh/plot.py”, line 106, in initialize_plot
fig = super().initialize_plot(ranges, plot, plots, **opts)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/bokeh/element.py”, line 1778, in initialize_plot
self._init_glyphs(plot, element, ranges, source)
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/plotting/bokeh/element.py”, line 1703, in _init_glyphs
with abbreviated_exception():
File “/mamba/envs/viz/lib/python3.10/site-packages/holoviews/core/options.py”, line 225, in exit
raise AbbreviatedException(etype, value, traceback)
holoviews.core.options.AbbreviatedException: ValueError: failed to validate CategoricalColorMapper(id=‘p1082’, …).factors: expected an element of either Seq(String), Seq(Tuple(String, String)) or Seq(Tuple(String, String, String)), got [-0.34630941924213765, -0.4202230403471461, -0.3321700288005509, -0.9989590278007672, -0.5261225993629424, -0.0952936117037364, -0.43282313436553466, -0.24268420243700106, -0.1786957920901429, 0.022206698300738736, -0.039250622364924936, 0.21170466334610297, -0.39013164439502646, -0.44546568208507153, -0.2212580753494784, 0.022712925118433702, 0.04364170573260395, 0.10903284718489914, 0.013821613282480882, -0.003143788745299858, -0.23108050434390037, -0.22219131202012932, 0.14258368320847836, -0.22097263296400982, -0.49395507658525234, -0.07763258509842785, 0.043733680527651586, -0.05620057774345, -0.17371156792899356, -0.12019083181504175, -0.12115438118392419, -0.23667801623627582, -0.0526391712426566, -0.08124337331406295, -0.2916591379123794, -0.43858576667945925, 0.04190594487187482, -0.014453387897209069, -0.2975835854494022, 0.08817866833065224, -0.19082593394217612, -0.2875591216721194, -0.0013185848550119061, -0.059245835887800524, 0.12684935353144766, -0.20466765176568202, -0.12553738101451373, -0.40925789890151165, 0.043694770251082815, 0.055833996596632574, 0.0367208757597588, 0.1280095028078243, -0.36268115290449643, -0.008924797631742365, 0.045819814498052835, -0.0716739507484121, -0.21369568362442948, 0.06664210592850583, 0.06633172588939473, 0.0790012330610601, 0.32713836094033333, 0.030373957920498462, 0.1641101837158203, 0.0924391370261688, -0.03690754496699711, -0.06230441245367402, 0.07849442279228569, 0.5508243641018282, 0.05856314562244123, 0.017195817359844767, -0.10619775282400212, -0.04660030911026425, 0.17014638456302933, 0.13892927964195323, 0.17035625269798516, -0.007196986797679728, -0.3144479130818077, 0.029479162735871256, 0.26783113140781795, 0.1792907577204943, 0.013725600716192332, -0.006785046628849045, 0.29130585128689646, -0.009153291921844442, -0.009808297009905686, 0.5989034693842541, 0.22338631307598433, 0.01250689141786765, 0.11643001740953451, 0.05659525648026076, 0.07665853834694261, -0.10538185249939858, -0.04762511800411673, 0.11359280234653113, 0.19731671840577292, 0.3279444607928603, 0.1336680352588182, -0.08909647127726927, -0.07526511170729222, 0.0037658908557176574, 0.26484615423526847, 0.0002515623486587515, -0.22495797592259947, 0.15544552988244575, -0.015755071675986443, -0.2120739861469602, -0.12281035064229898, 0.2100741750669748, -0.042553098710243376, -0.12155341184075397, 0.02928510850351529, 0.49658239139113647, -0.053715358908071664, 0.24061017369891785, 0.018680898143003333, -0.02209535160764986, -0.0194173061914249, -0.05481994811136914, -0.35714651432309097, -0.16143944658193732, -0.13841891818298535, -0.09694140684042907, 0.4159072464900859, -0.04905891418457031, 0.4015327346902495, -0.20117707718419453, -0.19463243506504213, -0.08324001264773173, 0.5964542675493689, 0.7322087015126542, -0.06418997528140835, -0.19471681855671719, -0.10356271494466895, 0.6689871694210119, 0.019051822934205376, 0.6459767336699507, -0.17578550614679145, 0.06246103333706543, 0.08191645607262998, 0.4585457346953792, -0.2443389892578125, -0.12290700373799623, 0.18758716579300128, 0.031181478933703488, -0.005461421107689546, 0.027284323367585017, -0.5866477337197835, -0.5128156135337129, -0.13555161799440896, -0.03779983748008675, -0.10924145578613179, -0.0469952098308859, 0.11655751616721055, -0.0036847268503947816, 0.24990453503347076, 0.15486376512294342, -0.19468913165885482, -0.1019133891536157, -0.28469580725389676, 0.07403538480798844, -0.03755195840267689, 0.10632163764766034, -0.18004448359271663, 0.06774136846251722, 0.11081308939777657, -0.050663245222896336, -0.22219548040963488, -0.20766196913231028, -0.047110353864802335, 0.01580284951930011, -0.44889071561413163, -0.04205193788354222, -0.10759075435317556, -0.11852678974886288, -0.09282568158788251, 0.156578224862443, 0.09178983907458971, 0.018758816276841728, -0.14386632426391088, 0.010333574162071812, 0.10409523072703664, -0.2892130251426295]

The error occurs in a larger application after some dataframe filtering manipulation …

But a simple example of what it should do is given by the following piece of code:

Essentialy, three columns of a dataframe (“lon”,“lat”, and variable =“tmo” or “smo”) are used to plot points on a geographical map. The points should be colored according to the values in the column “tmo” or “smo” which are floats (model errors).

The error message shown above complains that it’s getting an array of floats instead of the name of a column (string) it seems … (the values displayed are indeed the correct values of the dataframe column, “tmo”, passed as the actual argument “c=” in hvplot.points( )). I’m really passing c=“tmo” (the string name) …


def geomap(df2plot,variable):

#df2plot is a dataframe

variable is the name of a column in the dataframe

#“index” “ID” “lon” “lat” “date” “zobs” “tmo” “smo”
#0 2902761 130.41200 18.59300 20190603 2.91232 -0.346309 0.001427
#1 2902720 132.18400 19.76500 20190603 4.025281 -0.420223 -0.03113

print("lon",df2plot['lon'])
print("lat",df2plot['lat'])
print("tmo",df2plot['tmo'])    

ctitle="debug_hvplot_color"
pointmap = df2plot.hvplot.points(
        **x='lon',** 
        **y='lat',**
        **color=variable,**
        clim=(-1,1),
        size=30,
        geo=True,
        tiles='EsriImagery',
        coastline=True,
        cmap='bwr',
        cnorm='linear',
        data_aspect=1.0,
        colorbar=True,
        xlim=(130,180),
        ylim=(10,30),
        title=ctitle).opts(xlabel='lon', ylabel='lat')
   
return pointmap

print(“df2plot=”,df2plot)

view=geomap(df2plot,‘tmo’)

template = pn.template.FastListTemplate(
title=“Debug hvplot”,
main=[pn.Column(view)],
accent_base_color=“#88d8b0”,
header_background=“#88d8b0”,
sidebar_width=200,
).servable()

The map should look something like this:

Any ideas would be appreciated.

Thanks.


Latest Update:

I tried replacing

df2plot.hvplot.points(x=‘lon’,y=‘lat’, color=‘tmo’, …
by
df2plot.hvplot.points(x=‘lon’,y=‘lat’, color= color=dict({“field”:str(variable)}),

inspired by the docstring in “dataspec” core property in bokeh’s source code.

Now the error message is

2023-10-20 17:59:57,840 E-1001 (BAD_COLUMN_NAME): Glyph refers to nonexistent column name. This could either be due to a misspelling or typo, or due to an expected column being missing. : fill_color=‘tmo’ [no close matches], hatch_color=‘tmo’ [no close matches], line_color=‘tmo’ [no close matches] {renderer: GlyphRenderer(id=‘p1091’, …)}


Just before the df.hvplot.points() command the dataframe is what
I expect based on a few print() statements about the dataframe df2plot:

variable,type(df2plot[variable])= tmo <class ‘pandas.core.series.Series’>
df2plot.index= RangeIndex(start=0, stop=182, step=1)
df2plot.columns= Index([‘ID’, ‘lon’, ‘lat’, ‘date’, ‘datetime’, ‘tmo0’, ‘kmin’, ‘kmax’, ‘zobs’, ‘tmo’, ‘smo’, ‘smo0’], dtype=‘object’)
plot_profile_exploded: variable= tmo

Weird, the column ‘tmo’ is not found by hvplot.points() but is present in the df2plot.columns list! :slight_smile:

Reference to Bokeh source:

class DataSpec(Either):
“”" Base class for properties that accept either a fixed value, or a
string name that references a column in a
:class:~bokeh.models.sources.ColumnDataSource.

Many Bokeh models have properties that a user might want to set either
to a single fixed value, or to have the property take values from some
column in a data source. As a concrete example consider a glyph with
an ``x`` property for location. We might want to set all the glyphs
that get drawn to have the same location, say ``x=10``. It would be
convenient to  just be able to write:

.. code-block:: python

    glyph.x = 10

Alternatively, maybe the each glyph that gets drawn should have a
different location, according to the "pressure" column of a data
source. In this case we would like to be able to write:

.. code-block:: python

    glyph.x = "pressure"

Bokeh ``DataSpec`` properties (and subclasses) afford this ease of
and consistency of expression. Ultimately, all ``DataSpec`` properties
resolve to dictionary values, with either a ``"value"`` key, or a
``"field"`` key, depending on how it is set.

For instance:

.. code-block:: python

    glyph.x = 10          # => { 'value': 10 }

    glyph.x = "pressure"  # => { 'field': 'pressure' }

When these underlying dictionary dictionary values are received in
the browser, BokehJS knows how to interpret them and take the correct,
expected action (i.e., draw the glyph at ``x=10``, or draw the glyph
with ``x`` coordinates from the "pressure" column). In this way, both
use-cases may be expressed easily in python, without having to handle
anything differently, from the user perspective.

It is worth noting that ``DataSpec`` properties can also be set directly
with properly formed dictionary values:

.. code-block:: python

    glyph.x = { 'value': 10 }         # same as glyph.x = 10

    glyph.x = { 'field': 'pressure' } # same as glyph.x = "pressure"

Setting the property directly as a dict can be useful in certain
situations. For instance some ``DataSpec`` subclasses also add a
``"units"`` key to the dictionary. This key is often set automatically,
but the dictionary format provides a direct mechanism to override as
necessary. Additionally, ``DataSpec`` can have a ``"transform"`` key,
that specifies a client-side transform that should be applied to any
fixed or field values before they are uses. As an example, you might want
to apply a ``Jitter`` transform to the ``x`` values:

.. code-block:: python

    glyph.x = { 'value': 10, 'transform': Jitter(width=0.4) }

Note that ``DataSpec`` is not normally useful on its own. Typically,
a model will define properties using one of the subclasses such
as :class:`~bokeh.core.properties.NumberSpec` or
:class:`~bokeh.core.properties.ColorSpec`. For example, a Bokeh
model with ``x``, ``y`` and ``color`` properties that can handle
fixed values or columns automatically might look like:

.. code-block:: python

    class SomeModel(Model):

        x = NumberSpec(default=0, help="docs for x")

        y = NumberSpec(default=0, help="docs for y")

        color = ColorSpec(help="docs for color") # defaults to None

"""

bokeh.core.property.dataspec — Bokeh 3.3.0 Documentation