362 votes

Tracer deux histogrammes sur un seul graphique avec matplotlib

J'ai créé un histogramme en utilisant des données provenant d'un fichier et aucun problème. Maintenant, je voulais superposer les données d'un autre fichier dans le même histogramme, donc je fais quelque chose comme ceci

n,bins,patchs = ax.hist(mydata1,100)
n,bins,patchs = ax.hist(mydata2,100)

mais le problème est que pour chaque intervalle, seule la barre avec la valeur la plus élevée apparaît, et l'autre est cachée. Je me demande comment je pourrais tracer les deux histogrammes en même temps avec des couleurs différentes.

7voto

Voici une méthode simple pour tracer deux histogrammes, avec leurs barres côte à côte, sur le même graphique lorsque les données ont des tailles différentes :

def plotHistogram(p, o):
    """
    p and o are iterables with the values you want to 
    plot the histogram of
    """
    plt.hist([p, o], color=['g','r'], alpha=0.8, bins=50)
    plt.show()

7voto

Patrick FitzGerald Points 1347

Le tracé de deux histogrammes qui se chevauchent (ou plus) peut conduire à un tracé plutôt encombré. Je trouve que l'utilisation de histogrammes en escalier (alias histogrammes creux) améliore considérablement la lisibilité. Le seul inconvénient est que dans matplotlib, la légende par défaut d'un histogramme en escalier n'est pas correctement formatée, elle peut donc être modifiée comme dans l'exemple suivant :

import numpy as np                   # v 1.19.2
import matplotlib.pyplot as plt      # v 3.3.2
from matplotlib.lines import Line2D

rng = np.random.default_rng(seed=123)

# Create two normally distributed random variables of different sizes
# and with different shapes
data1 = rng.normal(loc=30, scale=10, size=500)
data2 = rng.normal(loc=50, scale=10, size=1000)

# Create figure with 'step' type of histogram to improve plot readability
fig, ax = plt.subplots(figsize=(9,5))
ax.hist([data1, data2], bins=15, histtype='step', linewidth=2,
        alpha=0.7, label=['data1','data2'])

# Edit legend to get lines as legend keys instead of the default polygons
# and sort the legend entries in alphanumeric order
handles, labels = ax.get_legend_handles_labels()
leg_entries = {}
for h, label in zip(handles, labels):
    leg_entries[label] = Line2D([0], [0], color=h.get_facecolor()[:-1],
                                alpha=h.get_alpha(), lw=h.get_linewidth())
labels_sorted, lines = zip(*sorted(leg_entries.items()))
ax.legend(lines, labels_sorted, frameon=False)

# Remove spines
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Add annotations
plt.ylabel('Frequency', labelpad=15)
plt.title('Matplotlib step histogram', fontsize=14, pad=20)
plt.show()

step_hist

Comme vous pouvez le voir, le résultat est assez propre. Ceci est particulièrement utile lorsque l'on superpose plus de deux histogrammes. Selon la façon dont les variables sont distribuées, cela peut fonctionner jusqu'à environ 5 distributions superposées. Au-delà, il faudrait utiliser un autre type de graphique, comme celui présenté ci-dessous. ici .

4voto

PV8 Points 4537

Il y a aussi une option qui est assez similaire à la réponse de Joaquin :

import random
from matplotlib import pyplot

#random data
x = [random.gauss(3,1) for _ in range(400)]
y = [random.gauss(4,2) for _ in range(400)]

#plot both histograms(range from -10 to 10), bins set to 100
pyplot.hist([x,y], bins= 100, range=[-10,10], alpha=0.5, label=['x', 'y'])
#plot legend
pyplot.legend(loc='upper right')
#show it
pyplot.show()

Donne le résultat suivant :

enter image description here

3voto

carl Points 25879

On dirait que vous voulez juste un graphique à barres :

Vous pouvez également utiliser des sous-plots.

0 votes

La différence est qu'avec hist vous obtenez un graphique de fréquence. vous devriez peut-être montrer comment faire. fréquence avec pandas + graphique en barres = hist()

3voto

黄锐铭 Points 131

Il y a un problème lorsque vous voulez tracer l'histogramme d'un tableau numpy à 2 dimensions. Vous devez permuter les 2 axes.

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(size=(2, 300))
# swapped_data.shape == (300, 2)
swapped_data = np.swapaxes(x, axis1=0, axis2=1)
plt.hist(swapped_data, bins=30, label=['x', 'y'])
plt.legend()
plt.show()

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X