Disons que j'ai des données sur 3 stratégies de trading, chacune avec et sans frais de transaction. Je souhaite tracer, sur les mêmes axes, la série chronologique de chacune des 6 variantes (3 stratégies * 2 coûts de trading). Je souhaite que les lignes "avec coût de transaction" soient tracées avec alpha=1
et linewidth=1
alors que je veux que les "aucuns frais de transaction" soient tracés avec alpha=0.25
et linewidth=5
. Mais je voudrais que la couleur soit la même pour les deux versions de chaque stratégie.
Je voudrais quelque chose dans le sens de:
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
for c in with_transaction_frame.columns:
ax.plot(with_transaction_frame[c], label=c, alpha=1, linewidth=1)
****SOME MAGIC GOES HERE TO RESET THE COLOR CYCLE
for c in no_transaction_frame.columns:
ax.plot(no_transaction_frame[c], label=c, alpha=0.25, linewidth=5)
ax.legend()
Quel est le code approprié à mettre sur la ligne indiquée pour réinitialiser le cycle de couleur afin qu'il soit "de retour au début" lorsque la deuxième boucle est invoquée?
Vous pouvez réinitialiser le colorcycle à l'original avec Axes.set_color_cycle . En regardant le code pour cela, il y a une fonction pour faire le travail réel:
def set_color_cycle(self, clist=None):
if clist is None:
clist = rcParams['axes.color_cycle']
self.color_cycle = itertools.cycle(clist
Et une méthode sur les Axes qui l'utilise:
def set_color_cycle(self, clist):
"""
Set the color cycle for any future plot commands on this Axes.
*clist* is a list of mpl color specifiers.
"""
self._get_lines.set_color_cycle(clist)
self._get_patches_for_fill.set_color_cycle(clist)
Cela signifie essentiellement que vous pouvez appeler set_color_cycle avec None comme seul argument, et il sera remplacé par le cycle par défaut trouvé dans rcParams ['axes.color_cycle'].
J'ai essayé cela avec le code suivant et j'ai obtenu le résultat attendu:
import matplotlib.pyplot as plt
import numpy as np
for i in range(3):
plt.plot(np.arange(10) + i)
# for Matplotlib version < 1.5
plt.gca().set_color_cycle(None)
# for Matplotlib version >= 1.5
plt.gca().set_prop_cycle(None)
for i in range(3):
plt.plot(np.arange(10, 1, -1) + i)
plt.show()
Comme la réponse donnée par @pelson utilise set_color_cycle
Et que cela est déconseillé dans Matplotlib 1.5, j'ai pensé qu'il serait utile d'avoir une version mise à jour de sa solution en utilisant set_prop_cycle
:
import matplotlib.pyplot as plt
import numpy as np
for i in range(3):
plt.plot(np.arange(10) + i)
plt.gca().set_prop_cycle(None)
for i in range(3):
plt.plot(np.arange(10, 0, -1) + i)
plt.show()
Remarquez aussi que j'ai dû changer np.arange(10,1,-1)
en np.arange(10,0,-1)
. Le premier a donné un tableau de seulement 9 éléments. Cela provient probablement de l'utilisation de différentes versions de Numpy. Le mien est 1.10.2.
MODIFIER : Suppression de la nécessité d'utiliser rcParams
. Merci à @divenex de l'avoir signalé dans un commentaire.
Puisque vous avez mentionné que vous utilisez Seaborn, ce que je recommanderais de faire est:
with sns.color_palette(n_colors=3):
ax.plot(...)
ax.plot(...)
Cela définira la palette de couleurs pour utiliser le cycle de couleurs actuellement actif, mais uniquement les trois premières couleurs de celui-ci. C'est également une solution à usage général pour chaque fois que vous souhaitez définir un cycle de couleur temporaire.
Notez que la seule chose qui doit réellement se trouver sous le bloc with
est ce que vous faites pour créer l'objet Axes
(c'est-à-dire plt.subplots
, fig.add_subplot()
, etc.). C'est juste à cause du fonctionnement du cycle de couleur matplotlib lui-même.
Faire ce que vous voulez spécifiquement, "réinitialiser" le cycle de couleur, est possible, mais c'est un hack et je ne le ferais dans aucun type de code de production. Voici cependant comment cela pourrait se produire:
f, ax = plt.subplots()
ax.plot(np.random.randn(10, 3))
ax._get_lines.color_cycle = itertools.cycle(sns.color_palette())
ax.plot(np.random.randn(10, 3), lw=5, alpha=.25)
Choisissez simplement vos couleurs et affectez-les à une liste, puis lorsque vous tracez vos données, parcourez un objet Zip
contenant votre colonne et la couleur que vous souhaitez.
colors = ['red', 'blue', 'green']
for col, color in Zip(colors, with_transaction_frame.columns):
ax.plot(with_transaction_frame[col], label=col, alpha=1.0, linewidth=1.0, color=color)
for col, color in Zip(no_transaction_frame.columns):
ax.plot(no_transaction_frame[col], label=col, alpha=0.25, linewidth=5, color=color)
Zip
crée une liste qui agrège les éléments de chacune de vos listes. Cela vous permet de parcourir facilement les deux en même temps.
Vous pouvez obtenir les couleurs de seaborn comme ceci: colors = sns.color_palette()
. La réponse de Ffisegydd fonctionnerait alors très bien. Vous pouvez également obtenir la couleur à tracer en utilisant l'opérateur module/reste (%): mycolor = colors[icolumn % len(colors]
. J'utilise souvent cette approche moi-même. Vous pourriez donc faire:
for icol, column in enumerate(with_transaction_frame.columns): mycolor = colors[icol % len(colors] ax.plot(with_transaction_frame[col], label=col, alpha=1.0, color=mycolor)
La réponse de Ffisegydd peut être plus "pythonique", cependant.