Como ocultar o código das células no notebook ipython visualizado com o nbviewer?

147

Eu tenho um notebook ipython / jupyter que visualizo usando o NBviewer.

Como ocultar todo o código do notebook renderizado pelo NBviewer, para que apenas a saída do código (por exemplo, gráficos e tabelas) e as células de marcação sejam exibidas?

lucacerona
fonte
10
Ainda não existe um botão para isso na interface do usuário padrão (fevereiro de 2016). IMHO isso é realmente muito chato. Esta está na lista de recursos que serão implementados: github.com/jupyter/notebook/issues/534 Isso é ótimo. Estou ansioso por isso.
estocástica
1
Por favor, dê uma olhada abaixo na resposta de Noah. Com a inclusão de um TemplateExporter, esse problema é resolvido independentemente do formato de saída. No momento da redação, a resposta de Noé substitui a resposta dura (que era uma boa solução antes do TemplateExporter).
Michaela

Respostas:

235
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>''')
harshil
fonte
5
Trabalhou para mim no iPython 3.1.0 se eu colocá-lo dentro da célula de código. Substituí o <form action ... > ... </form>com HTML simples comoThe 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>.
akhmed
Obrigado pela sua resposta! Veja minha resposta se você precisar ocultar o botão e a capacidade de ocultar ou mostrar determinados blocos de código como o Rstudio.
Jaycode
3
Obrigado, isso funciona e com 'salvar em html' também. Recomende colocar isso em sua própria célula na parte superior do notebook.
Vivek Gani
se você adicionar o atributo accesskey = "h" para o elemento de entrada que você pode então fazer o show hide com alt-h (em cromo pelo menos)
frankc
7
Como você mudaria isso para que ele nem mostrasse o botão, apenas ocultasse o código?
Harlekuin
79

Agora isso é possível diretamente do nbconvert a partir da versão 5.2.1 : o conteúdo pode ser filtrado usando as opções de exclusão do exportador de modelo interno . Por exemplo:

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

excluirá as células "código de entrada", ou seja, o próprio código. Existem opções semelhantes para excluir prompts, células de marcação ou saídas, ou ambas, entradas e saídas.

(Essas opções devem funcionar independentemente do formato de saída.)

Noé
fonte
3
esta é a melhor resposta
skurp
Onde a exportação .pdf é salva por padrão?
MyopicVisage 20/02/19
A mesma pasta do notebook .ipython. Use o argumento '--output NotebookNoCode' para renomear o arquivo.
MyopicVisage
Isso deveria funcionar no notebook?
Lcrmorin
@were_cat não, este é um comando shell usado para exportar o arquivo .ipynb notebook; Neste exemplo, ele é convertido em pdf
Noah
19

Eu usaria a hide_input_allpartir de nbextensions ( https://github.com/ipython-contrib/IPython-notebook-extensions ). Aqui está como:

  1. Descubra onde está o seu diretório IPython:

    from IPython.utils.path import get_ipython_dir
    print get_ipython_dir()
    
  2. Faça o download de nbextensions e mova-o para o diretório IPython.

  3. Edite seu arquivo custom.js em algum lugar do diretório IPython (o meu estava em profile_default / static / custom ) para ser semelhante ao custom.example.js no diretório nbextensions .

  4. Adicione esta linha ao custom.js :

    IPython.load_extensions('usability/hide_input_all')

O IPython Notebook agora terá um botão para alternar as células de código, independentemente da pasta de trabalho.

user394430
fonte
6
Apenas tentei isso - parece ajudar a ocultar as células de código durante a edição de um notebook, embora ao salvar o notebook em html (por exemplo, renderizar para o nbviewer) as células de código ainda apareçam.
Vivek Gani
@VivekGani apenas uma nota rápida que você pode manter as células ocultas escondidos no HTML exportado usando o modelo fornecido com o mesmo repo, consulte a página doc relevante (também, ver esta questão relevante )
GLS
15

A versão mais recente do notebook IPython não permite mais a execução de javascript nas células de remarcação; portanto, adicionar uma nova célula de remarcação com o seguinte código javascript não funcionará mais para ocultar suas células de código (consulte este link )

Altere ~ / .ipython / profile_default / static / custom / custom.js conforme abaixo:

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>")
});
Yangshun Tay
fonte
exatamente o que estou procurando!
lucky1928
Estranhamente, essa solução não funcionou para mim, pois o menu de exibição do iPython permanece inalterado. (iPython 3.1.0) Sua solução me inspirou a procurar mais e encontrar uma solução muito semelhante pelo p3trus que adicionou um botão ao invés de um menu e funcionou.
akhmed
1
@akhmed Talvez você possa consultar stackoverflow.com/a/29851084/1914781 . É uma pergunta diferente, mas útil para você!
12

Eu escrevi um código que realiza isso e adiciona um botão para alternar a visibilidade do código.

O seguinte está em uma célula de código na parte superior de um notebook:

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)

Você pode ver um exemplo de como isso fica no NBviewer aqui .

Atualização: Isso terá algum comportamento engraçado com as células Markdown no Jupyter, mas funciona bem na versão de exportação HTML do notebook.

Max Masnick
fonte
3
Isso funciona nas células de código, mas se você tiver células de remarcação, ele fará algo estranho. Ele mostra a remarcação como remarcação e, em seguida, mostra o mesmo conteúdo - mas formatado - abaixo.
23715 Scott Scott H
Acabei de descobrir que a única coisa errada é a especificação do nó. Em vez de '.input_area'e '.prompt', use 'div.input'e funciona como um encanto! Então, para recapitular, substitua jQuery("div.input").toggle();no lugar de jQuery('.input_area').toggle(); jQuery('.prompt').toggle();. @ Max Masnick, você poderia consertar sua resposta?
23715 Scott Scott H
Usando o "div.input" como a seleção do nó funciona, desde que você não interaja com as células de remarcação, mas eu descobri que se você interagir com as células de remarcação, poderá ter algum comportamento desagradável. Por exemplo, se você clicar duas vezes em uma célula de remarcação, ela ficará totalmente oculta. Então, como está, meu ajuste na solução de Max é bom para gerar HTML para compartilhar com outras pessoas, mas não para subsequentemente interagir demais com ele.
23715 Scott Scott H
Sim, então eu notei a mesma coisa que você fez com as células do Markdown sendo levantadas. Funciona bem na exportação de HTML, que é onde eu a uso. Vou editar a resposta para observar isso.
Max Masnick 24/07
1
Para remover as sobras de espaço à direita da remoção de ".prompt", basta adicionar esse código ao final do código acima. CSS = """#notebook div.output_subarea { max-width:100%;""" HTML('<style>{}</style>'.format(CSS)). Isso é muito útil para impressão.
Little Bobby Tables
9

Existe uma boa solução fornecida aqui que funciona bem para notebooks exportados para HTML. O site ainda tem links para este post da SO, mas não vejo a solução de Chris aqui! (Chris, onde você está?)

Essa é basicamente a mesma solução que a resposta aceita do harshil, mas tem a vantagem de ocultar o próprio código de alternância no HTML exportado. Também gosto que essa abordagem evite a necessidade da função HTML IPython.

Para implementar esta solução, adicione o seguinte código a uma célula 'Raw NBConvert' na parte superior do seu notebook:

<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>

Em seguida, basta exportar o notebook para HTML. Haverá um botão de alternância na parte superior do notebook para mostrar ou ocultar o código.

Chris também fornece um exemplo aqui .

Posso verificar se isso funciona no Jupyter 5.0.0

Atualização : Também é conveniente mostrar / ocultar os div.promptelementos junto com os div.inputelementos. Isso remove o In [##]:e Out: [##]texto e reduz as margens do lado esquerdo.

Ken
fonte
seria possível usar esse código para ocultar seletivamente saídas com o clique de um botão? IE $('div.output').next().hide('500');para ocultar a próxima saída? Eu tentei, mas não consigo fazer isso funcionar.
Brian Keith
9

Isso pode ser feito usando um ToggleButtonwidget IPython e um pouco de JavaScript. O código a seguir deve ser colocado em uma célula de código na parte superior do documento:

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)

Isso cria o seguinte botão para alternar entre mostrar / ocultar o código para o Jupyter Notebook, padronizado com o estado "ocultar":

Ocultar estado do código

Quando definido para o estado "show", você pode ver o código do Notebook Jupyter:

Mostrar estado do código

Além disso, embora muito desse código deva ser colocado no início do Notebook, o local do botão de alternância é opcional. Pessoalmente, prefiro mantê-lo na parte inferior do documento. Para fazer isso, basta mover a display(button)linha para uma célula de código separada na parte inferior da página:

Botão de alternância realocado

Erick Shepherd
fonte
7

Para uma melhor exibição com um documento impresso ou um relatório, também precisamos remover o botão e a capacidade de mostrar ou ocultar certos blocos de código. Aqui está o que eu uso (basta copiar e colar isso na sua primeira célula):

# 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>''')

