-
Notifications
You must be signed in to change notification settings - Fork 2
/
visualizer.py
139 lines (111 loc) · 5.39 KB
/
visualizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import streamlit as st
import polars as pl
import folium as fo
from streamlit_folium import st_folium
from typing import Dict #, List
#st.set_page_config(layout="wide")
schools_source = pl.read_excel("schools.xlsx").with_columns(pl.col("Katedry").str.split(", ").name.keep())
filter_targets = [ "Fakulta","Katedry", "Obory", "Stát"] # Mělo by reflektovat všechny potenciální filtrované sloupečky
display_targets = ["Fakulta","Katedry" , "Univerzita", "Obor", "Obory", "Stát", "URL", "ERASMUS CODE"]
#TODO: Obecně hodně těhle deklarací je sketch. Trochu se na to kouknout a optimalizovat.
schools:pl.DataFrame = schools_source.select(filter_targets) # Schools je subtabulka sloužící k filtrování a jiným sussy operacím. Asi tady deklarována zbytečně vysoko.
picks:Dict[str, pl.Series] = schools.to_dict() # Dictionary s filtrovacími klíčovými slovíčky pro každý sloupeček
for column in picks.keys():
print(column)
if column == "Katedry":
temp = picks[column].list.explode().unique()
print(f"Hello {temp.dtype}")
picks[column] = temp
picks[column] = ["---"] + picks[column].unique().sort(nulls_last=True).to_list()
def filter_schools(school_df:pl.DataFrame) -> pl.DataFrame:
"""Funkce na profiltrování škol dle více podmínek."""
filtered = school_df
filter_choice = []
for column in filtered.columns:
if column not in st.session_state: # Teoreticky by se nemělo stát (st.multiselect inicializuje ten column jako prázdný seznam, takže bude v session state)
continue
if len(st.session_state[column]) > 0:
if column == "Katedry":
print(f"{column} - {filtered.select(column).dtypes}/{st.session_state[column]}")
filter_choice.append(pl.col(column).list.eval(pl.element().is_in(st.session_state[column])).list.any())
continue
filter_choice.append(pl.col(column).is_in(st.session_state[column]))
if len(filter_choice) < 1: # Pokud nejsou žádný podmínky, dej filtru vždycky pravdivou podmínku
filter_choice = [True]
print(filter_choice)
return filtered.filter(filter_choice)
st.header("ERASMUS PřF UJEP")
st.divider()
# --- TABULKA ---
# Filtrování
filters = st.columns(len(filter_targets)) # Názvy filtrovaných sloupců
for index, column in enumerate(filter_targets):
with filters[index]:
st.session_state[column] = st.multiselect(label=column, options=picks[column]) # Samotné filtry, NOTE: This is kinda stupid?
schools = filter_schools(schools_source)
schools_sub = schools.select(display_targets)
# --- MAPA --- TODO: Mapa pod tabulkou je hodně špatnej design. Pokud ta tabulka bude moc velká, bude to chtít hodně scrollování před nalezením mapy. Posunout mapu nahoru, nebo aspoň vedle tabulky.
# Hranice mapy
max_lat, min_lat = 75, 33
max_long, min_long = 65, -31
# Inicializace mapy
europe = fo.Map(
[50.5, 14.25],
zoom_start=4, # Počáteční krok přiblížení, čím menší tím oddálenější
max_bounds=True, # Omezení tahání vedle
min_lat=min_lat,
max_lat=max_lat,
min_lon=min_long,
max_lon=max_long
)
# Barvy pro jednotlivé katedry
# category_colors = {
# "Turecká republika":"purple",
# "Švédské království":"lightblue",
# "Španělské království":"lightgreen",
# "Srbská republika":"purple",
# "Spolková republika Německo":"pink",
# "Slovinská republika":"lightgreen",
# "Slovenská republika":"pink",
# "Řecká republika":"purple",
# "Rumunsko":"purple",
# "Portugalská republika":"lightgreen",
# "Polská republika":"pink",
# "Maďarsko":"pink",
# "Lotyšská republika":"lightblue",
# "Litevská republika":"lightblue",
# "Italská republika":"lightgreen",
# "Chorvatská republika":"lightgreen",
# "Francouzská republika":"lightgreen",
# "Estonská republika":"lightblue",
# "Bulharská republika":"purple"
# }
# command k command c .... command k command u
category_colors = {"PřF": "pink"}
schools = schools.filter([pl.col("Longitude").is_not_null(), pl.col("Latitude").is_not_null()])
# Vytvoření Markerů na mapě
# Extrahování koordinací z dataframeu #TODO: Tohle je extrémně špatný přístup. Holy fuck.
#coords = zip(*(schools.get_column(col_name).to_list() for col_name in display_targets))
coords = zip(
schools.to_series(schools.get_column_index("Fakulta")).to_list(),
schools.to_series(schools.get_column_index("Univerzita")).to_list(),
schools.to_series(schools.get_column_index("Latitude")).to_list(),
schools.to_series(schools.get_column_index("Longitude")).to_list(),
schools.to_series(schools.get_column_index("Stát")).to_list(),
schools.to_series(schools.get_column_index("URL")).to_list()
)
# Iterace a zapsání do mapy
for coord in coords:
fakulta = coord[0]
color = category_colors.get(fakulta, "pink")
# Vytvoření popisu s názvem univerzity a URL
popup_content = f"<strong>{coord[1]}</strong><br><a href='{coord[5]}' target='_blank'>{coord[5]}</a>"
fo.Marker(
location=[coord[2], coord[3]],
popup=fo.Popup(popup_content),
icon=fo.Icon(color=color, icon="graduation-cap", prefix="fa")
).add_to(europe)
# Spuštění
st_folium(europe, use_container_width=True)
#st.session_state
st.dataframe(schools_sub, use_container_width=True, column_config={"URL":st.column_config.LinkColumn()})