¿Cómo ocultar el código de las celdas en el cuaderno de ipython visualizado con nbviewer?

147

Tengo un cuaderno de ipython / jupyter que visualizo usando NBviewer.

¿Cómo puedo ocultar todo el código del cuaderno representado por NBviewer, de modo que solo se muestre la salida del código (por ejemplo, gráficos y tablas) y las celdas de reducción?

lucacerona
fuente
10
Todavía no hay un botón existente para esto en la IU predeterminada (febrero de 2016). En mi humilde opinión esto es realmente muy molesto. Esto está en la lista de características que se implementarán: github.com/jupyter/notebook/issues/534 Eso es genial. Espero que.
estocástico
1
Por favor, eche un vistazo a continuación a la respuesta de Noah. Con la inclusión de un TemplateExporter, este problema se resuelve independientemente del formato de salida. Al momento de escribir, la respuesta de Noah reemplaza a la respuesta de Harshils (que fue una buena solución para el TemplateExporter).
MichaelA

Respuestas:

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
fuente
55
Me funcionó en iPython 3.1.0 si lo pongo dentro de la celda de código. He sustituido el <form action ... > ... </form>con HTML simple 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
¡Gracias por su respuesta! Vea mi respuesta si necesita que el botón esté oculto y la capacidad de ocultar o mostrar ciertos bloques de código como Rstudio.
jaycode
3
Gracias, esto funciona y con 'guardar en html' también. Recomiende colocar esto en su propia celda en la parte superior del cuaderno.
Vivek Gani
si agrega el atributo accesskey = "h" al elemento de entrada, puede hacer el show hide con alt-h (en Chrome al menos)
frankc
77
¿Cómo cambiarías esto para que ni siquiera muestre el botón, solo oculta el código?
Harlekuin
79

Esto ahora es posible directamente desde nbconvert a partir de la versión 5.2.1 : el contenido se puede filtrar utilizando las opciones de exclusión de exportador de plantillas incorporadas . Por ejemplo:

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

excluirá las celdas de "código de entrada", es decir, el código mismo. Existen opciones similares para excluir solicitudes, celdas de reducción, o salidas, o entradas y salidas.

(Estas opciones deberían funcionar independientemente del formato de salida).

Noé
fuente
3
esta es la mejor respuesta
skurp
¿Dónde guarda la exportación .pdf por defecto?
MyopicVisage
Misma carpeta que el cuaderno .ipython. Use el argumento '--output NotebookNoCode' para cambiar el nombre del archivo.
MyopicVisage
¿Se supone que esto se ejecuta en el cuaderno?
lcrmorin
@were_cat no, este es un comando de shell utilizado para exportar el archivo de cuaderno .ipynb; en este ejemplo, se convierte a pdf
Noah
19

Lo usaría hide_input_allde nbextensions ( https://github.com/ipython-contrib/IPython-notebook-extensions ). Así es cómo:

  1. Averigüe dónde está su directorio IPython:

    from IPython.utils.path import get_ipython_dir
    print get_ipython_dir()
    
  2. Descargue nbextensions y muévalo al directorio IPython.

  3. Edite su archivo custom.js en algún lugar del directorio IPython (el mío estaba en profile_default / static / custom ) para que sea similar al custom.example.js en el directorio nbextensions .

  4. Agregue esta línea a custom.js :

    IPython.load_extensions('usability/hide_input_all')

IPython Notebook ahora tendrá un botón para alternar celdas de código, sin importar el libro de trabajo.

usuario394430
fuente
66
Solo intenté esto: parece ayudar a ocultar las celdas de código mientras se edita un cuaderno, aunque al guardar el cuaderno en html (es decir, renderizar a nbviewer) las celdas de código todavía aparecen.
Vivek Gani
@VivekGani solo una nota rápida de que puede mantener las celdas ocultas ocultas en el html exportado utilizando la plantilla provista con el mismo repositorio, vea la página de documentación relevante (también, vea esta pregunta relevante )
glS
15

La versión más reciente del cuaderno de IPython ya no permite ejecutar javascript en celdas de descuento, por lo que agregar una nueva celda de descuento con el siguiente código de javascript ya no funcionará para ocultar las celdas de código (consulte este enlace )

Cambie ~ / .ipython / profile_default / static / custom / custom.js como se muestra a continuación:

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
fuente
exactamente lo que estoy buscando!
lucky1928
Curiosamente, esa solución no funcionó para mí, ya que el menú de visualización de iPython permanece sin cambios. (iPython 3.1.0) Su solución me inspiró a buscar más y encontrar una solución muy similar por p3trus que agregó un botón en lugar de un menú y funcionó.
akhmed
1
@akhmed Tal vez pueda consultar stackoverflow.com/a/29851084/1914781 . ¡Es una pregunta diferente pero es útil para usted!
12

Escribí un código que lo logra y agrega un botón para alternar la visibilidad del código.

Lo siguiente va en una celda de código en la parte superior de un cuaderno:

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)

