[PYTHON] Create a web app that can be easily visualized with Plotly Dash

What is Plotly Dash?

Plotly Dash (The official name seems to be Dash, but since there are various other apps named Dash, I will use this notation) is a frame of a Python web application. It is a work. There are many Python web frameworks such as Flask and Bottle, but Plotly Dash can incorporate visualized data using Plotly.

Installation

Install with pip. I have not confirmed whether it can be installed with conda.

pip install dash==0.17.7  # The core dash backend
pip install dash-renderer==0.7.4  # The dash front-end
pip install dash-html-components==0.7.0  # HTML components
pip install dash-core-components==0.11.0  # Supercharged components
pip install plotly==2.0.12  # Plotly graphing library used in examples

I will try to write for the time being

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np

x = np.linspace(-np.pi, np.pi, 10)
y = np.sin(x)
app = dash.Dash()

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

    html.Div(children='''
div text
    '''),

    dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': x, 'y': np.sin(x), 'type': 'line', 'name': 'line'},
                {'x': x, 'y': np.cos(x), 'type': 'bar', 'name': 'bar'},
            ],
            'layout': {
                'title': 'Graph title'
            }
        }
    )
])

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

Screenshot at 2017-08-05 13-45-20.png

You don't have to write HTML as above, you can just do the Python code. Plotly is responsible for drawing the graph.

Markdown It supports Markdown notation.

import dash
import dash_html_components as html
import dash_core_components as dcc

markdown_doc = dcc.Markdown('''
#Heading 1
##Heading 2
###Heading 3
---
*Bullets
*Bullets
---

[Rinku](http://commonmark.org/help)
![Image](https://images.plot.ly/static/marketing/dash/dash-logo.png)

>Quote
''')

app = dash.Dash()
app.layout = html.Div(markdown_doc)

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

image.png

I couldn't express the table in my environment. Please let me know if anyone has succeeded.

Live Updates It also supports dynamic graphs.

The example below uses psutil to monitor the resource status of the machine in real time.

import dash
from dash.dependencies import Input, Output, Event
import dash_core_components as dcc
import dash_html_components as html
import datetime
import plotly
import numpy as np
import pandas as pd
import psutil

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}

app = dash.Dash(__name__)
app.layout = html.Div(children=[
    html.Div([
        html.H4('Oreore system monitor'),
        html.Div(id='live-update-text'),
        dcc.Graph(id='live-update-graph'),
        html.H4('Process list'),
        html.Div(id='live-update-proc'),
        dcc.Interval(
            id='interval-component',
            interval=1 * 1000  # in milliseconds
        )
    ])
],
    style={'backgroundColor': colors['background'], 'color': colors['text']}
)


class Context:
    def __init__(self):
        self.t = []
        self.cpu = []
        self.per_cpu = [[] for x in range(psutil.cpu_count())]
        self.mem = []

    @classmethod
    def append_data(cls, d1, d2):
        n = len(d1)
        if n > 100:
            del d1[0:n - 99]
        d1.append(d2)


context = Context()

# The `dcc.Interval` component emits an event called "interval"
# every `interval` number of milliseconds.
# Subscribe to this event with the `events` argument of `app.callback`


@app.callback(Output('live-update-text', 'children'),
              events=[Event('interval-component', 'interval')])
def update_metrics():
    now = datetime.datetime.now()
    hour, minute, second = now.hour, now.minute, now.second
    style = {'padding': '5px', 'fontSize': '16px'}
    return [
        html.Span('CPU: {}%'.format(context.cpu[-1]), style=style),
        html.Span('Memory: {}%'.format(context.mem[-1]), style=style)
    ]


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph', 'figure'),
              events=[Event('interval-component', 'interval')])
def update_graph_live():
    # global context
    context.append_data(context.t, datetime.datetime.now())
    context.append_data(context.cpu, psutil.cpu_percent())
    for data, pct in zip(context.per_cpu, psutil.cpu_percent(percpu=True)):
        context.append_data(data, pct)
    context.append_data(context.mem, psutil.virtual_memory().percent)

    # Create the graph with subplots
    fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
    fig['layout']['margin'] = {
        'l': 30, 'r': 10, 'b': 30, 't': 10
    }
    fig['layout']['plot_bgcolor'] = colors['background']
    fig['layout']['paper_bgcolor'] = colors['background']
    fig['layout']['font'] = {'color': colors['text']}
    fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
    fig['layout']['yaxis1'].update(range=[0, 100])
    fig['layout']['yaxis2'].update(range=[0, 100])

    fig.append_trace({
        'x': context.t,
        'y': context.cpu,
        'name': 'cpu',
        'mode': 'lines',
        'type': 'scatter',
    }, 1, 1)
    for i, y in enumerate(context.per_cpu):
        fig.append_trace({
            'x': context.t,
            'y': y,
            'name': 'cpu {}'.format(i),
            'mode': 'lines',
            'type': 'scatter',
        }, 1, 1)
    fig.append_trace({
        'x': context.t,
        'y': context.mem,
        'name': 'memory',
        'mode': 'lines',
        'type': 'scatter',
        'fill': 'tonexty',
    }, 2, 1)

    return fig


