【问题标题】:Matplotlib plots: removing axis, legends and white spacesMatplotlib 绘图:删除轴、图例和空白
【发布时间】:2012-03-06 21:24:00
【问题描述】:

我是 Python 和 Matplotlib 的新手,我想简单地将颜色图应用到图像并写入生成的图像,而不使用通常由 matplotlib 自动添加的轴、标签、标题或任何东西。这是我所做的:

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    fig.axes.get_xaxis().set_visible(False)
    fig.axes.get_yaxis().set_visible(False)
    plt.savefig(outputname)

它成功移除了图形的轴,但保存的图形在实际图像周围出现了一个白色填充和一个框架。 如何删除它们(至少是白色填充)?谢谢

【问题讨论】:

标签: python matplotlib


【解决方案1】:
plt.axis('off')

plt.savefig('example.png',bbox_inches='tight',pad_inches = 0)

给我无边框的图像。

【讨论】:

    【解决方案2】:

    我一直在寻找几个代码来解决这个问题,而这个question 的验证答案是唯一对我有帮助的代码。

    这对于散点图和三元图很有用。您只需将边距更改为零即可。

    【讨论】:

      【解决方案3】:

      我发现这一切都有记录......

      https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.axis.html#matplotlib.axes.Axes.axis

      我的代码…… “bcK”是一张 512x512 的图片

      plt.figure()
      plt.imshow(bck)
      plt.axis("off")   # turns off axes
      plt.axis("tight")  # gets rid of white border
      plt.axis("image")  # square up the image instead of filling the "figure" space
      plt.show()
      

      【讨论】:

        【解决方案4】:

        感谢大家的精彩回答...我也遇到了同样的问题,只想绘制没有额外填充/空间等的图像,所以非常高兴在这里找到每个人的想法。

        除了没有填充的图像之外,我还希望能够轻松添加注释等,而不仅仅是简单的图像绘图。

        所以我最终做的是将David's answercsnemes' 结合起来,在图形创建时制作一个简单的包装器。当您使用它时,您以后不需要使用 imsave() 或其他任何东西进行任何更改:

        def get_img_figure(image, dpi):
            """
            Create a matplotlib (figure,axes) for an image (numpy array) setup so that
                a) axes will span the entire figure (when saved no whitespace)
                b) when saved the figure will have the same x/y resolution as the array, 
                   with the dpi value you pass in.
        
            Arguments:
                image -- numpy 2d array
                dpi -- dpi value that the figure should use
        
            Returns: (figure, ax) tuple from plt.subplots
            """
        
            # get required figure size in inches (reversed row/column order)
            inches = image.shape[1]/dpi, image.shape[0]/dpi
        
            # make figure with that size and a single axes
            fig, ax = plt.subplots(figsize=inches, dpi=dpi)
        
            # move axes to span entire figure area
            fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
        
            return fig, ax
        

        【讨论】:

          【解决方案5】:

          赞成的答案不再起作用。要让它工作,你需要 手动添加轴设置为[0, 0, 1, 1],或者删除图下的补丁。

          import matplotlib.pyplot as plt
          
          fig = plt.figure(figsize=(5, 5), dpi=20)
          ax = plt.Axes(fig, [0., 0., 1., 1.])
          fig.add_axes(ax)
          plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
          plt.axis('off')                                # same as: ax.set_axis_off()
          
          plt.savefig("test.png")
          
          

          或者,您可以删除补丁。您无需添加子图即可删除填充。这是从Vlady's answer below简化而来的

          fig = plt.figure(figsize=(5, 5))
          fig.patch.set_visible(False)                   # turn off the patch
          
          plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
          plt.axis('off')
          
          plt.savefig("test.png", cmap='hot')
          

          这是在 2019 年 6 月 19 日使用版本 3.0.3 进行测试的。图片见下图:

          更简单的做法是使用pyplot.imsave。详情see luator's answer bellow

          【讨论】:

          • 对我来说只有 Axes 版本有效。我得到了补丁关闭版本的填充。无论如何谢谢!
          【解决方案6】:

          我认为命令axis('off') 比单独更改每个轴和边框更简洁地解决了其中一个问题。然而,它仍然在边界周围留下空白区域。将bbox_inches='tight' 添加到savefig 命令几乎可以让您到达那里,您可以在下面的示例中看到剩余的空白要小得多,但仍然存在。

          请注意,较新版本的 matplotlib 可能需要 bbox_inches=0 而不是字符串 'tight'(通过 @episodeyang 和 @kadrach)

          from numpy import random
          import matplotlib.pyplot as plt
          
          data = random.random((5,5))
          img = plt.imshow(data, interpolation='nearest')
          img.set_cmap('hot')
          plt.axis('off')
          plt.savefig("test.png", bbox_inches='tight')
          

          【讨论】:

          • 按照 unutbu 的建议,您可以使用fig = plt.figure()ax = plt.axes([0,0,1,1]),然后是plt.imshow(data,interpolation="nearest"。结合plt.axis("off"),它应该摆脱图像本身之外的所有东西,希望!
          • 将问题中的方法 ({fig.axes.get_xaxis().set_visible(False) & fig.axes.get_yaxis().set_visible(False)} 与 {plt.axis('off ')}) 为我解决了这个问题。 (不再有空格)。并且不要忘记将 savefig 中的 {pad_inches} 设置为 0。
          • 我刚刚遇到了这个问题,这个线程中的解决方案和链接的解决方案都不起作用。但是,明确指定 bbox_inches=0 就可以了。
          • 请注意,如果您在 plt.imshow 上“绘图”,如 plt.plot(x,y),您需要确保将 xlim 和 ylim 设置为矩阵。
          • 这不再起作用了。我花了一个小时才弄明白。请参阅下面的答案。
          【解决方案7】:

          这应该会移除所有的内边距和边框:

          from matplotlib import pyplot as plt
          
          fig = plt.figure()
          fig.patch.set_visible(False)
          
          ax = fig.add_subplot(111)
          
          plt.axis('off')
          plt.imshow(data)
          
          extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
          plt.savefig("../images/test.png", bbox_inches=extent)
          

          【讨论】:

          • 被低估的答案!这让我达到了 99% 的目标。应该得到更多的支持,因为它是最新的
          • 如果您没有带有 extent = plt.gca().get_window_extent().transformed(fig.dpi_scale_trans.inverted()) 的 Axes 对象 (ax),它也可以工作。
          【解决方案8】:

          我喜欢ubuntu's 的答案,但它没有明确显示如何设置开箱即用的非方形图像的大小,因此我对其进行了修改以便于复制粘贴:

          import matplotlib.pyplot as plt
          import matplotlib.image as mpimg
          import numpy as np
          
          def save_image_fix_dpi(data, dpi=100):
              shape=np.shape(data)[0:2][::-1]
              size = [float(i)/dpi for i in shape]
          
              fig = plt.figure()
              fig.set_size_inches(size)
              ax = plt.Axes(fig,[0,0,1,1])
              ax.set_axis_off()
              fig.add_axes(ax)
              ax.imshow(data)
              fig.savefig('out.png', dpi=dpi)
              plt.show()
          

          如果保留 pixel_size/dpi=size,则无论您选择什么 dpi,都可以轻松保存无边框图像。

          data = mpimg.imread('test.png')
          save_image_fix_dpi(data, dpi=100)
          

          但是显示令人毛骨悚然。如果您选择小 dpi,您的图像尺寸可能会大于您的屏幕,并且在显示过程中会出现边框。不过,这并不影响保存。

          所以

          save_image_fix_dpi(data, dpi=20)
          

          显示变为边框(但保存工作):

          【讨论】:

            【解决方案9】:

            首先,对于某些图像格式(即TIFF),您实际上可以将颜色图保存在标题中,并且大多数查看器会使用颜色图显示您的数据。

            为了保存实际的matplotlib 图像,这对于向图像添加注释或其他数据很有用,我使用了以下解决方案:

            fig, ax = plt.subplots(figsize=inches)
            ax.matshow(data)  # or you can use also imshow
            # add annotations or anything else
            # The code below essentially moves your plot so that the upper
            # left hand corner coincides with the upper left hand corner
            # of the artist
            fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
            # now generate a Bbox instance that is the same size as your
            # single axis size (this bbox will only encompass your figure)
            bbox = matplotlib.transforms.Bbox(((0, 0), inches))
            # now you can save only the part of the figure with data
            fig.savefig(savename, bbox_inches=bbox, **kwargs)
            

            【讨论】:

              【解决方案10】:

              我从matehat, here那里学到了这个技巧:

              import matplotlib.pyplot as plt
              import numpy as np
              
              def make_image(data, outputname, size=(1, 1), dpi=80):
                  fig = plt.figure()
                  fig.set_size_inches(size)
                  ax = plt.Axes(fig, [0., 0., 1., 1.])
                  ax.set_axis_off()
                  fig.add_axes(ax)
                  plt.set_cmap('hot')
                  ax.imshow(data, aspect='equal')
                  plt.savefig(outputname, dpi=dpi)
              
              # data = mpimg.imread(inputname)[:,:,0]
              data = np.arange(1,10).reshape((3, 3))
              
              make_image(data, '/tmp/out.png')
              

              产量

              【讨论】:

              • 我很确定您有正确的答案(尽管可能有不止一种方法可以做到),但我想知道您能否解释一下为什么正确答案?你的代码怎么去掉空格?
              • @Yann,除了文档之外,我发现一次注释掉一行以查看每个命令的效果非常有帮助。这是经验主义的方式!
              • 去除白色边框的行是plt.Axes(fig, [0,0,1,1])。这告诉 matplotlib 创建一组轴,其左下角位于 (0 %, 0 %) 处,宽度和高度为 (100 %, 100 %)。
              • 这是更正确的答案,因为它不仅会删除已保存图像的空白,还会删除屏幕上的绘图。
              • 谢谢,这是唯一能在我的 Ubuntu 上正常工作的解决方案:)
              【解决方案11】:

              还没有人提到imsave,这使它成为单行:

              import matplotlib.pyplot as plt
              import numpy as np
              
              data = np.arange(10000).reshape((100, 100))
              plt.imsave("/tmp/foo.png", data, format="png", cmap="hot")
              

              它直接按原样存储图像,即不添加任何轴或边框/填充。

              【讨论】:

              • 这是我大部分时间都在做的事情,但在某些情况下我需要颜色条,在这些情况下 imsave 无法拯救我。
              【解决方案12】:

              可能最简单的解决方案:

              我只是简单地将问题中描述的方法和Hooked回答中的方法结合起来。

              fig = plt.imshow(my_data)
              plt.axis('off')
              fig.axes.get_xaxis().set_visible(False)
              fig.axes.get_yaxis().set_visible(False)
              plt.savefig('pict.png', bbox_inches='tight', pad_inches = 0)
              

              在这段代码之后没有空格和框架。

              【讨论】:

              • 您的方法确实删除了这张图片周围的所有空白,干得好,但我仍然不知道为什么添加命令fig.axes.get_xaxis().set_visible(False) 解决了这个问题。谢谢
              • 是的,如果您不调用此命令,大部分空格将被删除。但是在我的情况下,我的情节和 .png 图像的边缘之间仍然存在一些空间(可能是 2px 宽)。通过调用以下命令,我摆脱了那些顽固的空格。
              • 但请注意,如果同一图中存在多个轴(在我的情况下是图中的嵌入图像),上述操作将失败。解决方案:fig.axes[0],通常是所有或选定的轴。
              【解决方案13】:

              您还可以在bbox_inches 参数中指定图形的范围。这将消除图形周围的白色填充。

              def make_image(inputname,outputname):
                  data = mpimg.imread(inputname)[:,:,0]
                  fig = plt.imshow(data)
                  fig.set_cmap('hot')
                  ax = fig.gca()
                  ax.set_axis_off()
                  ax.autoscale(False)
                  extent = ax.get_window_extent().transformed(plt.gcf().dpi_scale_trans.inverted())
                  plt.savefig(outputname, bbox_inches=extent)
              

              【讨论】:

                猜你喜欢
                • 2021-11-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-12
                • 1970-01-01
                相关资源
                最近更新 更多