如何使Matplotlib散点图作为一组透明?

Jas*_*son 13 python transparency matplotlib scatter-plot

我正在使用Matplotlib制作一些散点图(python 3.4.0,matplotlib 1.4.3,在Linux Mint 17上运行).很容易为每个点单独设置alpha透明度; 有没有办法将它们设置为一个组,以便来自同一组的两个重叠点不会改变颜色?

示例代码:

import matplotlib.pyplot as plt
import numpy as np

def points(n=100):
    x = np.random.uniform(size=n)
    y = np.random.uniform(size=n)
    return x, y
x1, y1 = points()
x2, y2 = points()
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111, title="Test scatter")
ax.scatter(x1, y1, s=100, color="blue", alpha=0.5)
ax.scatter(x2, y2, s=100, color="red", alpha=0.5)
fig.savefig("test_scatter.png")
Run Code Online (Sandbox Code Playgroud)

结果输出:

在此输入图像描述

但我想要更像这样的东西:

在此输入图像描述

我可以通过保存为SVG并在Inkscape中手动分组,然后设置透明度来解决,但我真的更喜欢我可以编码的东西.有什么建议?

Fla*_*bes 9

是的,有趣的问题.您可以使用Shapely获取此散点图.这是代码:

import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
from shapely.geometry import Point
from shapely.ops import cascaded_union

n = 100
size = 0.02
alpha = 0.5

def points():
    x = np.random.uniform(size=n)
    y = np.random.uniform(size=n)
    return x, y

x1, y1 = points()
x2, y2 = points()
polygons1 = [Point(x1[i], y1[i]).buffer(size) for i in range(n)]
polygons2 = [Point(x2[i], y2[i]).buffer(size) for i in range(n)]
polygons1 = cascaded_union(polygons1)
polygons2 = cascaded_union(polygons2)

fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111, title="Test scatter")
for polygon1 in polygons1:
    polygon1 = ptc.Polygon(np.array(polygon1.exterior), facecolor="red", lw=0, alpha=alpha)
    ax.add_patch(polygon1)
for polygon2 in polygons2:
    polygon2 = ptc.Polygon(np.array(polygon2.exterior), facecolor="blue", lw=0, alpha=alpha)
    ax.add_patch(polygon2)
ax.axis([-0.2, 1.2, -0.2, 1.2])

fig.savefig("test_scatter.png")
Run Code Online (Sandbox Code Playgroud)

结果是:

测试分散


Ed *_*ith 8

有趣的问题,我认为任何透明度的使用都会导致您想要避免的堆叠效应.您可以手动设置透明度类型颜色以更接近您想要的结果,

import matplotlib.pyplot as plt
import numpy as np

def points(n=100):
    x = np.random.uniform(size=n)
    y = np.random.uniform(size=n)
    return x, y
x1, y1 = points()
x2, y2 = points()
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111, title="Test scatter")
alpha = 0.5
ax.scatter(x1, y1, s=100, lw = 0, color=[1., alpha, alpha])
ax.scatter(x2, y2, s=100, lw = 0, color=[alpha, alpha, 1.])
plt.show()
Run Code Online (Sandbox Code Playgroud)

不同颜色之间的重叠不包括在这种方式,但你得到,

在此输入图像描述

  • @ Kev1n91,将 alpha 设置为 1 以外的任何值(没有 alpha 的 RGB 值的默认值)意味着您可以看到重叠,这是 OP 指定的他们不想要的:“来自同一组的重叠点不会改变颜色” (2认同)

小智 7

只需传递一个参数edgecolors='none'即可plt.scatter()


小智 6

这是一个可怕的、可怕的黑客,但它有效。

您会看到,虽然 Matplotlib 将数据点绘制为可以重叠的单独对象,但它将它们之间的线绘制为单个对象 - 即使该线被数据中的 NaN 分成几段。

考虑到这一点,您可以这样做:

import numpy as np
from matplotlib import pyplot as plt

plt.rcParams['lines.solid_capstyle'] = 'round'

def expand(x, y, gap=1e-4):
    add = np.tile([0, gap, np.nan], len(x))
    x1 = np.repeat(x, 3) + add
    y1 = np.repeat(y, 3) + add
    return x1, y1

x1, y1 = points()
x2, y2 = points()
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111, title="Test scatter")
ax.plot(*expand(x1, y1), lw=20, color="blue", alpha=0.5)
ax.plot(*expand(x2, y2), lw=20, color="red", alpha=0.5)

fig.savefig("test_scatter.png")
plt.show()
Run Code Online (Sandbox Code Playgroud)

并且每种颜色都会与另一种颜色重叠,但不会与自身重叠。

在此处输入图片说明

一个警告是,您必须小心用于制作每个圆的两点之间的间距。如果它们两个相距很远,则在您的绘图上可以看到分离,但如果它们靠得太近,则 matplotlib 根本不会绘制线条。这意味着需要根据您的数据范围选择分离度,如果您打算制作交互式绘图,那么如果您缩小太多,则所有数据点都有可能突然消失,而如果您放大,则可能会拉伸太多了。

如您所见,我发现 1e-5 可以很好地分离范围为 [0,1] 的数据。