Làm cách nào để ẩn mã khỏi các ô trong sổ ghi chép ipython được trực quan hóa bằng nbviewer?


147

Tôi có một máy tính xách tay ipython / jupyter mà tôi hình dung bằng NBviewer.

Làm cách nào tôi có thể ẩn tất cả mã khỏi sổ ghi chép được hiển thị bởi NBviewer, để chỉ đầu ra của mã (ví dụ: ô và bảng) và các ô đánh dấu được hiển thị?


10
Vẫn chưa có nút nào cho giao diện người dùng mặc định này (tháng 2 năm 2016). IMHO này thực sự rất khó chịu. Đây là trong danh sách các tính năng sẽ được triển khai: github.com/jupyter/notebook/issues/534 Điều đó thật tuyệt. Tôi mong đợi nó.
ngẫu nhiên

1
Xin vui lòng xem bên dưới câu trả lời của Nô-ê. Với sự bao gồm của TemplateExporter, vấn đề này được giải quyết độc lập với định dạng đầu ra. Tại thời điểm viết Nô-ê trả lời thay thế câu trả lời khắc nghiệt (đó là một giải pháp tốt để tạo ra TemplateExporter).
MichaelA

Câu trả lời:


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

5
Làm việc cho tôi trên iPython 3.1.0 nếu tôi đặt nó bên trong ô mã. Tôi đã thay thế <form action ... > ... </form>bằng HTML đơn giản nhưThe 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

Cảm ơn bạn vì câu trả lời! Xem câu trả lời của tôi nếu bạn cần ẩn nút và khả năng ẩn hoặc hiển thị các khối mã nhất định như Rstudio.
jaycode

3
Cảm ơn, điều này hoạt động và với 'lưu vào html'. Đề nghị đặt cái này trong ô riêng của nó ở đầu vở.
Vivek Gani

nếu bạn thêm thuộc tính accesskey = "h" vào phần tử đầu vào thì bạn có thể thực hiện ẩn chương trình bằng alt-h (ít nhất là bằng chrome)
frankc

7
Làm thế nào bạn sẽ thay đổi điều này để nó thậm chí không hiển thị nút, nó chỉ ẩn mã?
Harlekuin

79

Điều này hiện có thể trực tiếp từ nbconvert kể từ phiên bản 5.2.1 : nội dung có thể được lọc bằng cách sử dụng các tùy chọn loại trừ nhà xuất khẩu mẫu tích hợp . Ví dụ:

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

sẽ loại trừ các ô "mã đầu vào", tức là chính mã. Các tùy chọn tương tự tồn tại để loại trừ lời nhắc, ô đánh dấu hoặc đầu ra hoặc cả đầu vào và đầu ra.

(Các tùy chọn này sẽ hoạt động không phân biệt định dạng đầu ra.)


3
đây là câu trả lời hay nhất
skurp

Xuất khẩu .pdf theo mặc định ở đâu?
MyopicVisage

Cùng thư mục với .ipython notebook. Sử dụng đối số '--output NotebookNoCode' để đổi tên tệp.
MyopicVisage

Đây có phải là để chạy trong máy tính xách tay?
lcrmorin

@were_cat không, đây là lệnh shell được sử dụng để xuất tệp sổ tay .ipynb; trong ví dụ này, nó được chuyển đổi thành pdf

19

