Emacs-Jupyter
文章目录
参考
- github: GitHub - nnicandro/emacs-jupyter: An interface to communicate with Jupyter ke…
- scimax-jupyter: scimax/scimax-jupyter.org at master · jkitchin/scimax · GitHub
- emacs-jupyter + org-mode + code-cells.el: Jupyter in the Emacs universe | Martí Bosch
功能简介
- 提供一个 emacs 内部界面友好的 ipython 命令行(自动补全,帮助弹出)
- 提供 org babel 支持,类似 ob-ipython
依赖
默认 python 环境要安装 jupyter
| |
pycse
scimax jupyter, 用来支持 jupyter 到 org-mode 数据转换
启动
启动一个 ipython 命令行入口
M-x jupyter-run-repl
连接已有的 ipython 命令行
M-x jupyter-connect-repl
- 注意: 需要用到 ipython 连接文件
什么是 connection file: 参见: Making kernels for Jupyter — jupyter_client 7.1.0 documentation
自动补全
C-M-i 手动触发,tab 键无效
帮助
M-i
历史
前后
M-p 和 M-n
查找
C-s 和 C-r
执行
类似 emacs 对 elisp 的快捷键, 以 C-c 为前缀 参考: GitHub - nnicandro/emacs-jupyter: An interface to communicate with Jupyter ke…
类似 ob-ipython 功能
参考: GitHub - nnicandro/emacs-jupyter: An interface to communicate with Jupyter ke… eg:
| |
hello
headers:
- :session
:kernel
- 指定 python 版本等
:results
raw
- 避免转换城 begin_export 对于生成的 latex 结果
scalar
生成的 列表 转换城 org mode plain list, 不是 python 列表
1print([1,2,3])[1, 2, 3]
output
对于 pd.DataFrame, 使用
:results output可以正常显示- 待议,有时不正常
- output 不可,但是 value/raw/scalar 都可以
:display
- 指定输出的 mime type
- 默认值: text/html
取值
- eg:
:display text/plain text/htmlplain 比 html 优先级高 display plainplain text
- eg:
:file
用于指定图片文件的位置
- 默认图片位置
org-babel-jpyter-resource-directory - 默认名称,随机生成
- 默认图片位置
:pandoc
- 格式问题
:async
- 异步执行问题,使用 ob-async
- 取值:
:async yes
使用 jupyter 替代 ob-python
代码: (org-babel-jupyter-override-src-block "python")
参考: GitHub - nnicandro/emacs-jupyter: An interface to communicate with Jupyter ke…
远程连接
通过 :session header 使用 tramp /ssh:host:/path/to/jupyter-connection-file.json 语法实现 例子:
| |
通过 tramp 打开 远程 repl
语法: M-x dired RET /jpy:localhost#8888:/
FAQ
报 json-readable-error 错误
参考: nnicandro/emacs-jupyter#301 Emacs 27 json-read: JSON readtable error: 76 原因分析: 当前 python 环境没有安装 jupyter
解决方案:
| |
报错 No org-babel-execute function for jupyter-python
参考: nnicandro/emacs-jupyter#306 No org-babel-execute function for jupyter-python
原因分析: 没有成功加载 ob-jupyter
解决方案:
| |
org-babel-jupyter-session-key: Need a valid session and a kernel to form a key
原因分析:未能启动 jupyter 后台
解决方案:
- revert-buffer
注释掉 session id
#+PROPERTY: header-args:jupyter-python :session jupyter-python-ae43ef8be0720e6d8693d0b25a77ef13
- 把这一行注释掉
切换 virtual env
手动刷新法
参考:emacs-jupyter/community - Gitter 步骤:
emacs 内部切换 virtualenv
M-x conda-env-activate
手动刷新 jupyter kernel
1(jupyter-available-kernelspecs 'refresh)
使用 ipykernel install 实现
参考:
- 官方:https://ipython.readthedocs.io/en/stable/install/kernel_install.html
- 详细使用:Using Multiple Python Versions and Environments with RStudio Workbench and Ju…
步骤:
在
root python(系统 python)下安装 ipykernel1python -m pip install ipykernel创建虚拟环境(已有可以跳过)
1conda create -n ml37 python=3.7激活环境
1conda activate ml37注册 kernel
1 2 3 4 5 6 7 8# * system系统, 安装配置位置: /usr/loca/share/jupyter/kernels/... python -m ipykernel install --name ml37 --display-name "Python3 (ml37)" # * user 当前用户, 安装配置位置: ~/.local/share/jupyter/kernels/... python -m ipykernel install --user --name ml37 --display-name "Python3 (ml37)" # * 安装到 conda base 中 python -m ipykernel install --prefix="d:/soft/miniconda3/" --name ml37 --display-name "Python3 (ml37)"
doom emacs
方法一
步骤:
- 在 shell: conda env activate my-env
- 修改 doom 环境变量文件 env: doom sync
- 启动 doom emacs
org babel jupyter 设置 kernel
通过 src block :kernel your-python-kernel 切换 kernel, 进而切换 python 版本和 virtual env
不设置 :kernel
| |
/usr
设置 :kernel
| |
/home/sawyer/miniconda3/envs/ml38
设置 默认 session 和 默认 kernel
#+PROPERTY: header-args:jupyter-python :session jupyter-python-ae43ef8be0720e6d8693d0b25a77ef13 :kernel chem38
快捷方法:
- 通过 yasnippt 实现, 键
<jps
注意
org-mode file 级别的设置
- 必须 revert-buffer 才能生效
- 不然,可能导致 执行代码块错误,因为探知不到正确的 :session 配置 :kernel 配置
图片展示
通过 IPython.display 模块实现不支持的绘图工具结果展示
| |
bokeh
参考
- scimax-jupyter: scimax/scimax-jupyter.org at master · jkitchin/scimax · GitHub
使用 IPython.display.Image 包裹
核心代码
1 2 3 4 5from IPython.display import Image filename = "./bokeh_line_square.png" export_png(p, filename=filename) # p 是 boken 的Figure 对象 Image(filename) # 在 org-mode 文件内部,生成 [[./path/to/mypiture.png]]已测试例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15import numpy as np from bokeh.plotting import figure, show from bokeh.io import output_file, export_png from IPython.display import Image x = np.linspace(1, 10, 10) y = x**2 p = figure(title="first figure y=x^2", x_axis_label="x", y_axis_label="y") square = p.line(x, y) # show(p) # 外部打开浏览其展示临时文件:html filename = "./bokeh_line_square.png" export_png(p, filename=filename) Image(filename) # 在 org-mode 文件内部,生成 [[./path/to/mypiture.png]]
使用 bokeh 制作 image object
中间 不生成 图片文件,而是使用图片对象
核心代码
1 2 3from bokeh.io.export import get_screenshot_as_png get_screenshot_as_png(p)完整代码
1 2 3 4 5 6 7 8 9 10 11 12import numpy as np from bokeh.plotting import figure, show from bokeh.io import output_file, export_png from IPython.display import Image from bokeh.io.export import get_screenshot_as_png x = np.linspace(1, 10, 10) y = x**2 p = figure(title="first figure y=x^2", x_axis_label="x", y_axis_label="y") square = p.line(x, y) # show(p) # 外部打开浏览其展示临时文件:html get_screenshot_as_png(p)
制作显示工具
工具代码
1 2 3 4 5from bokeh.io.export import get_screenshot_as_png def showobj(fig: "Figure", *args, **kwargs): return get_screenshot_as_png(fig, *args, **kwargs)用法
1showobj(p) # p 是 bokeh 的外部对象
plotly
支持更好,使用 pycse 实现
依赖安装:
| |
plotly 示范代码:
| |
exception backtrace 错误代码跳转
由 scimax-jupyter 提供
M-x scimax-jupyter-org-hydra/body 或者 <F12> e 或者 C-c C-h e
注意: 必须在代码块内部才能正确跳转
repl 和 scratch
jupyter repl
org-mode src block –> repl
- scimax-jupyter:
<F12> r - org babel core:
C-c C-v C-z
- scimax-jupyter:
jupyter scratch –> repl
C-c C-z
jupyter scratch
两种方式
jupyter repl buffer –> scratch
C-c C-s或M-x jupyter-repl-scratch-buffer
org-mode src block —> scatch
- scimax-jupyter: org-mode python 代码块内部
<F12> s- 有 bug, 不能用
src block as scratch
当前代码块执行 defun
C-M-x或M-x jupyter-eval-defun
行执行或选定区域执行 line || region
C-x C-e或M-x jupyter-eval-line-or-region
debug
scimax 官方方法
步骤
定义代码,使用
breakpoint()设置断点1 2 3 4def hello(x): 3 % x breakpoint() return 1/x- 执行 src block
- 跳转到 repl
F12 z - 执行代码,自动 进入 debug 状态
问题:
- 这种方法无效
ipython magic 方法
- 在 repl 中
- 使用 %debug || %%debug 包裹代码
- 调用 pdb 调试
emacs-jupyter + org-mode
如何设置 :kernel
当不指定 kernel 时
load library
(require 'jupyter) (require 'ob-jupyter)
- 打开 .org 文件
输入内容:
注意下面的例子,没有设置 :kernel
1 2 3 4 5 6 7 8 9 10 11 12 13#+PROPERTY: header-args:jupyter-python :session demo #+PROPERTY: header-args:jupyter-python+ :async yes #+begin_src jupyter-python import sys sys.prefix print(sys.prefix) #+end_src #+RESULTS: : /home/sawyer/miniconda3/envs/llm311
连接 jupyter repl
jupyter-connect-server-repl: 连接 jupyter 命令启动的 serverjupyter-connect-repl: 需要使用 connect 文件
编辑和执行
C-c h:jupyter-org-hydra/body: jupyter hydra 命令用来执行代码块的~运行~ 、编辑、跳转
指定 :kernel
load library
(require 'jupyter) (require 'ob-jupyter)
创建 kernel(第一次连接 juyter)
jupyter-server-launch-kernel如果已经创建过 kernel, 跳过这个步骤
- 包括之前在 emacs 或者在 jupyter notebook/lab 上手动运行的 .ipynb
连接 jupyter repl(已经连接jupyter 之后)
jupyter-connect-server-repl: 连接 jupyter 命令启动的 serverjupyter-connect-repl: 需要使用 connect 文件
在运行的 kernel 列表
jupyter-server-list-kernels
重命名 kernel
- 在
jupyter-server-list-kernels命令打开的界面上 这里启动了
jupyter-server-kernel-list-mode提供的功能:
jupyter-server-kernel-list-mode-map1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16(defvar jupyter-server-kernel-list-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-i") #'jupyter-server-kernel-list-do-interrupt) (define-key map (kbd "d") #'jupyter-server-kernel-list-do-shutdown) (define-key map (kbd "C-c C-d") #'jupyter-server-kernel-list-do-shutdown) (define-key map (kbd "C-c C-r") #'jupyter-server-kernel-list-do-restart) (define-key map [follow-link] nil) ;; allows mouse-1 to be activated (define-key map [mouse-1] #'jupyter-server-kernel-list-new-repl) (define-key map (kbd "RET") #'jupyter-server-kernel-list-new-repl) (define-key map (kbd "C-RET") #'jupyter-server-kernel-list-launch-kernel) (define-key map (kbd "C-<return>") #'jupyter-server-kernel-list-launch-kernel) (define-key map (kbd "<return>") #'jupyter-server-kernel-list-new-repl) (define-key map "R" #'jupyter-server-kernel-list-name-kernel) (define-key map "r" #'revert-buffer) (define-key map "g" #'revert-buffer) map))R: renamed: shutdownRET: create new kernelC-c C-i: interruptC-c C-r: restartC-c C-d: shutdown
- 在
kernel 的默认名称
- kernel 的 uuid
- 当前 jupyter notebook 启动使用的 kernel 的默认名称
python3
编辑 .org 文件(org-mode)
使用
:kernel指定 kernel1 2 3 4 5 6 7 8 9 10 11 12#+PROPERTY: header-args:jupyter-python :session demo :kernel python3 #+PROPERTY: header-args:jupyter-python+ :async yes #+begin_src jupyter-python import sys sys.prefix print(sys.prefix) #+end_src #+RESULTS: : /home/sawyer/miniconda3/envs/py311
repl 使用
步骤:
关联或创建 repl:
- 关联到已有的buffer:
jupyter-repl-associate-buffer 创建 buffer:
jupyter-connect-server-repl- 特点:可以选择 kernel 类型(对应 venv 环境)
- 关联到已有的buffer:
- 跳转到 repl buffer:
jupyter-repl-pop-to-buffer - 打开一个草稿 repl buffer(scratch):
jupyter-repl-scratch-buffer
使用 connection file + org-mode
使用这个麻烦方法的原因:
- 目标的测试结果表明, remote kernel +
jupyter-repl-associate-buffer只可以关联 .py 文件 buffer 和 remote repl - 但是如果使用
jupyter-repl-associate-buffer关联一个 org-mode, jupyter 只会尝试启动一个本地的 jupyter
方法:
准备 kernel 和 connection file
使用
jupyter-connect-server-repl和jupyter-server-launch-kernel等命令创建一个 kernel- 可以查看到 kernel 对应的 id
在 remote ssh host 上查看对应的 connect file 文件路径
- 潜在存放路径:
/home/<user>/.local/share/jupyter/runtime/kernel-<id>.json - 如果不正确,可以通过命令
jupyter --runtime-dir, 获取存储文件夹
- 潜在存放路径:
设置公共的header
#+PROPERTY: header-args:jupyter-python :session /sshfs:gpu:/home/sawyer/.local/share/jupyter/runtime/kernel-108e82e6-b11f-43d5-8b60-f136ff04f249.json
- 通过 ssh 指定使用的 kernel 的连接文件的路径
启动方法:
- 重新打开文件或者在上面的指令上面执行
Ctrl+c Ctrl+c
- 重新打开文件或者在上面的指令上面执行
- 正常使用 org-babel 的命令执行代码
例子:
| |
文章作者
上次更新 2025-09-24 (360d44c)