Search code examples
matplotlibbounding-box

How to make tight bounding boxes respect an invisible artist?


I want to export a figure whose bounding boxes should be tight, but accounting for an artist that is invisible. (I want to unveil that artist in a later variant of the plot, which shall have the same bounding boxes.)

My approach to this is:

from matplotlib import pyplot as plt

plt.plot([0,1])
title = plt.title("my invisible title")
title.set_visible(False)
plt.savefig(
        "invisible_artist.png",
        bbox_inches="tight", pad_inches=0,
        bbox_extra_artists=[title],
        facecolor="grey", # just to visualise the bbox
    )

This produces:

output of above script

For comparison, here is the output with the title left visible, which is what I would expect in this case:

output with visible title

Obviously, when the title is made invisible, no space is left for it, while additional space is added in other directions.

Why does this happen and how can I achieve the desired result, i.e., have the same bounding box in both cases?


Solution

  • Invisible artists are not taken into account for tight bbox calculations. Some workaround could be to make the title transparent,

    title.set_alpha(0)
    

    Or to use a whitespace as title

    plt.title(" ")
    

    More generally, you can of course get the tight bounding box before making the title invisible, then turn the title invisible and finally save the figure with the previously stored bbox.

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    ax.plot([0,1])
    title = ax.set_title("my invisible title")
    
    bbox = fig.get_tightbbox(fig.canvas.get_renderer())
    title.set_visible(False)
    
    plt.savefig(
            "invisible_artist.png",
            bbox_inches=bbox,
            facecolor="grey", # just to visualise the bbox
        )
    
    plt.show()
    

    image

    The drawback is that pad_inches only works for bbox_inches="tight". So to achieve the effect of pad_inches for such manually specified bbox one would need to manipulate the Bbox itself.