Tôi sẽ sử dụng hide_input_alltừ nbextensions ( https://github.com/ipython-contrib/IPython-notebook-extensions ). Đây là cách thực hiện:

  1. Tìm nơi thư mục IPython của bạn:

    from IPython.utils.path import get_ipython_dir
    print get_ipython_dir()
  2. Tải về nbextensions và di chuyển nó vào thư mục IPython.

  3. Chỉnh sửa tệp custom.js của bạn ở đâu đó trong thư mục IPython (của tôi nằm trong profile_default / static / custom ) tương tự như custom.example.js trong thư mục nbextensions .

  4. Thêm dòng này vào custom.js :

    IPython.load_extensions('usability/hide_input_all')

IPython Notebook bây giờ sẽ có một nút để chuyển đổi các ô mã, bất kể sổ làm việc.


6
Chỉ cần thử điều này - có vẻ như giúp ẩn các ô mã trong khi chỉnh sửa sổ ghi chép, mặc dù khi lưu sổ ghi chép vào html (tức là kết xuất với nbviewer), các ô mã vẫn xuất hiện.
Vivek Gani

@VivekGani chỉ cần lưu ý nhanh rằng bạn có thể giữ các ô ẩn trong html được xuất bằng cách sử dụng mẫu được cung cấp cùng một repo, xem trang tài liệu có liên quan (cũng vậy, xem câu hỏi có liên quan này )
glS

15

Phiên bản máy tính xách tay IPython mới nhất không cho phép thực thi javascript trong các ô đánh dấu nữa, vì vậy việc thêm một ô đánh dấu mới với mã javascript sau sẽ không hoạt động nữa để ẩn các ô mã của bạn (tham khảo liên kết này )

Thay đổi ~ / .ipython / profile_default / static / custom / custom.js như sau:

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

chính xác những gì tôi đang tìm kiếm!
lucky1928

Kỳ lạ là giải pháp đó không hiệu quả với tôi vì menu xem iPython vẫn không thay đổi. (iPython 3.1.0) Giải pháp của bạn đã truyền cảm hứng cho tôi tìm kiếm thêm và tìm một giải pháp tương tự bằng p3trus đã thêm một nút thay vì một menu và nó đã hoạt động.
akhmed

1
@akhmed Có lẽ bạn có thể tham khảo stackoverflow.com/a/29851084/1914781 . Đó là một câu hỏi khác biệt nhưng nó hữu ích cho bạn!

12

Tôi đã viết một số mã thực hiện điều này và thêm một nút để chuyển đổi khả năng hiển thị của mã.

Sau đây là một ô mã ở đầu một cuốn sổ:

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)

Bạn có thể xem một ví dụ về giao diện của NBviewer tại đây .

Cập nhật: Điều này sẽ có một số hành vi hài hước với các ô Markdown trong Jupyter, nhưng nó hoạt động tốt trong phiên bản xuất HTML của máy tính xách tay.


3
Điều này hoạt động trên các ô mã, nhưng nếu bạn có các ô đánh dấu thì nó sẽ làm một cái gì đó kỳ lạ. Nó cho thấy markdown như markdown , và sau đó hiển thị nội dung tương tự - nhưng định dạng - bên dưới.
Scott H

Tôi chỉ tìm ra rằng điều duy nhất sai là đặc tả nút. Thay vì '.input_area''.prompt', sử dụng 'div.input'và nó hoạt động như một bùa mê! Vì vậy, để tóm tắt, thay thế jQuery("div.input").toggle();ở vị trí jQuery('.input_area').toggle(); jQuery('.prompt').toggle();. @Max Masnick, bạn có thể sửa câu trả lời của mình không?
Scott H

Sử dụng "div.input" làm lựa chọn nút hoạt động miễn là bạn không tương tác với các ô đánh dấu, nhưng tôi chỉ nhận ra rằng nếu bạn tương tác với các ô đánh dấu, bạn có thể có một số hành vi thú vị. Ví dụ: nếu bạn bấm đúp vào một ô đánh dấu thì nó sẽ bị ẩn hoàn toàn. Vì vậy, như vậy, tinh chỉnh của tôi đối với giải pháp của Max là tốt để tạo HTML để chia sẻ với người khác, nhưng không phải vì sau đó tương tác quá nhiều với nó.
Scott H

Vâng, vì vậy tôi nhận thấy điều tương tự bạn đã làm với các tế bào Markdown bị xáo trộn. Nó hoạt động tốt trong xuất HTML, đó là nơi tôi sử dụng nó. Tôi sẽ chỉnh sửa câu trả lời để lưu ý điều này.
Max Masnick

