前言
~mpl_toolkits.mplot3d
生成的3D坐標系背景色是灰色的,刻度線也向內延伸了,如果搭配上其他白色背景的 2D 圖,看起來很奇怪,比如下面這張圖:
網上有一些辦法可以將3D坐標區的背景設置為白色,比如:
ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 1.0))
使用這段代碼可以改變背景色,但是解決不了刻度線向內延伸的問題,有沒有什么辦法可以一勞永逸的解決這兩個問題呢?
修改背景色
在 ~mpl_toolkits.mplot3d.axis3d.Axis
的類屬性定義處,有:
_AXINFO = {
'x': {
'i': 0,
'tickdir': 1,
'juggled': (1, 0, 2),
'color': (0.95, 0.95, 0.95, 0.5),
},
'y': {
'i': 1,
'tickdir': 0,
'juggled': (0, 1, 2),
'color': (0.90, 0.90, 0.90, 0.5),
},
'z': {
'i': 2,
'tickdir': 0,
'juggled': (0, 2, 1),
'color': (0.925, 0.925, 0.925, 0.5),
},
}
很容易看出 color
的值控制着3個平面的背景色,把 3 個 color
的值全部改為 (1, 1, 1, 1)
,背景色就全部變成白色的了。
修改刻度線
在 ~mpl_toolkits.mplot3d.axis3d.Axis
的構造函數中,有:
self._axinfo.update({
'label': {
'va': 'center',
'ha': 'center'
},
'tick': {
'inward_factor': 0.2,
'outward_factor': 0.1,
'linewidth': {
True: ( # major
rcParams['xtick.major.width'] if adir in 'xz' else
rcParams['ytick.major.width']),
False: ( # minor
rcParams['xtick.minor.width'] if adir in 'xz' else
rcParams['ytick.minor.width']),
}
},
'axisline': {
'linewidth': rcParams['axes.linewidth'],
'color': rcParams['axes.edgecolor'],
},
'grid': {
'color': rcParams['grid.color'],
'linewidth': rcParams['grid.linewidth'],
'linestyle': rcParams['grid.linestyle'],
},
})
測試一波后,發現 inward_factor
控制刻度線向外延伸部分的長度,outward_factor
控制向內延伸部分的長度,把 inward_factor
的值改為 0.3 ,outward_factor
的值改為0,就再也見不到煩人的內刻度線了( ̄︶ ̄)↗ 。
測試
# coding:utf-8
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from matplotlib.gridspec import GridSpec
from sklearn.datasets import make_s_curve
from sklearn.manifold import MDS, LocallyLinearEmbedding, Isomap
plt.style.use(['matlab'])
# 創建數據
X, c = make_s_curve(1000, random_state=0)
# 數據降維
X_mds = MDS().fit_transform(X)
X_pca = PCA(2).fit_transform(X)
X_iso = Isomap(n_neighbors=10).fit_transform(X)
X_lle = LocallyLinearEmbedding(n_neighbors=10).fit_transform(X)
Xs = [X_pca, X_iso, X_lle, X_mds]
titles = [
'Principal Components Analysis', 'Isometric Mapping',
'Locally Linear Embedding', 'Multiple Dimensional Scaling'
]
# 繪制圖像
fig = plt.figure('S型數據集上的流形學習', tight_layout=True)
gs = GridSpec(2, 3)
ax = fig.add_subplot(gs[:, 0], projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=c, cmap=plt.cm.Spectral)
ax.set(title='S curve', xlabel='x', ylabel='y', zlabel='z')
ax.view_init(14, -64)
for i, (x, title) in enumerate(zip(Xs, titles)):
ax = fig.add_subplot(gs[i // 2, i + 1 - 2 * (i // 2)])
ax.scatter(x[:, 0], x[:, 1], c=c, cmap=plt.cm.Spectral)
ax.set_title(title)
plt.show()
代碼 plt.style.use(['matlab'])
中用到的 mplstyle
文件見《如何美化 Matplotlib 的工具欄和繪圖風格》,運行得到的圖像如下:
至此美化大功告成,喜歡的話就點個贊吧 o( ̄▽ ̄)d