2016-09-07 15 views
1

У меня есть несколько функций, в которые я ввожу массив или dict, а также путь в качестве аргумента, и функция сохранит фигуру на пути к определенному пути.matplotlib очень медленно в построении

Пытаясь сохранить пример как можно меньше, но вот две функции:

def valueChartPatterns(dict,path): 
    seen_values = Counter() 

    for data in dict.itervalues(): 
     seen_values += Counter(data.values()) 

    seen_values = seen_values.most_common() 
    seen_values_pct = map(itemgetter(1), tupleCounts2Percents(seen_values)) 
    seen_values_pct = ['{:.2%}'.format(item)for item in seen_values_pct] 

    plt.figure() 

    numberchart = plt.bar(range(len(seen_values)), map(itemgetter(1), seen_values), width=0.9,align='center') 
    plt.xticks(range(len(seen_values)), map(itemgetter(0), seen_values)) 

    plt.title('Values in Pattern Dataset') 
    plt.xlabel('Values in Data') 
    plt.ylabel('Occurrences') 

    plt.tick_params(axis='both', which='major', labelsize=6) 
    plt.tick_params(axis='both', which='minor', labelsize=6) 
    plt.tight_layout() 

    plt.savefig(path) 
    plt.clf() 

def countryChartPatterns(dict,path): 
    seen_countries = Counter() 

    for data in dict.itervalues(): 
     seen_countries += Counter(data.keys()) 

    seen_countries = seen_countries.most_common() 

    seen_countries_percentage = map(itemgetter(1), tupleCounts2Percents(seen_countries)) 
    seen_countries_percentage = ['{:.2%}'.format(item)for item in seen_countries_percentage] 

    yvals = map(itemgetter(1), seen_countries) 
    xvals = map(itemgetter(0), seen_countries) 

    plt.figure() 

    countrychart = plt.bar(range(len(seen_countries)), yvals, width=0.9,align='center') 
    plt.xticks(range(len(seen_countries)), xvals) 

    plt.title('Countries in Pattern Dataset') 
    plt.xlabel('Countries in Data') 
    plt.ylabel('Occurrences') 

    plt.tick_params(axis='both', which='major', labelsize=6) 
    plt.tick_params(axis='both', which='minor', labelsize=6) 
    plt.tight_layout() 

    plt.savefig(path) 
    plt.clf() 

Очень минимальный пример ДИКТ есть, но фактически ДИКТ содержит 56000 значения:

dict = {"a": {"Germany": 20006.0, "United Kingdom": 20016.571428571428}, "b": {"Chad": 13000.0, "South Africa": 3000000.0},"c":{"Chad": 200061.0, "South Africa": 3000000.0} 
    } 

И в мой сценарий, я называю:

if __name__ == "__main__": 

    plt.close('all') 

    print "Starting pattern charting...\n" 

    countryChartPatterns(dict,'newPatternCountries.png')) 

    valueChartPatterns(dict,'newPatternValues.png')) 

Обратите внимание, я загружаю import matplotlib.pyplot as plt.

При запуске этого скрипта в PyCharm я получаю Starting pattern charting... в моей консоли, но функции занимают слишком много времени для построения.

Что я делаю неправильно? Должен ли я использовать гистограмму вместо штрихового графика, так как это должно достичь той же цели, что и число появлений стран/ценностей? Могу ли я каким-то образом изменить свой бэкэнд графического интерфейса? Любые советы приветствуются.

+0

Я бы время Как долго 'for' петля над словарем принимает; что для меня похож на подозреваемого, делающего вещи медленными. За гранью этого; без рабочего примера мы можем только догадываться ... – Bart

+0

Есть ли какие-либо стандартные вещи, которые можно сделать с помощью 'matplotlib' для ускорения? Попытка с небольшим набором данных работает абсолютно нормально. –

+0

Вы уверены, что это 'matplotlib', который работает медленно? Потому что небольшой набор данных также упрощает предварительную обработку. Не начинайте оптимизацию, пока вы не узнаете, какая часть медленная! Я бы использовал самый простой из всех таймеров (или просмотрел профилировщики Python); 'время импорта; t0 = time.time(); ваш код; print (time.time() - t0') и поместите такой таймер вокруг (1) предварительную обработку данных (петли 'for' и все остальное) и (2) часть графика. Мне интересно об итогах – Bart

ответ

1

Это испытание, которое я упоминал в предыдущих комментариях, в результате чего:

Elapsed pre-processing = 13.79 s 
Elapsed plotting = 0.17 s 
Pre-processing/plotting = 83.3654562565 

тест сценарий:

import matplotlib.pylab as plt 
from collections import Counter 
from operator import itemgetter 
import time 

def countryChartPatterns(dict,path): 
    # pre-processing ------------------- 
    t0 = time.time() 

    seen_countries = Counter() 

    for data in dict.itervalues(): 
     seen_countries += Counter(data.keys()) 

    seen_countries = seen_countries.most_common() 

    yvals = map(itemgetter(1), seen_countries) 
    xvals = map(itemgetter(0), seen_countries) 

    dt1 = time.time() - t0 
    print("Elapsed pre-processing = {0:.2f} s".format(dt1)) 

    t0 = time.time() 

    # plotting ------------------- 
    plt.figure() 

    countrychart = plt.bar(range(len(seen_countries)), yvals, width=0.9,align='center') 
    plt.xticks(range(len(seen_countries)), xvals) 

    plt.title('Countries in Pattern Dataset') 
    plt.xlabel('Countries in Data') 
    plt.ylabel('Occurrences') 

    plt.tick_params(axis='both', which='major', labelsize=6) 
    plt.tick_params(axis='both', which='minor', labelsize=6) 
    plt.tight_layout() 

    plt.savefig(path) 
    plt.clf() 

    dt2 = time.time() - t0 
    print("Elapsed plotting = {0:.2f} s".format(dt2)) 
    print("Pre-processing/plotting = {}".format(dt1/dt2)) 

if __name__ == "__main__": 
    import random as rd 
    import numpy as np 

    countries = ["United States of America", "Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua & Deps", "Argentina", "Armenia", "Australia", "Austria", "Azerbaijan"] 

    def item(): 
     return {rd.choice(countries): np.random.randint(1e3), rd.choice(countries): np.random.randint(1e3)} 
    dict = {} 
    for i in range(1000000): 
     dict[i] = item() 

    print("Starting pattern charting...") 

    countryChartPatterns(dict,'newPatternCountries.png') 
+0

Понял. Спасибо за указание. Я прочитал кое-что об изменении GUI-сервера, но явно не в моей проблеме. благодаря –

 Смежные вопросы

  • Нет связанных вопросов^_^