Molding with cycler

Article directory

matplotlib Tutorial notes

cycler

Before we start the tutorial, we need to understand the cycle module

from __future__ import print_function
from cycler import cycler
color_cycler = cycler(color=["r", "g", "b"])  #You can create a cycle object with cycle
color_cycler
'color'
'r'
'g'
'b'
len(color_cycler) #Get length
3
color_cycler.keys #Get key
{'color'}
from __future__ import print_function
for v in color_cycler:
    print(v)
{'color': 'r'}
{'color': 'g'}
{'color': 'b'}
cycler(ec=color_cycler) #You can use the existing cycle object as a parameter of cycle and return the same object
'ec'
'r'
'g'
'b'
for i in range(5):  #It's going to be a mistake, obviously
    print(color_cycler[i])
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-9-b6d40aff26d1> in <module>
      1 for i in range(5):  #It's going to be a mistake, obviously
----> 2     print(color_cycler[i])


C:\Ana\lib\site-packages\cycler.py in __getitem__(self, key)
    221                                 for k, v in six.iteritems(trans)))
    222         else:
--> 223             raise ValueError("Can only use slices with Cycler.__getitem__")
    224 
    225     def __iter__(self):


ValueError: Can only use slices with Cycler.__getitem__
cc = color_cycler()
for j, c in zip(range(5), cc): #In this way, we can actually get an infinite sequence
    print(j, c)
0 {'color': 'r'}
1 {'color': 'g'}
2 {'color': 'b'}
3 {'color': 'r'}
4 {'color': 'g'}
#The sum of two cycle objects will be combined in a way of "inner product"
lw_cycler = cycler(lw=range(1, 4)) #Notice len (LW cycle) = = 3
wc = lw_cycler + color_cycler #If they are different in length, they cannot be added
print(len(wc))
print(wc.keys)
for s in wc:
    print(s)
3
{'lw', 'color'}
{'lw': 1, 'color': 'r'}
{'lw': 2, 'color': 'g'}
{'lw': 3, 'color': 'b'}
#And are exchangeable
lw_c = lw_cycler + color_cycler
c_lw = color_cycler + lw_cycler
for j, (a, b) in enumerate(zip(lw_c, c_lw)):
    print("({j}) A: {A!r} B:{B!r}".format(
        j=j, A=a, B=b
    ))
(0) A: {'lw': 1, 'color': 'r'} B:{'color': 'r', 'lw': 1}
(1) A: {'lw': 2, 'color': 'g'} B:{'color': 'g', 'lw': 2}
(2) A: {'lw': 3, 'color': 'b'} B:{'color': 'b', 'lw': 3}
#Similar operations can be done by passing in multiple parameters of equal length at one time
wc = cycler(c=['r', 'g', 'b'], lw=range(1,4))
for s in wc:
    print(s)
{'c': 'r', 'lw': 1}
{'c': 'g', 'lw': 2}
{'c': 'b', 'lw': 3}
# Multiplication is similar to the definition of "outer product", that is to say, let's take a look at each of them
m_cycler = cycler(marker=['s', 'o'])
m_c = m_cycler * color_cycler
print(len(m_c))
print(m_c.keys)
for s in m_c:
    print(s)
6
{'marker', 'color'}
{'marker': 's', 'color': 'r'}
{'marker': 's', 'color': 'g'}
{'marker': 's', 'color': 'b'}
{'marker': 'o', 'color': 'r'}
{'marker': 'o', 'color': 'g'}
{'marker': 'o', 'color': 'b'}
#The two are not necessarily the same after multiplication exchange
c_m = color_cycler * m_cycler
for j, (a, b) in enumerate(zip(c_m, m_c)):
    print("({j}) A: {A!r} B: {B!r}".format(
        j=j, A=a, B=b
    ))
(0) A: {'color': 'r', 'marker': 's'} B: {'marker': 's', 'color': 'r'}
(1) A: {'color': 'r', 'marker': 'o'} B: {'marker': 's', 'color': 'g'}
(2) A: {'color': 'g', 'marker': 's'} B: {'marker': 's', 'color': 'b'}
(3) A: {'color': 'g', 'marker': 'o'} B: {'marker': 'o', 'color': 'r'}
(4) A: {'color': 'b', 'marker': 's'} B: {'marker': 'o', 'color': 'g'}
(5) A: {'color': 'b', 'marker': 'o'} B: {'marker': 'o', 'color': 'b'}
#Integer multiplication seems to simply multiply by several times
color_cycler * 2 # == 2 * color_cycler
'color'
'r'
'g'
'b'
'r'
'g'
'b'
color_cycler.concat(color_cycler)  #Follow up concat
'color'
'r'
'g'
'b'
'r'
'g'
'b'
color_cycler.concat(m_cycler)  #It seems that concat must have the same key
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-18-c4ba2b85481a> in <module>
----> 1 color_cycler.concat(m_cycler)  #It seems that concat must have the same key


