pandas e matplotlib em PyQt5 - Python - Portugal-a-Programar
By j6n1nhas,
May 4, 2020 in Python
j6n1nhas
Olá caros companheiros;
É a minha primeira publicação. No tempo da faculdade fiquei vidrado em C, mas não consegui continuar e acabei por não entrar no mercado de trabalho. Largos anos depois, há 1 ano sofri um acidente de trabalho que me escavacou a mão toda e desde então que tenho vindo a dedicar-me a Python.
Depois de passar o básico da linguagem, tenho vindo a explorar as bibliotecas e depois de passar por django, agora é a vez de PyQt5.
É extremamente complexo e há muitos conceitos que eu não conheço e antes de perceber como funcionam, preciso de saber o que são, por isso, está a levar algum tempo. A documentação é extremamente extensa, mas seca e técnica ao mesmo tempo. Por exemplo, estou a criar uma aplicação para chafurdar um pouco nos números nacionais do covid. Saquei os dados do SNS através de web scraping com requests e bs4, depois espetei tudo dentro de um csv e agora estou a trabalha-lo com o pandas. Na minha app, o simples facto de querer apresentar uma tabela com os dados, foi um desafio enorme para conseguir compreender o paradigma de model/view. Agora o desafio atual é conseguir apresentar gráficos na minha app.
Encontrei um snippet com uma solução que na verdade funciona, mas acho-a extremamente complexa e desconfio que haverá forma mais simples de o fazer. Tenho tido alguma dificuldade em encontrar documentação mais prática e terra a terra do que aquela que se encontra na página do pyqt5. Têm alguns links porreiros (pá) com informação sobre isso que me possam aconselhar?
Encontrei um guia porreiro (pá) que me está a conseguir explicar alguns conceitos básicos e essenciais do lado de matplotlib, como Figure, Axes, Axis e por aí...
Já agora, deixo-vos aí a solução que encontrei para renderizar um plot na minha app:
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as fg
from PyQt5.QtWidgets import (QMainWindow, QAction, QApplication, QLabel, QTableView, QHBoxLayout, QMenu, QTabWidget,
QFrame, QGroupBox, QCheckBox, QGridLayout)
from PyQt5.QtCore import QAbstractTableModel, QModelIndex, QVariant, Qt
self.ficheiro = 'covid.csv'
self.setWindowTitle("Dados COVID Portugal")
self.setGeometry(10, 10, 1000, 600)
self.criar_menus()
self.setCentralWidget(self.grupo)
self.grafico = MyCanvas()
self.dados = pd.read_csv(self.ficheiro)
grafico = self.dados.plot(x='Data',
y=['Casos confirmados', 'Mortos', 'Em vigilância', 'Casos recuperados',
'A aguardar resultado',
'Casos suspeitos', 'Casos não confirmados'],
kind='line', figsize=(20, 20), title='Números COVID em Portugal', grid=True)
self.dados.plot(ax=self.grafico.axes)
def __init__(self, width=5, height=4, dpi=100):
super(MyCanvas, self).__init__(fig)
O código não está pronto a correr, porque entretanto pus-me a chafurdar nele à procura de novas soluções e neste momento está a modos que "partido". Meti só os imports que estou a fazer, embora no excerto não esteja a usá-los todos, e a parte que interessa para o gráfico. Ora, a ideia que encontrei foi criar uma classe que herda de FigureCanvasQTAgg para depois instanciá-la na aplicação e usá-la para renderizar o gráfico. Não liguem à indentação; partam do princípio que está correta porque no editor está tudo bem e depois quando passo para aqui, fica assim como se pode ver.
Se alguém tiver alguma ideia mais simples de fazer isto, sem ter de criar uma classe, por exemplo, agradecia a dica. Entretanto vou continuar a batalhar para conseguir apresentar uma versão compacta que corra, para ajudar também que me possa vir a ajudar.
Abraços, cumprimentos e saudações!
Edited May 4, 2020 by j6n1nhas
Normalmente quando uso QT recorro ao wxFormBuilder, para desenhar os ecrãs, e à herança para por forma a poder manipular o output do wxFormBuilder sem estragar tudo cada vez que faço uma alteração na interface.
O padrão de model-view (MV) é uma derivação do model-view-controller (MVC) onde o controlador e a view ficam fundidos. Na verdade é bastante simples de compreender.
Tudo o que seja dados, as suas regras e a sua manipulação é model, e é ai que tal deve ser tratado.
Tudo o que seja visualização, design, look, objetos, interações com o utilizador, etc. é view, é aí que tal deve ser tratado.
Tudo o resto, ou seja controlar os acessos aos dados, controlar a interface, validar segurança, etc. é controller.
No teu caso, a view e o controller estão juntos porque é no mesmo local que manipulas a interface (por exemplo, escondes opções de menu ou desabilitas botões), recebes o input do utilizador (por exemplo um click num botão) e fazes a comunicação com o model (recebendo e enviando dados).
A ideia de herdares do FigureCanvasQTAgg para receber informação do Pandas e desenhar parece-me à partida, boa. Seria, pelo menos, uma hipótese que eu consideraria.
PS: não sei se isso é só um "exercício de carolice" ou se pretendes fazer análise mais profunda. Se queres fazer análises mais profundas, aconselho-te a usares o R.