1

Problem description:

When using the QuadMesh plot in HoloViews one can observe white lines between all quadrilateral tiles even when using options like line_alpha=0, line_width=0.

Default behaviour

These apparent lines are actually gaps between the quads, since if one replaces `bgcolor='black') the lines will appear black.

Enabling lines via linea_alpha=1, line_width=1, line_color='m' will paint the gaps over with magenta lines.

Forced line and background coloring

Question

Is it possible to eliminate these lines and if so, how should I go about doing it?

This may not much of a problem in case of a curvilinear tiling, but my actual data results in axisparallel tiling and incredibly ugly aliasing artefacts (I can't use Image since data is not equidistant).

Minimal working example

Would be the default examples from the HoloViews gallery referenced above:

import numpy as np
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')

n = 20
coords = np.linspace(-1.5, 1.5, n)
X,Y = np.meshgrid(coords, coords);
Qx = np.cos(Y) - np.cos(X)
Qz = np.sin(Y) + np.sin(X)
Z = np.sqrt(X**2 + Y**2)

qmesh = hv.QuadMesh((Qx, Qz, Z))

#plot default
qmesh

#plot with black background and magenta lines
qmesh.opts(line_alpha=1, line_width=1, line_color='m', bgcolor='black')
BigBen
  • 46,229
  • 7
  • 24
  • 40
Nox
  • 324
  • 3
  • 18
  • The above has been produced with `1.14.6` within a Jupyter notebook as well as an IPython console using Python 3. I was able to reproduce the problem on two different machines using Python 3.6.15 and 3.6.5 as well as Bokeh 2.3.1 and 2.3.3. – Nox Apr 06 '22 at 18:04

1 Answers1

2

You can't remove them.

holoviews QuadMesh builds irregular meshes with bokeh Patches glyphs

As of bokeh 2.4.2 it somehow has built-in gaps between adjacent patches as can be seen in that small sample code:

import numpy as np

from bokeh.models import ColumnDataSource, Patches
from bokeh.plotting import figure
from bokeh.io import show

xpts = np.array([0, 0, 1, 1])
ypts = np.array([0, 1, 1, 0])

source = ColumnDataSource(dict(
        xs=np.array([(xpts+j) for i in range(5) for j in range(5)]),
        ys=np.array([ypts+i for i in range(5) for j in range(5)]),
    )
)

fig = figure(
    title=None, width=300, height=300,
    min_border=0,background_fill_color="red")

glyph = Patches(xs="xs", ys="ys", fill_color="white",line_width=0)
fig.add_glyph(source, glyph)
fig.ygrid.visible = False
fig.xgrid.visible = False
show(fig)

enter image description here

So if you use holoview QuadMesh with bokeh to plot e.g. high resolution data with many patches, your zoomed out map colors will look all washed out because of all those gap lines between patches that let the background color through:

import numpy as np
from bokeh.models import ColumnDataSource, Patches
from bokeh.plotting import figure
from bokeh.io import show
from bokeh.palettes import viridis
import random

xpts = np.array([0, 0, 1, 1])
ypts = np.array([0, 1, 1, 0])

nx = 1000
ny = 500
colors = viridis(24)
source = ColumnDataSource(data=dict(
xs=np.array([(xpts+j) for i in range(ny) for j in range(nx)]),
ys=np.array([ypts+i for i in range(ny) for j in range(nx)]),
colors=np.array([random.choice(colors) for i in range(nx*ny)])
))

fig = figure(
    title=None, width=300, height=300,
    min_border=0)


glyph = Patches(xs="xs", ys='ys', fill_color='colors',line_width=0)
fig.add_glyph(source,glyph)
fig.ygrid.visible = False
fig.xgrid.visible = False
show(fig)

enter image description here

Compare to a similar map generated with matplotlib's pcolormesh to see how much more vibrant the colors should be:

import matplotlib.pyplot as plt
mpl_fig,ax = plt.subplots()
zz = np.random.rand(ny,nx)
ax.pcolormesh(zz)
plt.show(mpl_fig)

enter image description here

I opened an issue on bokeh's github: https://github.com/bokeh/bokeh/issues/12085

Seb
  • 1,765
  • 9
  • 23
  • Thanks for the explanation and the issue! I suspected a Bokeh problem, too, after trying it with the Matplotlib backend, but given a prior discussion in the comments (now gone) was unsure whether the problem may be the way BokehJS is treated. – Nox Apr 09 '22 at 19:03