web-dev-qa-db-fra.com

Tracer deux histogrammes à partir d'un pandas DataFrame dans un sous-tracé à l'aide de matplotlib

J'ai un pandas dataframe comme le suivant:

df = pd.DataFrame({ 'a_wood' : np.random.randn(100),
                 'a_grassland' : np.random.randn(100),
                 'a_settlement' : np.random.randn(100),
                 'b_wood' : np.random.randn(100),
                 'b_grassland' : np.random.randn(100),
                  'b_settlement' : np.random.randn(100)})

et je veux créer des histogrammes de ces données avec chaque en-tête de trame de données dans un sous-tracé.

fig, ax = plt.subplots(2, 3, sharex='col', sharey='row')

m=0
for i in range(2):
    for j in range(3):

        df.hist(column = df.columns[m], bins = 12, ax=ax[i,j], figsize=(20, 18))
        m+=1

Pour cela, le code précédent fonctionne parfaitement, mais maintenant je veux combiner les en-têtes a et b (par exemple "a_woods" et "b-woods") à une sous-intrigue afin qu'il n'y ait que trois histogrammes. J'ai essayé d'assigner deux colonnes à df.columns[[m,m+3]] mais cela ne fonctionne pas. J'ai également une colonne d'index avec des chaînes comme "day_1", que je veux être sur l'axe des x. Est-ce que quelqu'un peut m'aider?

C'est jusqu'où je suis arrivé. Histogram

6
Max2603

Je ne sais pas si j'ai bien compris votre question, mais quelque chose comme ça peut combiner les tracés. Vous voudrez peut-être jouer un peu avec l'alpha et changer les en-têtes.

#NOTE that you might want to specify your bins or they wont line up exactly
fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(20, 18))
n = 3
for j in range(n):
    df.hist(column=df.columns[j], bins=12, ax=ax[j], alpha=0.5, color='red')
    df.hist(column=df.columns[j+n], bins=12, ax=ax[j], alpha=0.5, color='blue')
    ax[j].set_title(df.columns[j][2:])

Pour les tracer les uns à côté des autres, essayez ceci:

#This example doesnt have the issue with different binsizes within one subplot
fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(20, 18))

n = 3
colors = ['red', 'blue']

axes = ax.flatten()
for i,j in Zip(range(n), axes):
    j.hist([df.iloc[:,i], df.iloc[:,i+n]], bins=12, color=colors)
    j.set_title(df.columns[i][2:])

Histogram, multiple bars in same bin

1
Alex

vous voulez quelque chose qui boucle dans chaque colonne et tracez ses données dans l'histogramme, non? Je peux vous suggérer de faire quelques modifications que vous pouvez réutiliser dans le futur code, avant de donner le code, il y a quelques conseils utiles qui sont utiles,

  1. Il faut savoir que les cadres de données ont un attribut qui peut être utilisé pour parcourir, par exemple, l'attribut .columns laisse avoir la liste des colonnes
  2. De plus, lors du traçage, j'ai remarqué que l'utilisation directe des coordonnées sur la grille ne permet pas à votre code d'être adaptable, vous devez donc `` aplatir '' les coordonnées de votre grille, d'où l'utilisation de ax.ravel() qui permet cela.
  3. enumerate() est toujours utile pour parcourir un objet tout en rendant disponible le ième élément et son index en même temps.
  4. Comprendre les sous-tracés en python est difficile au début, donc lire le code d'autres personnes est vraiment utile, je vous conseille fortement de regarder le tracé fait dans les exemples pour les fonctions scikit (cela a beaucoup aidé)

voici ma proposition de code:

fig, ax = plt.subplots(1, 3, sharex='col', sharey='row', figsize=(12,7))
ax = ax.ravel() 
# this method helps you to go from a 2x3 array coordinates to 
# 1x6 array, it will be helpful to use as below

for idx in range(3):
    ax[idx].hist(df.iloc[:,idx], bins=12, alpha=0.5)
    ax[idx].hist(df.iloc[:,idx+3], bins=12, alpha=0.5)
    ax[idx].set_title(df.columns[idx]+' with '+df.columns[idx+3])
    ax[idx].legend(loc='upper left')

the result looks like this

J'espère que cela vous sera utile, n'hésitez pas à me poser des questions si vous avez besoin de plus de détails :)

REMARQUE: ré-utilisé la réponse d'Alex pour modifier ma réponse. Vérifiez également ceci documentation matplotlib pour plus de détails. Dans ce cas précis, le point 3 n'est plus pertinent.

3
Eric