Найти - Пользователи
Полная версия: рисуем график использую библиотеку matplotlib.
Начало » Python для новичков » рисуем график использую библиотеку matplotlib.
1
bezrukov Ilya
Здравствуйте уважаемое сообщество,

учусь писать на питоне, написал скрипт рисующий график. Очень интересует насколько “правильно” пишу код, что можно улучшить, а как например вообще нельзя делать.

Так же вопрос к знатокам matplotlib, при решении данной задачи возникли проблемы с отображением значений на оси абсцисс. Точек по которым строится график может быть от 300 до “бесконечности”, даже при 300 точек подписи в оси х - сплошная не читаемая линия текста, существует ли какой нибудь стандартный механизм масштабрования, помимо “ручного” наименования точек set_xticklabels() ?


# -*- coding: utf-8 -*-

import sys
import os

#from numpy import exp, linspace
import matplotlib.pyplot as plt
import matplotlib.figure as fig


#решение проблемы с выводом на график русских шрифтов
from matplotlib import rcParams
rcParams['text.usetex']=False
rcParams['font.sans-serif'] = ['Liberation Sans']
rcParams['font.serif'] = ['Liberation Serif']


class Create_of_Graf():
"""docstring for Create_of_Graf"""

def chenge_time(self, data):
""" коныертируем время вида
%H:%M:%S,ms -> sec
"""
arr=data.split(':')
result = (float(arr[0])*3600) + (float(arr[1])*60) + (float(arr[2]))
return int(result)

def create_dict(self, data_dict, line):
"""docstring for create_dict
работает в генераторе
Заполняю словарь передавая функции строку из генератора
"""
data_dict['time'].append(self.chenge_time(line[0]))
data_dict['rate'].append( int(float(line[3].strip('Mbps'))))
data_dict['error'].append(line[13])

def parser_tsuc(self, name_file):
"""docstring for parser_tsuc
Открываем переданный файл парсим время, скорость, ошибки
на выходе словарь
"""
data_dict={'time':[], 'rate':[], 'error':[]}
[ self.create_dict(data_dict, line.split()) for line in open(name_file) if len(line.split()) > 12 ]
return data_dict

def spec_arr(self, data):
"""docstring for spec_arr
выборка 15 значений из массива
своеобразная реализация маштабирования шкалы абсцисс
"""
return sorted(data[::-(len(data)/15)])

def my_plot(self, rate, time, name_file='name_of_plot.png'):
"""docstring for my_plot
создаем график по входным данным данным
и записываем в файл
"""
fig1 = plt.figure(num = 0, figsize=(11, 4), linewidth = 1.0, frameon = True ,
subplotpars=fig.SubplotParams(left=0.05, bottom=0.15, right=0.97, top=0.9))
ax=fig1.add_subplot(111)
ax.plot(rate, 'b-')
ax.set_xticks((range(0, len(time), (len(time)/15))))
x_labels = ax.set_xticklabels((self.spec_arr(time)))
plt.axis([0, len(time), min(rate), max(rate) + 5]) # задание [xmin, xmax, ymin, ymax]
plt.xlabel(u'Время, с') # обозначение оси абсцисс
plt.ylabel(u'Скорость, Мбит/с') # обозначение оси ординат
plt.savefig(name_file, dpi=200)

def main(self, name_file):
"""docstring for main
центр программы - вызов методов
"""
data=self.parser_tsuc(name_file)
self.my_plot(data['rate'], data['time'], name_file.split('/')[-1].split('.')[0])


if __name__ == '__main__':
name_file=sys.argv[1]
cls=Create_of_Graf()
cls.main(name_file)
Спасибо за внимание))
doza_and
Вам надо было привести файл - чтобы было понятнее в чем проблема.

Я делаю немного не так
# -*- coding: cp1251 -*- # у меня винды

#решение проблемы с выводом на график русских шрифтов прописано в конфиграционный файл matplotlib
from pylab import * # все можно загрузить отсюда если вам не жалко текущее пространство имен
import datetime # рекомендованый способ представления даты и времени в питоне
import numpy as np # родной для matplotlib формат данных

# это моя запчасть которая читает текстовые файлы и делает списки плавающих целых значений и временных меток
# datetime крайне уродлив с точки зрения чтения из файлов и преобразования из строк может я чего не знаю.
# у matplotlib есть свой формат представления времени
from evaldict import Import
data=np.array(Import("out.dat"))

fig=figure()
plot(data[:,0],data[:,1])
xlabel(u'Время, с') # обозначение оси абсцисс
ylabel(u'Скорость, Мбит/с') # обозначение оси ординат
fig.autofmt_xdate() # эта строка разворачивает записи времени и они перестают сливаться
# show() обычно не использую поскольку по умолчанию у меня инетрактивный режим
файл имеет вид:
2010.11.22 20:26:06 0.0
2010.11.22 20:40:30 0.00999983333417
doza_and
off topic:
Есть еще предложения по совершенствованию вашего кода:
коныертируем -> конвертируем
chenge_time->change_time :)
Я в качестве GUI использую wxPython Если вам потребуется не просто сохранять картинки а делать приложения
с использованием wx то можно воспользоваться wxmpl-1.3.1
bezrukov Ilya
Ок, привожу файл - http://ifolder.ru/20412598

fig.autofmt_xdate() - если не менять код, дает немного не тот результат, что нужен.
Вероятно это из за того, что я строю график только по одной переменной ax.plot(rate).

покурю numpy.array как время появится.

Спасибо за комментарии, исправлю)

PS: графики мог строить по другому файлу.
пример графика с fig.autofmt_xdate()


и мой вариант подписи оси абсцисс
doza_and
Всегда рад подсказать если что пишите.
Но на мой вкус у вас получился достаточно нормальный график. Я так понял, что когда у вас много точек - то подписи сливаются? У меня такое было когда откладываются реальные время и дата их поворачивание и увеличение дистанции приводит к разрежению текста и на практике накладывание никогда не происходит. Если вы недовольны алгоритмом размещения тиков
то наверное надо установить максимальное количество тиков
ax.xaxis.set_major_locator(MaxNLocator(4))
напишите если получится - сам не пробовал.
cormorant
Никак не разберусь, как сделать свой формат подписей при масштабировании. Нашёл в доках вот что:
formatter = AutoDateFormatter()
formatter.scaled = {
365.0 : '%Y',
30. : '%b %Y',
1.0 : '%d.%m.%Y',
1./24. : '%H:%M:%S',
}
Но: AutoDateFormatter() takes at least 2 arguments (1 given)
Знает кто, как делается такое масштабирование?
doza_and
Посмотрите в документации работающий пример http://matplotlib.sourceforge.net/examples/pylab_examples/date_demo_rrule.html
я думаю вам поможет.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB