Dasboard Covid-19 em Python
Publicado por Pedro Fernandes (última atualização em 30/04/2023)
[ Hits: 2.224 ]
Homepage: https://github.com/PedroF37
Projeto Python de Dashboard do Covid-19 para praticar o pandas e o matplotlib
Projeto usa a API https://rapidapi.com/api-sports/api/covid-193/.
Precisa fazer o registro gratuito e pegar a chave. Coloca chave em arquivo views.py.
Fonte usada: Roboto
Original:
https://github.com/PedroF37/Dashboard-Covid
Arquivo: frontend.py
# -------------------------------------------------------------------------- #
# IMPORTAÇÕES
# tkinter
from tkinter import Tk, Frame, Label
from tkinter.ttk import Style, Treeview, Separator, Scrollbar
# matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
# views
from views import *
# -------------------------------------------------------------------------- #
# CONSTANTES
# Cores
COLOR1 = '#feffff' # Branco
COLOR2 = '#3a3a4d' # Fundo
COLOR3 = '#403d3d' # Letra
COLOR4 = '#6f9fbd' # Azul
COLORS_BAR = [
'#665191', '#a05195', '#d45087',
'#f95d6a', '#ff7c43', '#ffa600'
]
COLORS_PIE = [
'#5588bb', '#66bbbb', '#aa6644',
'#99bb55', '#ee9944', '#444466'
]
# -------------------------------------------------------------------------- #
# JANELA
window = Tk()
window.title('')
window.resizable(0, 0)
window.geometry('1100x550')
style = Style(window)
style.theme_use('clam')
# -------------------------------------------------------------------------- #
# FRAMES
title_frame = Frame(
window, width=1100, height=50,
pady=0, padx=0, bg=COLOR1
)
title_frame.grid(row=0, column=0)
Separator(
window, orient='horizontal'
).grid(
row=1, columnspan=1, ipadx=550
)
parent_frame = Frame(
window, width=1100, height=500,
pady=10, padx=10, bg=COLOR2
)
parent_frame.grid(row=2, column=0, sticky='nw')
# -------------------------------------------------------------------------- #
# CONFIGURANDO TITLE_FRAME
title_label = Label(
title_frame, text='Dashboard de COVID-19',
font=('Roboto 20 bold'), anchor='nw',
bg=COLOR1, fg=COLOR3
)
title_label.place(x=5, y=20)
# -------------------------------------------------------------------------- #
# CONFIGURANDO PARENT_FRAME
# Total de Casos
total_cases_frame = Frame(
parent_frame, width=178,
height=70, bg=COLOR1
)
total_cases_frame.place(x=0, y=0)
line_label = Label(
total_cases_frame, text='', width=2,
height=10, pady=0, padx=0,
font=('Roboto 1 bold'), anchor='nw',
bg=COLOR4, fg=COLOR3
)
line_label.place(x=0, y=0)
total_cases_label = Label(
total_cases_frame, text='Total de Casos',
height=1, pady=0, padx=0,
font=('Roboto 10 bold'), anchor='center',
bg=COLOR1, fg=COLOR3
)
total_cases_label.place(x=10, y=5)
number_cases_label = Label(
total_cases_frame, text=f"{totals[1]['Casos']:,.0f}",
height=1, pady=0, padx=0,
font=('Roboto 16'), anchor='center',
bg=COLOR1, fg=COLOR3
)
number_cases_label.place(x=20, y=35)
# Total de Recuperados
total_recovered_frame = Frame(
parent_frame, width=178,
height=70, bg=COLOR1
)
total_recovered_frame.place(x=188, y=0)
line_label = Label(
total_recovered_frame, text='', width=2,
height=10, pady=0, padx=0,
font=('Roboto 1 bold'), anchor='nw',
bg=COLOR4, fg=COLOR3
)
line_label.place(x=0, y=0)
total_recovered_label = Label(
total_recovered_frame, text='Total de Recuperados',
height=1, pady=0, padx=0,
font=('Roboto 10 bold'), anchor='center',
bg=COLOR1, fg=COLOR3
)
total_recovered_label.place(x=10, y=5)
number_recovered_label = Label(
total_recovered_frame, text=f"{totals[1]['Recuperados']:,.0f}",
height=1, pady=0, padx=0,
font=('Roboto 16'), anchor='center',
bg=COLOR1, fg=COLOR3
)
number_recovered_label.place(x=20, y=35)
# Total de Mortos
total_deaths_frame = Frame(
parent_frame, width=178,
height=70, bg=COLOR1
)
total_deaths_frame.place(x=376, y=0)
line_label = Label(
total_deaths_frame, text='', width=2,
height=10, pady=0, padx=0,
font=('Roboto 1 bold'), anchor='nw',
bg=COLOR4, fg=COLOR3
)
line_label.place(x=0, y=0)
total_deaths_label = Label(
total_deaths_frame, text='Total de Mortes',
height=1, pady=0, padx=0,
font=('Roboto 10 bold'), anchor='center',
bg=COLOR1, fg=COLOR3
)
total_deaths_label.place(x=10, y=5)
number_deaths_label = Label(
total_deaths_frame, text=f"{totals[1]['Mortes']:,.0f}",
height=1, pady=0, padx=0,
font=('Roboto 16'), anchor='center',
bg=COLOR1, fg=COLOR3
)
number_deaths_label.place(x=20, y=35)
# --- GRÁFICO BARRA --- #
# Top de 5 Países mais afetados
top_five_frame = Frame(
parent_frame, width=200,
height=500, bg=COLOR1
)
top_five_frame.place(x=560, y=0)
# Valores para gráfico
countries = [item[0] for item in top_countries]
values_list = [item[1] for item in top_countries]
# Container do gráfico e os eixos
figure = plt.Figure(figsize=(8.7, 3), dpi=60)
ax = figure.add_subplot(111)
# Grafico de barra horizontal
ax.barh(countries, values_list, align='center', color=COLORS_BAR)
ax.set_alpha(0.3)
# Configura os labels individuais das barras.
c = 0
for i in ax.patches:
# get_width (esquerda/direita), get_y (cima/baixo)
ax.text(
i.get_width() + .3, i.get_y() + .50,
str(values_list[c]), fontsize=12,
verticalalignment='center', fontstyle='italic',
weight='bold', color='dimgrey'
)
c += 1
# Formata os eixos do gráfico
ax.patch.set_facecolor('#FFFFFF')
ax.spines['bottom'].set_color('#CCCCCC')
ax.spines['bottom'].set_linewidth(1)
ax.spines['right'].set_linewidth(0)
ax.spines['top'].set_linewidth(0)
ax.spines['left'].set_color('#CCCCCC')
ax.spines['left'].set_linewidth(1)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_color('#DDDDDD')
ax.tick_params(bottom=False, left=False)
ax.set_axisbelow(False)
ax.xaxis.grid(False)
graph_title_label = Label(
top_five_frame, text='Top 5 Países mais afetados',
height=1, pady=5, padx=0, anchor='nw',
font=('Roboto 10 bold'), bg=COLOR1, fg=COLOR3
)
graph_title_label.grid(
row=0, column=0, padx=20,
pady=0, sticky='nsew'
)
top_five_canvas = FigureCanvasTkAgg(figure, top_five_frame)
top_five_canvas.get_tk_widget().grid(
row=1, column=0,
sticky='nsew', columnspan=2
)
# --- TABELA --- #
country_frame = Frame(parent_frame, width=700, height=500, bg=COLOR1)
country_frame.place(x=0, y=80)
# Estiliza a tabela
table_style = Style()
table_style.element_create('Custom.Treeheading.border', 'from', 'default')
table_style.layout('Custom.Treeview.Heading', [
('Custom.Treeheading.cell', {'sticky': 'nsew'}),
('Custom.Treeheading.border', {'sticky': 'nsew', 'children': [
('Custom.Treeheading.padding', {'sticky': 'nsew', 'children': [
('Custom.Treeheading.image', {'side': 'right', 'sticky': ''}),
('Custom.Treeheading.text', {'sticky': 'we'})
]})
]}),
])
table_style.configure(
'Custom.Treeview.Heading', background='#494d4a',
foreground='white', relief='raised'
)
table_style.map(
'Custom.Treeview.Heading', relief=[
('active', 'groove'),
('pressed', 'sunken')
],
background=[('selected', '#494d4a')]
)
# Cabeçalho da tabela
table_header = [
'País', 'Confirmados',
'Recuperados', 'Mortes',
'Data'
]
tree = Treeview(
country_frame, selectmode='extended',
style='Custom.Treeview', height=18,
columns=table_header, show='headings'
)
# Barra de rolagem vertical
vsb = Scrollbar(
country_frame, orient='vertical',
command=tree.yview
)
# Barra de rolagem horizontal
hsb = Scrollbar(
country_frame, orient='horizontal',
command=tree.xview
)
tree.configure(
yscrollcommand=vsb.set,
xscrollcommand=hsb.set
)
# Posicionamento
tree.grid(row=1, column=0, sticky='nsew')
vsb.grid(row=1, column=1, sticky='ns')
hsb.grid(row=2, column=0, sticky='ew')
country_frame.grid_rowconfigure(0, weight=2)
# Posicionamento do cabeçalho e dos dados
hd = ['nw', 'ne', 'ne', 'ne', 'center', 'center', 'center']
h = [140, 100, 100, 100, 91]
n = 0
for column in table_header:
tree.heading(column, text=column, anchor='center')
tree.column(column, width=h[n], anchor=hd[n])
n += 1
# Coloca dados na tabela
[tree.insert('', 'end', values=item) for item in country_list]
# --- GRÁFICO PIE --- #
# Continentes
continent_frame = Frame(
parent_frame, width=700,
height=500, bg=COLOR1
)
continent_frame.place(x=562, y=220)
figure = plt.Figure(figsize=(8.65, 3.9), dpi=60)
ax = figure.add_subplot(111)
wedges, texts = ax.pie(
values_continent_list, wedgeprops=dict(width=0.2),
colors=COLORS_PIE, shadow=True, startangle=-90
)
bbox_props = dict(boxstyle='square, pad=0.3', fc='w', ec='k', lw=0.72)
kw = dict(
arrowprops=dict(arrowstyle='-'),
bbox=bbox_props, zorder=0, va='center'
)
# Não vou nem fingir que sei o que este código faz!!
# Tudo copy/paste!!
for i, p in enumerate(wedges):
ang = (p.theta2 - p.theta1) / 2. + p.theta1
y = np.sin(np.deg2rad(ang))
x = np.cos(np.deg2rad(ang))
horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
connectionstyle = "angle,angleA=0,angleB={}".format(ang)
kw["arrowprops"].update({"connectionstyle": connectionstyle})
ax.annotate(
names_continent_list[i], xy=(x, y),
xytext=(1.35 * np.sign(x), 1.4 * y),
horizontalalignment=horizontalalignment, **kw
)
pie_title_label = Label(
continent_frame, text='Continentes mais afetados',
height=1, pady=5, padx=0, anchor='nw',
font=('Roboto 10 bold'), bg=COLOR1, fg=COLOR3
)
pie_title_label.grid(
row=0, column=0, padx=20,
pady=0, sticky='nsew'
)
continent_canvas = FigureCanvasTkAgg(figure, continent_frame)
continent_canvas.get_tk_widget().grid(
row=1, column=0,
sticky='nsew', columnspan=2
)
# -------------------------------------------------------------------------- #
# LOOP
window.mainloop()
# -------------------------------------------------------------------------- #
####################################################################################################
Arquivo: views.py
# -------------------------------------------------------------------------- #
# IMPORTAÇÕES
import requests
import pandas as pd
import numpy as np
# -------------------------------------------------------------------------- #
# CONSULTA/RESPOSTA DA API
url = "https://covid-193.p.rapidapi.com/statistics"
# Sua chave da API aqui.
headers = {
"X-RapidAPI-Key": "",
"X-RapidAPI-Host": "covid-193.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers).json()
response_list = [
[
info['continent'], info['country'], info['cases']['total'],
info['cases']['active'], info['cases']['recovered'],
info['deaths']['total'], info['day']
] for info in response['response']
]
# -------------------------------------------------------------------------- #
# DATAFRAME
df = pd.DataFrame(
response_list, columns=[
'Continente', 'País', 'Casos',
'Recuperados', 'Casos Ativos', 'Mortes', 'Data'
]
)
# -------------------------------------------------------------------------- #
# DADOS PARA GRÁFICO PIE
# Organizando dados por Continente
total_df = df.groupby(['Continente']).sum()
# Adicionando index
total_df['Nome'] = total_df.index
# Convertendo DataFrame em dicionario
total_dict = total_df.to_dict('recorde')
# Lista que contem os dados
totals = [item for item in total_dict]
# Dados dos Continentes (para o gráfico pie)
values_continent_list = [
totals[0]['Casos'], totals[2]['Casos'],
totals[3]['Casos'], totals[4]['Casos'],
totals[5]['Casos'], totals[6]['Casos']
]
names_continent_list = [
totals[0]['Nome'], totals[2]['Nome'],
totals[3]['Nome'], totals[4]['Nome'],
totals[5]['Nome'], totals[6]['Nome']
]
# -------------------------------------------------------------------------- #
# DADOS PARA TABELA (Treeview)
# Organizando por país
country_df = df.groupby(['País', 'Data']).sum()
# Adicionando index
country_df['Nome'] = country_df.index.get_level_values('País')
country_df['Data'] = country_df.index.get_level_values('Data')
country_df = country_df[['Nome', 'Casos', 'Recuperados', 'Mortes', 'Data']]
# Por algumna razão, os continentes aparecem
# como países. Excluimos.
exclude = [
'All', 'Africa', 'Asia',
'Europe', 'Oceania', 'South-America',
'North-America'
]
country_list = [
[
item[0], f'{item[1]:,.0f}', f'{item[2]:,.0f}',
f'{item[3]:,.0f}', item[4]
] for item in country_df.values.tolist()
if item[0] not in exclude
]
# -------------------------------------------------------------------------- #
# DADOS PARA GRÁFICO DE BARRA
top_countries_df = country_df[['Nome', 'Casos']]
top_countries_df = top_countries_df.sort_values(
by=['Casos'],
ascending=False
)
top_countries = [
[
country[0], country[1]
] for country in top_countries_df.head(10).values.tolist()
if country[0] not in exclude
]
top_countries = sorted(top_countries, key=lambda x: x[1])
# -------------------------------------------------------------------------- #
Verificar se um número é primo
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Adicionar botão "mostrar área de trabalho" no Zorin OS
Como montar um servidor de backup no linux
Trazendo de volta o Serviços em Segundo Plano no Plasma6









