如何在IPython Notebook中隐藏一个特定的单元格(输入或输出)?

63
有没有办法在IPython笔记本中选择性隐藏一个特定的输入或输出单元格?
我只能找到以下代码来显示/隐藏所有输入单元格。

http://blog.nextgenetics.net/?e=102

但是如果我只想隐藏笔记本的第一个输入单元格怎么办?


似乎没有简单的方法?我认为这很有用,因为有时您确实想隐藏一些太长或与上下文无关的单元格。 - Pan Yan
4
为了回答2018年的用户问题,您可以将工具更改为Jupyter Lab。在单元格(包括代码和输出)左侧会出现一个悬停工具,点击该工具将折叠该单元格,但不会更改原有意思。 - Lelouch Lamperouge
这段代码添加了一个按钮,用于隐藏具有名为“hideable”的标签的单元格(需要nbconvert 5.6.1):https://gitlab.tetras-libre.fr/tetras-libre/jupyter/nbviewer/snippets/6 - daxid
你好。我一直在寻找这个查询,但一直没有找到合适的答案来隐藏笔记本中的单元格,特别是当我们加载.ipynb文件时。你有找到如何做到这一点吗?还是你的查询与我的不同? - Meet
2
对我来说,有超过数百个单元格。其中一些需要显示代码,而其他单元格则不需要显示代码。我希望“不需要显示代码”的单元格在打开ipynb文件时立即隐藏。或者在打开后运行一个单元格之后隐藏。此外,我不希望观众看到我运行了一个单元格来隐藏其他单元格,因此本页的答案并不适用。有什么办法可以做到这一点吗? - Meet
13个回答

72

现在,nbconvert (自5.3.0版本起)使用标签来实现此功能。

以下是一个示例,演示如何从输出中删除特定的单元格。使用此笔记本。该示例包含三个单元格:一个markdown单元格,一个将被隐藏的代码单元格和一个不会被隐藏的代码单元格。

  1. 在笔记本或JupyterLab中内置的标签编辑器中,将remove_cell标签添加到您想要隐藏的任何单元格中(具体名称无关紧要)
  2. 使用nbconvert进行转换
jupyter nbconvert nbconvert-example.ipynb --TagRemovePreprocessor.remove_cell_tags='{"remove_cell"}'

任何带有remove_cell标签的单元格将从输出中删除。

hidden

除了整个单元格外,您还可以仅筛选输入或输出:

  • TagRemovePreprocessor.remove_input_tags
  • TagRemovePreprocessor.remove_single_output_tags
  • TagRemovePreprocessor.remove_all_outputs_tags

5
谢谢。但它只适用于HTML输出吗?如果使用jupyter nbconvert --to notebook --inplace ...,似乎在生成的.ipynb文件中没有任何隐藏的内容。 - qAp
6
我必须在 Windows 上更改引号;例如:jupyter nbconvert nbconvert-example.ipynb --TagRemovePreprocessor.remove_cell_tags="{'a', 'b'}" - Ninjakannon
2
我不得不将花括号({})更改为方括号([])(即使用 list),才能使其正常工作,即--TagRemovePreprocessor.remove_cell_tags='["remove_cell"]' - craymichael
1
请注意,在Jupyter Lab中,要添加标签,您需要将以下内容添加到单元格元数据中:tags: ["remove_cell"] - ostrokach
1
当导出为PDF时,似乎无法正常工作。 - AlvaroP
显示剩余2条评论

48

