如何隐藏代码从细胞在 ipython 笔记本可视化与 nbview?

我有一个 ipython/jupyter 笔记本,我使用 NBview 可视化。

我如何隐藏所有的代码从笔记本呈现的 NBview,以便只有输出的代码(如图和表)和标记单元格显示?

215346 次浏览
from IPython.display import HTML


HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')

最新的 IPython 笔记本版本不再允许在标记单元格中执行 javascript,所以添加一个带有以下 javascript 代码的新标记单元格将不再能够隐藏代码单元格(参见 这个链接)

修改 ~/. ipython/profile _ default/static/custom.js 如下:

code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}


$([IPython.events]).on("app_initialized.NotebookApp", function () {
$("#view_menu").append("<li id=\"toggle_toolbar\" title=\"Show/Hide code cells\"><a href=\"javascript:code_toggle()\">Toggle Code Cells</a></li>")
});

以下是 P3trus提出的另一种解决方案:

$([IPython.events]).on('notebook_loaded.Notebook', function(){
IPython.toolbar.add_buttons_group([
{
'label'   : 'toggle input cells',
'icon'    : 'icon-refresh',
'callback': function(){$('.input').slideToggle()}
}
]);
});
< p > 如 P3trus所述: ”[它]在 ipython 笔记本工具栏上添加了一个按钮来隐藏/显示输入代码单元格。要使用它,必须将 custom.js 文件放在 .ipython_<profile name>/static/custom/文件夹中,其中 是正在使用的 ipython 配置文件。”译注:

我自己的评论: 我验证了这个解决方案,它可以在 iPython3.1.0中工作。

我编写了一些代码来实现这一点,并添加了一个按钮来切换代码的可见性。

下面的代码单元格放在笔记本电脑的顶部:

from IPython.display import display
from IPython.display import HTML
import IPython.core.display as di # Example: di.display_html('<h3>%s:</h3>' % str, raw=True)


# This line will hide code by default when the notebook is exported as HTML
di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)


# This line will add a button to toggle visibility of code blocks, for use with the HTML export version
di.display_html('''<button onclick="jQuery('.input_area').toggle(); jQuery('.prompt').toggle();">Toggle code</button>''', raw=True)

你可以看到 这是 NBViewer 中的一个例子

这在 Jupyter 的 Markdown 单元格中会有一些有趣的行为,但是在笔记本的 HTML 导出版本中可以很好地工作。

