【问题标题】:In Python with Matplotlib how to check if a subplot is empty in the figure在带有 Matplotlib 的 Python 中,如何检查图中的子图是否为空
【发布时间】:2014-05-20 21:43:38
【问题描述】:

我有一些使用NetworkX 创建的图表,并使用Matplotlib 在屏幕上显示它们。具体来说,由于我事先不知道需要显示多少个图表,所以我在运行的图形上创建了一个subplot。这很好用。然而,在脚本中的某个点,一些subplots 被从图中删除,并且图中显示了一些 empty 子图。我想避免它,但我无法检索图中为空的子图。这是我的代码:

#instantiate a figure with size 12x12
fig = plt.figure(figsize=(12,12))

#when a graph is created, also a subplot is created:
ax = plt.subplot(3,4,count+1)

#and the graph is drawn inside it: N.B.: pe is the graph to be shown
nx.draw(pe, positions, labels=positions, font_size=8, font_weight='bold', node_color='yellow', alpha=0.5)

#many of them are created..

#under some conditions a subplot needs to be deleted, and so..
#condition here....and then retrieve the subplot to deleted. The graph contains the id of the ax in which it is shown.
for ax in fig.axes:
    if id(ax) == G.node[shape]['idax']:
         fig.delaxes(ax)

直到这里可以正常工作,但是当我显示该图时,结果如下所示:

您会注意到那里有两个空的子图......在第二个位置和第五个位置。我怎样才能避免它?或者..如何重新组织子图,使图中不再有空白?

感谢任何帮助!提前致谢。

【问题讨论】:

    标签: python matplotlib networkx figure subplot


    【解决方案1】:

    为此,我会保留一个轴列表,当我删除一个轴的内容时,我会将其换成一个完整的轴。我认为下面的例子解决了这个问题(或者至少给出了如何解决它的想法):

    import matplotlib.pyplot as plt
    
    # this is just a helper class to keep things clean
    class MyAxis(object):
        def __init__(self,ax,fig):
            # this flag tells me if there is a plot in these axes
            self.empty = False
            self.ax = ax
            self.fig = fig
            self.pos = self.ax.get_position()
    
        def del_ax(self):
            # delete the axes
            self.empty = True
            self.fig.delaxes(self.ax)
    
        def swap(self,other):
            # swap the positions of two axes
            #
            # THIS IS THE IMPORTANT BIT!
            #
            new_pos = other.ax.get_position()
            self.ax.set_position(new_pos)
            other.ax.set_position(self.pos)
            self.pos = new_pos
    
    def main():
        # generate a figure and 10 subplots in a grid
        fig, axes = plt.subplots(ncols=5,nrows=2)
    
        # get these as a list of MyAxis objects
        my_axes = [MyAxis(ax,fig) for ax in axes.ravel()]
    
        for ax in my_axes:
            # plot some random stuff
            ax.ax.plot(range(10))
    
        # delete a couple of axes
        my_axes[0].del_ax()
        my_axes[6].del_ax()
    
        # count how many axes are dead
        dead = sum([ax.empty for ax in my_axes])
    
        # swap the dead plots for full plots in a row wise fashion
        for kk in range(dead):
            for ii,ax1 in enumerate(my_axes[kk:]):
                if ax1.empty:
                    print ii,"dead"
                    for jj,ax2 in enumerate(my_axes[::-1][kk:]):
                        if not ax2.empty:
                            print "replace with",jj
                            ax1.swap(ax2)
                            break
                    break
    
    
    
        plt.draw()
        plt.show()
    
    if __name__ == "__main__":
        main()
    

    极其丑陋的 for 循环结构实际上只是一个占位符,用于举例说明如何交换轴。

    【讨论】:

    • 感谢您的提示,我将重新编写我的脚本。
    • 我无法让 dead 在 matplotlib 2.1.1 上工作。但是我发现has_data() 方法可以用作解决方法。即`dead = len(my_axes) -sum([ax.has_data() for ax in fig.my_axes])
    猜你喜欢
    • 1970-01-01
    • 2012-06-20
    • 2019-02-22
    • 2012-07-10
    • 1970-01-01
    • 2020-03-29
    • 2018-01-08
    • 1970-01-01
    • 2011-11-17
    相关资源
    最近更新 更多