Puede ver un ejemplo de cómo se ve esto en NBviewer aquí .

Actualización: Esto tendrá un comportamiento divertido con las celdas Markdown en Jupyter, pero funciona bien en la versión de exportación HTML del cuaderno.

Max Masnick
fuente
3
Esto funciona en celdas de código, pero si tiene celdas de reducción, hace algo extraño. Muestra el descuento como descuento , y luego muestra el mismo contenido, pero con formato, a continuación.
Scott H
Me acabo de dar cuenta de que lo único incorrecto es la especificación del nodo. ¡En lugar de '.input_area'y '.prompt', use 'div.input'y funciona como un encanto! Así que para recapitular, sustituto jQuery("div.input").toggle();en lugar del jQuery('.input_area').toggle(); jQuery('.prompt').toggle();. @Max Masnick, ¿podrías arreglar tu respuesta?
Scott H
El uso de "div.input" como selección de nodo funciona siempre y cuando no interactúes con las celdas de rebajas, pero acabo de darme cuenta de que si interactúas con las celdas de rebajas podrías tener un comportamiento extraño. Por ejemplo, si hace doble clic en una celda de reducción, se oculta por completo. Entonces, tal como está, mi ajuste a la solución de Max está bien para generar HTML para compartir con otros, pero no para posteriormente interactuar demasiado con él.
Scott H
Sí, entonces noté lo mismo que hiciste con las celdas Markdown que se levantaron. Funciona bien en la exportación de HTML, que es donde lo uso. Editaré la respuesta para notar esto.
Max Masnick
1
Para eliminar los restos del espacio derecho de la eliminación de ".prompt", simplemente agregue este código al final del código anterior. CSS = """#notebook div.output_subarea { max-width:100%;""" HTML('<style>{}</style>'.format(CSS)). Esto es muy útil para imprimir.
Little Bobby Tables
10

Esto se puede hacer usando un ToggleButtonwidget de IPython y un poco de JavaScript. El siguiente código debe colocarse en una celda de código en la parte superior del 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)

Esto crea el siguiente botón para alternar mostrar / ocultar el código para el Jupyter Notebook, por defecto en el estado "ocultar":

Ocultar estado del código

Cuando se establece en el estado "mostrar", puede ver el código para el Jupyter Notebook:

Mostrar estado del código

Por otro lado, si bien gran parte de este código debe colocarse al comienzo del Notebook, la ubicación del botón de alternancia es opcional. Personalmente, prefiero mantenerlo al final del documento. Para hacerlo, simplemente mueva la display(button)línea a una celda de código separada en la parte inferior de la página:

Botón de alternar reubicado

Erick Shepherd
fuente
9

Hay una buena solución proporcionada aquí que funciona bien para los cuadernos exportados a HTML. El sitio web incluso enlaza aquí con esta publicación SO, ¡pero no veo la solución de Chris aquí! (Chris, ¿dónde estás?)

Esta es básicamente la misma solución que la respuesta aceptada de harshil, pero tiene la ventaja de ocultar el código de alternancia en el HTML exportado. También me gusta que este enfoque evite la necesidad de la función HTML de IPython.

Para implementar esta solución, agregue el siguiente código a una celda 'Raw NBConvert' en la parte superior de su computadora portátil:

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

Luego, simplemente exporte el cuaderno a HTML. Habrá un botón de alternar en la parte superior del cuaderno para mostrar u ocultar el código.

Chris también proporciona un ejemplo aquí .

Puedo verificar que esto funciona en Jupyter 5.0.0

