Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyplot / matplotlib line plot - same color

I plot a simple line plot with matplotlib/pyplot. In the same plot, there are up to 20 lines. Matplotlib automatically chooses a line color. I need to draw the first of the lines in a thicker red.

So i tried:

if (i==0):                       # first line
    plt.plot(x, y, 'r', lw=2.5)
else:                            # other lines
    plt.plot(x, y)

So far very simple. First line is correct. But one of the other lines is red too. How can avoid this?

like image 262
mcatis Avatar asked Feb 11 '15 21:02

mcatis


People also ask

How do I assign a line color in matplotlib?

The usual way to set the line color in matplotlib is to specify it in the plot command. This can either be done by a string after the data, e.g. "r-" for a red line, or by explicitely stating the color argument.

How do you plot a line by color in python?

For example, you can set the color, marker, linestyle, and markercolor with: plot(x, y, color='green', linestyle='dashed', marker='o', markerfacecolor='blue', markersize=12).

What is %Matplotlib inline?

Matplotlib Inline command is a magic command that makes the plots generated by matplotlib show into the IPython shell that we are running and not in a separate output window. Different IPython IDEs offer a slightly different representation of the plots generated using matplotlib.

Is PLT show () blocking?

show() and plt. draw() are unnecessary and / or blocking in one way or the other.


2 Answers

The default jet color map goes from blue to red. Every builtin colormap also has a sister color map with the colors going in reverse order. The reversed color map has the same name with the suffix _r. Thus, jet_r goes from red to blue.

So you can give each line a unique color from the jet_r colormap by defining

color = cmap(float(i)/N)

where cmap is the jet_r colormap. The colormap cmap is a callable. When passed a float, it returns a RGB tuple. Thus, if float(i)/N is a distinct float between 0 and 1 for each line, then each line will automatically get a distinct color.


For example,

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 5, 100)
cmap = plt.get_cmap('jet_r')
N = 20
for i, n in enumerate(np.linspace(2.0, 0, N)):
    y = np.sin(x)*x**n
    color = cmap(float(i)/N)
    lw = 2.5 if i==0 else 1
    # zorder controls the order in which the lines are drawn. 
    # The line with the highest zorder lies on top.
    plt.plot(x, y, c=color, lw=lw, zorder=-i)
plt.show()

yields

enter image description here

like image 126
unutbu Avatar answered Sep 20 '22 08:09

unutbu


There are lots of ways you could potentially do this. Probably the simplest and most obvious would be to specify separate line colors for all 20 lines:

line_colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k', ...]

for ii in range(20):
    plt.plot(x, y, c=line_colors[ii])

Of course it would a bit of a pain to have to type out 20 different color strings!

You could also generate the colors by drawing an array of RGBA values from a colormap as in unutbu's answer, but most of the built-in colormaps contain red, so you'd have to either pick a colormap that doesn't contain red, design your own, or pick a range of float values between 0 and 1 that did not map to the red region of the colormap.

If you don't mind some colors being repeated, one potentially nicer option would be to use itertools.cycle to create a generator object that yields colors in a repeating cycle:

from itertools import cycle

color_cycle = cycle(['g', 'b', 'c', 'm', 'y', 'k'])

for ii in range(20):
    if ii == 0:
        plt.plot(x, y, c='r')
    else:
        plt.plot(x, y, c=cycle.next())

In fact, this is exactly how the default matplotlib color cycle works. Each axis object contains an itertools.cycle which sequentially changes the default color for each line that is drawn on that axis:

ax = plt.axes()

ax_color_cycle = ax._get_lines.color_cycle

print(ax_color_cycle)
# <itertools.cycle object at 0x7fdb91efae60>

print(ax_color_cycle.next())
# b

print(ax_color_cycle.next())
# g

print(ax_color_cycle.next())
# r

# etc.
like image 40
ali_m Avatar answered Sep 21 '22 08:09

ali_m