lucacerone
lucacerone

Reputation: 10109

How to hide code from cells in ipython notebook visualized with nbviewer?

I have an ipython/jupyter notebook that I visualize using NBviewer.

How can I hide all the code from the notebook rendered by NBviewer, so that only the output of code (e.g. plots and tables) and the markdown cells are shown?

Upvotes: 201

Views: 237207

Answers (24)

Stefan Simik
Stefan Simik

Reputation: 185

The code in original verified solution does not work anymore in latest JupyterLab 4.x.x

Try this code instead (tested in JupyterLab 4 and works):

# Special javascript code, that creates new BUTTON, which shows/hides all code.
# Button is visible also here in Python notebook, but really works and operates only in HTML export.

from IPython.display import HTML

HTML(
'''
<script>
    code_show = true;

    function code_toggle() {
        if (code_show) {
            document.querySelectorAll('.jp-CodeCell .jp-InputArea').forEach(function(el) {
               el.style.display = 'none';
            });
        } else {
            document.querySelectorAll('.jp-CodeCell .jp-InputArea').forEach(function(el) {
               el.style.display = 'block';
            });
        }
        code_show = !code_show
    }
</script>
<form action="javascript:code_toggle()">
    <input type="submit" value="Show / Hide code">
</form>
'''
)

Upvotes: 2

Sebastian
Sebastian

Reputation: 1

If you work manually (no bulk-runs/bulk-exports), there is a quite simple solution: add the following code block & execute it

from IPython.core.display import HTML
HTML('<style>.input, .jp-InputArea {display: none !important}</style>')

Code will disappear both in the "normal" UI and in print preview / export to HTML. Clear the output of this one cell to bring the code back, done

Note that the code is still there just not visible, so only use this when you want to show (or export use print preview to generate a PDF. That PDF looks pretty decent now. Do not use it when you want to keep the code to yourself)

Upvotes: 0

965311532
965311532

Reputation: 546

The problem I have with @harshil's answer is that it will not collapse hidden cells, leaving a somewhat ugly-looking empty space in their place (I'm using IPython 7.30.1 and nbconvert 6.3.0) [example].

This is because the input div is inside a wrapper, so when input is hidden, the wrapper doesn't collapse. (If you have no code cells without output, this won't be a problem for you, as when the input is hidden, it will collapse inside the wrapper, and therefore the output div will take up all the space).

Here's how you can do it (just put this in a cell):

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

Upvotes: 0

Lucas
Lucas

Reputation: 258

A script to show/hide Jupyter Notebook code cells both in edit interface and in the exported html

Just put this code in the first cell and run it:

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

Example in editor

Example exported HTML

Example Export

Upvotes: 12

Ashish Anand
Ashish Anand

Reputation: 2733

Many times, we need to hide some parts of codes while writing a long code.

Example: - Just on clicking "Code show/hide", we can hide 3 lines of codes.

enter image description here

So here is the function that you need to define for partially hiding few part of codes and then call it whenever you want to hide some code:

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)

Once we are ready with function definition, our next task is very easy. Just we need to call the function to hide/show the code.

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

Upvotes: 2

ivankeller
ivankeller

Reputation: 2053

Simple programmatic solution for exporting a notebook to HTML without the code cells (output only): add this code in a code cell of the notebook my_notebook.ipynb you want to export:

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)

Upvotes: -1

Naveen Kumar
Naveen Kumar

Reputation: 297

jupyter nbconvert yourNotebook.ipynb --no-input --no-prompt

jupyter nbconvert yourNotebook.ipynb This part of the code will take the latex file format of the jupyter notebook and converts it to a html

--no-input This is like a parameter we are saying during conversion that dont add any inputs : here the input to a cell is the code.. so we hide it

--no-prompt Here also we are saying, During conversion dont show any prompts form the code like errors or warnings in the final HTML file ) so that that html will have only the Text and the code output in the form of a report !!..

Hope it helps :)

Upvotes: 6

gocode
gocode

Reputation: 375

jupyter nbconvert testing.ipynb --to html --no-input

Upvotes: -2

Matěj M
Matěj M

Reputation: 109

Very easy solution using Console of the browser. You copy this into your browser console and hit enter:

$("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

Then you toggle the code of the cell simply by clicking on the number of cell input.

cell number

Upvotes: 3

Valentas
Valentas

Reputation: 2245

Convert cell to Markdown and use HTML5 <details> tag as in the example by 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>

Upvotes: 7

Erick Shepherd
Erick Shepherd

Reputation: 1443

This can be done using an IPython ToggleButton widget and a little bit of JavaScript. The following code should be placed into a code cell at the top of the document:

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)

This creates the following button to toggle showing/hiding the code for the Jupyter Notebook, defaulted to the "hide" state:

Hide code state

When set to the "show" state, you can then see the code for the Jupyter Notebook:

Show code state

As an aside, while much of this code should be placed at the beginning of the Notebook, the location of the toggle button is optional. Personally, I prefer to keep it at the bottom of the document. To do so, simply move the display(button) line to a separate code cell at the bottom of the page:

