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

Python 如何使Matplotlib散点图作为一个组透明?,python,matplotlib,transparency,scatter-plot,Python,Matplotlib,Transparency,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.r

我正在使用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")
此输出中的结果:

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


我可以通过另存为SVG,然后在Inkscape中手动分组,然后设置透明度来解决问题,但我更喜欢可以编写代码的东西。有什么建议吗?

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

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()
不同颜色之间的重叠不包括在这种方式中,但您可以


是的,有意思的问题。你可以用它得到这个散点图。代码如下:

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")
结果是:


这是一个非常非常糟糕的黑客行为,但它确实有效

您可以看到,虽然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()
每种颜色都会与另一种颜色重叠,但不会与自身重叠

一个警告是,你必须小心你用来做每个圆的两点之间的间距。如果它们相距很远,那么在绘图上可以看到分隔,但是如果它们太近,matplotlib根本不会绘制直线。这意味着需要根据数据的范围选择分隔,如果您计划制作交互式绘图,那么如果您放大太多,所有数据点都有突然消失的风险,如果放大太多,则会拉伸


如您所见,我发现1e-5对于[0,1]范围内的数据来说是一个很好的分离。只需将一个参数传递给
edgecolors='none'
plt.scatter()

可能不是,因为这样做与散点图通常试图显示的内容相反。在我从未预料到的地方使用shapely非常酷!你认为笛卡尔的
软件包会简化绘图吗?谢谢!是的,可以使用
笛卡尔
软件包。在
cascaded_union
:使用
descartes.PolygonPatch
创建修补程序后,使用
matplotlib.collections.PathCollection
并用
add_collection
替换
add_patch
。这将用更少的行完成这项工作。另外,它不需要额外的库!你不能通过蓝色看到红色,反之亦然。我认为颜色不对,应该是RGBA元组,而不是RGB,所以:[0,0,1,0.5]应该是透明的blue@Kev1n91,将alpha设置为除1以外的任何值(没有alpha的RGB值的默认值)意味着您可以看到OP指定的他们不想要的重叠:“来自同一组的重叠点不会改变颜色”这正是我所需要的!对于对数图,添加
[0,gap,nan]
不能在多个数量级上同时工作,因此我用
[1,1+gap,nan]
来代替。