我会使用来自 延长线(https://github.com/ipython-contrib/IPython-notebook-extensions)的 hide_input_all,方法如下:

  1. 找出 IPython 目录的位置:

    from IPython.utils.path import get_ipython_dir
    print get_ipython_dir()
    
  2. Download nbextensions and move it to the IPython directory.

  3. Edit your custom.js file somewhere in the IPython directory (mine was in profile_default/static/custom) to be similar to the custom.example.js in the nbextensions directory.

  4. Add this line to custom.js:

    IPython.load_extensions('usability/hide_input_all')
    

IPython Notebook will now have a button to toggle code cells, no matter the workbook.

为了更好地显示打印文档或报告,我们还需要删除按钮,以及显示或隐藏某些代码块的能力。下面是我使用的方法(只需将其复制粘贴到第一个单元格) :

# This is a cell to hide code snippets from displaying
# This must be at first cell!


from IPython.display import HTML


hide_me = ''
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show) {
$('div.input').each(function(id) {
el = $(this).find('.cm-variable:first');
if (id == 0 || el.text() == 'hide_me') {
$(this).hide();
}
});
$('div.output_prompt').css('opacity', 0);
} else {
$('div.input').each(function(id) {
$(this).show();
});
$('div.output_prompt').css('opacity', 1);
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input style="opacity:0" type="submit" value="Click here to toggle on/off the raw code."></form>''')

然后在你们的下一个牢房里:

hide_me
print "this code will be hidden"

还有

print "this code will be shown"

(纸张)以 HTML 格式列印或储存

对于那些希望打印纸输出上述答案本身似乎没有给出一个很好的最终输出。然而,使用@Max Masnick 的代码并添加以下内容可以将其打印在完整的 A4页面上。

from IPython.display import display
from IPython.display import HTML
import IPython.core.display as di


di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)


CSS = """#notebook div.output_subarea {max-width:100%;}""" #changes output_subarea width to 100% (from 100% - 14ex)
HTML('<style>{}</style>'.format(CSS))

缩进的原因是 Max Masnick 删除的提示部分意味着所有东西在输出时都向左移动。然而,这对限制为 max-width:100%-14ex;的输出的最大宽度没有任何影响。这将 output _ subarea 的最大宽度更改为 max-width:100%;

这将呈现一个 IPython 笔记本输出。但是,您将注意到能够查看输入代码。您可以复制一个笔记本,然后添加这个代码,如果需要共享的人谁不需要查看代码。

from IPython.display import HTML


HTML('''<script> $('div .input').hide()''')

接受的解决办法也适用于 Julia Jupiter/IJulia,但作了以下修改:

display("text/html", """<script>
code_show=true;
function code_toggle() {
if (code_show){
\$("div.input").hide();
} else {
\$("div.input").show();
}
code_show = !code_show
}
\$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>""")

特别注意:

  • 使用 display函数
  • 转义 $符号(否则视为变量)

有了上面所有的解决方案,即使你隐藏了代码,你仍然会得到高于你的数字的 [<matplotlib.lines.Line2D at 0x128514278>]垃圾,你可能不想要。

我认为,如果你真的想删除输入,而不仅仅是隐藏它 最干净的解决方案是将你的图片保存到隐藏单元格的磁盘上,然后使用例如 ![Caption](figure1.png)将图片包含在 Markdown 单元格中。译注:
提供了一个很好的解决方案 给你适用于导出为 HTML 的笔记本电脑。该网站甚至在这里链接回到这个 SO 职位,但我没有看到克里斯的解决方案在这里!(克里斯,你在哪里?)译注:

这个解决方案基本上与我们接受的解决方案相同,但是它的优点是在导出的 HTML 中隐藏了切换代码本身。我还喜欢这种方法避免了对 IPythonHTML 函数的需要。

要实现此解决方案,请在笔记本顶部的“原始 NBConvert”单元格中添加以下代码:

<script>
function code_toggle() {
if (code_shown){
$('div.input').hide('500');
$('#toggleButton').val('Show Code')
} else {
$('div.input').show('500');
$('#toggleButton').val('Hide Code')
}
code_shown = !code_shown
}


$( document ).ready(function(){
code_shown=false;
$('div.input').hide()
});
</script>
<form action="javascript:code_toggle()">
<input type="submit" id="toggleButton" value="Show Code">
</form>

然后简单地将笔记本导出到 HTML。在笔记本的顶部将有一个切换按钮来显示或隐藏代码。

Chris 还提供了一个 给你示例。

我可以证实这在木星5.0版本中是可行的

< p > 更新: 显示/隐藏 div.prompt元素以及 div.input元素也很方便。这将删除 In [##]:Out: [##]文本,并减少左侧的边距。译注:

给你是一篇很好的文章(和@Ken 发表的文章一样) ,介绍了如何为演示而润色 Jpuyter (新的 IPython)笔记本。有无数种方法可以使用 JS、 HTML 和 CSS 来扩展 Jupiter,包括从 javascript 与笔记本的 python 内核进行通信的能力。对于 %%HTML%%javascript,有一些神奇的修饰器,所以你可以在单元格中自己做这样的事情:

%%HTML
<script>
function code_toggle() {
if (code_shown){
$('div.input').hide('500');
$('#toggleButton').val('Show Code')
} else {
$('div.input').show('500');
$('#toggleButton').val('Hide Code')
}
code_shown = !code_shown
}


$( document ).ready(function(){
code_shown=false;
$('div.input').hide()
});
</script>
<form action="javascript:code_toggle()"><input type="submit" id="toggleButton" value="Show Code"></form>

我也可以保证克里斯的方法在木星4.X.X 上有效。

从版本 5.2.1开始,现在可以直接从 nb 转换实现这一点: 内容可以使用内置的 模板输出程序排除选项进行过滤。例如:

jupyter nbconvert --to pdf --TemplateExporter.exclude_input=True my_notebook.ipynb

将排除“输入代码”单元格(即代码本身)。类似的选择用于排除提示符、标记单元格或输出,或输入和输出。

(无论输出格式如何,这些选项都应该有效。)

这可以通过使用 IPythonToggleButton小部件和一点 JavaScript 来完成。应将下列代码放入文档顶部的代码单元格中:

import ipywidgets as widgets
from IPython.display import display, HTML


javascript_functions = {False: "hide()", True: "show()"}
button_descriptions  = {False: "Show code", True: "Hide code"}




def toggle_code(state):


"""
Toggles the JavaScript show()/hide() function on the div.input element.
"""


output_string = "<script>$(\"div.input\").{}</script>"
output_args   = (javascript_functions[state],)
output        = output_string.format(*output_args)


display(HTML(output))




def button_action(value):


"""
Calls the toggle_code function and updates the button description.
"""


state = value.new


toggle_code(state)


value.owner.description = button_descriptions[state]




state = False
toggle_code(state)


button = widgets.ToggleButton(state, description = button_descriptions[state])
button.observe(button_action, "value")


display(button)

这将创建以下按钮来切换显示/隐藏 Jupiter 笔记本的代码,默认为“ hide”状态:

Hide code state

当设置为“显示”状态时,你可以看到木星笔记本的代码:

Show code state

顺便说一句,虽然这些代码大部分应该放在笔记本电脑的开头,但是切换按钮的位置是可选的。就我个人而言,我更喜欢把它放在文档的底部。为此,只需将 display(button)行移动到页面底部的一个单独的代码单元格:

Relocated toggle button

将 cell 转换为 Markdown 并使用 HTML5<details>标记,如 joyrexus的示例所示:

https://gist.github.com/joyrexus/16041f2426450e73f5df9391f7f7ae5f

## collapsible markdown?


<details><summary>CLICK ME</summary>
<p>


#### yes, even hidden code blocks!


```python
print("hello world!")
```


</p>
</details>

使用浏览器控制台的非常简单的解决方案。将其复制到浏览器控制台,然后按下回车键:

$("div.input div.prompt_container").on('click', function(e){
$($(e.target).closest('div.input').find('div.input_area')[0]).toggle();
});

insert script into browser console

然后,通过单击单元格输入的数量来切换单元格的代码。

cell number

jupyter nbconvert testing.ipynb --to html --no-input
jupyter nbconvert yourNotebook.ipynb --no-input --no-prompt
< p > jupyter nbconvert yourNotebook.ipynb 这部分代码将采用 jupyter 笔记本的乳胶文件格式,并将其转换为 html

--no-input这就像我们在转换过程中说的一个参数,它不会添加任何输入: 这里输入到单元格的是代码。.所以我们把它藏起来

--no-prompt在这里我们还说,在转换期间不显示任何提示形式的代码,如错误或警告,在最终的 HTML 文件) ,这样的 HTML 将只有文本和代码输出的形式报告!..

希望对你有所帮助:)

简单的编程解决方案导出笔记本到 HTML 没有代码单元格(仅输出) : 添加这个代码在一个代码单元格的笔记本 my_notebook.ipynb你想要导出:

import codecs
import nbformat
import time
from IPython.display import Javascript
from nbconvert import HTMLExporter


def save_notebook():
display(
Javascript("IPython.notebook.save_notebook()"),
include=['application/javascript']
)


def html_export_output_only(read_file, output_file):
exporter = HTMLExporter()
exporter.exclude_input = True
output_notebook = nbformat.read(read_file, as_version=nbformat.NO_CONVERT)
output, resources = exporter.from_notebook_node(output_notebook)
codecs.open(output_file, 'w', encoding='utf-8').write(output)




# save notebook to html
save_notebook()
time.sleep(1)
output_file = 'my_notebook_export.html'
html_export_output_only("my_notebook.ipynb", output_file)


很多时候,在编写长代码时,我们需要隐藏代码的某些部分。

示例:-只要点击“代码显示/隐藏”,我们可以隐藏3行代码。

enter image description here

下面是一个函数,你需要定义它来部分地隐藏一些代码,然后当你想隐藏一些代码的时候调用它:

from IPython.display import HTML


def hide_toggle(for_next=False):
this_cell = """$('div.cell.code_cell.rendered.selected')""" ; next_cell = this_cell + '.next()';
toggle_text = 'Code show/hide'  # text shown on toggle link
target_cell = this_cell ;  js_hide_current = ''


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)

一旦我们准备好了函数定义,我们的下一个任务就非常简单了。我们只需要调用函数来隐藏/显示代码。

print("Function for hiding the cell")
hide_toggle()

在编辑界面和导出的 html 中显示/隐藏 Jupiter Notebook 代码单元格的脚本

只要把这段代码放在第一个单元格中并运行它:

%%HTML
<script>
function luc21893_refresh_cell(cell) {
if( cell.luc21893 ) return;
cell.luc21893 = true;
console.debug('New code cell found...' );
        

var div = document.createElement('DIV');
cell.parentNode.insertBefore( div, cell.nextSibling );
div.style.textAlign = 'right';
var a = document.createElement('A');
div.appendChild(a);
a.href='#'
a.luc21893 = cell;
a.setAttribute( 'onclick', "luc21893_toggle(this); return false;" );


cell.style.visibility='hidden';
cell.style.position='absolute';
a.innerHTML = '[show code]';
                

}
function luc21893_refresh() {
if( document.querySelector('.code_cell .input') == null ) {
// it apeears that I am in a exported html
// hide this code
var codeCells = document.querySelectorAll('.jp-InputArea')
codeCells[0].style.visibility = 'hidden';
codeCells[0].style.position = 'absolute';
for( var i = 1; i < codeCells.length; i++ ) {
luc21893_refresh_cell(codeCells[i].parentNode)
}
window.onload = luc21893_refresh;
}
else {
// it apperas that I am in a jupyter editor
var codeCells = document.querySelectorAll('.code_cell .input')
for( var i = 0; i < codeCells.length; i++ ) {
luc21893_refresh_cell(codeCells[i])
}
window.setTimeout( luc21893_refresh, 1000 )
}
}
    

function luc21893_toggle(a) {
if( a.luc21893.style.visibility=='hidden' ) {
a.luc21893.style.visibility='visible';
a.luc21893.style.position='';
a.innerHTML = '[hide code]';
}
else {
a.luc21893.style.visibility='hidden';
a.luc21893.style.position='absolute';
a.innerHTML = '[show code]';
}
}
    

luc21893_refresh()
</script>

编辑器中的示例

Example in editor

导出的 HTML 示例

Example Export

我在使用 @ 苛刻回答时遇到的问题是,它不会折叠隐藏的单元格,在它们的位置留下一个看起来有点丑陋的空白(我使用的是 IPython 7.30.1和 nbConver6.3.0) [例子]

这是因为 input Div位于包装器内部,所以当 input被隐藏时,包装器不会崩溃。(如果没有没有输出的代码单元格,这对您来说不是问题,因为当 input被隐藏时,它将折叠 在里面包装器,因此 output Div将占用所有的空间)。

你可以这样做(只需把它放在一个单元格中) :

from IPython.display import HTML


HTML('''<script>
var code_show = true;
function code_toggle() {
if (code_show) {
$( 'div[class*="code_cell"]:not(:has(.output))' ).hide();
$( 'div.input' ).hide();
} else {
$( 'div[class*="code_cell"]:not(:has(.output))' ).show();
$( 'div.input' ).show();
}
code_show = !code_show;
}
$( document ).ready(code_toggle);
</script>
To toggle on/off the raw code, click <a>href="javascript:code_toggle()">here</a>.''')