Actualización : también es conveniente mostrar / ocultar los div.promptelementos junto con los div.inputelementos. Esto elimina la In [##]:y Out: [##]texto y reduce los márgenes de la izquierda.

Conocido
fuente
¿Sería posible usar este código para ocultar selectivamente las salidas con el clic de un botón? IE $('div.output').next().hide('500');para ocultar la próxima salida? Lo he intentado yo mismo pero no puedo hacer que esto funcione.
Brian Keith
7

Para una mejor visualización con un documento impreso o un informe, también debemos eliminar el botón y la capacidad de mostrar u ocultar ciertos bloques de código. Esto es lo que uso (simplemente copie y pegue esto en su primera celda):

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

Luego en tus siguientes celdas:

hide_me
print "this code will be hidden"

y

print "this code will be shown"
Jaycode
fuente
¿Supongo que esto no funciona para las versiones más recientes / python 3?
baxx
Funciona con jupyter versión 4.3.0 con Python versión 3.6.1.
Alma Rahat
¡Gracias! Me alegra decir que esto también funciona con el cuaderno Jupyter 5.3.1 . Estoy usando Python versión 3.6.1
Amitrajit Bose
4

Esto generará una salida de notebook IPython. Sin embargo, notará que podrá ver el código de entrada. Puede copiar un cuaderno y luego agregar este código si es necesario para compartirlo con alguien que no necesita ver el código.

from IPython.display import HTML

HTML('''<script> $('div .input').hide()''')
Chase Wright
fuente
1
@Rocketq usa esto - from IPython.display import HTML HTML('''<script> $('div.input').show()''')
fixxxer
1

Aquí hay otra solución sugerida por p3trus :

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

Según lo descrito por p3trus : "[Se] agrega un botón a la barra de herramientas del cuaderno de ipython para ocultar / mostrar la celda del código de entrada. Para usarlo, debe colocar el archivo custom.js en su .ipython_<profile name>/static/custom/carpeta, donde es el perfil de ipython en uso ".

Mis propios comentarios: verifiqué esta solución y funciona con iPython 3.1.0.

akhmed
fuente
1

La solución aceptada también funciona en julia Jupyter / IJulia con las siguientes modificaciones:

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

nota en particular:

  • usa la displayfunción
  • escapar del $signo (de lo contrario visto como una variable)
gozzilli
fuente
Estoy confundido sobre cómo hacer que esto funcione. Se necesita una declaración de importación y qué tipo de cuadro debe ser el bloque. ¿Una sin formato o una caja de código?
J Spen
1

Aquí hay un buen artículo (el mismo que publicó @Ken) sobre cómo pulir los cuadernos Jpuyter (el nuevo IPython) para su presentación. Hay innumerables formas de extender Jupyter usando JS, HTML y CSS, incluida la capacidad de comunicarse con el núcleo de Python del portátil desde javascript. Hay decoradores mágicas para %%HTMLy %%javascriptpor lo que sólo puede hacer algo como esto en una célula por sí mismo:

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

También puedo garantizar que los métodos de Chris funcionan en jupyter 4.XX

ThisGuyCantEven
fuente
1

Solución muy fácil usando la consola del navegador. Copie esto en la consola de su navegador y presione enter:

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

insertar script en la consola del navegador

Luego, alterna el código de la celda simplemente haciendo clic en el número de entrada de la celda.

numero de celular

Matěj M
fuente
0

(Papel) Imprimir o guardar como HTML

Para aquellos de ustedes que desean imprimir en papel las salidas, las respuestas anteriores parecen no dar una buena salida final. Sin embargo, tomar el código de @Max Masnick y agregar lo siguiente le permite a uno imprimirlo en una 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))

La razón de la sangría es que la sección de solicitud eliminada por Max Masnick significa que todo se desplaza a la izquierda en la salida. Sin embargo, esto no hizo nada para el ancho máximo de la salida que estaba restringido a max-width:100%-14ex;. Esto cambia el ancho máximo de output_subarea a max-width:100%;.

Mesitas Bobby
fuente
0

Con todas las soluciones anteriores a pesar de que está ocultando el código, aún obtendrá la [<matplotlib.lines.Line2D at 0x128514278>]basura por encima de su figura que probablemente no desee.

Si realmente desea deshacerse de la entrada en lugar de solo ocultarla, creo que la solución más limpia es guardar sus figuras en el disco en celdas ocultas, y luego simplemente incluir las imágenes en las celdas Markdown usando, por ejemplo ![Caption](figure1.png).

maxymoo
fuente
3
Puede poner _ = plt.plot()para que no se imprima [<>]basura
jonnybazookatone
3
Colocar un punto y coma después de los comandos de trazado matplotlib suprimió la salida no deseada para mí.
DakotaD
0
jupyter nbconvert testing.ipynb --to html --no-input
gocode
fuente
0
jupyter nbconvert yourNotebook.ipynb --no-input --no-prompt
Naveen Kumar
fuente
66
Agregue alguna explicación en lugar de simplemente responder con un comando.
Fabian Bettag