該儲存庫包含我們在撰寫科學論文時發現有用/重要的工具、最佳實踐、技巧和其他指南的清單。有些是風格問題(我們傾向於遵循《芝加哥風格手冊》的指導方針),我們很清楚其他人喜歡以不同的方式做事,但我們無論如何都會列出它們以獲得一致的指導。請隨意適應、改變、忽略甚至挑戰我們所寫的一切!
排版是透過排列類型(即字母和符號)來組成文字。這主要是一個美學問題,但漂亮的排版使文件更容易閱讀,更令人愉悅,幫助讀者理解資訊。
我們在下面列出了一些排版技巧和工具,可在您撰寫文件時為您提供協助。有些技巧是特定於 LaTeX 的,但其他技巧無論您使用什麼都適用。
編寫 LaTeX 文件時,在來源文件中每行放置一個句子。寫:
This is my first sentence.
This is the second one.
而不是:
This is my first sentence. This is the second one.
這樣做的主要原因是原始程式碼控制和協作:在查看提交的變更時,如果它們各自位於單獨的行上,則更容易識別更改了哪些句子。因此,您的同事將能夠更輕鬆地看到更改。
另一個好處是,當我們的 LaTeX 編譯器僅給出行號時,您將能夠更好地識別錯誤。
下面我們將提到兩種大小寫:
對所有章節、小節等標題使用標題格式。為了幫助您使用正確的單字大寫,有一個方便的網站:capitalizemytitle.com。
有時,物件的名稱(例如圖、表、圖形或演算法)及其參考號會分成兩行。例如,物件的名稱可能位於一行,而參考號碼出現在下一行。
為了確保 LaTeX 將物件名稱及其引用保留在同一行,可以在物件和引用之間使用字元~
。透過以這種方式使用波浪號字元~
,您可以避免尷尬的換行符並保持 LaTeX 文件中物件名稱和引用編號的格式一致。
Figure~ ref { fig:example } displays that the project ...
為了確保您不會忘記使用波浪號字符,您可以透過建立自訂自動化命令來簡化流程。這是一個例子:
newcommand { refalg }[1]{Algorithm~ ref {# 1 }}
newcommand { refapp }[1]{Appendix~ ref {# 1 }}
newcommand { refchap }[1]{Chapter~ ref {# 1 }}
newcommand { refeq }[1]{Equation~ ref {# 1 }}
newcommand { reffig }[1]{Figure~ ref {# 1 }}
newcommand { refsec }[1]{Section~ ref {# 1 }}
newcommand { reftab }[1]{Table~ ref {# 1 }}
一旦定義了這些命令,就不必寫:
Figure~ ref { fig:example }
只需輸入:
reffig {fig:example}
(完整範例)
booktabs 可以幫助您製作乾淨、美觀的表格。
usepackage { booktabs }
% --
begin { table }
centering
begin { tabular }{lcc}
toprule
& multicolumn {2}{c}{Data} \ cmidrule (lr){2-3}
Name & Column 1 & Another column \
midrule
Some data & 10 & 95 \
Other data & 30 & 49 \
addlinespace
Different stuff & 99 & 12 \
bottomrule
end { tabular }
caption {My caption.}
label { tab-label }
end { table }
一般來說,避免在表格中使用垂直線。相反,如果您想對列進行分組,請使用cmidrule
在標題中進行。您也可以使用addlinespace
以間距取代水平線。
列標題應使用句子格式大寫(請參閱http://www.chicagomanualofstyle.org/15/ch13/ch13_sec019.html)。
您可以在此處找到有關表格格式的更多建議:http://www.inf.ethz.ch/personal/markusp/teaching/guides/guide-tables.pdf。這是一個很好的 GIF,它說明了其中一些規則:
(完整範例)
使用 siunitx 套件格式化所有數字、貨幣、單位等:
usepackage { siunitx }
% ---
This thing costs SI {123456}{ $ }.
There are num {987654} people in this room, SI {38}{ percent } of which are male.
您也可以使用它對數字進行四捨五入:
usepackage { siunitx }
% ---
sisetup {
round-mode = places,
round-precision = 3
} %
You can also round numbers, for example num {1.23456}.
最後,它可以幫助您更好地對齊表格中的數字:
usepackage { booktabs }
usepackage { siunitx }
% ---
begin { table }
centering
begin { tabular }{lS}
toprule
Name & {Value} \ % headers of S columns have to be in {}
midrule
Test & 2.3456 \
Blah & 34.2345 \
Foo & -6.7835 \
Bar & 5642.5 \
bottomrule
end { tabular }
caption {Numbers alignment with texttt { siunitx }.}
end { table }
(完整範例)
在編寫方程式時,以連貫一致的方式來編寫變數、向量、矩陣等會很有幫助。
我們提出以下書寫數學的規則:
$x$
)$mathbold{x}$
)$mathbold{X}$
)$X$
) mathbold
指令來自fixmath
軟體包,類似於boldmath
或bm
,不同之處在於所有符號都為斜體,甚至是希臘字母(其他軟體包不使用斜體希臘字母)。
在變數上新增索引或指數時,請確保將它們新增至變數樣式之外,即編寫$mathbold{x}_i$
而不是$mathbold{x_i}$
。
因為我們經常引用變量,所以我們建議定義以下兩個命令:
renewcommand { vec }[1]{ mathbold {#1}}
newcommand { mat }[1]{ mathbold {#1}}
然後,您可以在文件中使用$vec{x}$
和$mat{X}$
。如果您決定更改矩陣格式化方式,只需更改mat
命令,它將更新整個文件。
我們也建議為您最常使用的變數定義命令。例如,如果您經常使用vec{x}
和mat{X}
,請考慮定義以下命令:
newcommand { vx }{ vec {x}}
newcommand { vX }{ mat {X}}
然後,您可以編寫更緊湊的方程式: $vx^T vy = vZ$
。
請注意,您應該始終根據變數的類型來設定變數的樣式。例如,向量vx
的第 $i$ 個元素是x_i
而不是vx_i
(它是一個數字)。類似地,如果您有一個矩陣vX
,則可以將其第i列稱為vx_i
(它是一個向量,因此以粗體顯示),如果其元素x_{ij}
,而不是vX_i
和vX_{ij}
則可稱為一列。
使用(...)
編寫內聯方程式。您也可以使用$...$
,但它是一個 TeX 指令,會給出更晦澀的錯誤訊息。
要在自己的行上編寫中心方程,請不要使用$$...$$
(這是使用 LaTeX 的致命罪過之一)。它有效,但給出了錯誤的間距。使用begin{equation*}
或begin{align*}
代替。
(完整範例)
對於較長的文檔,例如碩士或博士論文,在參考書目中提供回溯參考文獻可能會很有用,以顯示參考文獻的引用位置。為此,只需將選項backref=page
新增至hyperref
:
usepackage [ backref=page ]{ hyperref }
您可以使用以下命令自訂反向引用的顯示方式:
renewcommand *{ backref }[1]{}
renewcommand *{ backrefalt }[4]{{ footnotesize [ %
ifcase #1 Not cited. %
or Cited on page~#2 %
else Cited on pages #2 %
fi %
]}}
圖表是任何論文的重要組成部分,因為它們可以向讀者傳達您的結果。您應該考慮每個圖表上的信息告訴您的讀者什麼,並且有足夠的資訊來支持您的訊息,而不是更多。例如,如果您想顯示 2d 點中的模式(有兩個分開的簇),則無需在軸上放置刻度和值(比例並不重要)?數字不宜太複雜。最好用多個圖形來傳達一兩個訊息(方法 A 比 B 更好,但收斂速度較慢),而不是用一個大而混亂的圖形。
有些圖是手工製作的,例如,為了解釋系統或給出全局圖景,而有些圖是數據驅動的,即說明一些數據。這些資料驅動的圖形應該盡可能編寫腳本:理想情況下,如果您的資料發生變化,您應該只需要運行一次腳本來更新您的圖形,而無需任何其他幹預(設定視圖、縮放、保存/裁剪圖形) , ETC)。同樣,如果生成圖形所需的數據需要花費數秒以上的時間才能生成,則您應該使用第一個腳本來計算和保存數據,並使用第二個腳本來繪製數據。這樣,您在處理繪圖時將節省大量時間:您不必在對圖形進行每個小更改後等待查看其效果。
我們還建議將用於生成圖形的命令保存在 LaTeX 檔案中,例如作為圖形上方的註釋,尤其是在腳本需要參數的情況下。
documentclass { article }
usepackage { graphicx }
begin { document }
% python figure_example.py --save ../../examples/figure/figure.eps
begin { figure }
centering
includegraphics {figure.eps}
caption {Example of a sigmoid function}
end { figure }
end { document }
如果可能,所有圖形的標籤、軸等都應使用相同的字體。實現此目的的一種解決方案是在生成圖形的腳本中定義圖形的大小,而不是在文件中重新調整圖形的大小(例如,不要在 LaTeX 文件中將圖形的寬度設為textwidth
)。
為了獲得一致的數字,我們建議使用輔助腳本,類似於我們的plot_utils.py
。使用此腳本,您只需呼叫figure_setup()
函數來定義所有尺寸,然後建立所需尺寸的圖形並儲存。
import argparse
import matplotlib . pyplot as plt
import numpy as np
import plot_utils as pu
def main ( args ):
x = np . linspace ( - 6 , 6 , 200 )
y = 1 / ( 1 + np . exp ( - x ))
pu . figure_setup ()
fig_size = pu . get_fig_size ( 10 , 5 )
fig = plt . figure ( figsize = fig_size )
ax = fig . add_subplot ( 111 )
ax . plot ( x , y , c = 'b' , lw = pu . plot_lw ())
ax . set_xlabel ( '$x$' )
ax . set_ylabel ( '$ \ sigma(x)$' )
ax . set_axisbelow ( True )
plt . grid ()
plt . tight_layout ()
if args . save :
pu . save_fig ( fig , args . save )
else :
plt . show ()
if __name__ == '__main__' :
parser = argparse . ArgumentParser ()
parser . add_argument ( '-s' , '--save' )
args = parser . parse_args ()
main ( args )
我們建議將所有資料儲存為EPS
格式。這樣,您就可以使用latex
和pdflatex
來產生文檔,並享受美麗的向量圖形和文字。
截至 2015 年 9 月,在 Mac OS X 以及最新版本的 Python、Matplotlib 和 TeX Live 上,列印直接從 Matplotlib 儲存為PDF
圖形時會出現品質損失。印在真紙上就變得清晰;親自嘗試一下。這是另一個偏好將 Matplotlib 產生的圖片保存在EPS
中的另一個原因。如果您確實只想保留圖形的 PDF 版本,請使用epspdf
命令列工具——生成的 PDF 將比 Matplotlib 直接生成的 PDF 更好。
為了完整起見,請注意還有另一個 Matplotlib 後端 PGF,它可以產生稍微更好的結果。然而,截至 2015 年 9 月,產生的 PDF 的重量是使用預設後端和epspdf
獲得的 PDF 的兩倍。
Matplotlib,即使使用緊湊的佈局功能,有時也會在邊距中添加過多的空白。 pdfcrop
是一個漂亮的命令列工具,可將 PDF 裁切為其最緊密的邊界框。
如果繪圖中有許多資料點,則產生的 EPS 檔案可能會非常大。您可以將圖形儲存為 PNG 文件,但這會導致文字模糊。解決方案是將圖形的部分進行柵格化,即告訴matplotlib
資料點必須在 EPS 檔案中呈現為點陣圖,而其餘部分則採用向量格式。
您可以將rasterized=True
關鍵字傳遞給matplotlib
中的大多數繪圖函數。您也可以使用zorder
使用不同的圖層,並告訴matplotlib
使用軸的set_rasterization_zorder()
方法對給定zorder
下面的所有圖層進行柵格化。有關光柵化的範例,請參閱figure_rasterized_example.py 和 http://matplotlib.org/examples/misc/rasterization_demo.html。