unique plot marker for each plot in matplotlib
Question:
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.
Answers:
Just manually create an array that contains marker characters and use that, e.g.:
markers=[',', '+', '-', '.', 'o', '*']
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()
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
import matplotlib.pyplot as plt
fig = plt.figure()
markers=['^', 's', 'p', 'h', '8']
for i in range(5):
plt.plot(x[i], y[i], c='green', marker=markers[i])
plt.xlabel('X Label')
plt.ylabel('Y Label')
plt.show()
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()
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()
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
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.
Just manually create an array that contains marker characters and use that, e.g.:
markers=[',', '+', '-', '.', 'o', '*']
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()
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
import matplotlib.pyplot as plt
fig = plt.figure()
markers=['^', 's', 'p', 'h', '8']
for i in range(5):
plt.plot(x[i], y[i], c='green', marker=markers[i])
plt.xlabel('X Label')
plt.ylabel('Y Label')
plt.show()
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()
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()
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