2016-05-04 9 views
2

私はmatplotlibを初めて使用し、ヒストグラムをプロットしようとしています。私は低いビン範囲に興味があり、したがって私のビン範囲を分割しますが、それは右の多くの白いスペースで醜いように見えます。 私はこのヒストグラムを生成し、いくつかのコードを持っているが、私はそのようなことを変えたい:低い範囲バーが良く示されるようにmatplotlibが下のビンを結合する

  • は、150以上のようにx軸の位置150の後にすべてのバーを兼ね備えています。
  • 異なる色に変更バー
  • 左端のバーの色を、X軸を表し
  • バーは5-40の間には、異なる色を40+異なる色

    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

    小さな例を作るための名誉(upvote)。 – roadrunner66

    答えて

    0

    私はあなたが何をしているかについて完全にはわかりません特に、あなたの単純な例と少し矛盾しているように見えます(私はパーセンタイルベースの色付けを意味します)。

    とにかくnumpyが既にインポートされているので、np.histogramを直接使用し、plt.barを手動で呼び出すことをおすすめします。これの主な利点は、(出力をより良くコントロールすることに加えて、わずかな作業量を犠牲にして)、各バーの色を含むリストを渡すことができることです。私は有益なコメントを残してみました

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

    Aはあなたの例のバージョンを変更しました。注目すべきは、np.histogramがビン値を生成し、それがplt.barに供給されることです。後者はplt.hist(特に、各バーの左右の側を手動で指定する必要があります)と比較して少し複雑な入力がありますが、これによりさらに大幅なカスタマイズが可能になります。

    「改善1」でわかるように、私はあなたのビンをthreshの値の上にマージし、他のものはそのまま残しました。私はあなたのx<50地域にもっと多くのスペースを残すためにこれを頼んだことを知っています。最後の値をbinrに手動でシフトし、最後の(マージした)バーをより強く引っ張ってこれを行うことができます。これを行う場合は、x軸にこれを示すにはplt.xlabelを使用してください。

    私がした理由ではなくこれは、このような操作によってデータが大きく歪曲し、多くの偏見につながるからです。あなたは一般的にこれを避けるべきです。バーを視覚的に歪ませたいと思っているなら、これでOKです。前の段落で書いたことをしてください。

    私は上記の結果を含めていますが、違いはオリジナルに比べて巨大ではありません。しかし、bins_colorarrayの導入により、ほとんどの操作をもっと簡単に行うことができると私は信じています。

    output

    関連する問題