当我移动图像时,我从一个子图中丢失了我的图像。(代码在木星实验室运行):
from mpl_toolkits.axes_grid1 import host_subplot
from mpl_toolkits import axisartist
hostImage = host_subplot(221, axes_class=axisartist.Axes)
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (-0.0014, 0), box_alignment=(1, 0))
hostImage.add_artist(ab)用上面的配置仍然可以看到图像。
接下来,当我更改参数时,图像消失了:
将图像向左移动,更改第7行
ab = AnnotationBbox(imagebox, (-0.0025, 0), box_alignment=(1, 0))
至
ab = AnnotationBbox(imagebox, (-0.5, 0), box_alignment=(1, 0))
改变子图变换线的矩阵布局
hostImage = host_subplot(221, axes_class=axisartist.Axes)
至
hostImage = host_subplot(111, axes_class=axisartist.Axes)
->如何显示我添加到一个子图中的所有内容(或多或少),而不管它离轴线“中心部分”有多远(两个轴之间的面积,在一个图的意义上是“轴”)?
使用plt.tight_layout()方法没有帮助。

这里是我使用的测试映像(红色菱形)。
%使我真正想达到的目标更加清晰(问题的实际背景):
我有线图显示约30个传感器的测量数据,这些传感器定位在一个非常复杂的三维测量装置的真实世界。传感器的位置对于任何试图理解图表的人来说都是至关重要的。所以这张图是一种图表的3D图例。在一幅图中,我显示了大约5-6个传感器的数据(单个图表中更多的传感器会使其不可读)。请参阅这个真实的示例(在工作中,我停下来发表我的问题):
这个例子是通过在带有曲线的子图下面创建第二个子图来建立的。第二个图有隐藏的轴(在轴的复数意义上)。这已经是一个可行的解决方案,也是我目前的基准。
顺便说一句,出于这个原因,我希望图像在图的下方,这样就不会为我绘制曲线的图表“浪费”水平空间。
因此,'3D图像传奇‘是最终输出的’全部一体‘的情节(.png)的组成部分,.pngs进入我的书面报告,这是我的最终目标。
在报告中,我还可以手工添加对应于一个图的每一幅图像,但是将所有的信息(图和图像)都包含在一个中的所有matplotlib图中,这样可以更方便地建立报告,而且也减少了错误的可能性(因为我有许多传感器和许多配置,因此创建了相当多的这样的图)。
除了上述解决方案之外,是什么引发了我的问题:
我希望最终将标签(matplotlib注释)放在图像上,将传感器名称放在图像的顶部,作为“叠加”。然后通过箭头线将这些标签与相应的曲线连接起来。这将使读者非常清楚和方便地了解哪条曲线对应于->图像中的哪个传感器位置,类似于“3D图例”。我找到了ConnectionPatch作为在子图之间画线的解决方案,但我得到了一条错误消息,我最终不想尝试解决,而是选择一种方法:将图像作为非常相同的曲线子图的一部分,因为在子图中连接标签很容易(实际上,您可以在我上传的图像中看到沿着右y轴放置的这样的传感器名称标签)。
为什么我要使用host_subplot__?
我在我的情节中有多达五个y轴(我知道这么高的y轴数量可能是有问题的,但请不要在这篇文章中讨论这个问题),而且我知道只有使用host_subplot使用.twinx()才有可能增加两个y轴。
P.S.:毕竟,我认为我现在应该降低我的高期望值,坚持我对两个子图的可行解决方案,放弃把第二个子图中的标签和第一个子图中的曲线连接起来的可能性。
发布于 2022-09-28 15:11:13
编辑2022-09-28:我已经通过浏览matplotlib.offsetbox.AnnotationBbox的帮助/py-代码为我的案例找到了解决方案:
例如,可以通过修改参数xybox of AnnotationBbox来达到预期的效果。
ab = AnnotationBbox(imagebox, xy = (1, 0), xybox = (2.0, 1.0), box_alignment=(1, 0))设置xybox = (2.0, 1.0),因此x值为2.0将图像移到绘图区域的右侧。
发布于 2022-08-24 18:17:37
Matplotlib 3.5 (或可能更好)
如果您正在使用Matplotlib 3.5 (或者可能更好),我认为这可以满足您的需要(或接近):
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as axisartist
hostImage = host_subplot(221, axes_class=axisartist.Axes)
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (-0.0025, 0), box_alignment=(1, 0))
hostImage.add_artist(ab)
hostImage.figure.subplots_adjust(left=0.69) # based on https://matplotlib.org/stable/tutorials/intermediate/tight_layout_guide.html saying how to manually adjust
hostImage.figure.set_size_inches((18, 10)) # from https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/figure.py; also see drevicko's comment https://stackoverflow.com/a/638443/8508004
hostImage.figure.savefig("my_image_test.png") # fix for `hostImage.savefig("my_image_test.png")`, based on https://forum.freecodecamp.org/t/attribute-error-axessubplot-object-has-no-attribute-savefig/46025这将在直接在JupyterLab输出中和在生成的图像文件中显示相同的图形视图。(实际大小可能略有不同,图像文件显示更好的分辨率。)**如果不想生成图像文件,则可以删除最后两行,只需包括调整**,figure.subplots_adjust(left=0.69),以说明所添加的注释框。
我在每一行的评论中都有相关的消息来源。
我的测试映像又宽又短,所以您可能需要调整figure.subplots_adjust(left=0.69)以适应您的需要。(现在我不喜欢这样,我不得不为figure.subplots_adjust()尝试非常高和低版本的figure.subplots_adjust()值,然后在一个公正的设置上磨练,但它起了作用。我会说,通常我在绘制子图(如这里 )之前就设置了数字大小,也许这样做会使它看起来不那么需要实验才能正常工作。但是,在Matplotlib文档中的布局中提到了手动调整的事实,对于图区域之外的元素,我认为有时需要进行一些调整。)
这里我使用hostImage.figure.set_size_inches((18, 10))。也许你不需要你的那么宽?
检查Matplotlib版本的代码:
import matplotlib
print (matplotlib.__version__ ) 3.5之前的Matplotlib版本(或者确切地说是3.2.1?)
上面的代码不适用于Matplotlib 3.2.1和所有其他代码。(在运行一个单元格中的MyBinder并重新启动内核之前,在运行这里之前,通过这里提供木星会话。)所产生的图像是好的,但直接输出在木星笔记本是截止,只显示一个碎片。
如果使用Matplotlib 3.2.1,下面的代码块可以满足您的需要(或关闭)。因为我无法在使用Matplotplib 3.2.1正确显示的木星单元中获得直接输出,这只会显示与生成的图像文件相关联的图形。
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as axisartist
hostImage = host_subplot(221, axes_class=axisartist.Axes)
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (-0.0025, 0), box_alignment=(1, 0))
hostImage.add_artist(ab)
hostImage.figure.subplots_adjust(left=0.69) # based on https://matplotlib.org/stable/tutorials/intermediate/tight_layout_guide.html saying how to manually adjust
hostImage.figure.set_size_inches((18, 10)) # from https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/figure.py; also see drevicko's comment https://stackoverflow.com/a/638443/8508004
hostImage.figure.savefig("my_image_test.png") # fix for `hostImage.savefig("my_image_test.png")`, based on https://forum.freecodecamp.org/t/attribute-error-axessubplot-object-has-no-attribute-savefig/460255
hostImage.figure.clf() # using this so, Jupyter won't display the Matplotlib plot object; instead we'll show the image file
from IPython.display import Image
Image(filename="my_image_test.png")上面介绍了我添加的共享行是如何工作的。
或者,当使用Matplotlib 3.2.1与这里这样的代码一起使用时,为了不显示matplotlib cruft (比如<Figure size 1296x720 with 0 Axes> ),您可以在两个单元格之间进行拆分。
第一单元的代码:
%%capture
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as axisartist
hostImage = host_subplot(221, axes_class=axisartist.Axes)
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (-0.0025, 0), box_alignment=(1, 0))
hostImage.add_artist(ab)
hostImage.figure.subplots_adjust(left=0.69) # based on https://matplotlib.org/stable/tutorials/intermediate/tight_layout_guide.html saying how to manually adjust
hostImage.figure.set_size_inches((18, 10)) # from https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/figure.py; also see drevicko's comment https://stackoverflow.com/a/638443/8508004
hostImage.figure.savefig("my_image_test.png") # fix for `hostImage.savefig("my_image_test.png")`, based on https://forum.freecodecamp.org/t/attribute-error-axessubplot-object-has-no-attribute-savefig/460255
hostImage.figure.clf() # using this so, Jupyter won't display the Matplotlib plot object; instead we'll show the image file第二单元的代码:
from IPython.display import Image
Image(filename="my_image_test.png")由于%%capture单元格的魔力,第一个单元将不会显示任何类型的输出。
更新:
(下面的代码仅用Matplotlib 3.5测试。)
基于添加示例图OP的一些选项和注释这里中的附加信息,我建议重新使用更简单的子图来安排这两个元素。(如果要复杂得多,我会建议其他方法来组合这两个元素。选项将包括:如果只是显示在木星,可以使用ipywidget的布局。如果目标是制作一个出版物质量的数字,那么枕头和ReportLab就会很有用。)
!curl -o testImage.png https://owncloud.tuwien.ac.at/index.php/s/3caJsb2PcwN7HdU/download
#based on https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html
# and https://www.moonbooks.org/Articles/How-to-insert-an-image-a-picture-or-a-photo-in-a-matplotlib-figure/
# and https://nbviewer.org/gist/fomightez/4c2116e50f080b1305c41b9ac70df124#Solution
# axis off for lower plot based on https://stackoverflow.com/a/10035974/8508004
import matplotlib.pyplot as plt
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
fig, axs = plt.subplots(2,1,figsize=(4, 8))
#fig.suptitle('Vertically stacked subplots')
axs[0].grid()
axs[1].grid()
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (0.5,0.5))
axs[1].add_artist(ab)
axs[1].axis('off');或者:
!curl -o testImage.png https://owncloud.tuwien.ac.at/index.php/s/3caJsb2PcwN7HdU/download
#based on https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html
# and https://www.moonbooks.org/Articles/How-to-insert-an-image-a-picture-or-a-photo-in-a-matplotlib-figure/
# and https://nbviewer.org/gist/fomightez/4c2116e50f080b1305c41b9ac70df124#Solution
# axis turned off for lower plot based on https://stackoverflow.com/a/10035974/8508004
import matplotlib.pyplot as plt
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
# data to plot based on https://stackoverflow.com/a/17996099/8508004 and converting it
# to work with subplot method
fig, axs = plt.subplots(2,1)
plt.subplots_adjust(hspace=1.8) # to move the bottom plot down some so not covering the top small one
#fig.suptitle('Vertically stacked subplots')
axs[0].plot(range(15))
axs[0].set_xlim(-7, 7)
axs[0].set_ylim(-7, 7)
axs[0].set_aspect('equal')
axs[1].grid()
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (0.5,0.5))
axs[1].add_artist(ab)
axs[1].axis('off');或者,如果要保存该数字,请如下所示:
!curl -o testImage.png https://owncloud.tuwien.ac.at/index.php/s/3caJsb2PcwN7HdU/download
#based on https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html
# and https://www.moonbooks.org/Articles/How-to-insert-an-image-a-picture-or-a-photo-in-a-matplotlib-figure/
# and https://nbviewer.org/gist/fomightez/4c2116e50f080b1305c41b9ac70df124#Solution
# axis turned off for lower plot based on https://stackoverflow.com/a/10035974/8508004
import matplotlib.pyplot as plt
from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox
import matplotlib.image as mpimg
# data to plot based on https://stackoverflow.com/a/17996099/8508004 and converting it
# to work with subplot method
fig, axs = plt.subplots(2,1)
plt.subplots_adjust(hspace=0.3) # to move the bottom plot down some so not covering the top small one
#fig.suptitle('Vertically stacked subplots')
axs[0].plot(range(15))
axs[0].set_xlim(-7, 7)
axs[0].set_ylim(-7, 7)
axs[0].set_aspect('equal')
axs[1].grid()
test_image = mpimg.imread('testImage.png')
imagebox = OffsetImage(test_image, zoom=1)
ab = AnnotationBbox(imagebox, (0.5,0.5))
axs[1].add_artist(ab)
axs[1].axis('off')
# to accomodate this adjustment in the figure that gets saved via `plt.savefig()`, increase figure size
fig.set_size_inches((4, 7)) # from https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/figure.py; also see drevicko's comment
plt.savefig("stacked.png");我不确定,虽然大小变化,在最上面的地方,如果你设置的大小,以便你可以容纳他们,但有一些磨练在正确的数字需要那里。
https://stackoverflow.com/questions/73475547
复制相似问题