axisartist 工具組#
警告
axisartist 使用自訂的 Axes 類別(衍生自 Matplotlib 原生的 Axes 類別)。副作用是,某些命令(主要與刻度相關)無法運作。
axisartist 包含一個自訂的 Axes 類別,旨在支援曲線網格(例如,天文學中的世界座標系統)。與 Matplotlib 原生的 Axes 類別使用 Axes.xaxis 和 Axes.yaxis 來繪製刻度、刻度線等不同,axisartist 使用特殊的藝術家 (AxisArtist) 來處理彎曲座標系統的刻度、刻度線等。

由於它使用特殊的藝術家,因此某些適用於 Axes.xaxis 和 Axes.yaxis 的 Matplotlib 命令可能無法運作。
axisartist#
axisartist 模組提供一個自訂(且非常實驗性)的 Axes 類別,其中每個軸(左、右、上和下)都有一個單獨的相關藝術家,負責繪製軸線、刻度、刻度標籤和標籤。您也可以建立自己的軸,該軸可以穿過軸座標中的固定位置,或資料座標中的固定位置(即,當視圖限制變更時,軸會浮動)。
預設情況下,軸類別的 xaxis 和 yaxis 為不可見,並且有 4 個額外的藝術家負責繪製「左」、「右」、「下」和「上」四個軸脊線。它們以 ax.axis["left"]、ax.axis["right"] 等方式存取,即 ax.axis 是一個包含藝術家的字典(請注意,ax.axis 仍然是一個可呼叫的方法,其行為與 Matplotlib 中的原始 Axes.axis 方法相同)。
若要建立 Axes,
import mpl_toolkits.axisartist as AA
fig = plt.figure()
fig.add_axes([0.1, 0.1, 0.8, 0.8], axes_class=AA.Axes)
或建立子圖
fig.add_subplot(111, axes_class=AA.Axes)
# Given that 111 is the default, one can also do
fig.add_subplot(axes_class=AA.Axes)
例如,您可以使用以下方式隱藏右側和頂部的脊線
ax.axis["right"].set_visible(False)
ax.axis["top"].set_visible(False)

也可以新增水平軸。例如,您可以在 y=0 處有一個水平軸(在資料座標中)。
ax.axis["y=0"] = ax.new_floating_axis(nth_coord=0, value=0)

或具有一些偏移的固定軸
# make new (right-side) yaxis, but with some offset
ax.axis["right2"] = ax.new_fixed_axis(loc="right", offset=(20, 0))
使用 ParasiteAxes 的 axisartist#
axes_grid1 工具組中的大多數命令都可以採用 axes_class 關鍵字引數,並且這些命令會建立給定類別的 Axes。例如,若要建立具有 axisartist.Axes 的主子圖,
import mpl_toolkits.axisartist as AA
from mpl_toolkits.axes_grid1 import host_subplot
host = host_subplot(111, axes_class=AA.Axes)
以下是一個使用 ParasiteAxes 的範例。

曲線網格#
AxisArtist 模組背後的動機是支援曲線網格和刻度。

浮動軸#
AxisArtist 也支援外軸定義為浮動軸的浮動軸。

axisartist 名稱空間#
axisartist 名稱空間包含一個衍生的 Axes 實作。最大的差異在於,負責繪製軸線、刻度、刻度標籤和軸標籤的藝術家與 Matplotlib 的 Axis 類別分離,後者在原始的 Matplotlib 中不僅僅是藝術家。此變更主要是為了支援曲線網格。以下是 mpl_toolkits.axisartist.Axes 與 Matplotlib 原生 Axes 的幾個不同之處。
軸元素(軸線(脊線)、刻度、刻度標籤和軸標籤)由 AxisArtist 實例繪製。與 Axis 不同,左軸、右軸、上軸和下軸由不同的藝術家繪製。而且它們每個都可能有不同的刻度位置和不同的刻度標籤。
格線由 Gridlines 實例繪製。此變更的動機是,在曲線座標中,格線可能不會穿過軸線(即,沒有相關的刻度)。在原始的 Axes 類別中,格線會繫結至刻度。
必要時可以旋轉刻度線(即,沿著格線)
總之,所有這些變更都是為了支援
曲線網格。
浮動軸