1
Để xóa phần còn lại của không gian bên phải khỏi phần ".prompt", chỉ cần thêm mã này vào cuối đoạn mã trên. CSS = """#notebook div.output_subarea { max-width:100%;""" HTML('<style>{}</style>'.format(CSS)). Điều này rất hữu ích cho việc in ấn.
Bàn Bobby nhỏ

9

Có một giải pháp tốt được cung cấp ở đây hoạt động tốt cho máy tính xách tay được xuất sang HTML. Trang web thậm chí còn liên kết lại ở đây với bài đăng SO này, nhưng tôi không thấy giải pháp của Chris ở đây! (Chris, bạn đang ở đâu?)

Về cơ bản, đây là giải pháp tương tự như câu trả lời được chấp nhận từ khắc nghiệt, nhưng nó có lợi thế là ẩn chính mã chuyển đổi trong HTML đã xuất. Tôi cũng thích cách tiếp cận này tránh sự cần thiết cho chức năng IPython HTML.

Để triển khai giải pháp này, hãy thêm đoạn mã sau vào ô 'NBConvert thô' ở đầu sổ ghi chép của bạn:

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

Sau đó, chỉ cần xuất sổ ghi chép sang HTML. Sẽ có một nút chuyển đổi ở đầu sổ ghi chép để hiển thị hoặc ẩn mã.

Chris cũng cung cấp một ví dụ ở đây .

Tôi có thể xác minh rằng điều này hoạt động trong Jupyter 5.0.0

Cập nhật : Cũng thuận tiện để hiển thị / ẩn các div.promptyếu tố cùng với các div.inputyếu tố. Điều này loại bỏ In [##]:Out: [##]văn bản và giảm lề bên trái.


có thể sử dụng mã này để ẩn chọn lọc các kết quả đầu ra chỉ bằng một nút bấm? IE $('div.output').next().hide('500');để ẩn đầu ra tiếp theo? Tôi đã cố gắng nhưng không thể làm việc này.
Brian Keith

9

Điều này có thể được thực hiện bằng cách sử dụng ToggleButtontiện ích IPython và một chút JavaScript. Mã sau đây phải được đặt vào một ô mã ở đầu tài liệu:

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)

Thao tác này tạo nút sau để chuyển đổi hiển thị / ẩn mã cho Notebook Jupyter, được mặc định ở trạng thái "ẩn":

Ẩn trạng thái mã

Khi được đặt ở trạng thái "hiển thị", bạn có thể thấy mã cho Sổ ghi chép Jupyter:

Hiển thị trạng thái mã

Bên cạnh đó, trong khi phần lớn mã này nên được đặt ở đầu Notebook, vị trí của nút chuyển đổi là tùy chọn. Cá nhân, tôi thích giữ nó ở dưới cùng của tài liệu. Để làm như vậy, chỉ cần di chuyển display(button)dòng đến một ô mã riêng ở cuối trang:

Nút chuyển đổi vị trí


7

Để hiển thị tốt hơn với tài liệu in hoặc báo cáo, chúng tôi cũng cần phải loại bỏ nút và khả năng hiển thị hoặc ẩn các khối mã nhất định. Đây là những gì tôi sử dụng (chỉ cần sao chép-dán này vào ô đầu tiên của bạn):

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

Sau đó, trong các ô tiếp theo của bạn:

hide_me
print "this code will be hidden"

print "this code will be shown"

Tôi đoán điều này không hoạt động cho các phiên bản gần đây nhất / python 3?
baxx

Hoạt động với phiên bản jupyter 4.3.0 với phiên bản Python 3.6.1.
Alma Rahat

Cảm ơn! Rất vui khi nói rằng điều này cũng hoạt động với máy tính xách tay Jupyter 5.3.1 . Tôi đang sử dụng phiên bản Python 3.6.1
Amitrajit Bose

4

Điều này sẽ khiến một đầu ra máy tính xách tay IPython. Tuy nhiên, bạn sẽ lưu ý có thể xem mã đầu vào. Bạn có thể sao chép sổ ghi chép, sau đó thêm mã này nếu cần để chia sẻ với người không cần xem mã.

