You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用mpl-scatter-density或datashader实现1D密度着色散点图

1D密度着色散点图的高效实现方案

针对你提到的两个核心需求,以下是具体的实现方案:


一、用datashader实现大数据量下的1D密度着色散点图

datashader专门针对大规模数据的可视化做了性能优化,计算密度的速度远快于gaussian_kde,完全适配10k+数据量的场景。核心思路是对y轴数据计算1D核密度,再将密度值映射为散点颜色,最后按密度排序绘制散点(让高密度点显示在上方)。

代码示例

import numpy as np
import matplotlib.pyplot as plt
import datashader as ds
from matplotlib.colors import Normalize

# 生成测试数据
data_x = np.broadcast_to(np.array([[1], [2], [3]]), (2, 3, 1000))
data_y = data_x * np.random.normal(size=(2, 3, 1000))

# 创建子图
nrows = 1
ncols = 2
size = 5
fig, ax_array = plt.subplots(
    nrows, ncols,
    figsize=(16/9 * ncols * size, nrows * size),
    squeeze=False
)

# 定义颜色映射与归一化规则
cmap = plt.cm.get_cmap('Reds')
norm = Normalize(vmin=0, vmax=1)

for i, ax_row in enumerate(ax_array):
    for j, axes in enumerate(ax_row):
        index = nrows * i + j
        x = data_x[index, :, :]
        y = data_y[index, :, :]
        
        for x_values, y_values in zip(x, y):
            # 用datashader计算y轴方向的1D密度
            df = {'y': y_values}
            cvs = ds.Canvas(plot_width=100, plot_height=1)
            agg = cvs.line(df, 'y', agg=ds.count())
            density = agg.to_numpy()[0]
            
            # 归一化密度值并生成对应颜色
            normalized_density = norm(density / density.max())
            color = cmap(normalized_density)
            
            # 按密度排序,确保高密度点在图层上方
            idx = normalized_density.argsort()
            x_sorted, y_sorted, color_sorted = x_values[idx], y_values[idx], color[idx]
            
            axes.scatter(x_sorted, y_sorted, c=color_sorted, s=10)

plt.tight_layout()
plt.show()

二、用mpl-scatter-density实现并适配plt.subplots

mpl-scatter-density默认通过fig.add_subplot(projection='scatter_density')创建专用轴,但也可以通过两种方式适配plt.subplots:

方法1:直接在plt.subplots中指定投影类型

通过subplot_kw参数统一设置所有子图的投影为scatter_density,无需逐个添加子图:

import numpy as np
import matplotlib.pyplot as plt
import mpl_scatter_density

# 生成测试数据
data_x = np.broadcast_to(np.array([[1], [2], [3]]), (2, 3, 1000))
data_y = data_x * np.random.normal(size=(2, 3, 1000))

# 创建带scatter_density投影的子图
nrows = 1
ncols = 2
size = 5
fig, ax_array = plt.subplots(
    nrows, ncols,
    figsize=(16/9 * ncols * size, nrows * size),
    squeeze=False,
    subplot_kw={'projection': 'scatter_density'}
)

cmap = plt.cm.get_cmap('Reds')

for i, ax_row in enumerate(ax_array):
    for j, axes in enumerate(ax_row):
        index = nrows * i + j
        x = data_x[index, :, :]
        y = data_y[index, :, :]
        
        for x_values, y_values in zip(x, y):
            # 绘制密度着色散点,自动计算密度并映射颜色
            density = axes.scatter_density(x_values, y_values, cmap=cmap)
            # 若需单独提取密度值,可通过axes.get_images()[0].get_array()获取

plt.colorbar(density, ax=ax_array)
plt.tight_layout()
plt.show()

方法2:手动给普通Axes添加ScatterDensityArtist

如果不想修改子图投影,可直接创建普通Axes,再手动添加ScatterDensityArtist,关键是要正确绑定轴并设置参数:

import numpy as np
import matplotlib.pyplot as plt
from mpl_scatter_density import ScatterDensityArtist
from matplotlib.colors import LogNorm

# 生成测试数据
data_x = np.broadcast_to(np.array([[1], [2], [3]]), (2, 3, 1000))
data_y = data_x * np.random.normal(size=(2, 3, 1000))

# 创建普通子图
nrows = 1
ncols = 2
size = 5
fig, ax_array = plt.subplots(
    nrows, ncols,
    figsize=(16/9 * ncols * size, nrows * size),
    squeeze=False
)

cmap = plt.cm.get_cmap('Reds')

for i, ax_row in enumerate(ax_array):
    for j, axes in enumerate(ax_row):
        index = nrows * i + j
        x = data_x[index, :, :]
        y = data_y[index, :, :]
        
        for x_values, y_values in zip(x, y):
            # 创建ScatterDensityArtist并添加到轴上
            artist = ScatterDensityArtist(
                axes, x_values, y_values,
                cmap=cmap, norm=LogNorm(vmin=1, vmax=100)
            )
            axes.add_artist(artist)
            # 手动设置轴范围以适配数据
            axes.set_xlim(x_values.min(), x_values.max())
            axes.set_ylim(y_values.min(), y_values.max())
            
plt.colorbar(artist, ax=ax_array)
plt.tight_layout()
plt.show()

补充说明

  • 数据量超10万时,优先选择datashader,其底层优化的密度计算逻辑能大幅缩短运行时间;mpl-scatter-density更贴近matplotlib生态,适合中等规模数据或需要与matplotlib其他功能结合的场景。
  • 若需要完全复刻gaussian_kde的1D密度效果,可在datashader中调整核函数参数,或预计算密度后用datashader映射颜色(前者速度优势更明显)。

内容的提问来源于stack exchange,提问作者Rober

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:57:16