Matplotlib: Plotting numerous disconnected line segments with different colors
use LineCollection
:
import numpy as npimport pylab as plfrom matplotlib import collections as mclines = [[(0, 1), (1, 1)], [(2, 3), (3, 3)], [(1, 2), (1, 3)]]c = np.array([(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1)])lc = mc.LineCollection(lines, colors=c, linewidths=2)fig, ax = pl.subplots()ax.add_collection(lc)ax.autoscale()ax.margins(0.1)
here is the output:
function plot
allows to draw multiple lines in one call, if your data is just in a list, just unpack it when passing it to plot
:
In [315]: data=[(1, 1), (2, 3), 'r', #assuming points are (1,2) (1,3) actually and, #here they are in form of (x1, x2), (y1, y2) ...: (2, 2), (4, 5), 'g', ...: (5, 5), (6, 7), 'b',]In [316]: plot(*data)Out[316]: [<matplotlib.lines.Line2D at 0x8752870>, <matplotlib.lines.Line2D at 0x8752a30>, <matplotlib.lines.Line2D at 0x8752db0>]
OK, I ended up rasterising the lines on a PIL image before converting it to a numpy array:
from PIL import Imagefrom PIL import ImageDrawimport random as rndimport numpy as npimport matplotlib.pyplot as pltN = 60000s = (500, 500)im = Image.new('RGBA', s, (255,255,255,255))draw = ImageDraw.Draw(im)for i in range(N): x1 = rnd.random() * s[0] y1 = rnd.random() * s[1] x2 = rnd.random() * s[0] y2 = rnd.random() * s[1] alpha = rnd.random() color = (int(rnd.random() * 256), int(rnd.random() * 256), int(rnd.random() * 256), int(alpha * 256)) draw.line(((x1,y1),(x2,y2)), fill=color, width=1)plt.imshow(np.asarray(im), origin='lower')plt.show()
This is by far the fastest solution and it fits my real-time needs perfectly. One caveat though is the lines are drawn without anti-aliasing.