[英]How to annotate 3d plot on Matplotlib?
I am trying to annotate a word text on my 3d plot diagram, I know ax.text is able to plot the text on my 3d plot however, the plt.annotate does a better job at that as it arrows the text to the coordinate which is what I need. I am trying to annotate a word text on my 3d plot diagram, I know ax.text is able to plot the text on my 3d plot however, the plt.annotate does a better job at that as it arrows the text to the coordinate which是我需要的。 Is there any way to use plt.annotate to plot on a 3d diagram?
有没有办法在 3d 图上使用 plt.annotate 到 plot ? I only know that it works on 2d.
我只知道它适用于二维。 Do let me know of a solution.
请让我知道解决方案。
plt.annotate(s='pppppp', xy=(1.5,0), xytext=(1.5,0)) //doesnt work on 3d
ax.text(1.5,0,0,'pppppp')
If you look the source code: https://matplotlib.org/3.1.1/_modules/mpl_toolkits/mplot3d/axes3d.html#Axes3D andhttps://matplotlib.org/_modules/matplotlib/axes/_axes.html#Axes , you will see that there is no ax.annotate()
method for 3d plots.如果查看源代码: https://matplotlib.org/3.1.1/_modules/mpl_toolkits/mplot3d/axes3d.html#Axes3D和https://matplotlib.org/_modules/matxeslib/_axes. ,您将看到 3d 图没有
ax.annotate()
方法。 Therefore, ax.annotate()
get's called as an Axes
method.因此,
ax.annotate()
get 被称为Axes
方法。 Therefore, it does not have the appropriate conversions for 3d plots.因此,它没有适合 3d 图的转换。 One way to get around this is by following this post's instructions Matplotlib: Annotating a 3D scatter plot .
解决这个问题的一种方法是按照这篇文章的说明Matplotlib: Annotating a 3D scatter plot 。
Follows an example using the post's solutions:以下是使用帖子解决方案的示例:
from mpl_toolkits.mplot3d.proj3d import proj_transform
from matplotlib.text import Annotation
import matplotlib as mpl
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(projection="3d")
class Annotation3D(Annotation):
'''Annotate the point xyz with text s'''
def __init__(self, s, xyz, *args, **kwargs):
Annotation.__init__(self,s, xy=(0,0), *args, **kwargs)
self._verts3d = xyz
def draw(self, renderer):
xs3d, ys3d, zs3d = self._verts3d
xs, ys, zs = proj_transform(xs3d, ys3d, zs3d, renderer.M)
self.xy=(xs,ys)
Annotation.draw(self, renderer)
def annotate3D(ax, s, *args, **kwargs):
'''add anotation text s to to Axes3d ax'''
tag = Annotation3D(s, *args, **kwargs)
ax.add_artist(tag)
return tag
annotate3D(ax, "HEllo world", [1, 1, 1])
plt.show()
Here is my modification of p479h's answer.这是我对 p479h 答案的修改。
It exposes Annotation3D.xy
for public access;它公开
Annotation3D.xy
以供公众访问; following Annotation.xy
's nature.遵循
Annotation.xy
的性质。
annotateND
returns 2D or 3D annotation based on type of ax
annotateND
根据ax
的类型返回 2D 或 3D 注释
from typing import Optional, Tuple, Union
from matplotlib.text import Annotation
from matplotlib import pyplot as plt
from mpl_toolkits import mplot3d as plt3d
class Annotation3D(Annotation):
"""
Annotation for 3D axes
Args:
text: text to display as annotation
xyz: annotation co-ordinates
*args: passed to `matplotlib.text.Annotation`
**kwargs: passed to `matplotlib.text.Annotation`
"""
def __init__(self, text: str, xyz: Tuple[float, float, float], *args,
**kwargs):
Annotation.__init__(self, text, xy=(0, 0), *args, **kwargs)
# 3D position
self._xyz = xyz
# Hard-set 2D projection
self._xy: Optional[Tuple[float, float]] = None
@property
def xy(self):
if self._xy is not None:
return self._xy
*xy2d, _ = plt3d.proj3d.proj_transform(*self._xyz, self.axes.M)
return xy2d
@xy.setter
def xy(self, val):
# publicly set
self._xy = val
@xy.deleter
def xy(self):
self._xy = None
# replace ax.annotate(*args, **kwargs) by annotateND(ax, *args, **kwargs)
def annotateND(ax: Union[plt.Axes, plt3d.axes3d.Axes3D], text: str,
xy: Tuple[float, ...], *args, **kwargs) -> Union[Annotation3D, Annotation]:
"""
Add annotation to 3D axes
Args:
ax: target (parent) axes
text: Annotation text
xy: annotation co-ordinates
*args: passed to `matplotlib.text.Annotation`
**kwargs: passed to `matplotlib.text.Annotation`
Returns:
AnnotationD
"""
if isinstance(ax, plt3d.axes3d.Axes3D):
a = Annotation3D(text, xy, *args, **kwargs)
ax.add_artist(a)
return a
return ax.annotate(text, xy, *args, **kwargs)
A step towards seamlessly replacing all ax.annotate(*args, **kwargs)
with annotateND(ax, *args, **kwargs)
for 2D or 3D axes.向 2D 或 3D 轴的
annotateND(ax, *args, **kwargs)
无缝替换所有ax.annotate(*args, **kwargs)
迈出了一步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.