Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cycle through both colours and linestyles on a matplotlib figure?

I have a bunch of graphs each with around 15 to 20 lines on each. I would like to cycle through colours and linestyles to get many unique lines. If I am using 6 colours and 4 linestyles there should be 20 unique lines, however the code below only produces 6. What am I doing wrong?

Here is a fake data set

import matplotlib.pyplot as plt
from cycler import cycler
import numpy
import seaborn
seaborn.set_style('white')

x = range(10)
ys = []
for i in range(20):
    ys.append(numpy.random.uniform(1, 10, size=10)*i)

This is what I can glean from other posts:

plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'y', 'c', 'k']) +
                           cycler('linestyle', ['-', '--', ':', '-.', '-', '--'])))

Note I have used duplicates in the linestyle cycler otherwise we get ValueError.

And plotting

plt.figure()
for i in range(20):
    plt.plot(x, ys[i], label=i)
plt.legend(loc=(1, 0.1))
plt.show()

enter image description here

like image 604
CiaranWelsh Avatar asked May 16 '18 13:05

CiaranWelsh


People also ask

How to implement different shades of color to matplotlib linestyle?

The color code chosen is ‘m’, which is magenta, and the line style chosen is ‘–, ‘which is dashed line style. Apart from single character colors, we can also implement different shades of a color to Matplotlib linestyle. The plt.plot function has a collection of optional parameters to do so.

How to modify the width of the plotline in Matplotlib Python?

We can customize linestyles in Matplotlib Python. We can modify the width of the plotline using the linewidth parameter. For the default plot, the line width is in pixels. So we will typically use 1 for a thin line, 2 for a medium line, 4 for a thick line, or more if we want a really thick line.

How to plot graph style in Python using matplotlib?

The matplotlib.pyplot.plot (*args, **kwargs) method of matplotlib.pyplot is used to plot the graphs. We can specify the graph style like color or line style. We look into various ways of implementing linestyles in Python.

What is the color code for Magenta in Matplotlib?

Abbreviated color code and line style are used. The color code chosen is ‘m’, which is magenta, and the line style chosen is ‘–, ‘which is dashed line style. Apart from single character colors, we can also implement different shades of a color to Matplotlib linestyle.


2 Answers

You probably want to multiply the two cyclers:

plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'y', 'c', 'k']) *
                           cycler('linestyle', ['-', '--', ':', '-.'])))

as stated here, the addition cycles both color and linestyle simultaneously, while the multiplication mixes all properties.

In this case you don't have to use duplicated linestyles, as color and linestyle don't have to have equal cycle length.

like image 129
CodeZero Avatar answered Nov 02 '22 23:11

CodeZero


As already mentioned by @datasailor you should multiply both cycles:

cycler_op1 = cycler('color', ['r', 'g', 'b', 'y', 'c', 'k']) \
            * cycler('linestyle', ['-', '--', ':', '-.', '-', '--'])

cycler_op2 = cycler('linestyle', ['-', '--', ':', '-.', '-', '--']) \
            * cycler('color', ['r', 'g', 'b', 'y', 'c', 'k'])

rc('axes', prop_cycle = cycler_op1 ) # or cycler_op2

Note that multiplication is not commutative and you get different result. Basically, in the first case the color is fixed and the linestyle changes. In the second case the linestyle is fixed and the color changes. In total 6x6 = 36 possibilities.

cycler_op1

cycler_op2

With such a large number of curves you may experiment with more colors and linestyles.

ls_cycler = cycler('linestyle',
                    [(0,()), # solid 
                     (0, (1, 10)), # loosely dotted
                     (0, (1, 5)), # dotted
                     (0, (1, 1)), # densely dotted
                     (0, (5, 10)), # loosely dashed
                     (0, (5, 5)), # dashed
                     (0, (5, 1)), # densely dashed
                     (0, (3, 10, 1, 10)), # loosely dashdotted
                     (0, (3, 5, 1, 5)), # dashdotted
                     (0, (3, 1, 1, 1)), # densely dashdotted
                     (0, (3, 10, 1, 10, 1, 10)), # loosely dashdotdotted
                     (0, (3, 5, 1, 5, 1, 5)), # dashdotdotted
                     (0, (3, 1, 1, 1, 1, 1))] # densely dashdotdotted
                  )

color_cycler = cycler('color', [plt.get_cmap('jet')(i/13) for i in range(13)] )

new_cycler = color_cycler + ls_cycler

Result looks like this:

new_cycler

like image 38
WoofDoggy Avatar answered Nov 03 '22 01:11

WoofDoggy