2016-05-04 11 views
2

Ich bin neu zu Matplotlib und versuchen, ein Histogramm zu plotten. Ich interessiere mich für einen niedrigeren Behälterbereich und spalte daher meinen Behälterbereich, aber er sieht ziemlich hässlich aus, mit viel Leerraum auf der rechten Seite. Ich habe einige Codes, um dieses Histogramm erzeugt, aber ich mag es, dass eine solche ändern:matplotlib zu kombinieren unteren Bins

  • alle Bars nach xaxis Position 150 kombinieren als 150+, so dass unterer Bereich Stäbe sind besser dargestellt.
  • Ändern die Farbe von Stangen
  • äußerste linke bar zu einer anderen Farbe
  • Stäbe, die x-Achse zwischen 5-40 unterschiedliche Farbe haben Zecken repräsentieren
  • Stäbe von 40+ verschiedenen Farben

    import matplotlib 
    matplotlib.use('PS') 
    import matplotlib.pyplot as plt 
    # sample data, These are not actual values since I have a large csv file 
    # with 1000's of rows. 
    values=[1,1,1,1,1,1,1,2,2,2,2,4,4,4,5,6,7,8,9,10,111,12,23,30,30,35,353,35,25,25,25,15,15,15,20,20,20,40,40,40,45,50,55,50,50,100,200,300,400] 
    
    limit1, limit2 = 50, 500 
    binwidth1, binwidth2 = 5, 100 
    binr=list(range(0, limit1, binwidth1)) + list(range(100, limit2, binwidth2)) 
    n, bins, patches=plt.hist(values, bins = binr) 
    one, fifty = np.percentile(values, [0.5,50]) 
    for patch, rightside, leftside in zip(patches, bins[1:], bins[:-1]): 
        if rightside < one: 
         patch.set_facecolor('green') 
        elif leftside > fifty: 
         patch.set_facecolor('red') 
    plt.title("Frequency Histogram") 
    plt.xlabel("Word Count") 
    plt.ylabel("Frequency") 
    plt.savefig(plot_file) 
    plt.close() 
    

enter image description here

+1

Kudos (upvote) für ein kleines Beispiel zu machen. – roadrunner66

Antwort

0

Ich bin nicht ganz klar darüber, was du bist Versuchen zu tun, vor allem, dass Ihre Erwartungen scheinen ein wenig widersprüchlich zu Ihrem einfachen Beispiel (ich meine die Perzentil-basierte Färbung).

Wie auch immer, ich schlage vor, dass Sie np.histogram direkt verwenden (da Sie numpy bereits importiert haben), und plt.bar manuell aufrufen. Der Hauptvorteil davon (abgesehen von einer besseren Kontrolle der Ausgabe, auf Kosten einer geringfügigen Steigerung der Anstrengung) besteht darin, dass Sie eine Liste mit der Farbe jedes Balkens übergeben können.

Eine modifizierte Version von Ihrem Beispiel:

values=[1,1,1,1,1,1,1,2,2,2,2,4,4,4,5,6,7,8,9,10,111,12,23,30,30,35,353,35,25,25,25,15,15,15,20,20,20,40,40,40,45,50,55,50,50,100,200,300,400] 

limit1, limit2 = 50, 500 
binwidth1, binwidth2 = 5, 100 
binr=list(range(0, limit1, binwidth1)) + list(range(100, limit2, binwidth2)) 

# improvement 1: merge bins above 150, keep the same maximum 
thresh = 150 
# keep the first value after the threshold too 
binr_tmp = [val for val in binr if val<=thresh] 
binr = binr_tmp + [binr[len(binr_tmp)], binr[-1]] 

# improvement 2: use np.histogram explicitly, feed into plt.bar later (for colors) 
bin_vals, bins = np.histogram(values, bins=binr) 
bins_left = binr[:-1] 
bins_width = np.diff(bins) 
bins_right = bins_left + bins_width 
one, fifty = np.percentile(values, [0.5,50]) 

# "change the color of bars": you did the same thing earlier 
# improvement: use a numpy.array for a colour list, set for each bar separately 
# (possibility for array indexing) 
# just don't forget to turn into a list() when calling plt.bar 
bins_color = np.array(['blue']*len(bins_left), dtype=object) 
bins_color[bins_left>fifty] = 'red' 
bins_color[bins_left+bins_width<one] = 'green' 

# "leftmost bar to a different color": 
bins_color[0] = 'magenta' 

# "bars from 40+ different color": would conflict with percentile-based original version 
thresh2 = 40 
#bins_color[bins_right>thresh2] = 'olive' 

hbars = plt.bar(left=bins_left, height=bin_vals, width=bins_width, color=list(bins_color)) 
plt.title("Frequency Histogram") 
plt.xlabel("Word Count") 
plt.ylabel("Frequency") 
#plt.savefig(plot_file) 
#plt.close() 
plt.show() 

Ich habe versucht, informative Kommentare zu hinterlassen. Zu beachten ist, dass np.histogram die Bin-Werte generiert, die in plt.bar eingespeist werden. Letzteres hat einen etwas komplizierteren Eingang im Vergleich zu plt.hist (insbesondere muss die linke und rechte Seite jedes Balkens manuell spezifiziert werden), aber dies ermöglicht auch eine viel größere Anpassung.

Wie Sie mit "Verbesserung 1" sehen können, fusionierte ich Ihre Bins über den thresh Wert, so dass die anderen intakt bleiben. Ich weiß, dass du darum gebeten hast, mehr Platz für deine Region zu lassen. Sie können dies tun, indem Sie den letzten Wert von binr manuell verschieben, indem Sie den letzten (verschmolzenen) Balken enger ziehen. Wenn Sie dies tun, sollten Sie plt.xlabel verwenden, um dies auf der X-Achse anzugeben.

Der Grund, dass ich tat nicht tun dies ist, dass Manipulationen wie diese stark verzerren Ihre Daten, was zu einer großen Voreingenommenheit. Sie sollten dies generell vermeiden. Wenn Sie die Balken visuell verzerren möchten und damit einverstanden sind, tun Sie einfach das, was ich im vorherigen Absatz geschrieben habe.

Ich schließe das Ergebnis der oben genannten, natürlich sind die Unterschiede nicht so groß im Vergleich zum Original. Ich glaube jedoch, dass die meisten Manipulationen, die Sie vornehmen möchten, mit der Einführung des bins_colorarray viel einfacher sind.

output

Verwandte Themen