Wie verstecke ich Code vor Zellen in einem mit nbviewer visualisierten ipython-Notizbuch?

147

Ich habe ein ipython / jupyter-Notizbuch, das ich mit NBviewer visualisiere.

Wie kann ich den gesamten Code aus dem von NBviewer gerenderten Notizbuch ausblenden, sodass nur die Ausgabe von Code (z. B. Diagramme und Tabellen) und die Markdown-Zellen angezeigt werden?

Lucaceron
quelle
10
In der Standard-Benutzeroberfläche (Februar 2016) ist hierfür noch keine Schaltfläche vorhanden. IMHO ist das wirklich sehr, sehr ärgerlich. Dies ist auf der Liste der Funktionen, die implementiert werden: github.com/jupyter/notebook/issues/534 Das ist großartig. Ich freue mich darauf.
stochastisch
1
Bitte werfen Sie einen Blick auf Noahs Antwort. Mit der Aufnahme eines TemplateExporters wird dieses Problem unabhängig vom Ausgabeformat gelöst. Zum Zeitpunkt des Schreibens ersetzt Noahs Antwort die Antwort von harsch (was eine gute Lösung vor dem TemplateExporter war).
MichaelA

Antworten:

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>''')
harsch
quelle
5
Hat für mich unter iPython 3.1.0 funktioniert, wenn ich es in die Codezelle gesteckt habe. Ich ersetzte das <form action ... > ... </form>durch einfaches HTML wieThe 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
Vielen Dank für Ihre Antwort! Siehe meine Antwort, wenn Sie die Schaltfläche ausblenden und bestimmte Codeblöcke wie Rstudio ausblenden oder anzeigen möchten.
Jaycode
3
Danke, das funktioniert und auch mit 'Speichern in HTML'. Empfehlen Sie, dies in einer eigenen Zelle oben im Notizbuch zu platzieren.
Vivek Gani
Wenn Sie dem Eingabeelement das Attribut accesskey = "h" hinzufügen, können Sie die Show mit alt-h ausblenden (mindestens in Chrome)
frankc
7
Wie würden Sie dies ändern, damit nicht einmal die Schaltfläche angezeigt wird, sondern nur der Code ausgeblendet wird?
Harlekuin
79

Dies ist ab Version 5.2.1 direkt von nbconvert aus möglich : Inhalte können mithilfe der integrierten Ausschlussoptionen für den Vorlagenexporter gefiltert werden . Beispielsweise:

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

schließt die "Eingabecode" -Zellen aus, dh den Code selbst. Ähnliche Optionen gibt es, um Eingabeaufforderungen, Markdown-Zellen oder Ausgänge oder sowohl Ein- als auch Ausgänge auszuschließen.

(Diese Optionen sollten unabhängig vom Ausgabeformat funktionieren.)

Noah
quelle
3
Dies ist die beste Antwort
Skurp
Wo speichert der PDF-Export standardmäßig?
MyopicVisage
Gleicher Ordner wie das .ipython-Notizbuch. Verwenden Sie das Argument '--output NotebookNoCode', um die Datei umzubenennen.
MyopicVisage
Soll das im Notebook laufen?
lcrmorin
@were_cat nein, dies ist ein Shell-Befehl, der zum Exportieren der IPynb-Notizbuchdatei verwendet wird. In diesem Beispiel wird es in PDF konvertiert
Noah
19

Ich würde hide_input_allvon nbextensions verwenden ( https://github.com/ipython-contrib/IPython-notebook-extensions ). Hier ist wie:

  1. Finden Sie heraus, wo sich Ihr IPython-Verzeichnis befindet:

    from IPython.utils.path import get_ipython_dir
    print get_ipython_dir()
  2. Laden Sie nbextensions herunter und verschieben Sie es in das IPython-Verzeichnis.

  3. Bearbeiten Sie Ihre custom.js Datei irgendwo im IPython Verzeichnis (Mine war in profile_default / static / custom ) an das ähnlich zu sein custom.example.js im nbextensions Verzeichnis.

  4. Fügen Sie diese Zeile zu custom.js hinzu :

    IPython.load_extensions('usability/hide_input_all')

IPython Notebook verfügt nun über eine Schaltfläche zum Umschalten von Codezellen, unabhängig von der Arbeitsmappe.

user394430
quelle
6
Ich habe es gerade versucht - es scheint hilfreich zu sein, die Codezellen beim Bearbeiten eines Notizbuchs auszublenden, obwohl beim Speichern des Notizbuchs in HTML (dh beim Rendern in nbviewer) die Codezellen weiterhin angezeigt werden.
Vivek Gani
@VivekGani nur eine kurze Anmerkung, dass Sie die versteckten Zellen im exportierten HTML-Code mit der Vorlage mit dem gleichen Repo versteckt halten können, siehe die entsprechende Dokumentseite (siehe auch diese relevante Frage )
glS
15

In der neuesten IPython-Notebook-Version ist die Ausführung von Javascript in Markdown-Zellen nicht mehr möglich. Das Hinzufügen einer neuen Markdown-Zelle mit dem folgenden Javascript-Code funktioniert also nicht mehr, um Ihre Codezellen auszublenden (siehe diesen Link ).

Ändern Sie ~ / .ipython / profile_default / static / custom / custom.js wie folgt:

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
quelle
genau das, wonach ich suche!
Lucky1928
Seltsamerweise hat diese Lösung bei mir nicht funktioniert, da das iPython-Ansichtsmenü unverändert bleibt. (iPython 3.1.0) Ihre Lösung hat mich dazu inspiriert, weiter zu suchen und eine sehr ähnliche Lösung von p3trus zu finden , bei der anstelle eines Menüs eine Schaltfläche hinzugefügt wurde und die funktioniert hat.
akhmed
1
@akhmed Vielleicht können Sie auf stackoverflow.com/a/29851084/1914781 verweisen . Es ist eine andere Frage, aber hilfreich für Sie!
12

Ich habe einen Code geschrieben, der dies erreicht, und eine Schaltfläche hinzugefügt, um die Sichtbarkeit des Codes umzuschalten.

Folgendes befindet sich in einer Codezelle oben in einem Notizbuch:

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)

Sie können sehen , ein Beispiel dafür , wie diese aussieht , ist in NBviewer hier .

Update: Dies hat ein komisches Verhalten mit Markdown-Zellen in Jupyter, funktioniert aber in der HTML-Exportversion des Notebooks einwandfrei.

Max Masnick
quelle
3
Dies funktioniert bei Codezellen, aber wenn Sie Markdown-Zellen haben, macht es etwas Seltsames. Es zeigt den Abschlag als Abschlag an und zeigt dann den gleichen Inhalt - aber formatiert - unten.
Scott H
Ich habe gerade herausgefunden, dass das einzige, was falsch ist, die Knotenspezifikation ist. Anstelle von '.input_area'und '.prompt'verwenden 'div.input'und es funktioniert wie ein Zauber! Also, um es noch einmal zusammenzufassen, ersetzen Sie jQuery("div.input").toggle();anstelle von jQuery('.input_area').toggle(); jQuery('.prompt').toggle();. @ Max Masnick, könnten Sie Ihre Antwort korrigieren?
Scott H
Die Verwendung von "div.input" als Knotenauswahl funktioniert, solange Sie nicht mit den Markdown-Zellen interagieren. Ich habe jedoch gerade herausgefunden, dass bei einer Interaktion mit den Markdown-Zellen möglicherweise ein unkonventionelles Verhalten auftritt. Wenn Sie beispielsweise auf eine Markdown-Zelle doppelklicken, wird diese vollständig ausgeblendet. So wie es ist, ist meine Optimierung von Max 'Lösung in Ordnung, um HTML zu generieren, um es mit anderen zu teilen, aber nicht, um anschließend zu viel damit zu interagieren.
Scott H
Ja, also habe ich das Gleiche bemerkt, was Sie mit den Markdown-Zellen gemacht haben, die alle aufgebockt wurden. Es funktioniert gut im HTML-Export, wo ich es benutze. Ich werde die Antwort bearbeiten, um dies zu notieren.
Max Masnick
1
Um den Rest des rechten Leerzeichens aus dem Entfernen von ".prompt" zu entfernen, fügen Sie diesen Code einfach am Ende des obigen Codes hinzu. CSS = """#notebook div.output_subarea { max-width:100%;""" HTML('<style>{}</style>'.format(CSS)). Dies ist sehr nützlich zum Drucken.
Little Bobby Tables
9

Es gibt eine schöne Lösung bereitgestellt , hier das funktioniert gut für Notebooks in HTML exportieren. Die Website verlinkt sogar hierher zurück zu diesem SO-Beitrag, aber ich sehe Chris 'Lösung hier nicht! (Chris, wo bist du?)

Dies ist im Grunde die gleiche Lösung wie die akzeptierte Antwort von harsch, hat jedoch den Vorteil, dass der Umschaltcode selbst im exportierten HTML-Code ausgeblendet wird. Mir gefällt auch, dass dieser Ansatz die Notwendigkeit der IPython-HTML-Funktion vermeidet.

Fügen Sie zum Implementieren dieser Lösung den folgenden Code zu einer 'Raw NBConvert'-Zelle oben in Ihrem Notizbuch hinzu:

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

Exportieren Sie dann einfach das Notizbuch in HTML. Oben im Notizbuch befindet sich eine Umschalttaste, mit der Sie den Code ein- oder ausblenden können.

Chris liefert hier auch ein Beispiel .

Ich kann überprüfen, ob dies in Jupyter 5.0.0 funktioniert

Update : Es ist auch praktisch, die div.promptElemente zusammen mit den div.inputElementen ein- / auszublenden . Dies entfernt den In [##]:und Out: [##]Text und reduziert die Ränder auf der linken Seite.

Ken
quelle
Wäre es möglich, diesen Code zu verwenden, um Ausgaben per Knopfdruck selektiv auszublenden? IE $('div.output').next().hide('500');, um die nächste Ausgabe auszublenden? Ich habe es selbst versucht, kann es aber nicht zum Laufen bringen.
Brian Keith
9

Dies kann mit einem IPython- ToggleButtonWidget und etwas JavaScript erfolgen. Der folgende Code sollte in eine Codezelle oben im Dokument eingefügt werden:

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)

Dadurch wird die folgende Schaltfläche zum Umschalten zwischen dem Ein- und Ausblenden des Codes für das Jupyter-Notizbuch (standardmäßig "Ausblenden") aktiviert.

Code-Status ausblenden

Wenn der Status "show" aktiviert ist, wird der Code für das Jupyter-Notizbuch angezeigt:

Code-Status anzeigen

Abgesehen davon sollte ein Großteil dieses Codes am Anfang des Notizbuchs platziert werden, die Position der Umschalttaste ist jedoch optional. Ich persönlich bevorzuge es, es am Ende des Dokuments zu belassen. Verschieben Sie dazu einfach die display(button)Zeile in eine separate Codezelle am unteren Rand der Seite:

Verschobene Umschalttaste

Erick Shepherd
quelle
7

Für eine bessere Anzeige mit einem gedruckten Dokument oder einem Bericht müssen wir auch die Schaltfläche entfernen und bestimmte Codeblöcke ein- oder ausblenden. Folgendes verwende ich (kopiere es einfach und füge es in deine erste Zelle ein):

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

Dann in Ihren nächsten Zellen:

hide_me
print "this code will be hidden"

und

print "this code will be shown"
Jaycode
quelle
Ich vermute, das funktioniert nicht für die neuesten Versionen / Python 3?
Baxx
Funktioniert mit Jupyter Version 4.3.0 mit Python Version 3.6.1.
Alma Rahat
Vielen Dank! Ich bin froh zu sagen, dass dies auch mit Jupyter Notebook 5.3.1 funktioniert . Ich benutze Python Version 3.6.1
Amitrajit Bose
4

Dadurch wird eine IPython-Notebook-Ausgabe gerendert. Sie werden jedoch feststellen, dass Sie den Eingabecode anzeigen können. Sie können ein Notizbuch kopieren und diesen Code bei Bedarf hinzufügen, um ihn für jemanden freizugeben, der den Code nicht anzeigen muss.

from IPython.display import HTML

HTML('''<script> $('div .input').hide()''')
Chase Wright
quelle
1
@ Rocketq verwenden diese - from IPython.display import HTML HTML('''<script> $('div.input').show()''')
fixxxer
4

Konvertieren Sie die Zelle in Markdown und verwenden Sie das HTML5- <details>Tag wie im Beispiel von 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
quelle
1

Hier ist eine andere von p3trus vorgeschlagene Lösung :

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

Wie von p3trus beschrieben : "[It] fügt der Symbolleiste des ipython-Notizbuchs eine Schaltfläche zum Ausblenden / Anzeigen der Eingabecodezelle hinzu. Um sie zu verwenden, müssen Sie die Datei custom.js in Ihrem .ipython_<profile name>/static/custom/Ordner ablegen ist das verwendete Ipython-Profil. "

Meine eigenen Kommentare: Ich habe diese Lösung überprüft und sie funktioniert mit iPython 3.1.0.

akhmed
quelle
1

Die akzeptierte Lösung funktioniert auch in Julia Jupyter / IJulia mit den folgenden Modifikationen:

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

Beachten Sie insbesondere:

  • Verwenden Sie die displayFunktion
  • Entkomme dem $Zeichen (sonst als Variable gesehen)
gozzilli
quelle
Ich bin verwirrt, wie ich das zum Laufen bringen kann. Wird eine Importanweisung benötigt und welche Art von Box soll der Block sein? Eine rohe oder eine Codebox?
J Spen
1

Hier ist ein schöner Artikel (der gleiche, den @ Ken gepostet hat) darüber, wie man Jpuyter-Notebooks (das neue IPython) für die Präsentation aufpoliert. Es gibt unzählige Möglichkeiten, Jupyter mithilfe von JS, HTML und CSS zu erweitern, einschließlich der Möglichkeit, über Javascript mit dem Python-Kernel des Notebooks zu kommunizieren. Es gibt magische Dekorateure für %%HTMLund %%javascriptso können Sie so etwas einfach in einer Zelle selbst machen:

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

Ich kann auch dafür bürgen, dass Chris 'Methoden in Jupyter 4.XX funktionieren

ThisGuyCantEven
quelle
1

Sehr einfache Lösung mit der Konsole des Browsers. Sie kopieren dies in Ihre Browserkonsole und drücken die Eingabetaste:

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

Skript in Browser-Konsole einfügen

Dann schalten Sie den Code der Zelle um, indem Sie einfach auf die Nummer der Zelleingabe klicken.

Handynummer

Matěj M.
quelle
0

(Papier) Drucken oder Speichern als HTML

Für diejenigen unter Ihnen, die die Ausgaben auf Papier drucken möchten, scheinen die obigen Antworten allein keine schöne endgültige Ausgabe zu ergeben. Wenn Sie jedoch den Code von @Max Masnick nehmen und den folgenden hinzufügen, können Sie ihn auf einer vollständigen A4-Seite drucken.

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

Der Grund für den Einzug ist, dass der von Max Masnick entfernte Eingabeaufforderungsabschnitt bedeutet, dass sich bei der Ausgabe alles nach links verschiebt. Dies hat jedoch nichts für die maximale Breite der Ausgabe getan, die auf beschränkt war max-width:100%-14ex;. Dies ändert die maximale Breite des Ausgabebereichs in max-width:100%;.

Kleine Bobby Tische
quelle
0

Mit all den oben genannten Lösungen, obwohl Sie den Code verstecken, erhalten Sie immer noch den [<matplotlib.lines.Line2D at 0x128514278>]Mist über Ihrer Figur, den Sie wahrscheinlich nicht wollen.

Wenn Sie die Eingabe tatsächlich entfernen möchten, anstatt sie nur auszublenden, ist es meiner Meinung nach die sauberste Lösung, Ihre Zahlen in versteckten Zellen auf der Festplatte zu speichern und dann nur die Bilder in Markdown-Zellen mit z ![Caption](figure1.png).

maxymoo
quelle
3
Sie können setzen _ = plt.plot(), um es nicht drucken zu lassen [<>]Mist
jonnybazookatone
3
Das Platzieren eines Semikolons nach den Plotbefehlen von matplotlib unterdrückte die unerwünschte Ausgabe für mich.
DakotaD
0
jupyter nbconvert testing.ipynb --to html --no-input
Gocode
quelle
0
jupyter nbconvert yourNotebook.ipynb --no-input --no-prompt
Naveen Kumar
quelle
6
Bitte fügen Sie eine Erklärung hinzu, anstatt einfach mit einem Befehl zu antworten.
Fabian Bettag