C:\Ana\lib\site-packages\cycler.py in concat(self, other)
    423             The concatenated `Cycler`
    424         """
--> 425         return concat(self, other)
    426 
    427 


C:\Ana\lib\site-packages\cycler.py in concat(left, right)
    459                                just_one=left.keys ^ right.keys)
    460 
--> 461         raise ValueError(msg)
    462 
    463     _l = left.by_key()


ValueError: Keys do not match:
	Intersection: set()
	Disjoint: {'marker', 'color'}
# Slicing operation
color_cycler[::-1] #Reverse order
'color'
'b'
'g'
'r'
color_cycler[:2]
'color'
'r'
'g'
color_cycler[1:]
'color'
'g'
'b'
#We can view it by the "by key" method. The feeling is to get a key and its value
c_m.by_key()
{'marker': ['s', 'o', 's', 'o', 's', 'o'],
 'color': ['r', 'r', 'g', 'g', 'b', 'b']}
#This dictionary can be used as a blueprint for creating a new cycler
bk = c_m.by_key()
bk['color'] = ['green'] * len(c_m)
cycler(**bk)
'color' 'marker'
'green' 's'
'green' 'o'
'green' 's'
'green' 'o'
'green' 's'
'green' 'o'

Some examples

from itertools import cycle
import matplotlib.pyplot as plt
from cycler import cycler
import numpy as np
fig, (ax1, ax2) = plt.subplots(1, 2, tight_layout=True,
                              figsize=(8, 4))
x = np.arange(10)
color_cycler = cycler(c=["r", "g", "b"])
for i, sty in enumerate(color_cycler):
    ax1.plot(x, x*(i+1), **sty)

for i, sty in zip(range(1, 5), cycle(color_cycler)):
    ax2.plot(x, x*i, **sty)
C:\Ana\lib\site-packages\matplotlib\figure.py:2366: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.
  warnings.warn("This figure includes Axes that are not compatible "

This example uses multiplication

fig, (ax1, ax2) = plt.subplots(1, 2, tight_layout=True,
                               figsize=(8, 4))
x = np.arange(10)

color_cycle = cycler(c=['r', 'g', 'b'])
ls_cycle = cycler('ls', ['-', '--'])
lw_cycle = cycler('lw', range(1, 4))

sty_cycle = ls_cycle * (color_cycle + lw_cycle)

for i, sty in enumerate(sty_cycle):
   ax1.plot(x, x*(i+1), **sty)

sty_cycle = (color_cycle + lw_cycle) * ls_cycle

for i, sty in enumerate(sty_cycle):
   ax2.plot(x, x*(i+1), **sty)

We always want to give different lines different plans

fig, ax = plt.subplots(tight_layout=True)
x = np.linspace(0, 2*np.pi, 1024)

for i, (lw, c) in enumerate(zip(range(4), ['r', 'g', 'b', 'k'])):
   ax.plot(x, np.sin(x - i * np.pi / 4),
           label=r'$\phi = {{{0}}} \pi / 4$'.format(i),
           lw=lw + 1, #lw linewidth
           c=c)

ax.set_xlim([0, 2*np.pi])
ax.set_title(r'$y=\sin(\theta + \phi)$')
ax.set_ylabel(r'[arb]')
ax.set_xlabel(r'$\theta$ [rad]')

ax.legend(loc=0);

More complex

fig, ax = plt.subplots(tight_layout=True)
x = np.linspace(0, 2*np.pi, 1024)

for i, (lw, c) in enumerate(zip(range(4), ['r', 'g', 'b', 'k'])):
   if i % 2:
       ls = '-'
   else:
       ls = '--'
   ax.plot(x, np.sin(x - i * np.pi / 4),
           label=r'$\phi = {{{0}}} \pi / 4$'.format(i),
           lw=lw + 1,
           c=c,
           ls=ls)

ax.set_xlim([0, 2*np.pi])
ax.set_title(r'$y=\sin(\theta + \phi)$')
ax.set_ylabel(r'[arb]')
ax.set_xlabel(r'$\theta$ [rad]')

ax.legend(loc=0);

Course

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

Our husband makes some sample data

x = np.linspace(0, 2 * np.pi, 50)
offsets = np.linspace(0, 2 * np.pi, 4, endpoint=False)
yy = np.transpose([np.sin(x + phi) for phi in offsets])
yy.shape
(50, 4)

Prop cycle: the property cycle, which controls some style s in future drawing

default_cycler = (cycler(color=['r', 'g', 'b', 'y']) +
                  cycler(linestyle=['-', '--', ':', '-.']))

plt.rc('lines', linewidth=4)  #Set the style of lines in the future
plt.rc('axes', prop_cycle=default_cycler) #Set the style of future axes

adopt matplotlib.axes.Axes.set_prop_cycle You can set the corresponding prop cycle

custom_cycler = (cycler(color=['c', 'm', 'y', 'k']) +
                 cycler(lw=[1, 2, 3, 4]))

fig, (ax0, ax1) = plt.subplots(nrows=2)
ax0.plot(yy) #default_cycler
ax0.set_title('Set default color cycle to rgby')
ax1.set_prop_cycle(custom_cycler)
ax1.plot(yy)
ax1.set_title('Set axes color cycle to cmyk')

# Add a bit more space between the two plots.
fig.subplots_adjust(hspace=0.3)
plt.show()

Function link

prop_cycle

Keywords: IPython

Added by p0pb0b on Sun, 10 Nov 2019 17:48:45 +0200