from IPython.display import HTML

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

1
@Rocketq sử dụng cái này - from IPython.display import HTML HTML('''<script> $('div.input').show()''')
fixxxer


1

Đây là một giải pháp khác được đề xuất bởi p3trus :

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

Như được mô tả bởi p3trus : "[Nó] thêm một nút vào thanh công cụ sổ ghi chép ipython để ẩn / hiển thị ô mã đầu vào. Để sử dụng, bạn phải đặt tệp custom.js vào .ipython_<profile name>/static/custom/thư mục của mình , trong đó là hồ sơ ipython đang sử dụng. "

Nhận xét của riêng tôi: Tôi đã xác minh giải pháp này và nó hoạt động với iPython 3.1.0.


1

Giải pháp được chấp nhận cũng hoạt động trong julia Jupyter / IJulia với các sửa đổi sau:

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

đặc biệt lưu ý:

  • sử dụng displaychức năng
  • thoát khỏi $dấu hiệu (nếu không được xem là một biến)

Tôi bối rối làm thế nào để làm việc này. Là một câu lệnh nhập khẩu cần thiết và loại hộp nên là khối. Một nguyên hoặc một hộp mã?
J Spen

1

Đây là một bài viết hay (cùng một bài @Ken đã đăng) về cách đánh bóng sổ ghi chép Jpuyter (IPython mới) để trình bày. Có vô số cách để mở rộng Jupyter bằng cách sử dụng JS, HTML và CSS, bao gồm khả năng giao tiếp với nhân python của máy tính xách tay từ javascript. Có những người trang trí ma thuật cho %%HTML%%javascriptvì vậy bạn chỉ có thể làm một cái gì đó như thế này trong một tế bào:

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

Tôi cũng có thể chứng minh các phương pháp của Chris hoạt động trong jupyter 4.XX


1

Giải pháp rất dễ dàng bằng Console của trình duyệt. Bạn sao chép nó vào bảng điều khiển trình duyệt của bạn và nhấn enter:

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

chèn tập lệnh vào bảng điều khiển trình duyệt

Sau đó, bạn chuyển mã của ô chỉ bằng cách nhấp vào số lượng ô nhập.

số tế bào


0

(Giấy) In hoặc lưu dưới dạng HTML

Đối với những người bạn muốn in ra giấy, các câu trả lời ở trên dường như không mang lại kết quả cuối cùng tốt đẹp. Tuy nhiên, lấy mã của @Max Masnick và thêm phần sau đây cho phép một người in nó trên một trang A4 đầy đủ.

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

Lý do cho thụt lề là phần nhắc nhở được xóa bởi Max Masnick có nghĩa là mọi thứ dịch chuyển sang trái trên đầu ra. Tuy nhiên, điều này không làm được gì cho độ rộng tối đa của đầu ra bị giới hạn max-width:100%-14ex;. Điều này thay đổi độ rộng tối đa của output_subarea thành max-width:100%;.


0

Với tất cả các giải pháp ở trên mặc dù bạn đang ẩn mã, bạn vẫn sẽ nhận được tin [<matplotlib.lines.Line2D at 0x128514278>]tào lao trên con số của bạn mà bạn có thể không muốn.

Nếu bạn thực sự muốn loại bỏ đầu vào thay vì chỉ ẩn nó, tôi nghĩ giải pháp sạch nhất là lưu số liệu của bạn vào đĩa trong các ô bị ẩn và sau đó chỉ bao gồm các hình ảnh trong các ô Markdown bằng cách sử dụng ![Caption](figure1.png) .


3
Bạn có thể đặt _ = plt.plot()để không in nó [<>]tào lao
jonnybazookatone

3
Đặt một dấu chấm phẩy sau các lệnh vẽ biểu đồ matplotlib đã triệt tiêu đầu ra không mong muốn đối với tôi.
DakotaD

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

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

6
Vui lòng thêm một số giải thích thay vì chỉ đơn giản là sử dụng một lệnh.
Fabian Bettag
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.