359 Stimmen

Zwei Histogramme in einem einzigen Diagramm mit matplotlib darstellen

Ich habe eine Histogrammdarstellung mit Daten aus einer Datei erstellt, und es gab keine Probleme. Nun wollte ich Daten aus einer anderen Datei im selben Histogramm überlagern, also habe ich etwas wie folgt gemacht

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

aber das Problem ist, dass für jedes Intervall nur der Balken mit dem höchsten Wert erscheint und die anderen ausgeblendet werden. Ich frage mich, wie ich beide Histogramme gleichzeitig mit unterschiedlichen Farben darstellen kann.

7voto

Hier ist eine einfache Methode, um zwei Histogramme mit nebeneinander liegenden Balken auf demselben Diagramm darzustellen, wenn die Daten unterschiedliche Größen haben:

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()

6voto

Patrick FitzGerald Punkte 2710

Die Darstellung von zwei sich überschneidenden Histogrammen (oder mehr) kann zu einer ziemlich unübersichtlichen Darstellung führen. Ich finde, dass die Verwendung von Stufenhistogramme (auch bekannt als hohle Histogramme) verbessert die Lesbarkeit erheblich. Der einzige Nachteil ist, dass in Matplotlib die Standardlegende für ein Stufenhistogramm nicht richtig formatiert ist, so dass sie wie im folgenden Beispiel bearbeitet werden kann:

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

Wie Sie sehen können, sieht das Ergebnis recht sauber aus. Dies ist besonders nützlich, wenn sich mehr als zwei Histogramme überlappen. Je nachdem, wie die Variablen verteilt sind, kann dies für bis zu etwa 5 überlappende Verteilungen funktionieren. Bei mehr Überschneidungen müsste eine andere Art von Diagramm verwendet werden, z. B. eines der folgenden aquí .

5voto

carl Punkte 48262

Es klingt, als ob Sie nur ein Balkendiagramm benötigen:

Alternativ können Sie auch Teilflächen verwenden.

4voto

PV8 Punkte 5125

Auch eine Option, die der Antwort von Joaquin sehr ähnlich ist:

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()

Ergibt die folgende Ausgabe:

enter image description here

3voto

黄锐铭 Punkte 181

Es gibt eine Einschränkung, wenn Sie das Histogramm aus einem 2-d Numpy-Array darstellen wollen. Sie müssen die 2 Achsen vertauschen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X