web-dev-qa-db-fra.com

Ajouter/créer dynamiquement des sous-parcelles dans matplotlib

Je veux créer un tracé composé de plusieurs sous-graphes avec des axes x/y partagés. Cela devrait ressembler à ceci dans la documentation (bien que mes intrigues secondaires soient des nuages ​​de points): (code ici)

3 subplots sharing x and y axis

Mais je veux créer les intrigues secondaires de manière dynamique!

Le nombre de sous-parcelles dépend donc de la sortie d'une fonction précédente. (Il y aura probablement environ 3 à 15 sous-parcelles par diagramme, chacune à partir d'un jeu de données distinct, en fonction de l'entrée de mon script.)

Quelqu'un peut-il me dire comment y parvenir? 

30
CodingCat
import matplotlib.pyplot as plt
from pylab import *
import numpy as np

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

subplots_adjust(hspace=0.000)
number_of_subplots=3

for i,v in enumerate(xrange(number_of_subplots)):
    v = v+1
    ax1 = subplot(number_of_subplots,1,v)
    ax1.plot(x,y)

plt.show()

Ce code fonctionne mais vous devrez corriger les axes. J'avais l'habitude de subplot de tracer 3 graphiques tous dans la même colonne. Tout ce que vous avez à faire est d’affecter un entier à la variable number_of_plots. Si les valeurs X et Y sont différentes pour chaque tracé, vous devrez les attribuer à chaque tracé.

subplot fonctionne comme suit si, par exemple, j'avais une valeur de sous-intrigue de 3,1,1. Cela crée une grille 3x1 et place le tracé en 1ère position. Lors de l'interaction suivante, si mes valeurs subplot étaient 3,1,2, cela crée à nouveau une grille 3x1 mais place le tracé en 2e position, etc. 

19
Harpal

Basé sur ce post , ce que vous voulez faire est quelque chose comme ceci:

import matplotlib.pyplot as plt

# Start with one
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3])

# Now later you get a new subplot; change the geometry of the existing
n = len(fig.axes)
for i in range(n):
    fig.axes[i].change_geometry(n+1, 1, i+1)

# Add the new
ax = fig.add_subplot(n+1, 1, n+1)
ax.plot([4,5,6])

plt.show() 

Cependant, Paul H 's answer pointe vers le sous-module appelé gridspec , ce qui pourrait faciliter ce qui précède. Je laisse cela comme un exercice pour le lecteur ^ _ ~.

14
Sardathrion

Supposons que vous connaissiez le total des sous-parcelles et le total des colonnes que vous souhaitez utiliser:

import matlab.pyplot as plt

# Subplots are organized in a Rows x Cols Grid
# Tot and Cols are known

Tot = number_of_subplots
Cols = number_of_columns

# Compute Rows required

Rows = Tot // Cols 
Rows += Tot % Cols

# Create a Position index

Position = range(1,Tot + 1)

Première instance de Lignes comptes uniquement pour les lignes complétées par des sous-parcelles, puis une ligne supplémentaire est ajoutée si 1, 2 ou ... Cols - 1 sous-parcelles doivent encore être localisées.

Puis créez figure et ajoutez des sous-parcelles avec une boucle pour la boucle .

# Create main figure

fig = plt.figure(1)
for k in range(Tot):

  # add every single subplot to the figure with a for loop

  ax = fig.add_subplot(Rows,Cols,Position[k])
  ax.plot(x,y)      # Or whatever you want in the subplot

plt.show()

Veuillez noter que vous avez besoin de la plage Position pour déplacer les sous-parcelles au bon endroit.

12
Matteo Scarponi

Au lieu de compter votre propre nombre de lignes et de colonnes, il m'a été plus facile de créer les sous-graphes en utilisant d'abord plt.subplots, puis de parcourir l'objet des axes pour ajouter des graphes.

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=3, ncols=2, figsize=(12, 8))
x_array = np.random.randn(6, 10)
y_array = np.random.randn(6, 10)

i = 0
for row in axes:
    for ax in row:
        x = x_array[i] 
        y = y_array[i]
        ax.scatter(x, y)
        ax.set_title("Plot " + str(i))
        i += 1
plt.tight_layout()
plt.show()

Ici, j’utilise i pour parcourir les éléments de x_array et y_array, mais vous pouvez également parcourir facilement des fonctions ou des colonnes de cadres de données pour générer dynamiquement des graphiques.

0
charleslow