2016-07-31 3 views
0

Я пытаюсь автоматизировать частотную диаграмму с matplotlib в Python, чтобы подсчитывать вхождения, вместо того, чтобы вручную записывать в Excel. Тем не менее, я не могу сделать аналогичную диаграмму, как я сделал в Excel. Возможно ли это с Matplotlib?Частотная диаграмма с matplotlib

В Excel:

enter image description here

Код:

#!/usr/bin/python 

import numpy as np 
import matplotlib.pyplot as plt 
from numpy import * 
import os 
import sys 
import csv 
from random import randint 

x = [6,0,0,26,0,0,0,0,5,0,7,0,12,12,0,0,0,3,0,5,5,0,10,4,3,5,1,0,2,0,0,1,0,8,0,3,7,1,0,0,0,1,1,0,0,0,0,0,7,16,0,0,0,5] 


plt.hist(x) 
plt.title("Frequency diagram") 
plt.xlabel("Value") 
plt.ylabel("Frequency") 
plt.show() 

Результат (читаемость не так хорошо, по сравнению с Excel, как я могу сделать его подобно тому, как граф первенствовать):

enter image description here

ответ

2
import numpy as np 
import matplotlib.pyplot as plt 

def make_hist(ax, x, bins=None, binlabels=None, width=0.85, extra_x=1, extra_y=4, 
       text_offset=0.3, title=r"Frequency diagram", 
       xlabel="Values", ylabel="Frequency"): 
    if bins is None: 
     xmax = max(x)+extra_x 
     bins = range(xmax+1) 
    if binlabels is None: 
     if np.issubdtype(np.asarray(x).dtype, np.integer): 
      binlabels = [str(bins[i]) if bins[i+1]-bins[i] == 1 else 
         '{}-{}'.format(bins[i], bins[i+1]-1) 
         for i in range(len(bins)-1)] 
     else: 
      binlabels = [str(bins[i]) if bins[i+1]-bins[i] == 1 else 
         '{}-{}'.format(*bins[i:i+2]) 
         for i in range(len(bins)-1)] 
     if bins[-1] == np.inf: 
      binlabels[-1] = '{}+'.format(bins[-2]) 
    n, bins = np.histogram(x, bins=bins) 
    patches = ax.bar(range(len(n)), n, align='center', width=width) 
    ymax = max(n)+extra_y 

    ax.set_xticks(range(len(binlabels))) 
    ax.set_xticklabels(binlabels) 

    ax.set_title(title) 
    ax.set_xlabel(xlabel) 
    ax.set_ylabel(ylabel) 
    ax.set_ylim(0, ymax) 
    ax.grid(True, axis='y') 
    # http://stackoverflow.com/a/28720127/190597 (peeol) 
    ax.spines['top'].set_visible(False) 
    ax.spines['right'].set_visible(False) 
    ax.spines['bottom'].set_visible(False) 
    ax.spines['left'].set_visible(False) 
    # http://stackoverflow.com/a/11417222/190597 (gcalmettes) 
    ax.xaxis.set_ticks_position('none') 
    ax.yaxis.set_ticks_position('none') 
    autolabel(patches, text_offset) 

def autolabel(rects, shift=0.3): 
    """ 
    http://matplotlib.org/1.2.1/examples/pylab_examples/barchart_demo.html 
    """ 
    # attach some text labels 
    for rect in rects: 
     height = rect.get_height() 
     if height > 0: 
      plt.text(rect.get_x()+rect.get_width()/2., height+shift, '%d'%int(height), 
        ha='center', va='bottom') 

x = [6,0,0,26,0,0,0,0,5,0,7,0,12,12,0,0,0,3,0,5,5,0,10,4,3,5,1,0,2,0,0,1,0,8,0, 
    3,7,1,0,0,0,1,1,0,0,0,0,0,7,16,0,0,0,5,41] 
fig, ax = plt.subplots(figsize=(14,5)) 
# make_hist(ax, x) 
# make_hist(ax, [1,1,1,0,0,0], extra_y=1, text_offset=0.1) 
make_hist(ax, x, bins=list(range(10))+list(range(10,41,5))+[np.inf], extra_y=6) 
plt.show() 

enter image description here

make_hist попытки определить, если все значения в x - целые числа. Если это так, он использует метки битов на основе целых чисел. Например, метка ячейки 10-14 представляет диапазон [10, 14] (включительно).

Если, с другой стороны, x содержит поплавки, то make_hist будет использовать полуоткрытые надписи на основе флоат-битов. Например, 10-15 будет представлять полуоткрытый диапазон [10, 15).

+0

Вау! спасибо, что много кода. Однако, когда я меняю значения списка на, например, 'x = [1,1,1,0,0,0], диаграмма не отображается правильно? Это динамично? Поскольку значения будут разными. – user3580316

+0

Я был один за другим в своем определении «бункеров». Возможно, попробуйте еще раз. – unutbu

+0

Спасибо. Тем не менее, мне интересно, почему он не показывает никаких значений выше 35? Возможно ли, например, иметь последний колл как «40 +», где значения выше 40 являются частью? Поскольку значения 'x' могут меняться и не статичны. Большое спасибо за вашу помощь. – user3580316

0

Matplotli b поддерживает стиль. Вы можете предпочесть стиль ggplot:

plt.style.use('ggplot') 

Есть много других Premade стилей, или вы можете создать свой собственный: http://matplotlib.org/users/style_sheets.html