Então, nas suas próximas células:

hide_me
print "this code will be hidden"

e

print "this code will be shown"
jaycode
fonte
Eu estou supondo que isso não funciona para as versões mais recentes / python 3?
Baxx
Funciona com o jupyter versão 4.3.0 com o Python versão 3.6.1.
Alma Rahat 23/08
Obrigado! É um prazer dizer que isso também funciona com o notebook Jupyter 5.3.1 . Estou usando o Python versão 3.6.1
Amitrajit Bose
4

Isso renderizará uma saída do notebook IPython. No entanto, você poderá visualizar o código de entrada. Você pode copiar um bloco de anotações e adicionar esse código, se necessário, para compartilhar com alguém que não precisa visualizá-lo.

from IPython.display import HTML

HTML('''<script> $('div .input').hide()''')
Chase Wright
fonte
1
@Rocketq use this - from IPython.display import HTML HTML('''<script> $('div.input').show()''')
fixxxer 12/09/18
4

Converta a célula em Markdown e use a <details>tag HTML5 como no exemplo 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>
Valentas
fonte
1

Aqui está outra solução sugerida pelo p3trus :

$([IPython.events]).on('notebook_loaded.Notebook', function(){
    IPython.toolbar.add_buttons_group([
        {
             'label'   : 'toggle input cells',
             'icon'    : 'icon-refresh', 
             'callback': function(){$('.input').slideToggle()}
        }
    ]);
});

