首页 > 解决方案 > 用透明度绘制数千条线的最简单方法

问题描述

我正在寻找最简单的方法来合理快速地绘制多条线(〜20000),同时支持透明度或子像素宽度或两者兼而有之,这样它们在相互分层时不会只是创建一个完全黑色的图像。

我尝试了 matplotlib,但由于每一行都是它自己的轴,所以它非常慢,尽管它看起来是迄今为止最好的:

import matplotlib.pyplot as plt

# test data in format my real data will use

test_data_as_lines = [((random()*2000, random()*2000),
                        (random()*2000, random()*2000))
                        for x in range(0,20000)]

#format for matplotlib and plot

fig= plt.figure(figsize=(10,10))
axes= fig.add_axes([0.05,0.05,0.9,0.9])

for i in test_data_as_lines:

    x = (i[0][0],i[1][0])
    y = (i[0][1],i[1][1])

    axes.plot(x,y, 'black', linewidth=0.1, alpha=0.5)

plt.show()

有没有更快的方法来做到这一点?

我也尝试使用 PIL 进行绘图,但它不支持亚像素线宽,并且 alpha 透明度只能应用于整个图像,而不是单个元素:

from PIL import Image, ImageDraw

test_data_as_lines = [((random()*1000, random()*1000),
                        (random()*1000, random()*1000))
                        for x in range(0,20000)]

im = Image.new('RGB', (1000, 1000), (255,255,255))
draw = ImageDraw.Draw(im)

for i in test_data_as_lines:

    draw.line((i[0][0],i[0][1], i[1][0], i[1][1]), fill=(0, 0, 0), width=1)

im.show()

这只是画了一个黑色方块。

最后我尝试了 John Zelle 的简单 graphics.py 示例库,但这也不支持透明度或子像素宽度,而且速度更慢。它基于 tkinter,我认为它具有相同的限制,所以我没有为此烦恼。

我试图避免pygame。那是我最好的选择吗?

谢谢

标签: pythonmatplotlibgraphics

解决方案


摆脱 for 循环将使您的代码更简单、更快。由于该方法plot可以一次处理多行,因此您可以使用

axes.plot(*test_data_as_lines, alpha=0.5, color="black", linewidth=0.1)

在我的笔记本电脑上,有 5000 行,使用 for 循环执行代码大约需要 93 秒,而上面的命令大约需要 10 秒


推荐阅读