如何在数据着色器热图中填充或插入空 space(欠采样)的稀疏数据?
How do you fill or intrerpolate sparse data empty space (undersampling) in a datashader heatmap?
在数据着色器中绘制一组数据时,如果 X 轴具有离散数字和欠采样,则会在可以看到背景的列之间留出间隙。
我一直在尝试通过尝试设置更大的点大小或使用 dynspread 传递函数来解决此问题。运气不好 - 很可能是我不知道应用这些的正确方法。
这里是重现我的意思的示例代码:
import pandas as pd
import numpy as np
import datashader as ds, colorcet
import holoviews as hv
from holoviews.operation.datashader import datashade
from holoviews import opts
# generate random dataset 0 - 10000
image = np.random.randn(250, 1024, 1024) + 10000
z, x, y = image.shape
print("z, x, y =", z, x, y)
# rearrange data to 'z' + 'value' array and convert to dataframe
arr = np.column_stack((np.repeat(np.arange(z),y*x), image.ravel()))
df = pd.DataFrame(arr, columns = ['X', 'Y'])
### Plot using in datashader
map = ds.Canvas(plot_width=800, plot_height=800)
agg = map.points(df, 'X', 'Y' )
pts = ds.tf.shade(agg, cmap=colorcet.fire)
ds.tf.set_background(pts, 'white')
当然,使用散景绘制同一组图像显示的是同一件事。更糟糕的是,如果你放大:
hv.extension("bokeh")
datashade(hv.Points(df), cmap=colorcet.fire).relabel('Value heatmap').opts(height=700, width=800)
Datashader 在这种情况下按设计工作。当将点渲染到栅格网格中时,它会向您显示可用的实际点数据,直到像素网格可以显示的限制为止。如果一个像素中有多个数据点,则聚合它们的计数或值。如果某些像素没有数据,则不显示数据。
听起来您想要的绘图类型不同于数据阴影像素热图。也许:
- 如果您的数据代表来自底层栅格或四边形网格的常规样本,请使用数据阴影 hv.Image or hv.Quadmesh 图(或直接调用 canvas.raster 或 canvas.quadmesh),而不是 hv.Points 或 canvas.points 图
- 如果您的数据代表来自基础连续分布的任意位置的样本,您可以在计算 Delaunay 或其他类型的三角剖分后使用数据阴影 hv.TriMesh 或 canvas.trimesh 图填充点之间以便它定义一个表面。
- 如果您的数据代表来自非连续分布的任意位置的样本,但您仍想用连续函数对其进行近似,则可以使用(非数据阴影)hv.Bivariate 图,计算平滑内核密度估计可以有效地“连接点”,如您所描述的,但也可以消除局部密度差异。
None 这些选项完全符合您在这里的要求,但我认为 TriMesh 的行为最符合您的建议,同时对于缩小的情况仍然表现相似。
在数据着色器中绘制一组数据时,如果 X 轴具有离散数字和欠采样,则会在可以看到背景的列之间留出间隙。
我一直在尝试通过尝试设置更大的点大小或使用 dynspread 传递函数来解决此问题。运气不好 - 很可能是我不知道应用这些的正确方法。
这里是重现我的意思的示例代码:
import pandas as pd
import numpy as np
import datashader as ds, colorcet
import holoviews as hv
from holoviews.operation.datashader import datashade
from holoviews import opts
# generate random dataset 0 - 10000
image = np.random.randn(250, 1024, 1024) + 10000
z, x, y = image.shape
print("z, x, y =", z, x, y)
# rearrange data to 'z' + 'value' array and convert to dataframe
arr = np.column_stack((np.repeat(np.arange(z),y*x), image.ravel()))
df = pd.DataFrame(arr, columns = ['X', 'Y'])
### Plot using in datashader
map = ds.Canvas(plot_width=800, plot_height=800)
agg = map.points(df, 'X', 'Y' )
pts = ds.tf.shade(agg, cmap=colorcet.fire)
ds.tf.set_background(pts, 'white')
当然,使用散景绘制同一组图像显示的是同一件事。更糟糕的是,如果你放大:
hv.extension("bokeh")
datashade(hv.Points(df), cmap=colorcet.fire).relabel('Value heatmap').opts(height=700, width=800)
Datashader 在这种情况下按设计工作。当将点渲染到栅格网格中时,它会向您显示可用的实际点数据,直到像素网格可以显示的限制为止。如果一个像素中有多个数据点,则聚合它们的计数或值。如果某些像素没有数据,则不显示数据。
听起来您想要的绘图类型不同于数据阴影像素热图。也许:
- 如果您的数据代表来自底层栅格或四边形网格的常规样本,请使用数据阴影 hv.Image or hv.Quadmesh 图(或直接调用 canvas.raster 或 canvas.quadmesh),而不是 hv.Points 或 canvas.points 图
- 如果您的数据代表来自基础连续分布的任意位置的样本,您可以在计算 Delaunay 或其他类型的三角剖分后使用数据阴影 hv.TriMesh 或 canvas.trimesh 图填充点之间以便它定义一个表面。
- 如果您的数据代表来自非连续分布的任意位置的样本,但您仍想用连续函数对其进行近似,则可以使用(非数据阴影)hv.Bivariate 图,计算平滑内核密度估计可以有效地“连接点”,如您所描述的,但也可以消除局部密度差异。
None 这些选项完全符合您在这里的要求,但我认为 TriMesh 的行为最符合您的建议,同时对于缩小的情况仍然表现相似。