我想绘制一个具有非常小的alpha值的大量(约100万)重叠半透明线。 我尝试了matplotlib,但显然不可能将alpha值设置为低于某个值(1/256)(参见https://github.com/matplotlib/matplotlib/issues/2287) 切换到OpenGL没有帮助,我有同样的问题(参见例如http://www.opengl.org/discussion_boards/showthread.php/170674-Alpha-Buffer-Alpha-Bits)。
是否有一种简单的方法来绘制具有非常小的alpha值的线条?
答案 0 :(得分:1)
你需要一个行累加器,这里是从scikit-image修改的代码:
import cython
import numpy as np
@cython.wraparound(False)
@cython.boundscheck(False)
def acc_lines(Py_ssize_t[:, ::1] lines, int w, int h):
cdef int[:, ::] count
cdef char steep = 0
cdef Py_ssize_t sx, sy, d, i, idx, r, c, dx, dy, x, y, x2, y2
count = np.zeros((h, w), int)
for idx in range(lines.shape[0]):
steep = 0
x = lines[idx, 0]
y = lines[idx, 1]
x2 = lines[idx, 2]
y2 = lines[idx, 3]
dx = x2 - x
dy = y2 - y
if dx < 0:
dx = -dx
if dy < 0:
dy = -dy
sx = 1 if (x2 - x) > 0 else -1
sy = 1 if (y2 - y) > 0 else -1
if dy > dx:
steep = 1
x, y = y, x
dx, dy = dy, dx
sx, sy = sy, sx
d = (2 * dy) - dx
for i in range(dx):
if steep:
r = x
c = y
else:
r = y
c = x
if 0 <= r < h and 0 <= c < w:
count[r, c] += 1
while d >= 0:
y = y + sy
d = d - (2 * dx)
x = x + sx
d = d + (2 * dy)
r = y2
c = x2
if 0 <= r < h and 0 <= c < w:
count[r, c] += 1
return count.base
这是一个演示如何使用它的演示:
from matplotlib.collections import LineCollection
w = h = 512
lines = np.random.randint(0, 512, size=(10000, 4))
count = acc_lines(lines, w, h)
fig, axes = pl.subplots(1, 2, figsize=(10, 5))
lc = LineCollection(lines.reshape(-1, 2, 2), alpha=0.015, color="black")
axes[0].imshow(count, cmap="gray_r")
axes[1].add_collection(lc)
axes[1].axis((0, w, h, 0))
axes[0].set_aspect("equal")
axes[1].set_aspect("equal")
这是输出,左边是acc_lines
计算的图像,右边是LineCollection