如何填充散点图matplotlib中不同类的区域?

Posted

技术标签:

【中文标题】如何填充散点图matplotlib中不同类的区域?【英文标题】:How to fill the area of different classes in scatter plot matplotlib? 【发布时间】:2021-01-03 18:30:46 【问题描述】:

我正在使用 matplotlib 绘制我的 pandas 数据,我的绘图如下所示:

数据集中有四个类。我想为每个班级的背景区域着色,像这样

我的 matplotlib 代码如下所示:

import pandas as pd
df = pd.read_csv('normalized.csv')
fig    = plt.figure(figsize=(8,8))
plt.scatter(df['p1'], df['p2'], c= list(df['cs']), alpha=0.9)
plt.show()

我也为此尝试了 sns:

import pandas as pd
df = pd.read_csv('normalized.csv')
sn.FacetGrid(df, hue="cs", size = 8).map(plt.scatter, "p1", "p2").add_legend()
plt.show()

如何填充任何模块中四个类的背景区​​域?

【问题讨论】:

您的第一个问题可能是如何定义the backgroud area for each class 你需要训练一个分类器来预测背景的颜色。然后您可以使用np.meshgrid 在散点图后面创建一个网格。 Here is an example 使用 K-最近邻分类器。 【参考方案1】:

填充的轮廓可以作为背景:

import numpy as np
import matplotlib.pyplot as plt

N = 100
M = 4
points = np.random.normal(np.tile(np.random.uniform(1, 10, 2 * M), N)).reshape(-1, 2)
group = np.tile(np.arange(M), N)

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 5), sharey=True, sharex=True)
cmap = plt.cm.get_cmap('tab10', 4)
ax1.scatter(points[:, 0], points[:, 1], c=group, cmap=cmap)

ax2.scatter(points[:, 0], points[:, 1], c=group, cmap=cmap)
ax2.tricontourf(points[:, 0], points[:, 1], group, levels=np.arange(-0.5, 4), zorder=0, cmap=cmap, alpha=0.3)
plt.show()

请注意,等高线图还会创建一些中间值的狭窄区域,因为它只查看数值并假设区域 0 和区域 2 之间必须存在一些小区域 1。

更复杂的方法使用最近邻拟合:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import neighbors

N = 100
M = 4
points = np.random.normal(np.tile(np.random.uniform(1, 10, 2 * M), N)).reshape(-1, 2)
groups = np.tile(np.arange(M), N)

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 5), sharey=True, sharex=True)
cmap = ListedColormap(['orange', 'cyan', 'cornflowerblue', 'crimson'])
ax1.scatter(points[:, 0], points[:, 1], c=groups, cmap=cmap)

ax2.scatter(points[:, 0], points[:, 1], c=groups, cmap=cmap)

clf = neighbors.KNeighborsClassifier(10)
clf.fit(points, groups)

x_min, x_max = points[:, 0].min() - 1, points[:, 0].max() + 1
y_min, y_max = points[:, 1].min() - 1, points[:, 1].max() + 1
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 50),
                     np.linspace(y_min, y_max, 50))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
ax2.imshow(Z, extent=[x_min, x_max, y_min, y_max], cmap=cmap, alpha=0.3, aspect='auto', origin='lower')
plt.show()

【讨论】:

【参考方案2】:

如果您不需要填充空间并且不担心区域重叠(您的数据点显示一些重叠),那么您可以尝试填充每个子集定义的凸包。

import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull
N = 100
points = [np.random.normal(np.tile(np.random.uniform(1, 5, 2), N)).reshape(-1, 2) for i in range(4)]
colors = ['r', 'g', 'b', 'k']
for k in range(4):
    hull = ConvexHull(points[k])
    plt.plot(points[k][:,0], points[k][:,1], '.', color = colors[k])
    plt.fill(points[k][hull.vertices,0], points[k][hull.vertices,1], color = colors[k], alpha=0.3)

stack.imgur.com/2562R.png

【讨论】:

随机数据生成行取自@JohanC 回答

以上是关于如何填充散点图matplotlib中不同类的区域?的主要内容,如果未能解决你的问题,请参考以下文章

matplotlib可视化基本散点图在图像指定区域绘制方框并进行自定义色彩填充(Draw Rectangle filled with color)

matplotlib可视化基本散点图在图像指定区域绘制方框(Draw Rectangle)

matplotlib 中具有重叠点的散点图的可视化

Matplotlib 散点图图例

核心图:散点图填充区域的多种颜色

Matplotlib散点图传奇