数据着色器 canvas.line() 别名

Lou*_*ouc 4 python data-visualization bokeh datashader

我使用散景来绘制温度曲线,但在某些情况下,数据集非常大(> 500k 测量值)并且我对散景的用户体验滞后(事件与 output_backend="webgl")。所以我正在试验数据着色器以获得更快的渲染和更流畅的用户体验。

但是datashader给出的视觉效果没有bokeh的结果好看,datashader的结果有锯齿:

在此处输入图片说明

我通过以下代码获得了这种并排比较:

import pandas as pd
import datashader as ds
import datashader.transfer_functions as tf
from bokeh.plotting import figure
from bokeh.io import output_notebook, show
from bokeh.models import ColumnDataSource
from bokeh.layouts import row
import numpy as np

output_notebook()

# generate signal
n = 2000
start = 0
end = 70
signal = [np.sin(x) for x in np.arange(start, end, step=(end-start)/n)]
signal = pd.DataFrame(signal, columns=["signal"])
signal = signal.reset_index()

# create a bokeh plot
source = ColumnDataSource(signal)
p = figure(plot_height=300, plot_width=400, title="bokeh plot")
p.line(source=source, x="index", y="signal")

# create a datashader image and put it in a bokeh plot
x_range = (signal["index"].min(), signal["index"].max())
y_range = (signal["signal"].min(), signal["signal"].max())
cvs = ds.Canvas(x_range=x_range, y_range=y_range, plot_height=300, plot_width=400)
agg = cvs.line(signal, 'index', 'signal')
img = tf.shade(agg)
image_source = ColumnDataSource(data=dict(image = [img.data]))
q = figure(x_range=x_range, y_range=y_range, plot_height=300, plot_width=400, title="datashader + bokeh")
q.image_rgba(source = image_source,
             image="image",
             dh=(y_range[1] - y_range[0]),
             dw=(x_range[1] - x_range[0]),
             x=x_range[0],
             y=y_range[0],
             dilate=False)

# visualize both plot, bokeh on left
show(row(p, q))
Run Code Online (Sandbox Code Playgroud)

您知道如何修复这种混叠并获得平滑的结果吗?(类似于散景的结果)

Jam*_*nar 5

这是您的代码的可运行版本,在 Jupyter 笔记本中使用 HoloViews:

import pandas as pd, numpy as np, holoviews as hv
from holoviews.operation.datashader import datashade, dynspread
hv.extension("bokeh")
%opts Curve RGB [width=400]
n, start, end = 2000, 0, 70
sine = [np.sin(x) for x in np.arange(start, end, step=(end-start)/n)]
signal = pd.DataFrame(sine, columns=["signal"]).reset_index()
curve = hv.Curve(signal)

curve + datashade(curve)
Run Code Online (Sandbox Code Playgroud)

前

确实,这里的数据阴影输出看起来不太好。与 datashader 的其余部分一样,Datashader 的时间序列支持旨在允许对栅格网格上大量数学上完美(即无限细)的曲线进行准确的累积和求和,以便每条曲线上的每个 x 位置都落入一个且唯一网格中的一个 y 位置。在这里,您似乎只是想要大型时间序列的服务器端渲染,这需要对网格中的多个附近 bin 进行部分递增,并且数据着色器尚未针对此进行优化。

您已经可以做的一件事是以高分辨率渲染曲线,然后“展开”它,以便每个非零像素也将显示在相邻像素中:

curve + dynspread(datashade(curve, height=1200, width=1200, dynamic=False, \
                            cmap=["#30a2da"]), max_px=3, threshold=1)
Run Code Online (Sandbox Code Playgroud)

传播

在这里,我将颜色设置为匹配 Bokeh 的默认值,然后强制 HoloView 的“dynspread”功能扩展 3 个像素。在您的版本中使用 Datashader+Bokeh,您将执行 ``img = tf.spread(tf.shade(agg), px=3)` 并增加 Canvas 调用中的绘图大小以获得类似的结果。

我还没有尝试过对 tf.shade() 或 tf.spread() 的结果运行简单的平滑过滤器,但它们都只返回 RGB 图像,所以一些像这样的过滤器可能会产生很好的结果。

真正的解决方案是为数据着色器实现一个可选的抗锯齿线条绘制功能,在首先绘制线条时运行而不是稍后修复像素,但这需要一些工作。欢迎投稿!