web-dev-qa-db-fra.com

Comment obtenir différentes lignes de couleur pour différentes parcelles dans une même figure?

J'utilise matplotlib pour créer les tracés. Je dois identifier chaque parcelle avec une couleur différente qui devrait être générée automatiquement par Python.

Pouvez-vous s'il vous plaît me donner une méthode pour mettre différentes couleurs pour différentes parcelles dans la même figure?

170
pottigopi

Matplotlib le fait par défaut.

Par exemple.:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)
plt.show()

Basic plot demonstrating color cycling

Et, comme vous le savez peut-être déjà, vous pouvez facilement ajouter une légende:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

Basic plot with legend

Si vous souhaitez contrôler les couleurs qui seront cyclées:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow'])

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

Plot showing control over default color cycling

J'espère que ça aidera un peu! Si vous ne connaissez pas matplotlib, le tutoriel est un bon point de départ .

Modifier:

Tout d’abord, si vous voulez tracer un graphique sur une figure, soit:

  1. Mettez-les sur des parcelles différentes (envisagez d'utiliser quelques sous-parcelles sur une figure), ou
  2. Utilisez autre chose que la couleur (c'est-à-dire les styles de marqueur ou l'épaisseur de trait) pour les distinguer.

Sinon, vous allez vous retrouver avec un complot très désordonné! Soyez gentil avec tous ceux qui vont lire ce que vous faites et n'essayez pas de mettre 15 choses différentes dans une seule figure !!

Au-delà de cela, beaucoup de personnes sont daltoniennes à des degrés divers et il est difficile de distinguer entre de nombreuses couleurs subtiles différentes.

Cela dit, si vous voulez vraiment mettre 20 lignes sur un axe avec 20 couleurs relativement distinctes, voici une façon de le faire:

import matplotlib.pyplot as plt
import numpy as np

num_plots = 20

# Have a look at the colormaps here and decide which one you'd like:
# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
colormap = plt.cm.Gist_ncar
plt.gca().set_color_cycle([colormap(i) for i in np.linspace(0, 0.9, num_plots)])

# Plot several different functions...
x = np.arange(10)
labels = []
for i in range(1, num_plots + 1):
    plt.plot(x, i * x + 5 * i)
    labels.append(r'$y = %ix + %i$' % (i, 5*i))

# I'm basically just demonstrating several different legend options here...
plt.legend(labels, ncol=4, loc='upper center', 
           bbox_to_anchor=[0.5, 1.1], 
           columnspacing=1.0, labelspacing=0.0,
           handletextpad=0.0, handlelength=1.5,
           fancybox=True, shadow=True)

plt.show()

Unique colors for 20 lines based on a given colormap

360
Joe Kington

Les mettre plus tard

Si vous ne connaissez pas le nombre de parcelles que vous allez tracer, vous pouvez modifier les couleurs une fois que vous les avez tracées en récupérant le nombre directement à partir de la parcelle à l'aide de .lines, j'utilise cette solution:

Quelques données aléatoires

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)


for i in range(1,15):
    ax1.plot(np.array([1,5])*i,label=i)

Le morceau de code dont vous avez besoin:

colormap = plt.cm.Gist_ncar #nipy_spectral, Set1,Paired   
colors = [colormap(i) for i in np.linspace(0, 1,len(ax1.lines))]
for i,j in enumerate(ax1.lines):
    j.set_color(colors[i])


ax1.legend(loc=2)

Le résultat est le suivant: enter image description here

33
G M

Je voudrais proposer une légère amélioration par rapport à la dernière réponse de boucle donnée dans le post précédent (ce post est correct et doit toujours être accepté). L'hypothèse implicite faite lors de l'étiquetage du dernier exemple est que plt.label(LIST) place le numéro d'étiquette X dans LIST avec la ligne correspondant à la Xème fois que plot a été appelée. J'ai déjà rencontré des problèmes avec cette approche. La méthode recommandée pour créer des légendes et personnaliser leurs étiquettes en fonction de la documentation de matplotlibs ( http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-legend-item ) est de: un sentiment chaleureux que les étiquettes vont avec les parcelles exactes que vous pensez qu'ils font:

...
# Plot several different functions...
labels = []
plotHandles = []
for i in range(1, num_plots + 1):
    x, = plt.plot(some x vector, some y vector) #need the ',' per ** below
    plotHandles.append(x)
    labels.append(some label)
plt.legend(plotHandles, labels, 'upper left',ncol=1)

**: Les légendes Matplotlib ne fonctionnent pas

2
Tommy

TL; DR Non, cela ne peut pas être fait automatiquement . Oui c'est possible.

import matplotlib.pyplot as plt
my_colors = plt.rcParams['axes.prop_cycle']() # <<< note that we CALL the prop_cycle
fig, axes = plt.subplots(2,3)
for ax in axes.flatten(): ax.plot((0,1), (0,1), **next(my_colors))

enter image description here Chaque parcelle (axes) d'une figure (figure) a son propre cycle de couleurs - si vous ne forcez pas une couleur différente pour chaque parcelle, toutes les parcelles partagent le même ordre de couleurs mais si on étire un peu ce que "automatiquement" signifie, cela peut être fait.


Le PO a écrit

[...] Je dois identifier chaque parcelle avec une couleur différente qui devrait être générée automatiquement par [Matplotlib].

Mais ... Matplotlib génère automatiquement des couleurs différentes pour chaque courbe.

In [10]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [11]: plt.plot((0,1), (0,1), (1,2), (1,0));
Out[11]:

enter image description here

Alors pourquoi la demande de l'OP? Si nous continuons à lire, nous avons

Pouvez-vous s'il vous plaît me donner une méthode pour mettre différentes couleurs pour différentes parcelles dans la même figure?

et cela a du sens, car chaque parcelle (chaque axes dans le langage de Matplotlib) a son propre color_cycle (ou plutôt, en 2018, son prop_cycle) et chaque parcelle (axes ) réutilise les mêmes couleurs dans le même ordre.

In [12]: fig, axes = plt.subplots(2,3)

In [13]: for ax in axes.flatten():
    ...:     ax.plot((0,1), (0,1))

enter image description here

Si tel est le sens de la question initiale, une possibilité est de nommer explicitement une couleur différente pour chaque tracé.

Si les tracés (comme cela arrive souvent) sont générés dans une boucle, nous devons avoir une variable de boucle supplémentaire pour remplacer la couleur automatiquement choisie par Matplotlib.

In [14]: fig, axes = plt.subplots(2,3)

In [15]: for ax, short_color_name in Zip(axes.flatten(), 'brgkyc'):
    ...:     ax.plot((0,1), (0,1), short_color_name)

enter image description here

Une autre possibilité consiste à instancier un objet cycleur

from cycler import cycler
my_cycler = cycler('color', ['k', 'r']) * cycler('linewidth', [1., 1.5, 2.])
actual_cycler = my_cycler()

fig, axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot((0,1), (0,1), **next(actual_cycler))

enter image description here

Notez que type(my_cycler) est cycler.Cycler mais type(actual_cycler) est itertools.cycle.

2
gboffi