進階用法#
本頁包含更進階的主題,以防您想更深入了解如何使用 Sphinx-Gallery。
為 Sphinx-Gallery 擴展您的 Makefile#
本節描述對文件 Makefile 的一些常見擴展,這些擴展對於 Sphinx-Gallery 很有用。
清除圖庫檔案#
一旦您的圖庫運作正常,您可能需要完全刪除 Sphinx-Gallery 產生 的所有檔案,以進行乾淨的建置。為此,我們建議將以下內容添加到您的 Sphinx Makefile
中
clean:
rm -rf $(BUILDDIR)/*
rm -rf auto_examples/
如果您已變更 gallery_dirs
設定變數,您需要調整第二個 rm
命令。
在不執行任何範例的情況下建置圖庫#
如果您希望在不先執行範例的情況下建置圖庫(例如,如果範例需要很長時間才能執行),請將以下內容新增至您的 Makefile
。
html-noplot:
$(SPHINXBUILD) -D plot_gallery=0 -b html $(ALLSPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
了解您的圖庫檔案#
圖庫已建置完成,現在您和您專案的所有使用者都可以開始使用它。產生圖庫所需的所有暫存檔案(rst 檔案、圖片、快取物件等)都儲存在您在 gallery_dirs
中設定的位置。進入文件 HTML 版本的最終檔案具有特定的命名空間,以避免與您自己的檔案和圖片發生衝突。
我們的命名空間慣例是以 sphx_glr
為所有內容加上前綴,並將路徑分隔符號變更為底線。例如,範例 'plot_0_sin.py' 產生的第一張圖片的名稱為 sphx_glr_plot_0_sin_001.png
,其縮圖為 sphx_glr_plot_0_sin_thumb.png
您也可以使用 literalinclude
指令將圖庫指令碼的一部分包含在您文件的其他位置,以限制程式碼重複
.. literalinclude:: ../examples/plot_0_sin.py
:language: python
:start-after: # License: BSD 3 clause
:end-before: # To avoid matplotlib
上述指令會插入以下區塊
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.xlabel(r"$x$")
plt.ylabel(r"$\sin(x)$")
警告
使用 literalinclude 很脆弱,當範例變更時很容易損壞(當使用行號而不是 start-after
和 end-before
時更是如此)。請謹慎使用:直接連結到範例是更穩健的替代方案。
交叉參考#
您也可以使用類似的命名慣例來交叉參考範例。例如,如果我們要參考範例 入門範例 - 繪製 sin,我們只需呼叫其參考 :ref:`sphx_glr_auto_examples_plot_0_sin.py`
。請注意,我們已在 sphx_glr_
後面包含範例檔案的路徑(相對於 conf.py
檔案)。路徑分隔符號會取代為底線。
了解警告和錯誤輸出#
在建置文件期間,執行圖庫 Python 檔案中的程式碼區塊時發生的任何警告或錯誤都會以粉紅色顯示。也會列印錯誤發生的 .py
檔案路徑和行號。例如,範例 無法執行的範例 會引發以下錯誤
File "<full_path>/examples/no_output/plot_raise.py", line 27, in <module>
iae
NameError: name 'iae' is not defined
圖庫 Python 檔案的文字 (reST) 區塊中的問題會在 Sphinx 將產生的 .rst
檔案轉換為 HTML 時導致警告或錯誤。這些將由 Sphinx 在建置文件期間,於程式碼區塊錯誤之後以粉紅色列印。在這種情況下,將列印 .rst
檔案路徑和 .rst
檔案行號。若要修正問題,您將需要修改原始 .py
檔案,而不是產生的 .rst
檔案。若要找出問題所在,您需要將列印的行號上的 .rst
檔案內容與原始 .py
檔案內容進行比對。
範例 .rst
警告
<full_path>/auto_examples/plot_example.rst:19: WARNING: Explicit markup ends without a blank line; unexpected unindent.
上面的警告是由於 plot_example.rst
中的第 19 行所引起。需要修改原始 plot_example.py
檔案來修正它。Sphinx-Gallery 只會(重新)建置新的、修改過的或失敗的範例,因此重新執行文件建置應該只會重新建置修改過的範例,以便快速迭代。
撰寫自訂圖片抓取器#
警告
自訂抓取器的 API 目前為實驗性質。
依預設,Sphinx-Gallery 支援 Matplotlib 的圖片抓取 (matplotlib_scraper()
)。如果您想要擷取其他 python 套件的輸出,請先判斷您要擷取的物件是否具有 _repr_html_
方法。如果有的話,您可以使用設定 capture_repr
(控制擷取的輸出) 來控制物件的顯示,而無需撰寫自訂抓取器。此設定允許擷取原始 html 輸出,其過程類似於其他基於 html 的顯示,例如 jupyter。如果第一個選項不起作用,本節將說明如何撰寫自訂抓取器。
圖片抓取器是執行以下動作的函式(或可呼叫的類別執行個體)
收集最新程式碼執行中建立的圖片清單。
將這些圖片以 PNG、JPEG、SVG、GIF 或 WebP 格式寫入磁碟(分別具有 .png、.jpg、.svg、.gif 或 .webp 副檔名)
傳回將這些圖片嵌入到建置文件的 reST。
函式應採用以下輸入(依此順序)
block
- Sphinx-Gallery.py
檔案會分成連續的「程式碼」和 reST「文字」行,稱為「區塊」。對於每個區塊,都會建立具有 (“type”, “content”, “lineno”) 項目的 namedtuple(例如,('code', 'print("Hello world")', 5)
)。‘label’ 是一個字串,可以是
'text'
或'code'
。在此內容中,它應該只會是'code'
,因為此函式只會針對程式碼區塊呼叫。‘content’ 是一個字串,其中包含程式碼區塊的實際內容。
‘lineno’ 是一個整數,指示區塊開始的行號。
block_vars
- 包含設定和執行時變數的字典。對於圖像擷取器而言,其中一個重要的元素是'image_path_iterator'
,它是一個可迭代物件,會回傳符合 Sphinx-Gallery 命名慣例的圖像檔案絕對路徑。該路徑指向gallery_dirs/images
目錄(設定和使用 Sphinx-Gallery),而圖像檔案名稱為'sphx_glr_'
,接著是來源.py
檔案的名稱,然後是一個數字,從 1 開始,每次迭代增加 1。預設檔案格式為'.png'
。例如:'home/user/Documents/module/auto_examples/images/sphx_glr_plot_mymodule_001.png'
。如果需要不同的圖像副檔名,擷取器負責替換預設的 .png 副檔名。只有支援的圖像副檔名(見上文)才能讓檔案被 Sphinx-Gallery 挑選到。gallery_conf
- 包含 Sphinx-Gallery 設定的字典,設定於doc/conf.py
中的sphinx_gallery_conf
下 (設定)。特別要注意的是,image_srcset 設定將提供使用者指定的圖像解析度(以浮點數表示),您的自訂擷取器可以使用這些解析度來啟用多解析度圖像。
它應該回傳一個包含 reST 字串,用於在文件中嵌入此圖形。請參考 matplotlib_scraper()
以了解擷取器函式的範例 (點擊函式名稱下方的「source」即可查看原始碼)。matplotlib_scraper()
使用輔助函式 sphinx_gallery.scrapers.figure_rst()
來協助產生 reST (見下文)。
此函式將針對您範例中的每個程式碼區塊呼叫一次。Sphinx-Gallery 將負責縮放圖像,以用於圖庫索引頁面的縮圖。PNG、JPEG 和 WebP 圖像會使用 Pillow 進行縮放,而 SVG 和 GIF 圖像則會複製。
警告
SVG 圖像不適用於 latex
建置模式,因此在建置 PDF 版本的檔案時無法正常運作。您可能會想考慮使用 sphinxcontrib-svg2pdfconverter。
範例 1:Matplotlib 樣式的擷取器#
例如,我們將展示一個假設套件的擷取器範例程式碼。它使用類似於 sphinx_gallery.scrapers.matplotlib_scraper()
在幕後所採用的方法,該方法使用輔助函式 sphinx_gallery.scrapers.figure_rst()
來建立標準化的 reST。如果您的套件將用於將圖像檔案寫入磁碟 (例如,PNG 或 JPEG),我們建議您使用類似的方法。
def my_module_scraper(block, block_vars, gallery_conf):
import mymodule
# We use a list to collect references to image names
image_names = list()
# The `image_path_iterator` is created by Sphinx-Gallery, it will yield
# a path to a file name that adheres to Sphinx-Gallery naming convention.
image_path_iterator = block_vars['image_path_iterator']
# Define a list of our already-created figure objects.
list_of_my_figures = mymodule.get_figures()
# Iterate through figure objects, save to disk, and keep track of paths.
for fig, image_path in zip(list_of_my_figures, image_path_iterator):
fig.save_png(image_path)
image_names.append(image_path)
# Close all references to figures so they aren't used later.
mymodule.close('all')
# Use the `figure_rst` helper function to generate the reST for this
# code block's figures. Alternatively you can define your own reST.
return figure_rst(image_names, gallery_conf['src_dir'])
此程式碼可以定義在您的 conf.py
檔案中,或者作為一個模組匯入到您的 conf.py
檔案中 (請參閱匯入可呼叫物件)。使用此擷取器所需的設定如下所示
sphinx_gallery_conf = {
...
'image_scrapers': ('matplotlib', "my_module._scraper.my_module_scraper"),
}
其中 Sphinx-Gallery 將解析字串 "my_module._scraper.my_module_scraper"
以匯入可呼叫的函式。
範例 2:偵測磁碟上的圖像檔案#
這裡有另一個範例,假設圖像已*寫入磁碟*。在這種情況下,我們不會*產生*任何圖像檔案,我們只會產生將它們嵌入文件中所需的 reST。請注意,仍然需要執行範例腳本來擷取檔案,但不需要在執行期間產生圖像。
我們假設此函式定義在您的套件中名為 _scraper
的模組中。以下是擷取器程式碼
from glob import glob
import shutil
import os
from sphinx_gallery.scrapers import figure_rst
def png_scraper(block, block_vars, gallery_conf):
# Find all PNG files in the directory of this example.
path_current_example = os.path.dirname(block_vars['src_file'])
pngs = sorted(glob(os.path.join(path_current_example, '*.png')))
# Iterate through PNGs, copy them to the Sphinx-Gallery output directory
image_names = list()
image_path_iterator = block_vars['image_path_iterator']
seen = set()
for png in pngs:
if png not in seen:
seen |= set(png)
this_image_path = image_path_iterator.next()
image_names.append(this_image_path)
shutil.move(png, this_image_path)
# Use the `figure_rst` helper function to generate reST for image files
return figure_rst(image_names, gallery_conf['src_dir'])
然後,在我們的 conf.py
檔案中,我們包含以下程式碼
sphinx_gallery_conf = {
...
'image_scrapers': ('matplotlib', 'my_module._scraper.png_scraper'),
}
範例 3:使用 SVG 格式的 matplotlib#
sphinx_gallery.scrapers.matplotlib_scraper()
支援 **kwargs
來傳遞給 matplotlib.figure.Figure.savefig()
,其中一個是 format
引數。請參閱 編寫自訂圖像擷取器 以了解支援的格式。若要使用 SVG,您可以定義以下函式並確保它是可匯入的
def matplotlib_svg_scraper(*args, **kwargs):
return matplotlib_scraper(*args, format='svg', **kwargs)
然後在您的 conf.py
中
sphinx_gallery_conf = {
...
'image_scrapers': ("sphinxext.matplotlib_svg_scraper",),
...
}
您也可以在每個圖像的基礎上使用不同的格式,但這需要編寫自訂的擷取器類別或函式。
範例 4:Mayavi 擷取器#
過去,Sphinx-Gallery 支援擷取 Mayavi 圖形以及 matplotlib 圖形。然而,由於維護擷取器的複雜性,此支援已在 0.12.0 版本中被棄用。若要繼續使用 Mayavi 擷取,請考慮使用類似以下的方法
from sphinx_gallery.scrapers import figure_rst
def mayavi_scraper(self, block, block_vars, gallery_conf):
from mayavi import mlab
image_path_iterator = block_vars['image_path_iterator']
image_paths = list()
e = mlab.get_engine()
for scene, image_path in zip(e.scenes, image_path_iterator):
try:
mlab.savefig(image_path, figure=scene)
except Exception:
mlab.close(all=True)
raise
# make sure the image is not too large
scale_image(image_path, image_path, 850, 999)
if 'images' in gallery_conf['compress_images']:
optipng(image_path, gallery_conf['compress_images_args'])
image_paths.append(image_path)
mlab.close(all=True)
return figure_rst(image_paths, gallery_conf['src_dir'])
將自訂擷取器與 Sphinx-Gallery 整合#
Sphinx-Gallery 計畫在內部只維護一個擷取器:matplotlib。如果您在此擷取器中擴展或修正錯誤,我們歡迎 PR 來改進它!
另一方面,如果您為不同的繪圖函式庫開發了自訂擷取器,且該擷取器對更廣泛的社群有幫助,我們鼓勵您讓它與 Sphinx-Gallery 協同運作,然後在外部 (可能在它擷取的套件中) 維護它,然後將其與 Sphinx-Gallery 整合並宣傳。您可以
將其貢獻到 重設模組 中外部支援的擷取器清單。
選用:在您的模組根目錄新增自訂勾點以簡化擷取器的使用。以 PyVista 為例,新增
pyvista._get_sg_image_scraper()
以回傳要由 Sphinx-Gallery 使用的callable
擷取器,允許 PyVista 使用者只需像使用'matplotlib'
一樣使用字串。sphinx_gallery_conf = { ... 'image_scrapers': ('pyvista',) }
Sphinx-Gallery 將匯入指定的模組 (此處為
pyvista
) 並使用其中定義的_get_sg_image_scraper
函式作為擷取器。
在每個範例之前重設#
Sphinx-Gallery 支援在每個範例腳本執行之前和/或之後執行的「重設」函式。這在 Sphinx-Gallery 中原生使用,以「重設」視覺化套件 matplotlib
和 seaborn
的行為 (重設模組)。但是,此功能可用於重設其他函式庫、修改原生重設函式庫的重設行為,或在每個腳本的開始和/或結束時執行任意自訂函式。
這是透過將自訂函式新增到 conf.py
中定義的重設元組來完成的。此函式應接受兩個變數:一個名為 gallery_conf
的字典 (即您的 Sphinx-Gallery 設定) 和一個名為 fname
的字串 (即目前正在執行的 Python 腳本的檔案名稱)。通常不需要使用這些變數來執行您想要的任何重設行為,但為了相容性,必須將它們包含在函式定義中。
例如,若要將 matplotlib 重設為始終使用 ggplot
樣式,您可以執行以下操作
def reset_mpl(gallery_conf, fname):
from matplotlib import style
style.use('ggplot')
任何自訂函式都可以在 conf.py
中定義 (或匯入) 並提供給 reset_modules
設定鍵。若要新增上述定義的函式 (假設您已使其可匯入)
sphinx_gallery_conf = {
...
'reset_modules': ("sphinxext.reset_mpl", "seaborn"),
}
在上面的設定中,"seaborn"
指的是原生 seaborn 重設函式 (請參閱 重設模組)。
注意
不鼓勵使用諸如 reset_mpl
之類的重設器,這些重設器會偏離使用者在手動執行範例時所體驗的標準行為,因為這會導致渲染的範例與本機輸出之間不一致。
如果自訂函式需要知道它是在範例之前或之後執行,則可以使用包含三個參數的函式簽章,其中第三個參數必須命名為 when
def reset_mpl(gallery_conf, fname, when):
import matplotlib as mpl
mpl.rcParams['lines.linewidth'] = 2
if when == 'after' and fname=='dashed_lines':
mpl.rcParams['lines.linestyle'] = '-'
傳遞給 when
的值可以是 'before'
或 'after'
。如果 設定 中的 reset_modules_order
設定為 'before'
或 'after'
,則 when
的值將始終與 reset_modules_order
的設定值相同。此函式簽名僅在與設定為 'both'
的 reset_modules_order
結合使用時才有用。
修改 Sphinx-Gallery CSS#
Sphinx-Gallery 的 .css
檔案控制範例庫的外觀,您可以在這裡找到。這些預設的 .css
檔案會新增到您的建置中。具體來說,它們會複製到您的 gallery_dir
的 _build/html/_static/
中。
您可以使用Sphinx 設定 html_static_path
來新增您自己的自訂 .css
檔案。例如,在您的 conf.py
檔案中使用 html_static_path
設定,列出任何包含您的自訂靜態檔案的路徑。
html_static_path = ['_static']
# Custom CSS paths should either relative to html_static_path
# or fully qualified paths (eg. https://...)
html_css_files = ['my_custom.css', 'other_change.css']
預設的 Sphinx-Gallery .css
檔案會複製到您的建置中,順序在您的 html_static_path
設定中的檔案**之後**。這表示您 html_static_path
中與 Sphinx-Gallery .css
檔案同名的檔案將會被覆寫。您可以輕鬆避免這種情況,因為所有 Sphinx-Gallery .css
檔案都加上了 'sg_' 前綴 (例如,'sg_gallery.css')。有關此的更多詳細資訊,請參閱PR #845。
例如,自訂 css 可以用於修改程式碼連結和縮圖大小的外觀。
停用滑鼠懸停時的縮圖文字#
.sphx-glr-thumbcontainer[tooltip]:hover::before,
.sphx-glr-thumbcontainer[tooltip]:hover::after {
display: none;
}
僅使用 Sphinx-Gallery 樣式#
如果您只想使用 sphinx-Gallery CSS 檔案,而不是使用 sphinx_gallery.gen_gallery
擴充功能,您可以在 conf.py
中使用
extensions = ['sphinx_gallery.load_style']
這只會導致將 gallery.css
檔案新增到您的建置中。