这是 Mathmagician 答案的扩展,使您能够:

  • 切换仅一个单元格(JS 函数名称具有随机后缀,因此如果使用超过一次,则不会与其他用法冲突
  • 切换当前单元格下方的单元格 - 这在 RISE 演示中非常方便,您可能希望显示代码,然后将其隐藏以显示其输出

toggle 示例

您需要首先运行以下代码来定义 hide_toggle 函数:

from IPython.display import HTML
import random

def hide_toggle(for_next=False):
    this_cell = """$('div.cell.code_cell.rendered.selected')"""
    next_cell = this_cell + '.next()'

    toggle_text = 'Toggle show/hide'  # text shown on toggle link
    target_cell = this_cell  # target cell to control with toggle
    js_hide_current = ''  # bit of JS to permanently hide code in current cell (only when toggling next cell)

    if for_next:
        target_cell = next_cell
        toggle_text += ' next cell'
        js_hide_current = this_cell + '.find("div.input").hide();'

    js_f_name = 'code_toggle_{}'.format(str(random.randint(1,2**64)))

    html = """
        <script>
            function {f_name}() {{
                {cell_selector}.find('div.input').toggle();
            }}

            {js_hide_current}
        </script>

        <a href="javascript:{f_name}()">{toggle_text}</a>
    """.format(
        f_name=js_f_name,
        cell_selector=target_cell,
        js_hide_current=js_hide_current, 
        toggle_text=toggle_text
    )

    return HTML(html)

然后在单元格中像这样使用它:

x = 1
y = 2
print('Result is {} + {}'.format(x, y))

hide_toggle()

或者这样做(如果您想切换下一个单元格)

hide_toggle(for_next=True)

2
好的,谢谢。我现在已经将它更改为向后兼容的字符串格式化方式了。 - Ferrard
@Ferrard,感谢您提供RISE演示文稿的参考 - 我之前不知道有这样的选项。 - garej
1
这太棒了!谢谢。 - Sandalaphon
3
请注意,此方法仅适用于Jupyter Notebook。而且无法在Jupyter Lab中使用或导出为html。 - Nor.Z
如果有人需要隐藏前一个单元格,只需在上面的代码中将 .next() 替换为 .prev()。 - charmd
显示剩余3条评论

15

以下是一种通过编辑单元格元数据来隐藏HTML/PDF输出中的单元格的方法。

我使用的版本是:

$ jupyter notebook --version

4.1.0

$ jupyter nbconvert --version

4.2.0

  1. 按照Github上的安装说明下载ipython笔记本扩展模板:pip install https://github.com/ipython-contrib/IPython-notebook-extensions/tarball/master
  2. 运行jupyter notebook
  3. 转到localhost:8888/nbextensions(或您开始的任何端口),然后激活Printview
  4. 返回localhost:8888/tree,创建一个新的笔记本并进入其中
  5. 创建一个代码单元格,并在其中编写一些能产生输出的代码,例如print("You can see me") #but not me
  6. 转到View > Cell Toolbar > Edit Metadata
  7. 单击现在显示在单元格右上方的编辑元数据按钮
  8. 添加'hide_input':True到json中,例如我的json如下:{ "collapsed": false, "hide_input": true, "trusted": true }
  9. 保存笔记本
  10. 回到终端并执行jupyter nbconvert --to pdf --template printviewlatex.tplx notebookname.ipynb(如果您的笔记本名为notebookname.ipynb.ipynb

现在您应该在目录中拥有一个名为notebookname.pdf的文档。希望里面只有文本You can see me ... 手指交叉。


3
好的细节。不好的流程:太过繁琐。难道我们不能在单元格本身中加入注释吗?这个流程很难处理。 - WestCoastProjects

12

你隐藏所有输入单元的解决方案可以更改为只影响一个单元。

'div.input' 更改为 'div.cell.code_cell.rendered.selected div.input'

HTML('''<script>
code_show=true; 
function code_toggle() {
    if (code_show){
        $('div.cell.code_cell.rendered.selected div.input').hide();
    } else {
        $('div.cell.code_cell.rendered.selected div.input').show();
    }
    code_show = !code_show
} 

$( document ).ready(code_toggle);
</script>

To show/hide this cell's raw code input, click <a href="javascript:code_toggle()">here</a>.''')

当您单击单元格输出上的“点击此处”提示时,该单元格将成为“选定”单元格,因此变得隐藏。

如果您的 JavaScript 代码在<script></script>标签中执行切换操作,可以使用以下一行代码:

$( document ).ready(code_toggle);

如果输入单元格执行时,该块将自动被隐藏(默认情况下)。

请注意,如果您想默认隐藏单元格输入,则必须使用 运行单元格Ctrl+Return)选项运行该单元格,而不是使用 运行并选择/插入以下单元格 选项。否则,JavaScript 将在移动“选定”标签到下一个单元格之前提示,这可能会导致隐藏没有其输出中的“点击此处”切换链接的单元格。在这种情况下,您需要 检查 单元格并浏览相关标记,将 display='none'; 更改为 display='block';

请注意,这必须放置在单元格中任何代码的末尾,并且您需要在执行此代码之前从 IPython.display 中导入 HTML。您可以通过执行以下操作来实现:

from IPython.display import HTML

3
我正在使用这个解决方案。我已将其隐藏,但是当我导出为HTML时,代码会显示出来。如何在不显示特定单元格的情况下导出笔记本? - nahusznaj
尝试了很多方法,但只有这个真正有效。谢谢! - Uncle Meh

9

好的,尝试了这里提供的答案都没有成功。我发现了kirbs的这个扩展。Hide_code nbextension 它运行得非常好。但是建议您执行以下操作:

首先,请确保您已更新jupyter、nbconverter、nbconverter扩展和jupyter serverextension。如果您已经这样做了,那么可以在anaconda提示符(以管理员权限打开)中执行以下操作:

  1. pip install hide_code
  2. jupyter nbextension install --py hide_code
  3. jupyter nbextension enable --py hide_code
  4. jupyter serverextension enable --py hide_code

最后,如果您使用anaconda分发来打开笔记本,则还要使用以下命令:

  1. jupyter nbextension install --sys-prefix --py hide_code
  2. jupyter nbextension enable --sys-prefix --py hide_code
  3. jupyter serverextension enable --sys-prefix --py hide_code

如果执行这些命令时没有错误,那么您将能够在工具栏中看到并使用隐藏代码选项,如下所示:

隐藏代码工具栏

完成了!如果您使用导出按钮,那么就大功告成了!

导出按钮

祝您好运!


7

关于输出,在Jupiter笔记本中,工具栏上也有一个选项:

enter image description here

您可以使用Clear清除输出,也可以使用Toggle隐藏它。在两种情况下,不会删除单元格内计算的任何变量。


清除输出并不等同于省略或隐藏输出。它只是清除输出单元格,直到再次运行输入单元格。这并不是一个解决方案。 - Benjamin R

6

如果有人发现排除所有代码单元格有帮助(这不是本文所要求的),您可以添加此标志:nbconvert --TemplateExporter.exclude_code_cell=True


--TemplateExporter.exclude_input=True也很有用! - rickhg12hs
这也不包括图像。有没有办法保留绘制的图像? - Abay Bektursun
@AbayBektursun 这个选项 exclude_code_cell 不应该排除输出单元格中的任何图像。 - shouldsee

3

更新:似乎已合并到https://github.com/ipython-contrib/IPython-notebook-extensions/。 - Hans

3

使用该代码:

# @hidden
from IPython.display import HTML
HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('.cm-comment:contains(@hidden)').closest('div.input').hide();
 } else {
 $('.cm-comment:contains(@hidden)').closest('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
The raw code for this IPython notebook is by default hidden for easier reading.
To toggle on/off the raw code, click <a href="javascript:code_toggle()">here</a>.''')

本文内容来自这里,经过本人修改。

你可以用注释隐藏代码行:

# @hidden

2

@Mathmagician的解决方案几乎完美,但有许多副作用。

更正确的方式应该是:

from IPython.core.display import display, HTML
toggle_code_str = '''
<form action="javascript:code_toggle()"><input type="submit" id="toggleButton" value="Toggle Code"></form>
'''

toggle_code_prepare_str = '''
    <script>
    function code_toggle() {
        if ($('div.cell.code_cell.rendered.selected div.input').css('display')!='none'){
            $('div.cell.code_cell.rendered.selected div.input').hide();
        } else {
            $('div.cell.code_cell.rendered.selected div.input').show();
        }
    }
    </script>

'''

display(HTML(toggle_code_prepare_str + toggle_code_str))

def toggle_code():
    display(HTML(toggle_code_str))

toggle_code 函数可以放置在其他代码之前的某个代码单元格中,因此,如果该单元格中的代码执行速度较慢,则不会产生副作用。同时,它还解决了“运行单元格并选择/插入以下”的问题。

它会添加切换按钮,但初始状态无法进行管理。


2
当我运行这段代码时,如何使默认视图实际上将代码切换关闭? - newbie
这在某种程度上是有效的。但是,如果我们这样做并且意外或故意刷新(重新加载)笔记本窗口(或浏览器窗口),那么切换按钮下一次将刷新浏览器窗口而不是切换,除非我们再次运行每个切换函数调用。我不知道是什么原因导致了这种情况。 - Meet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接