342 words
1 minute
如何美化 Matplotlib 3D坐标系
前言
~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-8import matplotlib.pyplot as pltfrom sklearn.decomposition import PCAfrom matplotlib.gridspec import GridSpecfrom sklearn.datasets import make_s_curvefrom 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
Share
If this article helped you, please share it with others!
如何美化 Matplotlib 3D坐标系
https://blog.aegisr.xyz/posts/beautify-matplotlib-3d-axis/ Some information may be outdated
Related Posts Smart
1
如何美化 Matplotlib 的工具栏和绘图风格
技术 matplotlib 功能十分强大,就是工具栏丑了点。本文介绍如何魔改 matplotlib 的工具栏样式,并分享一份按照 MATLAB 编写的 matplotlib 样式文件。
2
如何在pyqt中实现丝滑滚动字幕
技术 通过定时器定时刷新加绘制两段完整的字符串,实现 PyQt 中的丝滑滚动字幕效果.
3
如何使用 C++ 和 OpenCV 实现截屏
技术 使用 Windows API 和 OpenCV 实现屏幕截屏,包含屏幕缩放率的计算,支持截取指定区域。
4
IDEA 添加 Maven Archetype 无效的处理
技术 在 IDEA 中点击新建 Maven 模块,会发现他已经为我们罗列出来了许多的 archetype,但有些时候满足不了我们的需求。
5
《声之形》:声音若有形状,那一定是和解的模样
小说 初看时,我以为它在讲校园欺凌;再看时,我发觉它在讲自我救赎。