我试图从一些单独的轴(如matplotlib.lines.Line2D
对象)中提取线条(作为matplotlib.axes.Axes
对象),并将其绘制在不同的图(例如子图)上。我正尝试使用Axes.add_line()
(如前所述的这里函数)来实现这一点,如下所示:
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
figS = Figure(figsize=(15, 5))
figC = Figure(figsize=(15, 5))
figT = Figure(figsize=(15, 5))
yS = np.sin(t)
yC = np.cos(t)
yT = np.tan(t)
axS = figS.add_axes([0, 0, 1, 1])
lS = axS.plot(t, yS)
axC = figC.add_axes([0, 0, 1, 1])
lC = axC.plot(t, yC)
axT = figT.add_axes([0, 0, 1, 1])
lT = axT.plot(t, yT)
supSFig, axsSF = plt.subplots(3, figsize=(15, 15))
axsSF[0].add_line(lS)
axsSF[1].add_line(lC)
axsSF[2].add_line(lT)
但我收到以下警告/错误:
MatplotlibDeprecationWarning: Passing argument *line* of unexpected type list to add_line which only accepts <class 'matplotlib.lines.Line2D'> is deprecated since 3.5 and will become an error two minor releases later.
AttributeError Traceback (most recent call last)
Input In [79], in <cell line: 2>()
1 supSFig, axsSF = plt.subplots(3, figsize=(15, 15))
----> 2 axsSF[0].add_line(lS)
3 axsSF[1].add_line(lC)
4 axsSF[2].add_line(lT)
File /usr/local/lib/python3.8/dist-packages/matplotlib/axes/_base.py:2279, in _AxesBase.add_line(self, line)
2275 """
2276 Add a `.Line2D` to the Axes; return the line.
2277 """
2278 self._deprecate_noninstance('add_line', mlines.Line2D, line=line)
-> 2279 self._set_artist_props(line)
2280 if line.get_clip_path() is None:
2281 line.set_clip_path(self.patch)
File /usr/local/lib/python3.8/dist-packages/matplotlib/axes/_base.py:1101, in _AxesBase._set_artist_props(self, a)
1099 def _set_artist_props(self, a):
1100 """Set the boilerplate props for artists added to Axes."""
-> 1101 a.set_figure(self.figure)
1102 if not a.is_transform_set():
1103 a.set_transform(self.transData)
AttributeError: 'list' object has no attribute 'set_figure'
我从我转介在文章中提到的日期了解到,这在早期版本中是可能的,现在是一个不受欢迎的特性。我正在使用matplotlib
版本的3.5.1
。现在如何实现相同的功能?是否有解决办法或任何较新的功能将行对象绘制为axes对象?
发布于 2022-05-25 17:25:03
在阅读了一段时间之后,我碰巧遇到了这文档。正如艺术家在艺术家中提到的那样,上面的错误基本上是某个地方限制的结果。错误并不明显,因此根据示例,我们需要:
重写基本方法,以便艺术家可以包含另一个艺术家。
因此,添加以下内容将有所帮助:
import matplotlib.lines as lines
import matplotlib.transforms as mtransforms
import matplotlib.text as mtext
class CustLine(lines.Line2D):
def __init__(self, *args, **kwargs):
# we'll update the position when the line data is set
self.text = mtext.Text(0, 0, '')
super().__init__(*args, **kwargs)
# we can't access the label attr until *after* the line is
# initiated
self.text.set_text(self.get_label())
def set_figure(self, figure):
self.text.set_figure(figure)
super().set_figure(figure)
def set_axes(self, axes):
self.text.set_axes(axes)
super().set_axes(axes)
def set_transform(self, transform):
# 2 pixel offset
texttrans = transform + mtransforms.Affine2D().translate(2, 2)
self.text.set_transform(texttrans)
super().set_transform(transform)
def set_data(self, x, y):
if len(x):
self.text.set_position((x[-1], y[-1]))
super().set_data(x, y)
def draw(self, renderer):
# draw my label at the end of the line with 2 pixel offset
super().draw(renderer)
self.text.draw(renderer)
现在,所需要做的就是替换以下内容:
supSFig, axsSF = plt.subplots(3, figsize=(15, 15))
axsSF[0].add_line(lS)
axsSF[1].add_line(lC)
axsSF[2].add_line(lT)
通过以下方式:
supSFig, axsSF = plt.subplots(3, figsize=(15, 15))
axsSF[0].add_line(CustLine(lS[0].get_xdata(), lS[0].get_ydata()))
axsSF[1].add_line(CustLine(lC[0].get_xdata(), lC[0].get_ydata()))
axsSF[2].add_line(CustLine(lT[0].get_xdata(), lT[0].get_ydata()))
这一方法运行良好,似乎是将行传递给Axes.add_lines()
方法的最佳方法,用于matplotlib
v3.5+
。任何其他的解决办法也是受欢迎的。
P.S.:请注意xdata
和ydata
是强制性的论点。
https://stackoverflow.com/questions/72376057
复制相似问题