Personal opinions about best practices for Panel + HoloViews

Sorry, but I still don’t see the relation to the modal-browser issue.
Do you think because of endless dmap retriggering the object is not rendered in chrome/edge?

Oh sorry, I’m just using this thread to take notes for an eventual best practices guide; not as a reply to your question.

I would love to see how you create more complicated Holoviews objects from scratch and even more interested in how you set options. I have been struggling setting opts such as line_color or other more niche options while overlaying geofeatures and other plots (Say FilledContours, WindBarbs and coastline). It gets even trickier if you try and change them later as now it is an Overlay.

I have been struggling setting opts such as line_color or other more niche options while overlaying geofeatures and other plots

You can target specific elements: Overlay([hv_obj1, hv_obj2]).opts("Curve", line_color="red")


Collecting more best practices things here:

  • Generally, try to replace HoloViews usage with hvPlot. At a certain point of complexity, such as with the use of ‘.select’, it might be better to stick with HoloViews.
  • Almost always, try to replace the use of datashade with rasterize (read this page). Essentially, rasterize allows Bokeh to handle the colormapping instead of Datashader.
  • Remove all pn.interact usage
  • Try to avoid .param.watch() usage. This is pretty low-level and verbose approach Prefer using pn.bind(). Read this page for explanation.
  • For apps built using a class approach, when they create a view() method and call it directly, update the class by inheriting from pn.viewable.Viewer and replace view() by __panel__(). Here is an example.
3 Likes

Revising:

set loading=True/False inside a try/finally block 6 so that widgets are disabled while loading, and upon completion/something goes wrong, the widgets are always reactivated.

Philipp mentioned we could simply do with param.update

import time
import panel as pn

pn.extension()

layout = pn.WidgetBox(pn.widgets.TextInput(), pn.widgets.Button(name="Click me!"))
layout
with layout.param.update(loading=True):
    time.sleep(2)
    layout[0].value = "Loaded!"

From Marc

1 Like

Using flexbox instead of column / row

1 Like

Adding another to the list: toggling axiswise, framewise, shared_axes,

Started migrating over here; let me know if you have feedback!

1 Like

Widgets should not be used like param