Dash ve Plotly ile Raporlama Ekranları Hazırlama

1. DASH Nedir?

Dash, web uygulamaları oluşturmak için geliştirilen bir Python frameworküdür. Ancak veri görselleştirme uygulamalarına daha uygundur. Dash framework, Flask, Plotly.js, ve React.js kütüphaneleri üzerine kurulu olarak geliştirilmiştir. Dash ile interaktif tablolar, grafikler ve veri görselleştirmeleri javascript bilmeden kolaylıkla geliştirilebilinir.

Python ile Veri analizi, veri keşfi, görselleştirme, modelleme, cihaz kontrolü ve raporlama yapan kişiler dash ile kolaylıkla analitik web uygulamaları geliştirebilir.

Ayrıca dash te CSS ve Html‘ in gücünden de yaralanılarak grafik ve tablolarınızı çarpıcı hale getirebilirsiniz.

2. Kurulumlar

Dash’ i bilgisayarımıza yüklemeden önce bilgisayarımızda python3 ‘ ün kurulu olması gerekiyor. Bunun için bilgisayarımıza https://www.anaconda.com/ web sitesinden Anaconda kurabiliriz. Anaconda’ yı kurduktan sonra bilgisayarımızda Dash uygulamaları için virtual(sanal) ortam oluşturup bunun içine aşağıdaki paketleri yükleyeceğiz.

conda create --name dash # anacondada virtual ortam oluşturmak
conda activate dash veya source active dash #windows veya linuxte virtual ortamı aktive etmek

Dash’le ilgili aşağıdaki komutları kullanabilirsiniz. Yada sadece pip install dash derseniz aşağıdaki paketlerin hepsini yüklemiş olursunuz.

pip install Flask
pip install dash
pip install plotly
pip install dash_html_components # dash html components
pip install dash_core_components # dash core components 
pip install dash-table # data table components

pip freeze komutu yazarak sanal ortama yüklenmiş python paketlerini görebiliriz.

3. DASH’ e Giriş

Dash’ te dash html komponentler ve dash core komponentler interaktif tablo ve grafikler oluşturmak için kullanılır. Aşağıda olan kodda dash ile oluşturulan komponentin aslında html olarak neyi ifade ettiğini anlayabilirsiniz.

import dash_html_components as html
# Dash html code in python
html.Div([
    html.H1('İlk Uygulama'),
    html.Div([
        html.P("Dash, Python class' larını HTML elementlerine dönüştürür."),
        html.P("Bu dönüşümde Javascript frontendde kullanılır.")
    ])
])
 # Yukarıdaki python kodun web tarayıcıda gösterilecek HTML hali
  <div>
    <h1>First Dash App</h1>
    <div>
        <p>Dash converts Python classes into HTML</p>
        <p>This conversion happens behind the scenes by Dash's JavaScript front-end</p>
    </div>
</div>

Dash uygulamaları temelde 2 bölümden oluşuyor. Layout ve Callbacks. Layout ile Dash uygulamasının nasıl görüneceği, Callbacks’ler ile de uygulamanın nasıl interaktif olarak çalışacağını tanımlarız.

4. Layout ve İlk Uygulama

Dash’te uygulamanın görsel komponentlerini oluşturmak için Python classları tanımlanmıştır. Bu komponenler, dash_core_components ve dash_html_components paketlerinde tanımlanmıştır ve bunları projenize dahil ederek kullanabiliriz.

Dash Core Componentler, interaktif dashboard’ lar hazırlamak için çeşitli componentlerden oluşmuştur. Kısaca bunlar

  1. Graphs: Grafikler oluşturmak için
  2. Tabs: Tablar(sekmeler) oluşturmak için
  3. Dropdown: Açılır liste oluşturmak için
  4. Sliders: Slider oluşturmak için
  5. DatePickers: Tarih veya tarih aralığı seçmek için
  6. Table: Tabloları göstermek için
  7. Markdown: Markdown olarak kullanılır.
  8. Checklist: Checklist seçenekleri için
  9. RadioItems: Radio butonları için
  10. Location: Browserda location bar sunmak için
  11. Store: Borwserda veri saklamak için olan komponentlerden oluşmaktadır.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import dash_table

external_stylesheets = [''] #harici css dosyya yolu tanımlanabilir.

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(children=[
    html.H1(children='Merhaba Dash'),

    html.Div(children='''
        DASH: İlk Dash uygulaması.
    '''),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'Ankara'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'İstanbul'},
            ],
            'layout': {
                'title': 'Dash Veri Görselleştirme'
            }
        }
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

İlk önce “app = dash.Dash(__name__)” ile DASH objesi oluşturduk. Daha sonra uygulamada app.layout ile layoutun nasıl olacağını tanımladık.

Layoutta dcc.Graph() ile uygulamamızda grafiği tanımladık. Grafiğin içine data ve grafiğin türü ile ilgili bilgileri girdik.