mpl_toolkits.axisartist.Axes 類別定義了 axis 屬性,該屬性是一個 AxisArtist 實例的字典。預設情況下,此字典有 4 個 AxisArtist 實例,負責繪製左軸、右軸、下軸和上軸。
xaxis 和 yaxis 屬性仍然可用,但它們設定為不可見。由於使用單獨的藝術家進行軸渲染,因此 Matplotlib 中某些與軸相關的方法可能沒有效果。除了 AxisArtist 實例之外,mpl_toolkits.axisartist.Axes 還會具有 gridlines 屬性 (Gridlines),該屬性顯然會繪製格線。
在 AxisArtist 和 Gridlines 中,刻度和格線位置的計算都會委派給 GridHelper 類別的實例。mpl_toolkits.axisartist.Axes 類別使用 GridHelperRectlinear 作為格線協助程式。GridHelperRectlinear 類別是 Matplotlib 原生 Axes 的 xaxis 和 yaxis 的包裝函式,旨在以 Matplotlib 原生軸的方式運作。例如,使用 set_ticks 方法等方式變更刻度位置應如預期般運作。但是,藝術家屬性(例如,色彩)的變更通常不會生效,儘管已盡力確保會尊重一些經常變更的屬性(色彩等)。
AxisArtist#
AxisArtist 可以視為具有以下屬性的容器藝術家,這些屬性會繪製刻度、標籤等。
line
major_ticks, major_ticklabels
minor_ticks, minor_ticklabels
offsetText
label
line#
衍生自 Line2D 類別。負責繪製脊狀線。
major_ticks, minor_ticks#
衍生自 Line2D 類別。請注意,刻度是標記。
major_ticklabels, minor_ticklabels#
衍生自 Text。請注意,它不是 Text 藝術家的列表,而是一個單一的藝術家(類似於集合)。
axislabel#
衍生自 Text。
預設 AxisArtists#
預設情況下,會定義以下軸藝術家。
ax.axis["left"], ax.axis["bottom"], ax.axis["right"], ax.axis["top"]
頂部和右側軸的刻度標籤和軸標籤設定為不可見。
例如,如果您想要變更底部 x 軸的 major_ticklabels 的色彩屬性
ax.axis["bottom"].major_ticklabels.set_color("b")
同樣地,若要讓刻度標籤不可見
ax.axis["bottom"].major_ticklabels.set_visible(False)
AxisArtist 提供一個輔助方法來控制刻度、刻度標籤和標籤的可見性。若要讓刻度標籤不可見,
ax.axis["bottom"].toggle(ticklabels=False)
若要讓所有刻度、刻度標籤和(軸)標籤不可見
ax.axis["bottom"].toggle(all=False)
若要關閉所有項目但開啟刻度
ax.axis["bottom"].toggle(all=False, ticks=True)
若要開啟所有項目但關閉(軸)標籤
ax.axis["bottom"].toggle(all=True, label=False)
ax.axis 的 __getitem__ 方法可以採用多個軸名稱。例如,若要開啟「上」和「右」軸的刻度標籤,
ax.axis["top", "right"].toggle(ticklabels=True)
請注意,ax.axis["top", "right"]
會傳回一個簡單的 Proxy 物件,該物件會將以上程式碼轉譯為如下程式碼。
for n in ["top", "right"]:
ax.axis[n].toggle(ticklabels=True)
因此,for 迴圈中的任何傳回值都會被忽略。您不應將它用於簡單方法以外的任何用途。
就像清單索引 ":" 表示所有項目一樣,即
ax.axis[:].major_ticks.set_color("r")
變更所有軸的刻度色彩。
如何做#
變更刻度位置和標籤。
與原始 Matplotlib 的軸相同
ax.set_xticks([1, 2, 3])
變更軸屬性,例如色彩等。
變更適當藝術家的屬性。例如,若要變更刻度標籤的色彩
ax.axis["left"].major_ticklabels.set_color("r")
若要變更多個軸的屬性
ax.axis["left", "bottom"].major_ticklabels.set_color("r")
或變更所有軸的屬性
ax.axis[:].major_ticklabels.set_color("r")
若要變更刻度大小(長度),您需要使用 axis.major_ticks.set_ticksize 方法。若要變更刻度方向(刻度預設與刻度標籤方向相反),請使用 axis.major_ticks.set_tick_out 方法。
若要變更刻度和刻度標籤之間的間距,請使用 axis.major_ticklabels.set_pad 方法。
若要變更刻度標籤和軸標籤之間的間距,請使用 axis.label.set_pad 方法。
刻度標籤的旋轉和對齊#
這也與標準 Matplotlib 非常不同,而且可能會造成混淆。當您想要旋轉刻度標籤時,請先考慮使用 "set_axis_direction" 方法。
ax1.axis["left"].major_ticklabels.set_axis_direction("top")
ax1.axis["right"].label.set_axis_direction("left")

