以编程方式将单元格添加到ipython笔记本以生成报表

时间:2012-11-28 21:30:23

标签: ipython ipython-notebook reproducible-research

我已经看到了iPython开发人员关于如何将ipython笔记本转换为a blog post, a pdf,甚至转换为entire book(~min 43)的一些讨论。 PDF-to-X converter解释以markdown或代码编写的iPython单元格,并在一个步骤中吐出新格式化的文档。

我的问题是我想生成一个大型文档,其中许多图形和部分是以编程方式生成的 - 类似于this。为了使用上面的方法在iPython中工作,我需要能够编写一个能编写其他iPython-Code-Blocks的函数。这种能力是否存在?

#some pseudocode to give an idea
for variable in list:
    image = make_image(variable)
    write_iPython_Markdown_Cell(variable)
    write_iPython_Image_cell(image)

我认为这可能有用,所以我想知道是否:

  1. 可以通过iPython生成iPython单元
  2. 如果这是一个坏主意的原因,我应该坚持像模板库(Jinja)这样的“经典”解决方案。
  3. 感谢, zach cp

    编辑: 根据托马斯的建议,我发布了ipython mailing list并得到了一些关于这个想法的可行性的反馈。简而言之 - 有一些技术上的困难使得这个想法不太适合原始想法。对于您想要生成markdown -cells和相应图像/表的重复报告,通过ipython内核/浏览器工作比直接使用像Jinja这样的模板系统生成报告要复杂得多。

8 个答案:

答案 0 :(得分:15)

Fernando Perez here的笔记本要点演示了如何以编程方式创建新单元格。请注意,您也可以传入元数据,因此,如果您要生成报告并希望将笔记本转换为幻灯片,则可以轻松指明该单元格应该是幻灯片,子幻灯片,片段等。 / p>

你可以添加任何类型的单元格,所以你想要的东西现在很简单(虽然问题被提出时可能不是这样!)。例如,类似这样的(未经测试的代码)应该有效:

from IPython.nbformat import current as nbf

nb = nbf.new_notebook()

cells = []

for var in my_list:
    # Assume make_image() saves an image to file and returns the filename
    image_file = make_image(var)
    text = "Variable: %s\n![image](%s)" % (var, image_file)
    cell = nbf.new_text_cell('markdown', text)
    cells.append(cell)

nb['worksheets'].append(nbf.new_worksheet(cells=cells))

with open('my_notebook.ipynb', 'w') as f:
        nbf.write(nb, f, 'ipynb')

答案 1 :(得分:8)

我不会判断这是否是一个好主意,但如果你在笔记本中调用get_ipython().set_next_input(s),它将创建一个字符串为s的新单元格。这就是IPython内部用于%load%recall命令的内容。

答案 2 :(得分:4)

请注意,Tal接受的答案有点弃用,并且不得不弃用:在ipython v3中,您可以(/应该)直接导入nbformat,然后您需要指定您想要的笔记本版本创建

所以,

from IPython.nbformat import current as nbf

成为

from nbformat import current as nbf

变为

from nbformat import v4 as nbf

然而,在最终版本中,兼容性中断,因为write方法位于父模块nbformat中,其中Fernando Perez使用的所有其他方法都是在v4模块中,虽然其中一些名称不同(例如new_text_cell('markdown', source)变为new_markdown_cell(source))。

Here是v3做事方式的一个示例:请参阅generate_examples.py代码和plotstyles.ipynb输出。在撰写本文时,IPython 4是如此新颖,以至于使用网络界面并点击“新笔记本”#39;仍然生产v3笔记本。

答案 3 :(得分:2)

使用魔法可以是另一种解决方案。例如

get_ipython().run_cell_magic(u'HTML', u'', u'<font color=red>heffffo</font>')

现在您可以在单元格中以编程方式生成HTML,您可以根据需要以任何方式进行格式化。当然支持图像。如果您想重复生成多个单元格的输出,只需将上面的多个字符串作为占位符即可。

P.S。我曾经有过这种需要并且达到了这个主题。我想在那时渲染一个表(不是列表和元组的ascii输出)。后来我发现pandas.DataFrame非常适合我的工作。它会自动生成HTML格式的表格。

答案 4 :(得分:0)

下面是函数的代码,它将加载文件的内容并将其插入笔记本的下一个单元格中:

from IPython.display import display_javascript

def make_cell(s):
   text = s.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
   text2 = """var t_cell = IPython.notebook.get_selected_cell()
   t_cell.set_text('{}');
   var t_index = IPython.notebook.get_cells().indexOf(t_cell);
   IPython.notebook.to_code(t_index);
   IPython.notebook.get_cell(t_index).render();""".format(text)
   display_javascript(text2, raw=True)

def insert_file(filename):
   with open(filename, 'r') as content_file:
       content = content_file.read()
   make_cell(content)

查看详情in my blog.

答案 5 :(得分:0)

在Jupyter笔记本中运行:

!pip install p2j

然后,使用命令行转到文件所在的相应目录并执行:

python p2j <myfile.py> -t <myfile.ipynb> 

答案 6 :(得分:0)

使用命令行转到myfile.py文件所在的目录 并执行(示例): C:\ MyDir \ pip安装p2j

然后执行: C:\ MyDir \ p2j myfile.py -t myfile.ipynb

答案 7 :(得分:0)

作为对Tal's answer aboveupdates from Chris Barnes的轻微更新,并对nbformat docs进行了一些挖掘,以下内容对我有用:

import nbformat
from nbformat import v4 as nbf

nb = nbf.new_notebook()

cells = [
    nbf.new_code_cell(f"""print("Doing the thing: {i}")""")
    for i in range(10)
]

nb.cells.extend(cells)

with open('generated_notebook.ipynb', 'w') as f:
    nbformat.write(nb, f)

然后,您可以在需要的地方启动新的人造笔记本并剪切粘贴粘贴的单元格。

这不太可能是执行任何操作的最佳方法,但它作为肮脏的hack很有用。 ?

此功能适用于以下版本:

Package              Version
-------------------- ----------
ipykernel            5.3.0
ipython              7.15.0
jupyter              1.0.0
jupyter-client       6.1.3
jupyter-console      6.1.0
jupyter-core         4.6.3
nbconvert            5.6.1
nbformat             5.0.7
notebook             6.0.3
...