Conforme descrito por p3trus : "[It] adiciona um botão à barra de ferramentas do notebook ipython para ocultar / mostrar a célula do código de entrada. Para usá-lo, você deve colocar o arquivo custom.js em sua .ipython_<profile name>/static/custom/pasta, onde é o perfil do ipython em uso. "

Meus próprios comentários: verifiquei esta solução e funciona com o iPython 3.1.0.

akhmed
fonte
1

A solução aceita também funciona em julia Jupyter / IJulia com as seguintes modificações:

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>""")

observe em particular:

  • use a displayfunção
  • escapar do $sinal (visto como uma variável)
gozzilli
fonte
Estou confuso sobre como fazer isso funcionar. É necessária uma declaração de importação e que tipo de caixa deve ser o bloco. Um cru ou uma caixa de código?
precisa
1

Aqui está um bom artigo (o mesmo que o @Ken postou) sobre como aperfeiçoar os notebooks Jpuyter (o novo IPython) para apresentação. Existem inúmeras maneiras de estender o Jupyter usando JS, HTML e CSS, incluindo a capacidade de se comunicar com o kernel python do notebook a partir de javascript. Existem decoradores mágicos para %%HTMLe, %%javascriptportanto, você pode fazer algo assim em uma célula sozinha:

%%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>

Também posso garantir que os métodos de Chris funcionam no jupyter 4.XX

ThisGuyCantEven
fonte
1

Solução muito fácil usando o console do navegador. Você copia isso no console do navegador e pressiona enter:

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

Inserir script no console do navegador

Em seguida, você alterna o código da célula simplesmente clicando no número de entrada da célula.

número do celular

Matěj M
fonte
0

(Papel) Imprimindo ou salvando como HTML

Para aqueles que desejam imprimir em papel, as respostas acima, por si só, parecem não fornecer uma boa saída final. No entanto, pegar o código de @Max Masnick e adicionar o seguinte permite imprimi-lo em uma página A4 completa.

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))

O motivo do recuo é que a seção de prompt removida por Max Masnick significa que tudo muda para a esquerda na saída. No entanto, isso não fez nada para a largura máxima da saída que estava restrita max-width:100%-14ex;. Isso altera a largura máxima da sub-área de saída para max-width:100%;.

Little Bobby Tables
fonte
0

Com todas as soluções acima, mesmo que você esteja ocultando o código, você ainda terá a [<matplotlib.lines.Line2D at 0x128514278>]porcaria acima do valor que provavelmente não deseja.

Se você realmente deseja se livrar da entrada em vez de apenas escondê-la, acho que a solução mais limpa é salvar suas figuras em disco em células ocultas e incluir apenas as imagens nas células Markdown usando, por exemplo ![Caption](figure1.png).

maxymoo
fonte
3
Você pode colocar _ = plt.plot()para não imprimi-lo [<>]porcaria
jonnybazookatone
3
Colocar um ponto-e-vírgula após os comandos de plotagem matplotlib suprimiu a saída indesejada para mim.
DakotaD 7/08
0
jupyter nbconvert testing.ipynb --to html --no-input
gocode
fonte
0
jupyter nbconvert yourNotebook.ipynb --no-input --no-prompt
Naveen Kumar
fonte
6
Por favor, adicione alguma explicação em vez de simplesmente responder com um comando.
Fabian Bettag