set_axis_direction 的參數是 ["left"、"right"、"bottom"、"top"] 其中之一。
您必須了解方向的一些基本概念。
有一個參考方向,其定義為座標增加時軸線的方向。例如,左 x 軸的參考方向是從下到上。
刻度、刻度標籤和軸標籤的方向、文字角度和對齊方式是根據參考方向來判斷的
label_direction 和 ticklabel_direction 是參考方向的右側 (+) 或左側 (-)。
刻度預設會朝向與刻度標籤相反的方向繪製。
刻度標籤和標籤的文字旋轉方向分別參考 ticklabel_direction 或 label_direction 屬性決定。刻度標籤和標籤的旋轉是錨定的。

另一方面,還有一個「axis_direction」的概念。這是針對每個「底部」、「左側」、「頂部」和「右側」軸的上述屬性的預設設定。
參考方向 |
標籤方向 |
標籤旋轉 |
水平對齊 |
垂直對齊 |
---|---|---|---|---|
左 |
'-' |
180 |
右 |
置中 |
底部 |
'+' |
0 |
置中 |
頂部 |
右 |
'+' |
0 |
右 |
置中 |
頂部 |
'-' |
180 |
置中 |
底部 |
參考方向 |
標籤方向 |
標籤旋轉 |
水平對齊 |
垂直對齊 |
---|---|---|---|---|
左 |
'-' |
90 |
右 |
置中 |
底部 |
'+' |
0 |
置中 |
基準線 |
右 |
'+' |
-90 |
右 |
置中 |
頂部 |
'-' |
180 |
置中 |
基準線 |
並且,'set_axis_direction("top")' 表示調整文字旋轉等設定,使其適用於「頂部」軸。軸方向的概念在彎曲軸中會更為清晰。

axis_direction 可以在 AxisArtist 層級調整,也可以在其子繪圖物件(例如,刻度、刻度標籤和軸標籤)的層級調整。
ax1.axis["left"].set_axis_direction("top")
會變更與「左」軸相關的所有繪圖物件的 axis_direction,而
ax1.axis["left"].major_ticklabels.set_axis_direction("top")
只會變更主要刻度標籤的 axis_direction。請注意,在 AxisArtist 層級設定 set_axis_direction 會變更 ticklabel_direction 和 label_direction,而變更刻度、刻度標籤和軸標籤的 axis_direction 不會影響它們。
如果您想讓刻度向外,刻度標籤在軸內,請使用 invert_ticklabel_direction 方法。
ax.axis[:].invert_ticklabel_direction()
一個相關的方法是「set_tick_out」。它會讓刻度向外(事實上,它會讓刻度朝向與預設方向相反的方向)。
ax.axis[:].major_ticks.set_tick_out(True)

總結來說,
AxisArtist 的方法
set_axis_direction:「左」、「右」、「底部」或「頂部」
set_ticklabel_direction:「+」或「-」
set_axislabel_direction:「+」或「-」
invert_ticklabel_direction
刻度的方法(major_ticks 和 minor_ticks)
set_tick_out:True 或 False
set_ticksize:以點為單位的尺寸
刻度標籤的方法(major_ticklabels 和 minor_ticklabels)
set_axis_direction:「左」、「右」、「底部」或「頂部」
set_rotation:相對於參考方向的角度
set_ha 和 set_va:請參閱下方
軸標籤的方法(label)
set_axis_direction:「左」、「右」、「底部」或「頂部」
set_rotation:相對於參考方向的角度
set_ha 和 set_va
調整刻度標籤對齊方式#
刻度標籤的對齊方式會經過特殊處理。請參閱下方