Relocated toggle button

Upvotes: 15

Noah
Noah

Reputation: 22636

This is now possible directly from nbconvert as of version 5.2.1: content can be filtered using the built-in template exporter exclude options. For example:

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

will exclude the "input code" cells, ie the code itself. Similar options exist to exclude prompts, markdown cells, or outputs, or both inputs and outputs.

(These options should work irrespective of output format.)

Upvotes: 137

Ken
Ken

Reputation: 114

There is a nice solution provided here that works well for notebooks exported to HTML. The website even links back here to this SO post, but I don't see Chris's solution here! (Chris, where are you at?)

This is basically the same solution as the accepted answer from harshil, but it has the advantage of hiding the toggle code itself in the exported HTML. I also like that this approach avoids the need for the IPython HTML function.

To implement this solution, add the following code to a 'Raw NBConvert' cell at the top of your 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>

Then simply export the notebook to HTML. There will be a toggle button at the top of the notebook to show or hide the code.

Chris also provides an example here.

I can verify that this works in Jupyter 5.0.0

Update: It is also convenient to show/hide the div.prompt elements along with the div.input elements. This removes the In [##]: and Out: [##] text and reduces the margins on the left.

Upvotes: 8

ThisGuyCantEven
ThisGuyCantEven

Reputation: 1267

Here is a nice article (the same one @Ken posted) on how to polish up Jpuyter (the new IPython) notebooks for presentation. There are countless ways to extend Jupyter using JS, HTML, and CSS, including the ability to communicate with the notebook's python kernel from javascript. There are magic decorators for %%HTML and %%javascript so you can just do something like this in a cell by itself:

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

I can also vouch Chris's methods work in jupyter 4.X.X.

Upvotes: 1

user4284784
user4284784

Reputation:

The newest IPython notebook version do not allow executing javascript in markdown cells anymore, so adding a new markdown cell with the following javascript code will not work anymore to hide your code cells (refer to this link)

Change ~/.ipython/profile_default/static/custom/custom.js as below:

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

Upvotes: 16

maxymoo
maxymoo

Reputation: 36545

With all the solutions above even though you're hiding the code, you'll still get the [<matplotlib.lines.Line2D at 0x128514278>] crap above your figure which you probably don't want.

If you actually want to get rid of the input rather than just hiding it, I think the cleanest solution is to save your figures to disk in hidden cells, and then just including the images in Markdown cells using e.g. ![Caption](figure1.png).

Upvotes: -1

gozzilli
gozzilli

Reputation: 8337

The accepted solution also works in julia Jupyter/IJulia with the following modifications:

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

note in particular:

  • use the display function
  • escape the $ sign (otherwise seen as a variable)

Upvotes: 0

Chase Wright
Chase Wright

Reputation: 369

This will render an IPython notebook output. However, you will note be able to view the input code. You can copy a notebook, then add this code if needed to share with someone who does not need to view the code.

from IPython.display import HTML

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

Upvotes: 5

Little Bobby Tables
Little Bobby Tables

Reputation: 4744

(Paper) Printing or Saving as HTML

For those of you wishing to print to paper the outputs the above answers alone seem not to give a nice final output. However, taking @Max Masnick's code and adding the following allows one to print it on a full A4 page.

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

The reason for the indent is that the prompt section removed by Max Masnick means everything shifts to the left on output. This however did nothing for the maximum width of the output which was restricted to max-width:100%-14ex;. This changes the max width of the output_subarea to max-width:100%;.

Upvotes: -2

jaycode
jaycode

Reputation: 2958

For better display with printed document or a report, we need to remove the button as well, and the ability to show or hide certain code blocks. Here's what I use (simply copy-paste this to your first cell):

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

Then in your next cells:

hide_me
print "this code will be hidden"

and

print "this code will be shown"

Upvotes: 5

Max Masnick
Max Masnick

Reputation: 3287

I wrote some code that accomplishes this, and adds a button to toggle visibility of code.

The following goes in a code cell at the top of a 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)

You can see an example of how this looks in NBviewer here.

Update: This will have some funny behavior with Markdown cells in Jupyter, but it works fine in the HTML export version of the notebook.

Upvotes: 18

user394430
user394430

Reputation: 2957

I would use hide_input_all from nbextensions (https://github.com/ipython-contrib/IPython-notebook-extensions). Here's how:

  1. Find out where your IPython directory is:

    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.

Upvotes: 23

akhmed
akhmed

Reputation: 3635

Here is another solution suggested by p3trus:

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

As described by p3trus: "[It] adds a button to the ipython notebook toolbar to hide/show the input code cell. To use it, you have to put the custom.js file in your .ipython_<profile name>/static/custom/ folder, where is the ipython profile in use."

My own comments: I verified this solution and it works with iPython 3.1.0.

Upvotes: 1

harshil
harshil

Reputation: 3250

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

Upvotes: 293

Related Questions