Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unique plot marker for each plot in matplotlib

I have a loop where i create some plots and I need unique marker for each plot. I think about creating function, which returns random symbol, and use it in my program in this way:

for i in xrange(len(y)):
    plt.plot(x, y [i], randomMarker())

but I think this way is not good one. I need this just to distinguish plots on legend, because plots must be not connected with lines, they must be just sets of dots.

like image 478
user983302 Avatar asked Oct 26 '12 17:10

user983302


4 Answers

itertools.cycle will iterate over a list or tuple indefinitely. This is preferable to a function which randomly picks markers for you.

Python 2.x

import itertools
marker = itertools.cycle((',', '+', '.', 'o', '*')) 
for n in y:
    plt.plot(x,n, marker = marker.next(), linestyle='')

Python 3.x

import itertools
marker = itertools.cycle((',', '+', '.', 'o', '*')) 
for n in y:
    plt.plot(x,n, marker = next(marker), linestyle='')

You can use that to produce a plot like this (Python 2.x):

import numpy as np
import matplotlib.pyplot as plt
import itertools

x = np.linspace(0,2,10)
y = np.sin(x)

marker = itertools.cycle((',', '+', '.', 'o', '*')) 

fig = plt.figure()
ax = fig.add_subplot(111)

for q,p in zip(x,y):
    ax.plot(q,p, linestyle = '', marker=marker.next())
    
plt.show()

Example plot

like image 123
Mr. Squig Avatar answered Oct 14 '22 20:10

Mr. Squig


It appears that nobody has mentioned the built-in pyplot method for cycling properties yet. So here it is:

import numpy as np
import matplotlib.pyplot as plt
from cycler import cycler

x = np.linspace(0,3,20)
y = np.sin(x)

fig = plt.figure()
plt.gca().set_prop_cycle(marker=['o', '+', 'x', '*', '.', 'X']) # gca()=current axis

for q,p in zip(x,y):
    plt.plot(q,p, linestyle = '')

plt.show()

Marker cycle only

However, this way you lose the color cycle. You can add back color by multiplying or adding a color cycler and a marker cycler object, like this:

fig = plt.figure()

markercycle = cycler(marker=['o', '+', 'x', '*', '.', 'X'])
colorcycle = cycler(color=['blue', 'orange', 'green', 'magenta'])
# Or use the default color cycle:
# colorcycle = cycler(color=plt.rcParams['axes.prop_cycle'].by_key()['color'])

plt.gca().set_prop_cycle(colorcycle * markercycle) # gca()=current axis

for q,p in zip(x,y):
    plt.plot(q,p, linestyle = '')

plt.show()

Marker and color cycle combined by multiplication

When adding cycles, they need to have the same length, so we only use the first four elements of markercycle in that case:

plt.gca().set_prop_cycle(colorcycle + markercycle[:4]) # gca()=current axis

Marker and color cycle combined by addition

like image 28
Fritz Avatar answered Oct 14 '22 20:10

Fritz


You can also use marker generation by tuple e.g. as

import matplotlib.pyplot as plt
markers = [(i,j,0) for i in range(2,10) for j in range(1, 3)]
[plt.plot(i, 0, marker = markers[i], ms=10) for i in range(16)]

See Matplotlib markers doc site for details.

In addition, this can be combined with itertools.cycle looping mentioned above

like image 9
Pavel Prochazka Avatar answered Oct 14 '22 20:10

Pavel Prochazka


Just manually create an array that contains marker characters and use that, e.g.:

 markers=[',', '+', '-', '.', 'o', '*']
like image 1
Bitwise Avatar answered Oct 14 '22 20:10

Bitwise