python - 如何在 3D 图中旋转偏移文本?

标签 python matplotlib

我正在尝试在 Matplotlib 中绘制一个 3D 图形,并使用偏移文本中的比例。为此,我使用了 ImportanceOfBeingErnest's custom axis' major formatter 以便在 latex 格式中使用此比例:

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from mpl_toolkits.mplot3d import Axes3D  
from matplotlib import cm
import numpy as np

class OOMFormatter(matplotlib.ticker.ScalarFormatter):
    def __init__(self, order=0, fformat="%1.1f", offset=True, mathText=True):
        self.oom = order
        self.fformat = fformat
        matplotlib.ticker.ScalarFormatter.__init__(self,useOffset=offset,useMathText=mathText)
    def _set_order_of_magnitude(self):
        self.orderOfMagnitude = self.oom
    def _set_format(self, vmin=None, vmax=None):
        self.format = self.fformat
        if self._useMathText:
             self.format = r'$\mathdefault{%s}$' % self.format


x = np.linspace(0, 22, 23)
y = np.linspace(-10, 10, 21)
X, Y = np.meshgrid(x, y)
V = -(np.cos(X/10)*np.cos(Y/10))**2*1e-4

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
surf = ax.plot_surface(X, Y, V, cmap=cm.jet,
                       linewidth=0, antialiased=False)
ax.zaxis.set_major_formatter(OOMFormatter(int('{:.2e}'.format(np.min(V)).split('e')[1]), mathText=True))
ax.zaxis.set_rotate_label(False) 
ax.set_xlabel(r'$x$ (cm)', size=20, labelpad=10)
ax.set_ylabel(r'$y$ (cm)', size=20, labelpad=10)
ax.set_zlabel(r'$A_z$', size=20, labelpad=10)
这导致下图:
Figure 1: initial plot
请注意,比例(zaxis 偏移文本,x 10^{-4})旋转了 90 度。为了解决这个问题,我尝试访问偏移文本的元素并将其旋转设置为 0:
ax.zaxis.get_offset_text().set_rotation(0)
ax.zaxis.get_offset_text().get_rotation()
>>> 0
这是没有用的,因为偏移文本没有旋转一英寸。然后我尝试在运行 plot 函数时打印文本对象:
surf = ax.plot_surface(X, Y, V, cmap=cm.jet,
                       linewidth=0, antialiased=False)
.
.
.
print(ax.zaxis.get_offset_text())
>>>Text(1, 0, '')
这让我觉得偏移文本可能没有存储在这个变量中,但是当我在不调用 plot 函数的情况下运行相同的命令时,它会返回我期望它返回的内容:
print(ax.zaxis.get_offset_text())
>>>Text(-0.1039369506424546, 0.050310729257045626, '$\\times\\mathdefault{10^{−4}}\\mathdefault{}$')
我究竟做错了什么?

最佳答案

我不得不说,这是一个很好的和有趣的问题,我为此挠了一阵子……
您可以使用 ot = ax.zaxis.get_offset_text() 访问偏移文本.很容易隐藏它ot.set_visible(False) ,但由于某些未知原因,它无法旋转 ot.set_rotation(90) .我试图用 print(ot.get_text()) 打印文本值,但这不会输出任何内容,除非绘图已经绘制。只有在绘图完成后才返回'$\\times\\mathdefault{10^{-4}}\\mathdefault{}$' .这告诉我这可能是问题的根源。无论您对偏移文本应用什么,它都会在图形生成的最后一步被覆盖,并且会失败。
我得出的结论是,最好的方法是隐藏偏移量并在图形上注释自己。您可以使用以下代码段以编程方式执行此操作:

ax.zaxis.get_offset_text().set_visible(False)
exponent = int('{:.2e}'.format(np.min(V)).split('e')[1])
ax.text(ax.get_xlim()[1]*1.1, ax.get_ylim()[1], ax.get_zlim()[1],
        '$\\times\\mathdefault{10^{%d}}\\mathdefault{}$' % exponent)
结果:
graph with custom offset text

关于python - 如何在 3D 图中旋转偏移文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68143699/

相关文章:

python - 如何用 pandas 和 matplotlib 绘制两个分类(名义)系列之间的比较

python - 如何在 matplotlib 中可视化 95% 的置信区间?

Python 与正在运行的进程交互

python - 即使在 headless 模式下,是否可以在带有 Chrome 的 Selenium 上使用 `element.click()`?

python - Pycharm 与使用相等运算符执行的 None 比较

python - 使用在 windows 上为 linux 创建的 conda env

python - Twisted:如何知道何时收到所有数据?

python - 在 matplotlib 中绘制单元格平均值而不是线图

python - Seaborn distplot 与来自不同数组的 rugplot

python - Matplotlib 动画 : first frame remains in canvas when using blit