如何制作按密度着色的散点图?

2025-02-18 09:24:00
admin
原创
120
摘要:问题描述:我想制作一个散点图,其中每个点都由附近点的空间密度着色。 我遇到过一个非常类似的问题,它使用 R 展示了一个示例:R 散点图:符号颜色代表重叠点的数量使用 matplotlib 在 python 中完成类似操作的最佳方法是什么?解决方案 1:除了hist2d或hexbin正如@askewchan 所...

问题描述:

我想制作一个散点图,其中每个点都由附近点的空间密度着色。

我遇到过一个非常类似的问题,它使用 R 展示了一个示例:

R 散点图:符号颜色代表重叠点的数量

使用 matplotlib 在 python 中完成类似操作的最佳方法是什么?


解决方案 1:

除了hist2dhexbin正如@askewchan 所建议的,您可以使用与您链接到的问题中接受的答案相同的方法。

如果你想这样做:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)

# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)

fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=100)
plt.show()

在此处输入图片描述

如果您希望按密度顺序绘制点,以便最密集的点始终位于顶部(类似于链接的示例),只需按 z 值对它们进行排序。我还将在这里使用较小的标记尺寸,因为它看起来更好一些:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)

# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)

# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]

fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=50)
plt.show()

在此处输入图片描述

解决方案 2:

绘制 >100k 个数据点?

接受的答案是,使用gaussian_kde()将花费大量时间。在我的计算机上,100k 行大约需要11 分钟。在这里,我将添加两种替代方法(mpl-scatter-density和datashader),并将给定的答案与相同的数据集进行比较。

下面我使用了100k行的测试数据集:

import matplotlib.pyplot as plt
import numpy as np

# Fake data for testing
x = np.random.normal(size=100000)
y = x * 3 + np.random.normal(size=100000)

输出和计算时间比较

以下是不同方法的比较。

1: mpl-scatter-density

安装

pip install mpl-scatter-density

示例代码

import mpl_scatter_density # adds projection='scatter_density'
from matplotlib.colors import LinearSegmentedColormap

# "Viridis-like" colormap with white background
white_viridis = LinearSegmentedColormap.from_list('white_viridis', [
    (0, '#ffffff'),
    (1e-20, '#440053'),
    (0.2, '#404388'),
    (0.4, '#2a788e'),
    (0.6, '#21a784'),
    (0.8, '#78d151'),
    (1, '#fde624'),
], N=256)

def using_mpl_scatter_density(fig, x, y):
    ax = fig.add_subplot(1, 1, 1, projection='scatter_density')
    density = ax.scatter_density(x, y, cmap=white_viridis)
    fig.colorbar(density, label='Number of points per pixel')

fig = plt.figure()
using_mpl_scatter_density(fig, x, y)
plt.show()

绘制这个花了0.05秒:
使用 mpl-scatter-density

放大后看起来也很漂亮:
放大 mpl-scatter-density

2: datashader

  • Datashader是一个有趣的项目。它在 datashader 0.12 中增加了对 matplotlib 的支持。

安装

pip install datashader

代码(dsshow的源代码和参数列表):

import datashader as ds
from datashader.mpl_ext import dsshow
import pandas as pd


def using_datashader(ax, x, y):

    df = pd.DataFrame(dict(x=x, y=y))
    dsartist = dsshow(
        df,
        ds.Point("x", "y"),
        ds.count(),
        vmin=0,
        vmax=35,
        norm="linear",
        aspect="auto",
        ax=ax,
    )

    plt.colorbar(dsartist)


fig, ax = plt.subplots()
using_datashader(ax, x, y)
plt.show()
  • 绘制这个花了 0.83 秒:

在此处输入图片描述

  • 也可以通过第三个变量进行着色。第三个参数dsshow控制着色。更多示例请参见此处,dsshow 的源代码请参见此处。

3: scatter_with_gaussian_kde

def scatter_with_gaussian_kde(ax, x, y):
    # https://stackoverflow.com/a/20107592/3015186
    # Answer by Joel Kington

    xy = np.vstack([x, y])
    z = gaussian_kde(xy)(xy)

    ax.scatter(x, y, c=z, s=100, edgecolor='')
  • 画这个花了11分钟:
    scatter_with_gaussian_kde

4: using_hist2d

import matplotlib.pyplot as plt
def using_hist2d(ax, x, y, bins=(50, 50)):
    # https://stackoverflow.com/a/20105673/3015186
    # Answer by askewchan
    ax.hist2d(x, y, bins, cmap=plt.cm.jet)
  • 绘制这个bins=(50,50)花了0.021秒:
    使用_hist2d_50

  • 绘制这个 bins=(1000,1000) 花了 0.173 秒:
    使用_hist2d_1000

  • 缺点:放大后的数据看起来不如使用 mpl-scatter-density 或 datashader 时的效果好。此外,您还必须自行确定 bin 的数量。

放大 hist2d 1000bins

5: density_scatter

  • 代码与Guillaume的回答相同。

  • 使用 bins=(50,50) 绘制此图耗时 0.073 秒:
    密度散射_50箱

  • 使用 bins=(1000,1000) 绘制此图花费了 0.368 秒:
    密度散射_1000箱

解决方案 3:

此外,如果点的数量使得 KDE 计算太慢,则可以在 np.histogram2d 中插入颜色[更新以回应评论:如果您希望显示颜色条,请使用 plt.scatter() 而不是 ax.scatter() 后跟 plt.colorbar()]:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.colors import Normalize 
from scipy.interpolate import interpn

def density_scatter( x , y, ax = None, sort = True, bins = 20, **kwargs )   :
    """
    Scatter plot colored by 2d histogram
    """
    if ax is None :
        fig , ax = plt.subplots()
    data , x_e, y_e = np.histogram2d( x, y, bins = bins, density = True )
    z = interpn( ( 0.5*(x_e[1:] + x_e[:-1]) , 0.5*(y_e[1:]+y_e[:-1]) ) , data , np.vstack([x,y]).T , method = "splinef2d", bounds_error = False)

    #To be sure to plot all data
    z[np.where(np.isnan(z))] = 0.0

    # Sort the points by density, so that the densest points are plotted last
    if sort :
        idx = z.argsort()
        x, y, z = x[idx], y[idx], z[idx]

    ax.scatter( x, y, c=z, **kwargs )

    norm = Normalize(vmin = np.min(z), vmax = np.max(z))
    cbar = fig.colorbar(cm.ScalarMappable(norm = norm), ax=ax)
    cbar.ax.set_ylabel('Density')

    return ax


if "__main__" == __name__ :

    x = np.random.normal(size=100000)
    y = x * 3 + np.random.normal(size=100000)
    density_scatter( x, y, bins = [30,30] )

IT科技

解决方案 4:

您可以制作直方图:

import numpy as np
import matplotlib.pyplot as plt

# fake data:
a = np.random.normal(size=1000)
b = a*3 + np.random.normal(size=1000)

plt.hist2d(a, b, (50, 50), cmap=plt.cm.jet)
plt.colorbar()

第二个主义

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3970  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2740  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   79  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   87  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   74  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用