def get_proc_df():
    def get_proc(proc):
        try:
            pinfo = proc
        except psutil.NoSuchProcess:
            pass
        return (pinfo.pid, pinfo.name(), pinfo.memory_percent(), pinfo.cpu_percent())

    data = [get_proc(proc) for proc in psutil.process_iter()]
    df = pd.DataFrame(data, columns=['pid', 'name', 'memory', 'cpu'])
    df['memory'] = df['memory'].map(lambda x: '{:.2f}%'.format(x))
    df['cpu'] = df['cpu'] / psutil.cpu_count()
    df['cpu'] = df['cpu'].map(lambda x: '{:.2f}%'.format(x))
    return df.sort_values('cpu', ascending=False)


@app.callback(Output('live-update-proc', 'children'),
              events=[Event('interval-component', 'interval')])
def generate_table():
    df = get_proc_df()
    max_rows = 10
    return html.Table(
        # Header
        [html.Tr([html.Th(col) for col in df.columns])] +

        # Body
        [html.Tr([
            html.Td(df.iloc[i][col], style={'width': '8em'}) for col in df.columns
        ]) for i in range(min(len(df), max_rows))]
    )


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

Peek 2017-08-05 16-52.gif

Interactive operation

You can interactively control the output contents while operating the UI. I will write how to do it soon.

Recommended Posts

Create a web app that can be easily visualized with Plotly Dash
Tornado-Let's create a Web API that easily returns JSON with JSON
Create a web API that can deliver images with Django
Create a simple web app with flask
[Python] Make a graph that can be moved around with Plotly
Make a currency chart that can be moved around with Plotly (2)
Make a currency chart that can be moved around with Plotly (1)
You can easily create a GUI with Python
Create a web application that recognizes numbers with a neural network
Let's make a diagram that can be clicked with IPython
Web App Development Practice: Create a Shift Creation Page with Django! (Shift creation page)
Make a Spinbox that can be displayed in Binary with Tkinter
I made a shuffle that can be reset (reverted) with Python
Make a Spinbox that can be displayed in HEX with Tkinter
[Python] Draw elevation data on a sphere with Plotly and draw a globe that can be rotated round and round
Play like a web app with ipywidgets
Create a GUI app with Python's Tkinter
Daemonize a Python web app with Supervisor
Create a web service with Docker + Flask
Create a BOT that can call images registered with Discord like pictograms
The LXC Web Panel that can operate LXC with a browser was wonderful
How to make a rock-paper-scissors bot that can be easily moved (commentary)
Web App Development Practice: Create a Shift Creation Page with Django! (Introduction)
[Can be done in 10 minutes] Create a local website quickly with Django
Draw a graph that can be moved around with HoloViews and Bokeh
I wanted to quickly create a mail server that can be used freely with postfix + dovecot on EC2
A memo for making a figure that can be posted to a journal with matplotlib
A web app that just does Hello World with Go's net / http package
File types that can be used with Go
Create an app that guesses students with python
I tried to create a class that can easily serialize Json in Python
I want to create a priority queue that can be updated in Python (2.7)
Create a page that loads infinitely with python
[kotlin] Create an app that recognizes photos taken with a camera on android
Format DataFrame data with Pytorch into a form that can be trained with NN
I made a familiar function that can be used in statistics with Python
List packages that can be updated with pip
How to create a multi-platform app with kivy
Create a web app that converts PDF to text using Flask and PyPDF2
Create a Python console application easily with Click
"Gazpacho", a scraping module that can be used more easily than Beautiful Soup
I tried to easily create a high-precision 3D image with one photo [1]. (Depth can now be edited in PNG.)
Web App Development Practice: Create a Shift Creation Page with Django! (Write a base template)
Convert images from FlyCapture SDK to a form that can be used with openCV
Web App Development Practice: Create a Shift Creation Page with Django! (Authentication system processing)
Web App Development Practice: Create a Shift Creation Page with Django! (Experiment on admin page)
Create a flag in settings that will be True only when testing with Django
[Python] Introduction to web scraping | Summary of methods that can be used with webdriver
I tried to make a memo app that can be pomodoro, but a reflection record
How to create a property of relations that can be prefetch_related by specific conditions
Create a Todo app with Django REST Framework + Angular
Create a native GUI app with Py2app and Tkinter
Create a Todo app with the Django REST framework
Why not create a stylish table easily with Python?
Color list that can be set with tkinter (memorial)
Python knowledge notes that can be used with AtCoder
Create a chatbot that supports free input with Word2Vec
Create a Todo app with Django ③ Create a task list page
Create an app that guesses students with python-GUI version
Create a Todo app with Django ⑤ Create a task editing function
Deploy a real-time web app with swampdragon x apache