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?

0


source to share


1 answer


I have done python building in two ways:



  • pychart: hasn't been released since 2006, so I stopped using it.
  • gnuplot: written in C, can be fast for your purposes, and quite flexible. This means writing the gnuplot file and feeding it into the gnuplot binary.
-2


source







All Articles