automatically choose different line markers

How can I automatically cycle through distinctive line markers?

I want a semilog plot, composed of a number of lines. Each line should have
a different color and marker.

Cycling through the colors is automatic, but not the markers.

BTW, shouldn't this behavior be the default? I would just like to say
markers=True and get this behavior.

Hi,

The best way to do this is to use a generator:

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

def _ncycle(iterable,n):
“”"
Method to create a generator from an iterable. It keeps the

current position of the iterable in memory.  Each time the
next() method for the iterable is called, it will return the
next item.  If there are no more items, it will cycle to the
first item.

"""

for item in itertools.cycle(iterable):
    yield item

colors = _ncycle((‘r’,‘g’,‘b’,‘c’,‘y’,‘m’,‘k’),1)
markers = _ncycle((‘o’,‘s’,‘v’),1)

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

for i in range(n):
x = np.arange(0,10)
y = np.sin(x)+i-n/2
c = colors.next()
if c == ‘r’:
marker = markers.next()

ax.plot(x,y,c=c,marker=marker)

plt.show()

···

On Fri, Nov 5, 2010 at 8:29 AM, Neal Becker <ndbecker2@…287…> wrote:

How can I automatically cycle through distinctive line markers?

I want a semilog plot, composed of a number of lines. Each line should have

a different color and marker.

Cycling through the colors is automatic, but not the markers.

BTW, shouldn’t this behavior be the default? I would just like to say

markers=True and get this behavior.


The Next 800 Companies to Lead America’s Growth: New Video Whitepaper

David G. Thomson, author of the best-selling book "Blueprint to a

Billion" shares his insights and actions to help propel your

business during the next growth cycle. Listen Now!

http://p.sf.net/sfu/SAP-dev2dev


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Aman Thakral
B.Eng & Biosci, M.Eng Design

How can I automatically cycle through distinctive line markers?

I want a semilog plot, composed of a number of lines. Each line should have

a different color and marker.

I simply use:

colors = [‘b’, ‘r’, ‘c’, ‘m’, ‘k’, ‘g’, ‘y’]

symbols = [‘-’, ‘–’, ‘-.’, ‘:’]

nc = len(colors)

ns = len(symbols)

cs = 0

cc = 0

for i in numpy.arange(len(parameters_list)):

plt.plot(x, y, colors[cc%nc] + symbols[cs%ns], label=r’\Delta x_{min} = ' + str(dxmin[j]) + ', N = ' + str(Ns[i]) + r'')

cc += 1

if (cc == nc):

cc = 0

cs += 1

This will cycle through symbols when colors run out. You can indent or not “cs” to cycle through symbols too.

I like the thought, but I'm not sure why you're making it so
complicated by wrapping it. itertools.cycle by itself is perfect, and
there's no reason to prime it by calling next() before the plot. The
following is a bit more succint IMO:

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

colors = itertools.cycle(['r','g','b','c','y','m','k'])
markers = itertools.cycle(['o','s','v'])

fig = plt.figure()
ax = fig.add_subplot(111)
for i in range(10):
    x = np.linspace(0, 2*np.pi)
    y = np.sin(x) + np.random.randn(*x.shape)
    ax.plot(x, y, c=colors.next(), marker=markers.next())

plt.show()

Also, you can avoid calling colors.next() and markers.next() if you
put them in a zip command along with range().

Ryan

···

On Fri, Nov 5, 2010 at 8:07 AM, Aman Thakral <aman.thakral@...287...> wrote:

Hi,

The best way to do this is to use a generator:

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

def _ncycle(iterable,n):
"""
Method to create a generator from an iterable. It keeps the
current position of the iterable in memory. Each time the
next() method for the iterable is called, it will return the
next item. If there are no more items, it will cycle to the
first item.
"""

for item in itertools\.cycle\(iterable\):
    yield item

colors = _ncycle(('r','g','b','c','y','m','k'),1)
markers = _ncycle(('o','s','v'),1)

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Honestly, I can’t even remember why it is wrapped. I think this is just a relic of some old example that I had lying around. Serves me right for just copying and pasting without thinking :stuck_out_tongue: . A straight call to itertools.cycle is definitely much cleaner. Also, is there an example of this in the docs? If not, it would be a useful addition. Seems like a common feature to address.

Cheers,
Aman

···

On Mon, Nov 8, 2010 at 10:41 PM, Ryan May <rmay31@…287…> wrote:

On Fri, Nov 5, 2010 at 8:07 AM, Aman Thakral <aman.thakral@…287…> wrote:

Hi,

The best way to do this is to use a generator:

import itertools

import matplotlib.pyplot as plt

import numpy as np

def _ncycle(iterable,n):

"""
Method to create a generator from an iterable.  It keeps the
current position of the iterable in memory.  Each time the
next() method for the iterable is called, it will return the
next item.  If there are no more items, it will cycle to the
first item.
"""
for item in itertools.cycle(iterable):
    yield item

colors = _ncycle((‘r’,‘g’,‘b’,‘c’,‘y’,‘m’,‘k’),1)

markers = _ncycle((‘o’,‘s’,‘v’),1)

I like the thought, but I’m not sure why you’re making it so

complicated by wrapping it. itertools.cycle by itself is perfect, and

there’s no reason to prime it by calling next() before the plot. The

following is a bit more succint IMO:

import itertools

import matplotlib.pyplot as plt

import numpy as np

colors = itertools.cycle([‘r’,‘g’,‘b’,‘c’,‘y’,‘m’,‘k’])

markers = itertools.cycle([‘o’,‘s’,‘v’])

fig = plt.figure()

ax = fig.add_subplot(111)

for i in range(10):

x = np.linspace(0, 2*np.pi)

y = np.sin(x) + np.random.randn(*x.shape)

ax.plot(x, y, c=colors.next(), marker=markers.next())

plt.show()

Also, you can avoid calling colors.next() and markers.next() if you

put them in a zip command along with range().

Ryan

Ryan May

Graduate Research Assistant

School of Meteorology

University of Oklahoma