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_color
array
viel einfacher sind.
Kudos (upvote) für ein kleines Beispiel zu machen. – roadrunner66