Jupyter notebook最簡原型界面設計- ipywidgets與lineup_widget

?Tkinter的GUI設計 和 django頁面設計,那麼筆者只是想快速做個demo原型,以上的內容能不能結合著來,有一些簡單的交互 + web可以快速訪問的到,於是就看到了jupyter notebook這兩個庫,非常簡單的玩具,來看看唄~ ipywidgets比較強調輸入項的各式花樣,但是其對輸出內容的格式的花樣非常少。

原文見:

Jupyter notebook最簡原型界面設計 - ipywidgets與lineup_widget?

blog.csdn.net圖標


一 ipywidgets

文檔:ipywidgets.readthedocs.io

github:github.com/jupyter-widg

安裝:

# 方式一
pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension
# 方式二
conda install -c conda-forge ipywidgets

效果:

(參考自:

A very simple demo of interactive controls on Jupyter notebook?

towardsdatascience.com

參考於:

Interactive Visualizations In Jupyter Notebook?

towardsdatascience.com

來看一些組件與模塊。

1.1 基礎組件

主要參考:Widget List

1.1.1 button 按鈕

widgets.Button(
description=Click me,
disabled=False,
button_stylex=success, # success, info, warning, danger or
tooltip=Click me,
icon=check
)

# 調整按鈕
from ipywidgets import Button, Layout

b = Button(description=(50% width, 80px height) button,
layout=Layout(width_=50%, height=80px),
button_stylex=success)
b

button是作為輸入項的,

1.1.2 IntSlider、FloatSlider

widgets.FloatSlider(
value=7.5,
min=0,
max=10.0,
step=0.1,
description=Test:,
disabled=False,
continuous_update=False,
orientation=horizontal,
readout=True,
readout_format=.1f,
)

一個整數型滑塊,一個數值型滑塊。

1.1.3 FloatProgress / IntProgress

widgets.IntProgress(
value=7,
min=0,
max=10,
step=1,
description=Loading:,
bar_stylex=, # success, info, warning, danger or
orientation=horizontal
)

widgets.FloatProgress(
value=7.5,
min=0,
max=10.0,
step=0.1,
description=Loading:,
bar_stylex=info,
orientation=horizontal
)

一個整數型進度條,一個數值型進度條。

1.1.4 Text、Textarea

widgets.Text(
value=Hello World,
placeholder=Type something,
description=String:,
disabled=False
)

widgets.Textarea(
value=Hello World,
placeholder=Type something,
description=String:,
disabled=False
)

一般來說,textarea比text更好用,模塊是可伸縮的。

1.1.5 圖片Image

file = open("images/WidgetArch.png", "rb")
image = file.read()
widgets.Image(
value=image,
format=png,
width_=300,
height=400,
)

1.2 單控制項 - interact 簡單交互

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
def f(segx,opt):
if opt:
return segx
else:
return 1
interact(f, segx=10, opt = True)

interact代表交互,第一個f代表函數,segxopt都代表f函數的參數。 - segx代表滑條 - opt = True/False代表選項框

注意interact,相當於給函數f賦值,除了第一個,之後的參數都是第一個函數的參數,名字需對齊。

1.3 單控制項 - interact_manual簡單交互

from ipywidgets import FloatSlider
# 橫軸進度可以拖拽
def slow_function(i):
print(int(i),list(x for x in range(int(i)) if
str(x)==str(x)[::-1] and
str(x**2)==str(x**2)[::-1]))
return

interact_manual(slow_function,i=FloatSlider(min=1e5, max=1e7, step=1e5));

FloatSlider表示拖拽滑塊,interact_manual(函數,函數參數),此時函數參數是由拖拽滑塊FloatSlider來確定。 與interact的區別: interact是實時改變,interact_manual是人工點擊RUN才能執行一次。

1.4 單控制項 - interactive_output + HBox交互

from IPython.display import display, HTML
a = widgets.IntSlider()
b = widgets.IntSlider()
c = widgets.IntSlider()
ui = widgets.HBox([a, b, c])

def f(a, b, c):
print((a, b, c))

out = widgets.interactive_output(f, {a: a, b: b, c: c})

display(ui, out)

a,b,c是三個滑塊,通過widgets.HBox進行拼接成為一個Box組件。 interactive_output(函數,函數參數),函數參數是一個組合Box組件。 display是展示滑塊組合以及輸出項。

1.5 單控制項 - 文本交互

widgets.Textarea(
value=Hello World, # 默認語句
placeholder=Type something,
description=String:, # 框的名字
disabled=False # 是否可修改
)

Textarea是一個比較長的文本框作為輸入項。

1.6 兩個控制項 - 組合交互jslink

# jslink
# 兩個控制項的交互
a = widgets.FloatText()
b = widgets.FloatSlider()
display(a,b)

mylink = widgets.jslink((a, value), (b, value))

jslink把控制項a,b組合起來,a是文本控制項,b是數值控制項。

1.7 多模塊 - 控制項獨立分屏Accordion

accordion = widgets.Accordion(children=[widgets.Text(), widgets.Text()])
accordion.set_title(0, Text1)
accordion.set_title(1, Text2)
accordion

可以把兩個組件獨立的鏈接在一起,而不是如jslink交互影響。

# 選項分屏
tab_contents = [P0, P1, P2, P3, P4]
children = [widgets.Text(description=name) for name in tab_contents]
tab = widgets.Tab()
tab.children = children
for i in range(len(children)):
tab.set_title(i, str(i))
tab

多個控制項獨立組合。

# 雙模塊分屏 + 選項分屏
tab_nest = widgets.Tab()
tab_nest.children = [accordion, accordion]
tab_nest.set_title(0, An accordion)
tab_nest.set_title(1, Copy of the accordion)
tab_nest

多個控制項組合獨立分開。

1.8 一些小案例

1.8.1 圖形 + 滑塊

%matplotlib inline
from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np

def f(m, b):
plt.figure(2)
x = np.linspace(-10, 10, num=1000)
plt.plot(x, m * x + b)
plt.ylim(-5, 5)
plt.show()

interactive_plot = interactive(f, m=(-2.0, 2.0), b=(-3, 3, 0.5))
# m代表範圍
output = interactive_plot.children[-1]
output.layout.height = 350px
interactive_plot

interactive(函數,函數參數),m/b都是可變滑塊。

第二個案例: 來著:

3.3. Mastering widgets in the Jupyter Notebook?

ipython-books.github.io圖標

@widgets.interact_manual(
color=[blue, red, green], lw=(1., 10.))
def plot(freq=1., color=blue, lw=2, grid=True):
t = np.linspace(-1., +1., 1000)
fig, ax = plt.subplots(1, 1, figsize=(8, 6))
ax.plot(t, np.sin(2 * np.pi * freq * t),
lw=lw, color=color)
ax.grid(grid)

interact_manual是單控制項函數交互,此時通過裝飾器,interact_manual(函數,函數參數)中的函數被隱去。

1.8.2 一個可控的進度讀條

# 一個可控的進度條
play = widgets.Play(
# interval=10,
value=0,
min=0,
max=100,
step=1,
description="Press play",
disabled=False
)
#slider = widgets.IntSlider()
slider = widgets.FloatProgress(
value=50,
min=0,
max=100.0,
step=1,
description=Loading:,
bar_stylex=success,
orientation=horizontal
)

widgets.jslink((play, value), (slider, value))
widgets.HBox([play, slider])

Play是一個控制按鈕,FloatProgress是一個數值進度條。 通過jslink將兩個空間鏈接,點擊按鈕就Loading就可以開始走動。

1.8.3 顏色篩選器

# 顏色選擇器
widgets.ColorPicker(
concise=False,
description=Pick a color,
value=blue,
disabled=False
)

點擊之後就會出現顏色篩選內容,篩選出來的結果為該顏色的具體數值,#800080

1.8.4 複雜輸入框

# 複合功能
from ipywidgets import Layout, Button, Box, FloatText, Textarea, Dropdown, Label, IntSlider

form_item_layout = Layout(
display=flex,
flex_flow=row,
justify_content=space-between
)

form_items = [
Box([Label(value=Age of the captain), IntSlider(min=40, max=60)], layout=form_item_layout),
Box([Label(value=Egg style),
Dropdown(options=[Scrambled, Sunny side up, Over easy])], layout=form_item_layout),
Box([Label(value=Ship size),
FloatText()], layout=form_item_layout),
Box([Label(value=Information),
Textarea()], layout=form_item_layout)
]

form = Box(form_items, layout=Layout(
display=flex,
flex_flow=column,
border=solid 2px,
align_items=stretch,
width_=50%
))
form

form_item_layout統一的Box布局, Dropdown是下拉框,一個Box是一個獨立組件。 form_items是多個Box的組合,Box( [Label(),Textarea()] , layout ) => Box( [前綴名,控制項函數] , 布局 )

.


二 lineup_widget

github:github.com/datavisyn/li

這是一個專門為展示dataframe + ipywidgets而來的包。

參考:

Jupyter Widget?

lineup.js.org圖標

2.1 安裝

## install Jupyter Widgets
pip install ipywidgets
jupyter nbextension enable --py widgetsnbextension

## install library
pip install lineup_widget
jupyter nbextension enable --py --sys-prefix lineup_widget

2.2 主函數

w = lineup_widget.LineUpWidget(df, options=dict(rowHeight=20))

_data = List(trait=Dict(), default_value=[]).tag(sync=True)
_columns = List(trait=Dict(), default_value=[]).tag(sync=True)
options = Dict(traits=dict(filterGlobally=Bool(), singleSelection=Bool(), noCriteriaLimits=Bool(), animated=Bool(),
sidePanel=Enum((True, False, collapsed)), summaryHeader=Bool(), overviewMode=Bool(),
hierarchyIndicator=Bool(), labelRotation=Int(), ignoreUnsupportedBrowser=Bool(),
rowHeight=Int(), rowPadding=Int(), groupHeight=Int(), groupPadding=Int(),
expandLineOnHover=Bool(), defaultSlopeGraphMode=Enum((item, band))),
default_value=dict(filterGlobally=True, singleSelection=False, noCriteriaLimits=False, animated=True,
sidePanel=collapsed, summaryHeader=True, overviewMode=False,
hierarchyIndicator=True, labelRotation=0, ignoreUnsupportedBrowser=False,
rowHeight=18, rowPadding=2, groupHeight=40, groupPadding=5,
expandLineOnHover=False, defaultSlopeGraphMode=item
)).tag(sync=True)
rankings = List(trait=Dict(traits=dict(columns=List(trait=Union((Unicode(), Dict()))), sort_by=List(trait=Unicode()),
group_by=List(trait=Unicode())),
default_value=dict(columns=[_*, *], sort_by=[], group_by=[])), default_value=[]).tag(
sync=True)

其中options之中有非常多的參數,由於文檔也沒具體說明,筆者這邊只對幾個參數有了解。 其中:sidePanel=Enum((True, False, collapsed))代表側邊的面板是否打開,筆者覺得很礙人,一般是sidePanel = False

2.3 案例

案例一:

import lineup_widget
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list(ABCD))

w = lineup_widget.LineUpWidget(df)
w.on_selection_changed(lambda selection: print(selection))
w

非常簡單,唯一需要整理的就是df,一個DataFrame的格式作為輸入,其他不用調整任何東西,就可以使用了。

案例二:

from __future__ import print_function
from ipywidgets import interact, interactive, interact_manual

def selection_changed(selection):
return df.iloc[selection]

interact(selection_changed, selection=lineup_widget.LineUpWidget(df));

三 相似的Jupyter畫圖小模塊

參考於:

Authoring Custom Jupyter Widgets?

blog.jupyter.org

3.1 d3-slider widget

This custom d3-slider widget wraps a simple custom slider based on the fantastic d3.js library. You can run and try it on the Binder repo or watch it on nbviewer.

pip install jupyter_widget_d3_slider

3.2 drawing-pad

This small drawing pad app, is inspired from this codepen. You can run and try it on the Binder repo or watch it on nbviewer.

pip install jupyter-drawing-pad

3.3 ipypivot

The ipypivot widget, wraps the convenient PivotTable.js library. You can run and try it on the binder repo or watch it on nbviewer.

pip install ipypivot


推薦閱讀:

TAG:Python | GUI設計 | JupyterNotebook(IPythonNotebook) |