En sonda app.run_server(debug=True) ile uygulamamızı başlatıyoruz. Uygulamayı çalıştırıdığımızda web tarayıcıda aşağıdaki çıktıyı alırız.

5. DASH Callbacks

Dash uygulamalında Grafiklerimizi interaktif yapmak için yazacağımız fonksiyonun başında @app.callback() dekoratörünü kullanırız.

Aşağıda en basit callback uygulamasını inceleyelim. İlk önce layoutumuzda input alacağımız dash core elementini tanımlıyoruz. Bu htmlde form elementinin karşılığıdır. Bu input elementinin değerine callback dekoratöründe elementin id=’my-id’ değeri ile ulaşılır ve bunu fonksiyonda kullanırız. Daha sonra layoutta bu value nerede kullanılacak ve nerede output olarak render edeceksek dekoratörde layouttaki elemente id=’my-div’ ile ulaşırız ve fonksiyonun özelliğine göre ya bir grafik yada bir çıktı elementi döndürebiliriz.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.layout = html.Div([
    dcc.Input(id='my-id', value='initial value', type='text'),
    html.Div(id='my-div')
])

@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='my-id', component_property='value')]
)
def update_output_div(input_value):
    return 'Girdiğiniz değer: "{}"'.format(input_value)

if __name__ == '__main__':
    app.run_server(debug=True)

update_output_div() fonksiyonun üzerine yazdığımız app.callback() dekoratörü ile layoutmuzu interaktif hale getirdik. Çıktı olarak ta 5 girdiğimiz değeri çıktı olarakta 5 gördük.

Daha gelişmiş bir callback uygulamasına bakalım.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    dcc.Graph(id='graph-with-slider'),
    dcc.Slider(
        id='year-slider',
        min=df['year'].min(),
        max=df['year'].max(),
        value=df['year'].min(),
        marks={str(year): str(year) for year in df['year'].unique()},
        step=None
    )
])

@app.callback(
    Output('graph-with-slider', 'figure'),
    [Input('year-slider', 'value')])
def update_figure(selected_year):
    filtered_df = df[df.year == selected_year]
    traces = []
    for i in filtered_df.continent.unique():
        df_by_continent = filtered_df[filtered_df['continent'] == i]
        traces.append(dict(
            x=df_by_continent['gdpPercap'],
            y=df_by_continent['lifeExp'],
            text=df_by_continent['country'],
            mode='markers',
            opacity=0.7,
            marker={
                'size': 15,
                'line': {'width': 0.5, 'color': 'white'}
            },
            name=i
        ))

    return {
        'data': traces,
        'layout': dict(
            xaxis={'type': 'log', 'title': 'GDP Per Capita',
                   'range':[2.3, 4.8]},
            yaxis={'title': 'Life Expectancy', 'range': [20, 90]},
            margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
            legend={'x': 0, 'y': 1},
            hovermode='closest',
            transition = {'duration': 500},
        )
    }


if __name__ == '__main__':
    app.run_server(debug=True)

Grafiğimize bir slider ekleyerek interaktif hale getirdik. Layoutta dcc.Graph(id=’graph-with-slider’) ile tanımlayarak grafiğin render edileceği yeri belirleriz. Dikkat edilirse Input köşeli parantez içinde tanımlanıyor.

Aşağıda yazdığımız uygulamanın çıktısı.

6. DASH DATATABLE

Dash datatable, tablolarda veriyi bir arada görme , sıralama ve interaktiflik sağlama için oluşturulan komponenttir. Aşağıda Dash ile oluşturulan en basit dash datatable.

import dash
import dash_table
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')

app = dash.Dash(__name__)

app.layout = dash_table.DataTable(
    id='table',
    columns=[{"name": i, "id": i} for i in df.columns],
    data=df.to_dict('records'),
)

if __name__ == '__main__':
    app.run_server(debug=True)

Çıktı olarak aşağıdaki tabloyu görebiliriz.

Bu tabloya DASH’in dokumantasyonuna bakarak bir sürü özellik katabiliriz.

KAYNAKLAR

  1. https://medium.com/plotly/introducing-dash-5ecf7191b503
  2. https://medium.com/analytics-vidhya/building-a-dashboard-app-using-plotlys-dash-a-complete-guide-from-beginner-to-pro-61e890bdc423
  3. https://dash.plotly.com/
  4. https://hackersandslackers.com/plotly-dash-with-flask/
  5. https://medium.com/swlh/dashboards-in-python-for-beginners-and-everyone-else-using-dash-f0a045a86644
  6. https://levelup.gitconnected.com/dashboards-in-python-for-beginners-using-dash-live-updates-and-streaming-data-into-a-dashboard-37660c1ba661
  7. https://towardsdatascience.com/how-to-build-a-complex-reporting-dashboard-using-dash-and-plotl-4f4257c18a7f