使用布局模板#
正如我们在Layout of Jupyter widgets中展示的,可以使用灵活的GridBox规范来排列多个小部件。然而,使用该规范需要一些CSS属性的理解,可能会带来陡峭的学习曲线。在这里,我们将介绍基于GridBox构建的布局模板,这些模板简化了常见小部件布局的创建。
# Utils widgets
from ipywidgets import Button, Layout, jslink, IntText, IntSlider
def create_expanded_button(description, button_style):
return Button(description=description, button_style=button_style, layout=Layout(height='auto', width='auto'))
top_left_button = create_expanded_button("Top left", 'info')
top_right_button = create_expanded_button("Top right", 'success')
bottom_left_button = create_expanded_button("Bottom left", 'danger')
bottom_right_button = create_expanded_button("Bottom right", 'warning')
top_left_text = IntText(description='Top left', layout=Layout(width='auto', height='auto'))
top_right_text = IntText(description='Top right', layout=Layout(width='auto', height='auto'))
bottom_left_slider = IntSlider(description='Bottom left', layout=Layout(width='auto', height='auto'))
bottom_right_slider = IntSlider(description='Bottom right', layout=Layout(width='auto', height='auto'))
2x2 网格#
你可以使用TwoByTwoLayout小部件轻松创建一个2x2矩阵布局的4个小部件:
from ipywidgets import TwoByTwoLayout
TwoByTwoLayout(top_left=top_left_button,
top_right=top_right_button,
bottom_left=bottom_left_button,
bottom_right=bottom_right_button)
如果您没有为某些插槽定义小部件,布局将通过合并相邻单元格来自动重新配置自身
TwoByTwoLayout(top_left=top_left_button,
bottom_left=bottom_left_button,
bottom_right=bottom_right_button)
如果不想要这种行为,你可以在TwoByTwoLayout 构造函数的参数中传递merge=False
TwoByTwoLayout(top_left=top_left_button,
bottom_left=bottom_left_button,
bottom_right=bottom_right_button,
merge=False)
即使在布局初始化后,您仍然可以添加缺失的小部件:
layout_2x2 = TwoByTwoLayout(top_left=top_left_button,
bottom_left=bottom_left_button,
bottom_right=bottom_right_button)
layout_2x2
layout_2x2.top_right = top_right_button
您也可以使用小部件的链接功能,根据另一个小部件来更新某个小部件的属性:
app = TwoByTwoLayout(top_left=top_left_text, top_right=top_right_text,
bottom_left=bottom_left_slider, bottom_right=bottom_right_slider)
link_left = jslink((app.top_left, 'value'), (app.bottom_left, 'value'))
link_right = jslink((app.top_right, 'value'), (app.bottom_right, 'value'))
app.bottom_right.value = 30
app.top_left.value = 25
app
你可以使用自定义控件轻松创建更复杂的布局。例如,你可以使用bqplot图形控件来添加图表:
import bqplot as bq
import numpy as np
size = 100
np.random.seed(0)
x_data = range(size)
y_data = np.random.randn(size)
y_data_2 = np.random.randn(size)
y_data_3 = np.cumsum(np.random.randn(size) * 100.)
x_ord = bq.OrdinalScale()
y_sc = bq.LinearScale()
bar = bq.Bars(x=np.arange(10), y=np.random.rand(10), scales={'x': x_ord, 'y': y_sc})
ax_x = bq.Axis(scale=x_ord)
ax_y = bq.Axis(scale=y_sc, tick_format='0.2f', orientation='vertical')
fig = bq.Figure(marks=[bar], axes=[ax_x, ax_y], padding_x=0.025, padding_y=0.025,
layout=Layout(width='auto', height='90%'))
from ipywidgets import FloatSlider
max_slider = FloatSlider(min=0, max=10, default_value=2, description="Max: ",
layout=Layout(width='auto', height='auto'))
min_slider = FloatSlider(min=-1, max=10, description="Min: ",
layout=Layout(width='auto', height='auto'))
app = TwoByTwoLayout(top_left=min_slider,
bottom_left=max_slider,
bottom_right=fig,
align_items="center",
height='700px')
jslink((y_sc, 'max'), (max_slider, 'value'))
jslink((y_sc, 'min'), (min_slider, 'value'))
jslink((min_slider, 'max'), (max_slider, 'value'))
jslink((max_slider, 'min'), (min_slider, 'value'))
max_slider.value = 1.5
app
应用布局#
AppLayout 是一个小部件布局模板,允许您创建类似应用程序的小部件排列。它包含一个页眉、一个页脚、两个侧边栏和一个中央面板:
from ipywidgets import AppLayout, Button, Layout
header_button = create_expanded_button('Header', 'success')
left_button = create_expanded_button('Left', 'info')
center_button = create_expanded_button('Center', 'warning')
right_button = create_expanded_button('Right', 'info')
footer_button = create_expanded_button('Footer', 'success')
AppLayout(header=header_button,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=footer_button)
然而借助自动合并功能,可以实现许多其他布局:
AppLayout(header=None,
left_sidebar=None,
center=center_button,
right_sidebar=None,
footer=None)
AppLayout(header=header_button,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=None)
AppLayout(header=None,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=None)
AppLayout(header=header_button,
left_sidebar=left_button,
center=center_button,
right_sidebar=None,
footer=footer_button)
AppLayout(header=header_button,
left_sidebar=None,
center=center_button,
right_sidebar=right_button,
footer=footer_button)
AppLayout(header=header_button,
left_sidebar=None,
center=center_button,
right_sidebar=None,
footer=footer_button)
AppLayout(header=header_button,
left_sidebar=left_button,
center=None,
right_sidebar=right_button,
footer=footer_button)
您还可以使用pane_widths和pane_heights参数修改窗格的相对和绝对宽度与高度。这两个参数都接受一个包含三个元素的序列,每个元素可以是整数(相当于赋予行/列的权重)或格式为'1fr'(与整数相同)或'100px'(绝对尺寸)的字符串。
AppLayout(header=header_button,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=footer_button,
pane_widths=[3, 3, 1],
pane_heights=[1, 5, '60px'])
网格布局#
GridspecLayout 是一个 N×M 网格布局,允许使用类似于 matplotlib 的 GridSpec 的 API 进行灵活的布局定义。
你可以使用 GridspecLayout 来定义一个简单的等距网格。例如,创建一个4x3的布局:
from ipywidgets import GridspecLayout
grid = GridspecLayout(4, 3)
for i in range(4):
for j in range(3):
grid[i, j] = create_expanded_button('Button {} - {}'.format(i, j), 'warning')
grid
要使小部件跨越多个列和/或行,可以使用切片表示法:
grid = GridspecLayout(4, 3, height='300px')
grid[:3, 1:] = create_expanded_button('One', 'success')
grid[:, 0] = create_expanded_button('Two', 'info')
grid[3, 1] = create_expanded_button('Three', 'warning')
grid[3, 2] = create_expanded_button('Four', 'danger')
grid
您仍可使用相同的索引表示法更改存储在网格中的小部件属性。
grid = GridspecLayout(4, 3, height='300px')
grid[:3, 1:] = create_expanded_button('One', 'success')
grid[:, 0] = create_expanded_button('Two', 'info')
grid[3, 1] = create_expanded_button('Three', 'warning')
grid[3, 2] = create_expanded_button('Four', 'danger')
grid
grid[0, 0].description = "I am the blue one"
注意: 只需传递目标小部件所占据的网格单元之一的索引即可。在此上下文中不支持切片。
如果已有小组件与要添加的小组件位置冲突,该小组件将从网格中移除:
grid = GridspecLayout(4, 3, height='300px')
grid[:3, 1:] = create_expanded_button('One', 'info')
grid[:, 0] = create_expanded_button('Two', 'info')
grid[3, 1] = create_expanded_button('Three', 'info')
grid[3, 2] = create_expanded_button('Four', 'info')
grid
grid[3, 1] = create_expanded_button('New button!!', 'danger')
注意: 此上下文中支持切片。
grid[:3, 1:] = create_expanded_button('I am new too!!!!!', 'warning')
使用GridspecLayout创建散点图#
在这些示例中,我们将演示如何使用GridspecLayout和bqplot widget创建多面板散点图。要运行此示例,您需要安装bqplot包。
例如,可以使用以下代码片段获取跨多个维度的散点图:
import bqplot as bq
import numpy as np
from ipywidgets import GridspecLayout, Button, Layout
n_features = 5
data = np.random.randn(100, n_features)
data[:50, 2] += 4 * data[:50, 0] **2
data[50:, :] += 4
A = np.random.randn(n_features, n_features)/5
data = np.dot(data,A)
scales_x = [bq.LinearScale() for i in range(n_features)]
scales_y = [bq.LinearScale() for i in range(n_features)]
gs = GridspecLayout(n_features, n_features)
for i in range(n_features):
for j in range(n_features):
if i != j:
sc_x = scales_x[j]
sc_y = scales_y[i]
scatt = bq.Scatter(x=data[:, j], y=data[:, i], scales={'x': sc_x, 'y': sc_y}, default_size=1)
gs[i, j] = bq.Figure(marks=[scatt], layout=Layout(width='auto', height='auto'),
fig_margin=dict(top=0, bottom=0, left=0, right=0))
else:
sc_x = scales_x[j]
sc_y = bq.LinearScale()
hist = bq.Hist(sample=data[:,i], scales={'sample': sc_x, 'count': sc_y})
gs[i, j] = bq.Figure(marks=[hist], layout=Layout(width='auto', height='auto'),
fig_margin=dict(top=0, bottom=0, left=0, right=0))
gs
样式属性#
您可以指定额外的样式属性来修改布局。例如,您可以使用 height 和 width 参数更改整个布局的大小。
AppLayout(header=None,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=None,
height="200px", width="50%")
窗格之间的间隙可以通过 grid_gap 参数来增加或减少:
AppLayout(header=None,
left_sidebar=left_button,
center=center_button,
right_sidebar=right_button,
footer=None,
height="200px", width="50%",
grid_gap="10px")
此外,您可以使用justify_content和align_items属性来控制布局内小部件的对齐方式:
from ipywidgets import Text, HTML
TwoByTwoLayout(top_left=top_left_button, top_right=top_right_button,
bottom_right=bottom_right_button,
justify_items='center',
width="50%",
align_items='center')
对于其他对齐选项,可以使用通用名称(top 和 bottom)或其 CSS 等效项(flex-start 和 flex-end):
TwoByTwoLayout(top_left=top_left_button, top_right=top_right_button,
bottom_right=bottom_right_button,
justify_items='center',
width="50%",
align_items='top')
示例#
在这个notebook中,你将找到一个使用AppLayout的完整示例。
