Úvod¶
Kým v predchádzajúcich prednáškach sme sa venovali statickým vizualizáciám (najmä pomocou knižníc Matplotlib a Seaborn), v tejto časti sa zameriame na vytváranie interaktívnych grafov. Interaktívne grafy môžu používateľovi (alebo vývojárovi) priniesť:
- jednoduché zoomovanie a presúvanie v grafe,
- tooltipy – zobrazovanie detailov pri prechode myšou,
- filtrovanie a prepínanie rôznych vrstiev priamo v grafickom výstupe,
- prípadne kompletnú malú "webovú aplikáciu" (napr. cez Bokeh server alebo Plotly Dash).
V rámci tejto prednášky sa sústredíme na:
- Plotly (základné použitie a vytváranie interaktívnych grafov v
plotly.express
aplotly.graph_objects
), - Bokeh (základná predstava o tom, ako kresliť interaktívne grafy a využívať tzv. tools),
- ipywidgets (ako rýchlo vnoriť interaktivitu do Jupyter Notebooku, napr. pre Matplotlib či Plotly grafy).
Cieľom je, aby ste získali praktický prehľad o tom, kedy a ako využiť tieto nástroje pri spracovaní a prezentácii dát.
Plotly¶
Plotly je knižnica napísaná v Pythone, ktorá umožňuje vytvárať interaktívne vizualizácie priamo v Jupyter Notebooku, ale aj následne exportovať do HTML. Poskytuje dva hlavné prístupy:
- plotly.express (ďalej označované ako
px
): jednoduchšie API, veľmi rýchla tvorba grafov (podobne akoseaborn
), - plotly.graph_objects (označované ako
go
): pokročilejšie a flexibilnejšie API s detailnou kontrolou.
Inštalácia a import¶
Plotly nainštalujete napríklad príkazom:
pip install plotly
V Jupyter Notebooku stačí potom importovať požadované moduly:
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.express as px
import pandas as pd
# Vytvoríme jednoduchý DataFrame
df = pd.DataFrame({
"Fruit": ["Apples", "Oranges", "Bananas", "Grapes"],
"Amount": [10, 15, 7, 12]
})
# Vytvorenie a zobrazenie grafu
fig = px.bar(df, x="Fruit", y="Amount", title="Jednoduchý Bar Chart")
fig.show()
Základné interaktívne grafy (plotly.express)¶
Knižnica plotly.express (skrátene px
) ponúka jednoduché funkcie ako px.scatter()
, px.line()
, px.bar()
, atď., ktoré fungujú podobne ako sns.scatterplot()
a spol. Základné parametre zvyknú byť:
data_frame
(Pandas DataFrame),x
,y
,- prípadne
color
,size
,symbol
, … (obdobahue
,size
,style
z iných knižníc), title
,labels
, …
Na ukážku použijeme vstavané dáta z knižnice Plotly. Pár zaujímavých datasetov je dostupných aj cez px.data
(napr. px.data.gapminder()
).
Dataset gapminder, ktorý nájdete napríklad prostredníctvom px.data.gapminder()
, je veľmi populárny zdroj dát používaný na demonštráciu dynamiky socio-ekonomického vývoja krajín po celom svete. Tento dataset pochádza zo zdrojov organizácie Gapminder Foundation a obsahuje údaje, ktoré umožňujú sledovať vývoj rôznych krajín počas niekoľkých desaťročí.
Hlavné Premenné v Datasete¶
- country: Názov krajiny, pre ktorú sú údaje zaznamenané.
- continent: Kontinent, na ktorom sa krajina nachádza. Táto kategorizácia umožňuje regionálne porovnania.
- year: Rok, v ktorom boli údaje zozbierané. Dataset pokrýva viacero rokov (napríklad od 1952 do 2007), čo umožňuje sledovať časové trendy.
- lifeExp: Priemerná dĺžka života (life expectancy) obyvateľov danej krajiny. Tento ukazovateľ slúži ako jeden zo sociálnych indikátorov kvality života.
- pop: Počet obyvateľov krajiny. Ukazuje veľkosť populácie a umožňuje analýzu demografických trendov.
- gdpPercap: Hrubý domáci produkt na hlavu (GDP per capita). Poskytuje prehľad o hospodárskej výkonnosti krajiny a umožňuje porovnanie medzi rôznymi ekonomikami.
# Vstavaný dataset Gapminder (demografické údaje krajín)
gapminder = px.data.gapminder()
gapminder.head()
Scatter plot¶
Najjednoduchšou ukážkou bude scatter plot s farebným rozlíšením naprílklad v našom prípade kontinentu.
Parametre:
- data_frame: Pandas DataFrame obsahujúci zdrojové dáta.
- x: Stĺpec s hodnotami pre os X.
- y: Stĺpec s hodnotami pre os Y.
- color: Rozlíšenie bodov farbami podľa kategorizácie (napr. kontinent).
- size: Veľkosť bodov určená hodnotami z daného stĺpca (napr. populácia).
- hover_name: Informácie (napr. názov krajiny) zobrazené pri prejdení myšou nad bodom.
- log_x: Nastavenie logaritmickej škály pre os X pre prehľadnejšie zobrazenie dát s veľkým rozsahom.
- title: Názov grafu.
help(px.scatter)
fig = px.scatter(
gapminder.query("year == 2007"),
x="gdpPercap",
y="lifeExp",
color="continent",
hover_name="country",
size="pop",
log_x=True, # X-ová os logaritmická (prehľadnejšie pri veľkých rozdieloch)
title="GDP vs Life Expectancy (2007)"
)
fig.show()
Pri prechode myšou vidíme detailné informácie (krajina, hodnota, kontinent, atď.). Vpravo hore je legend s možnosťou zapínať/vypínať kontinent. V ľavom hornom rohu nájdeme ikony na sťahovanie grafu do PNG, reset zoomu, atď.
Line plot¶
Teraz môžeme ukázať príklad zobrazenia trendu (vývoja) v čase. Napr. pre vybranú krajinu zobrazíme, ako sa mení lifeExp a gdpPercap.
fig_line = px.line(
gapminder.query("country == 'Slovak Republic'"),
x="year",
y="lifeExp",
title="Vývoj strednej dĺžky života v SR"
)
fig_line.show()
Podobne dokážeme zobraziť stĺpcový graf (px.bar()
), histogram (px.histogram()
), boxplot (px.box()
), atď.
Pokročilejšie možnosti (plotly.graph_objects)¶
Modul plotly.graph_objects (go
) poskytuje detailný prístup k tzv. Figure a Trace objektom. Môžeme ho použiť napríklad, ak potrebujeme:
- kombinovať viac rôznych typov grafov do jedného,
- presnejšie nastavovať layout, legendu, osi,
- vytvárať subploty (cez
make_subplots
).
Základná štruktúra je:
fig = go.Figure()
fig.add_trace(
go.Scatter(
x=[...],
y=[...],
mode='lines+markers',
name='...'
)
)
fig.update_layout(...)
fig.show()
Ukážme si aspoň krátky príklad.
Export grafov¶
Plotly graf môžeme jednoducho uložiť buď do obrázka (statický PNG), alebo do samostatného HTML súboru (zachováva interaktivitu). Jednoduchý spôsob:
# Uloženie do HTML
fig.write_html('moj_graf.html')
# Uloženie do PNG (vyžaduje kaleido alebo orca)
fig.write_image('moj_graf.png')
from plotly.subplots import make_subplots
# Vyfiltrujeme dáta pre Japonsko (prípadne môžete použiť inú krajinu)
data_japan = gapminder[gapminder['country'] == 'Japan']
# Vytvoríme figúru s dvoma y-osiami
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Pridáme trendovú čiaru pre priemernú dĺžku života (lifeExp)
fig.add_trace(
go.Scatter(
x=data_japan['year'],
y=data_japan['lifeExp'],
mode='lines',
name='Life Expectancy',
line=dict(color='blue', width=3)
),
secondary_y=False
)
# Pridáme body (markers) pre populáciu (pop)
fig.add_trace(
go.Scatter(
x=data_japan['year'],
y=data_japan['pop'],
mode='markers',
name='Population',
marker=dict(size=10, color='red', opacity=0.8)
),
secondary_y=True
)
# Aktualizácia layoutu grafu
fig.update_layout(
title='Trend Life Expectancy a Population pre Japonsko',
xaxis_title='Year',
template='plotly_white'
)
fig.update_yaxes(title_text="Life Expectancy", secondary_y=False)
fig.update_yaxes(title_text="Population", secondary_y=True)
fig.show()
# Uloženie do HTML
fig.write_html('moj_graf.html')
# Uloženie do PNG (vyžaduje kaleido alebo orca)
fig.write_image('moj_graf.png')
!pip install bokeh
!pip install bokeh_sampledata
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import ColumnDataSource
# Aby sa grafy zobrazovali v notebooku
output_notebook()
Základná práca s figure
¶
Základom Bokeh grafu je objekt figure
, do ktorého pridávame tzv. glyphs (prvky ako circle
, line
, bar
a pod.).
Príklad:
- Vytvoríme figure s názvom a popiskami osí,
p.circle(...)
pridá body do grafu.
Interaktívne nástroje¶
Bokeh ponúka tzv. Tools. Napríklad, defaultne môžeme mať:
pan
(posúvanie),wheel_zoom
(zoomovanie kolieskom myši),box_zoom
(zoomovanie označením obdĺžnika),hover
(zobrazenie detailov pri prechode),- a ďalšie.
Môžeme ich definovať pri vytváraní figure:
p = figure(tools='pan,wheel_zoom,hover')
Pre hover tool môžeme detailnejšie nastaviť, čo sa zobrazuje (napr. v rámci tooltips
parametra).
# Vyberieme dáta za rok 2007
data2007 = gapminder[gapminder['year'] == 2007]
# Vytvorenie ColumnDataSource pre Bokeh
source = ColumnDataSource(data2007)
# Vytvorenie grafu (figure) s použitím width a height
p = figure(
title="Gapminder 2007 - Bokeh Demo",
x_axis_label="GDP per Capita",
y_axis_label="Life Expectancy",
width=600,
height=400,
x_axis_type="log" # Logaritmická os pre GDP
)
# Vykreslenie bodov pomocou metódy circle
p.circle(
x="gdpPercap",
y="lifeExp",
size=7,
color="navy",
alpha=0.5,
source=source
)
# Zobrazenie grafu
show(p)
Po zobrazení v Jupyter Notebooku vidíme panel s nástrojmi (napr. zoom, pan, reset, save) a pri hoverovaní sa zobrazujú základné informácie.
from bokeh.models import HoverTool
# Načítanie dát Gapminder a filtrovanie pre rok 2007
gapminder = px.data.gapminder()
data2007 = gapminder[gapminder['year'] == 2007]
source = ColumnDataSource(data=data2007)
p = figure(
title="Gapminder 2007 - Bokeh Demo",
x_axis_label="GDP per Capita",
y_axis_label="Life Expectancy",
width=600,
height=400,
x_axis_type="log"
)
p.circle(
x="gdpPercap",
y="lifeExp",
size=7,
color="navy",
alpha=0.5,
source=source
)
# Vytvorenie a pridanie HoverTool
hover = HoverTool(tooltips=[
("Country", "@country"),
("GDP per Capita", "@gdpPercap"),
("Life Expectancy", "@lifeExp"),
("Population", "@pop")
])
p.add_tools(hover)
show(p)
Bokeh server a rozšírenia¶
Bokeh je možné použiť aj na tvorbu komplexných webových aplikácií, kde je tzv. Bokeh server, ktorý umožňuje:
- dynamické aktualizácie grafov pri zmene datasetu,
- prepojenie s widgetmi (slidermi, dropdownmi),
- streaming dát v reálnom čase.
Keďže ide o rozsiahlejšiu tému, v základnom prehľade spomenieme len to, že okrem zobrazenia v notebooku (output_notebook
) môžeme tiež použiť output_file('nazov.html')
a show(p)
, čím vygenerujeme interaktívnu HTML stránku.
ipywidgets + Matplotlib/Plotly¶
Inštalácia a import¶
Knižnica ipywidgets dokáže vytvoriť widgety v Jupyter Notebooku (slidery, políčka, drop-down menu), ktoré vedia priamo ovplyvniť vykreslenie grafu. Nainštalujeme ju príkazom:
pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension
interact
a interactive
¶
Základné funkcie sú interact
a interactive
, ktoré z funkcie generujú interaktívny widget. Napr.:
def plot_matplotlib(country='Japan'):
# Vyfiltrujeme dáta pre vybranú krajinu
data = gapminder[gapminder['country'] == country]
plt.figure(figsize=(8, 4))
plt.plot(data['year'], data['lifeExp'], marker='o', linestyle='-', color='blue')
plt.title(f'Trend dĺžky života pre {country}')
plt.xlabel('Rok')
plt.ylabel('Life Expectancy')
plt.grid(True)
plt.show()
# Vytvorenie widgetu; parameter `country` sa bude prepájať so zoznamom unikátnych krajín
interact(plot_matplotlib, country=sorted(gapminder['country'].unique()))
Po spustení sa objaví slider pre parameter freq
. Pri zmene slidera sa automaticky prekreslí graf. Podobný prístup funguje aj s Plotly figúrami.
Ipywidgets teda umožňuje rýchlu interaktivitu priamo v notebooku bez potreby iných serverov. Hodí sa najmä na demonštrácie alebo exploratívnu analýzu.
Zhrnutie¶
V tejto prednáške sme sa pozreli na rôzne spôsoby, ako v Pythone tvoriť interaktívne grafy:
- Plotly:
plotly.express
na rýchle a jednoduché grafy,plotly.graph_objects
na detailné nastavovanie.
- Bokeh:
- tvorba figure, pridávanie glyphs,
- panel nástrojov (hover, pan, zoom, atď.),
- možnosť využiť Bokeh server.
- ipywidgets:
- rýchle pridanie sliderov, buttonov, meniacich parametre grafu,
- integrácia do Jupyter Notebooku.
Kedy ktorý nástroj?¶
- Plotly je skvelý na väčšinu bežných interaktívnych vizualizácií. Dá sa ľahko exportovať do HTML.
- Bokeh ponúka priame napojenie na Bokeh server, čím je možné tvoriť bohatšie aplikácie.
- ipywidgets je rýchla cesta, ako si v notebooku vytvoriť menšie "interaktívne hračky".
Referencie a doplnkové zdroje¶
Touto prednáškou sme si rozšírili obzory v oblasti interaktívnych vizualizácií. V praxi vám práve tento typ grafov môže veľmi pomôcť pri prezentácii výsledkov analýzy kolegom, nadriadeným alebo klientom, ktorí ocenia možnosť "pohrať sa" so zobrazenými dátami.