【问题标题】:plotting semitransparent lines / 16bit alpha values绘制半透明线 / 16 位 alpha 值
【发布时间】:2014-07-23 22:21:12
【问题描述】:

我想绘制大量(大约 100 万条)具有非常小的 alpha 值的重叠半透明线。 我尝试了 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 值绘制线条?

【问题讨论】:

  • 您为 OpenGL 链接到的线程有两个答案(浮点值和每组件 16 位值),人们报告说他们让它们工作,尽管它们可能是不可移植的.那么,这些答案对您不起作用吗?如果没有,您到底尝试了什么,出了什么问题?
  • Agg 渲染器中的颜色仅限于 4x8 位 (RGBA) 我怀疑您可以说服 Agg 使用更高的位深度,但这将涉及修改 c++ 层。

标签: python opengl matplotlib alpha alphablending


【解决方案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绘制的图像

【讨论】:

  • 谢谢它解决了这个问题!尽管我不得不将代码从 count = np.zeros((h, w), int) 更改为 count = np.zeros((h, w), np.intc) 以使其在我的系统上运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 2011-04-07
  • 2011-11-18
相关资源
最近更新 更多