調整間距#
要變更刻度和刻度標籤之間的間距
ax.axis["left"].major_ticklabels.set_pad(10)
或刻度標籤和軸標籤之間的間距
ax.axis["left"].label.set_pad(10)

GridHelper#
要實際定義曲線座標,您必須使用自己的網格輔助器。提供了一個通用版本的網格輔助器類別,此類別應足以應付大多數情況。使用者可以提供兩個函數,定義從曲線座標到(直線)圖像座標的轉換(及其反向配對)。請注意,雖然刻度和網格是針對曲線座標繪製的,但軸本身的資料轉換 (ax.transData) 仍然是直線(圖像)座標。
from mpl_toolkits.axisartist.grid_helper_curvelinear \
import GridHelperCurveLinear
from mpl_toolkits.axisartist import Axes
# from curved coordinate to rectlinear coordinate.
def tr(x, y):
x, y = np.asarray(x), np.asarray(y)
return x, y-x
# from rectlinear coordinate to curved coordinate.
def inv_tr(x, y):
x, y = np.asarray(x), np.asarray(y)
return x, y+x
grid_helper = GridHelperCurveLinear((tr, inv_tr))
fig.add_subplot(axes_class=Axes, grid_helper=grid_helper)
您可以使用 Matplotlib 的 Transform 實例來代替(但必須定義反向轉換)。通常,曲線座標系統中的座標範圍可能有限,或可能有循環。在這些情況下,需要更客製化的網格輔助器版本。
import mpl_toolkits.axisartist.angle_helper as angle_helper
# PolarAxes.PolarTransform takes radian. However, we want our coordinate
# system in degree
tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform()
# extreme finder: find a range of coordinate.
# 20, 20: number of sampling points along x, y direction
# The first coordinate (longitude, but theta in polar)
# has a cycle of 360 degree.
# The second coordinate (latitude, but radius in polar) has a minimum of 0
extreme_finder = angle_helper.ExtremeFinderCycle(20, 20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),
)
# Find a grid values appropriate for the coordinate (degree,
# minute, second). The argument is a approximate number of grids.
grid_locator1 = angle_helper.LocatorDMS(12)
# And also uses an appropriate formatter. Note that the acceptable Locator
# and Formatter classes are different than that of Matplotlib's, and you
# cannot directly use Matplotlib's Locator and Formatter here (but may be
# possible in the future).
tick_formatter1 = angle_helper.FormatterDMS()
grid_helper = GridHelperCurveLinear(tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
tick_formatter1=tick_formatter1
)
同樣地,軸的 *transData* 仍然是直線座標(圖像座標)。您可以手動執行兩個座標之間的轉換,也可以為了方便起見而使用 Parasite Axes。
ax1 = SubplotHost(fig, 1, 2, 2, grid_helper=grid_helper)
# A parasite axes with given transform
ax2 = ax1.get_aux_axes(tr, "equal")
# note that ax2.transData == tr + ax1.transData
# Anything you draw in ax2 will match the ticks and grids of ax1.

FloatingAxis#
浮動軸是指其中一個資料座標固定的軸,也就是說,它的位置不是固定在 Axes 座標中,而是隨著軸的資料限制變更而變更。可以使用 *new_floating_axis* 方法建立浮動軸。但是,您有責任將產生的 AxisArtist 正確新增至軸。建議的方法是將其作為軸的 axis 屬性的項目新增。
# floating axis whose first (index starts from 0) coordinate
# (theta) is fixed at 60
ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60)
axis.label.set_text(r"$\theta = 60^{\circ}$")
axis.label.set_visible(True)
請參閱此頁的第一個範例。
目前限制和待辦事項#
程式碼需要更多精煉。以下是不完整的問題和待辦事項清單
沒有簡單的方法來支援使用者客製化的刻度位置(針對曲線網格)。需要建立新的 Locator 類別。
FloatingAxis 可能有座標限制,例如,x = 0 的浮動軸,但 y 僅從 0 跨越到 1。
FloatingAxis 的軸標籤位置需要選擇性地以座標值給定。例如,x=0 的浮動軸,標籤在 y=1