What is the pythonic way to plot a large number of points with different appearances?
I am trying to plot a large number of points that have different appearances (shape, edge color, face, color, etc.) and I find it plot
takes a very long time to plot an obvious path (using for each point). I see various ways to improve performance, but I find that they either decrease flexibility when a point occurs, or turn out to be much lower than I think is correct.
For example, if I have
fig, ax = matplotlib.pyplot.subplots() rands = numpy.random.random_sample((n,))
where n
is some large number, then using plot
to plot each point
for x in range(n):
ax.plot(x, rands[x], 'o', color=str(rands[x]), mec=str(1-rands[x]))
takes a very long time and seems very ineffective. Much faster results can be achieved by plotting multiple points at once
ax.plot(range(n), rands, 'o', color='b', mec='r')
but with the loss of control over many features of individual points (here, for example, neither color
, nor mec
can be a list, and many other aspects have the same restrictions). Using convenience methods likescatter
ax.scatter(range(n), rands, marker='o', color=[str(y) for y in rands])
also gives quick results; but again with the loss of a lot of flexibility (although the points can be colored individually, the plot
remaining options for setting the functions of individual points are not supported) and some automatic axis limitation (use set_xlim
and set_ylim
seems necessary to perform plot
automatically).
Finally, I see many examples that use graphical elements such as circles in combination with collections , which, although "quickly used for normal use cases", will result in code that looks "low-level" to me
patches = []
colors = []
for x in range(n):
circ = matplotlib.patches.Circle((x/float(n), rands[x]), .01)
colors.append([rands[x],rands[x],rands[x]])
patches.append(circ)
collection = matplotlib.collections.PatchCollection(patches)
collection.set_facecolor(colors)
collection.set_edgecolor([[1-h for h in c] for c in colors])
ax.add_collection(collection)
since it not only breaks the abstraction of construction points, but also requires significant scaling and tuning to restore (even partially) the appearance provided automatically plot
(here, for example, matplotlib.pyplot.axis('equal')
you need to avoid distorted "points",).
This is frustrating because it plot
seems like a natural method of use, as it ensures the individual points are set correctly and results in numbers that scale well and with axes that are naturally limited - it is too slow when using point at a time and does not accept lists as arguments for most properties.
What is the correct pythonic way of plotting a large number of points, where the features of each point (marker, edge color, face color, alpha, size, etc.) can potentially be customized? Is using circles (or other shapes) and collections (followed by scaling and other drawing adjustments) really the preferred (or at least necessary) approach?
source to share