警告: 此笔记本需要一个运行中的内核才能完全交互,请在本地运行或在 mybinder 上运行。
仪表板: 或者通过使用Voila渲染此笔记本来获取仪表板:
一个Plotly热图#
确保你先完成了Vaex-jupyter教程。
创建自己的可视化的最简单方法是遵循与Vaex-jupyter教程中描述的类似方法,我们在那里使用matplotlib来创建图表。然而,当使用plotly时,我们可以首先构建小部件,并在每次回调时更新相关组件。这比每次更新时创建一个全新的小部件要高效得多。
为了解决这个两步过程(初始化和更新),我们编写了一个实现dunder调用方法的包装类,使其可调用(像函数一样)。
[1]:
import vaex
import numpy as np
import vaex.jupyter.model as vjm
import matplotlib.pyplot as plt
# Fetch a dataset
df = vaex.datasets.helmi_de_zeeuw.fetch()
[2]:
# Define the axes
extend = 50
x_axis = vjm.Axis(df=df, expression=df.x, shape=100, min=-extend, max=extend)
y_axis = vjm.Axis(df=df, expression=df.y, shape=140, min=-extend, max=extend)
# in this case we need to know the min and max directly
await vaex.jupyter.gather()
[3]:
import plotly.graph_objs as go
class PlotlyHeatmap:
def __init__(self, x_axis, y_axis, figure_height=500, figure_width=400, title="Hi vaex, hi plotly"):
self.x_axis = x_axis
self.y_axis = y_axis
self.heatmap = go.Heatmap()
self.layout = go.Layout(height=figure_height,
width=figure_width,
title=title,
xaxis=go.layout.XAxis(title=str(x_axis.expression),
range=[x_axis.min, x_axis.max]
),
yaxis=go.layout.YAxis(title=str(y_axis.expression),
range=[y_axis.min, y_axis.max]
)
)
self.fig = go.FigureWidget(data=[self.heatmap], layout=self.layout)
# we respond to zoom/pan
self.fig.layout.on_change(self._pan_and_zoom, 'xaxis.range', 'yaxis.range')
def _pan_and_zoom(self, layout, xrange, yrange):
self.x_axis.min, self.x_axis.max = xrange
self.y_axis.min, self.y_axis.max = yrange
def __call__(self, data_array):
ar = data_array.data # take the numpy array data
assert data_array.ndim == 2
dim_x = data_array.dims[0]
dim_y = data_array.dims[1]
x0, x1 = data_array.coords[dim_x].attrs['min'], data_array.coords[dim_x].attrs['max']
y0, y1 = data_array.coords[dim_y].attrs['min'], data_array.coords[dim_y].attrs['max']
dx = (x1 - x0)/data_array.shape[0]
dy = (y1 - y0)/data_array.shape[1]
z = np.log1p(ar).T
self.fig.update_traces(dict(z=z, x0=x0, y0=y0, dx=dx, dy=dy))
heatmap_plotly.fig.update_layout(
xaxis=go.layout.XAxis(title=dim_x, range=[x0, x1]),
yaxis=go.layout.YAxis(title=dim_y, range=[y0, y1])
)
heatmap_plotly = PlotlyHeatmap(x_axis, y_axis)
[4]:
# we use `heatmap_plotly` as a callable function
da_view = df.widget.data_array(axes=[x_axis, y_axis], display_function=heatmap_plotly)
# we display the progress bar and possible output (stack traces)
display(da_view)
# and the plotly figure widget
display(heatmap_plotly.fig)
我们还可以创建表达式小部件来直接编辑上图上的轴
[5]:
x_widget = df.widget.expression(x_axis)
y_widget = df.widget.expression(y_axis)
display(x_widget)
display(y_widget)
使用 ipyvuetify 我们可以创建漂亮的按钮并为它们分配一些功能:
[6]:
import ipyvuetify as v
# A button to reset the figure ot its initial state
button_reset = v.Btn(children=['reset'])
def reset(*ignore_arguments):
x_axis.expression = df.x
y_axis.expression = df.y
button_reset.on_event('click', reset)
# A button that presents a specific figure
button_fireball = v.Btn(children=['fireball'])
def fireball(*ignore_arguments):
x_axis.expression = np.log(df.x**2)
y_axis.expression = df.y
button_fireball.on_event('click', fireball)
preset_widget = v.Col(children=[button_reset, button_fireball])
preset_widget
Voila vuetify 设置#
我们可以使用Voila更优雅地展示在此笔记本中创建的可视化。
[7]:
from vaex.jupyter.widgets import ContainerCard, Html, LinkList
[9]:
LinkList(items=
[{'title': 'Vaex', 'url': 'https://vaex.io', 'img': 'https://vaex.io/img/logos/logo-grey.svg', },
{'title': 'Vaex on GitHub', 'url': 'https://github.com/vaexio/vaex', 'img': 'https://github.githubassets.com/pinned-octocat.svg'},
{'title': 'Vaex DataFrame server', 'url': 'http://dataframe.vaex.io/', 'icon': 'mdi-database'},
{'title': 'Voila (dashboard)', 'url': 'https://github.com/voila-dashboards/voila', 'icon': 'dashboard'},
{'title': 'Plotly', 'url': 'https://plotly.com/', 'img': 'https://plotly.com/img/favicon.ico'},
], _metadata={'mount_id': 'content-nav'})
[10]:
card_widget = ContainerCard(title=f'{len(df):,} Simulated stars',
subtitle="using vaex-jupyter",
main=heatmap_plotly.fig,
controls=[x_widget, y_widget, preset_widget],
show_controls=True,
card_props={'style': 'width: 420px;', 'class': 'pa-2 ma-4'},
_metadata={'mount_id': 'content-main'}
)
[11]:
# You do not have to render the widget for it to show up in voila-vuetify
card_widget
[12]:
Html(tag='span',
children=['Simulated stars'],
_metadata={'mount_id': 'content-bar'})
Html(tag='span',
children=['Resources'],
_metadata={'mount_id': 'content-title'});