用 IPython notebook + nvd3 实现交互式调试

用 IPython notebook + nvd3 实现交互式调试

发布于:2014/08/31 18:22:52

IPython(http://ipython.org/) 是一款 Python 的增强IDE,而 IPython notebook 则是在网页上实现了更为强大的交互功能的 IPython

本文的内容旨在简要的介绍使用 IPython notebook 的方法,并重点介绍利用 IPython notebook + nvd3 图形库进行交互式的调试

一、准备

# 安装 IPython 及 nvd3

$ sudo pip install ipython python-nvd3

# 安装 numpy、scipy、matplotlib

$ sudo pip install numpy scipy matplotlib

# 打开 IPython

$mkdir~/notebook

$ ipython notebook ~/notebook

点击New Notebook打开一个新页面,就算准备完成了

Untitled0那一栏可以自由设定文件名,按command + s就可以保存

二、为数值运算做准备

数值运算会需要用到 numpy、scipy、matplotlib 这些常用库,直接在 IPython notebook 里写一句%pylab inline就自动的导入了这些库

在 IPython 里,代码被分为一个一个的 cell ,按shift + ENTER可以执行当前选定的 cell, 也可以在菜单里点选 CELL -> Run ALL 从上至下运行所有的 cell,在运行大段的代码的时候,当你改变了某个上游的代码块,可能不仅仅需要重新 Run 这个或全部的 cell,还需要点击 Kernel Restart 来重启后台,来清理掉命名空间中之前留下的各种变量或导入的模块

三、简单的绘图

因为之前使用 %pylab inline 已经自动引入了 numpy 和 matplotlib 库,现在可以直接在 notebook 里绘图了

Ipython %pylab 会自动引入 numpy,相当于执行了 from numpy import *; import numpy as np ,所以你既可以直接用 numpy 里的内容,也可以按照习惯用 np.xxx 的方式来使用

# 在 IPython notebook 里绘图x = np.linspace(0,10,50)y = np.sin(x)z = np.cos(x)plot(x, y)scatter(x, z)

plot 和 scatter 都是 matplotlib 中的接口,你可以在下面的地址中获取到更多的信息

matplotlib-绘制精美的图表

Matplotlib Gallery

本文的目的并不是介绍 matplotlib 绘图,所以先跳过了

四、使用 IPython 的交互式功能

IPython 提供了功能强大的交互式操作 iteract 接口,使用户可以通过交互式的操作来调节参数

# 引入 interact 模块fromIPython.html.widgetsimportinteract, IntSliderWidget# 把之前的画图函数改写成依赖于参数的函数deftest_interact(min_, max_, steps_):x = np.linspace(min_, max_, steps_)    y = np.sin(x)    z = np.cos(x)    plot(x, y)    scatter(x, y)# 使用 interact 来交互式的调试参数interact(test_interact,# 为每一个参数设定一个 interact 控件min_=IntSliderWidget(min=1,# 最小值max=10,# 最大值step=1,# 每次调节的步长value=1),# 初始值max_=IntSliderWidget(min=10, max=20, step=1, value=10),        steps_=IntSliderWidget(min=10, max=100, step=10, value=50))

我们现在可以用鼠标拖动来简单的调节效果了

IPython 的 widgets 还有

Widget, DOMWidget, CallbackDispatcher

CheckboxWidget, ToggleButtonWidget

ButtonWidget

ContainerWidget, PopupWidget

FloatTextWidget, BoundedFloatTextWidget, FloatSliderWidget, FloatProgressWidget

ImageWidget

IntTextWidget, BoundedIntTextWidget, IntSliderWidget, IntProgressWidget

RadioButtonsWidget, ToggleButtonsWidget, DropdownWidget, SelectWidget

TabWidget, AccordionWidget

HTMLWidget, LatexWidget, TextWidget, TextareaWidget

interact, interactive, fixed

官方文档(http://ipython.org/ipython-doc/dev/api/index.html)的资料少的可怜,我一般都是上这里http://nullege.com/codes/search/IPython.html.widgets.DropdownWidget来查看接口的用法,其实大部分的用法都比较一致,就是传递一个 min, max, step 值, dropdown 传的是 dict 或 list,每个接口都有一个 value 参数来设定初始值

其实常用的就是 IntSliderWidget、FloatSliderWidget、DropdownWidget、RadioButtonsWidget ,用法也不难,试一试就出来了,这里也就不详细介绍了

五、使用 nvd3

现在我们已经会用 matplotlib 画图,而且还会使用 active 来进行交互式的调试,其实已经能解决日常中的绝大部分需求了。不过在 IPython notebook 中使用 matplotlib 有一个美中不足的地方就是不能对图形进行交互式操作,当我们绘制一个三维图的时候,可能需要拖动才能看清楚图形的结构,而 IPython 中的 matplotlib 对此就无能为力了。不过好在 IPython 强大到可以近乎完美的支持 HTML,也就是说你可以随意的去挑选你喜欢的 JavaScript 图形库来进行绘图。这里我们选择在科学数据绘制上表现出众的 D3 (http://d3js.org/

nvd3(http://nvd3.org/)是对 d3 的封装,而 python-nvd3 则是一个能够生成 nvd3 网页代码(html & javascript)的 python 模块,我们用 python-nvd3 来生成 HTML 代码,然后用 IPython 的 HTML 模块提供的功能来显示

OK,图形按照我们所想的画出来了~

和 matplotlib 相比,图形更加美观,而且更重要的是有了交互功能

*六、nvd3 的高级使用

python-nvd3 提供的接口实在少的可怜。比如如果我想改变 tooltip 的内容让它显示我希望的内容,或者我希望在一个数据集内也有不同的显示方式(比如不同 size 或颜色等等),这些在 nvd3 中都是可以实现的功能,但是 python-nvd3 却没有提供相应的接口

好在 python-nvd3 返回了 HTML 代码,我的解决办法是直接用正则去匹配 HTML 代码,然后插入我想要实现功能的 javascript 代码

我也在探索更好的实现办法,所以这段就不详细介绍了,如果你只是迫切的需要类似的功能,可以考虑使用我目前的解决办法

1、替换 tooltip

# 这个函数的功能是替换 python-nvd3 生成的 HTML代码# 参数 nodes 是一个形如 [{‘id’: name, ‘x’: 1, 'y': 2, 'value': 23}, {}, ...] 的数据块# 让 tooltip 去遍历 nodes,找出 x 和 y 匹配的 node, 然后显示其 id 值defreplace_tooltip(html, nodes):"""Change the D3 chart's tooltip

"""tooltip_content ="""

chart.tooltipContent(function(key, y, e, graph) {{

var nodes = {0};

var content = '';

var group = Number(key.split('_')[1]);

var x = graph.point.x;

var y = graph.point.y;

for(var i in nodes){{

var point = nodes[i];

if(point['x'] == x && point['y'] == y){{

content += '' + point['id'] + '';

break;

}}

}}

content += '

' + x.toString() + ' ' + y.toString();

return content;

}});

""".format(str(nodes))    p = re.compile(r'\bchart.tooltipContent[.\S\s]*''return tooltip_str;\s*\}\);')    html = p.sub(tooltip_content, html)returnhtml

2、让同组数据有不同的显示效果

# 这个函数也是替换 python-nvd3 生成的 HTML# nodes 的结构同上# anomaly 是一个形如 [id, id] 的列表# 其实原理和上面的一样,都是根据 x 和 y 匹配,然后修改 nvd3 的数据集 DATA_TCS (TCS是我的画布名,这个的命名规则是 DATA_,你可以去看自己的 python-nvd3 生成的 HTML 代码)defmark_anomalies_axis(nodes, anomalies, html):"""Mark the anomalies points

"""anoma_ls = []foranomalyinanomalies:fornodeinnodes:ifnode['id'] == anomaly:                anoma_ls.append({'x': node['x'],'y': node['y']})    _mark_anoma_js ="""

anomalies = {0};

// mark anomalies

for(var ia in anomalies) {{

anoma = anomalies[ia];

for(var ig in data_TCS) {{

var group = data_TCS[ig];

for(var ip in group['values']) {{

var p = group['values'][ip];

if(p['x']==anoma['x'] && p['y']==anoma['y']) {{

p['size'] = 0.9;

break;

}}

}}

}}

}}

nv.addGraph(function() {{

""".format(str(anoma_ls))    p = re.compile(r'\bnv\.addGraph\(function\(\) {')    html = p.sub(_mark_anoma_js, html)returnhtml

效果图

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容