Home > Enterprise >  How to reduce space between text box and chart without moving the text box?
How to reduce space between text box and chart without moving the text box?

Time:09-01

I am trying to plot various time series data in separate columns in a pandas dataframe with subplots() while automatically placing a text box for the data source at the bottom of the figure.

Everything works fine except that pandas/Matplotlib puts too much space in between the last plot and the text box at the bottom of the plots unless I reformat the dates in the index, for example, using strftime() which I don't wish to do. How do I expand the plots only towards the bottom (I need the otherwise empty spaces to the left and right) while keeping the text at the bottom and without making any modifications to the dataframe's index? I have tried fig.tight_layout() but it did not help much.

I understand the problem is triggered by the dataframe's index having an irregular date at the end (all other dates are quarter-ends) because the problem gets resolved if I exclude the last row in the dataframe being plotted or if I replace its date with the next quarter-end date.

Here is the code (I have modified the actual code and data as much as possible in order to simplify things) and its (undesired) output:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

np.random.seed(0)

no = 54
dates = pd.date_range("20090101", periods=no, freq="Q")
df1 = pd.DataFrame(np.random.randn(no, 2), index=dates, 
    columns=["Istanbul", "Kyiv"])

no = 1
dates = pd.date_range("20220826", periods=no)
df2 = pd.DataFrame(np.random.randn(no, 2), index=dates, 
    columns=["Istanbul", "Kyiv"])

df1 = pd.concat([df1,df2])

height = 8
fig, axes = plt.subplots(df1.shape[1], 1, figsize=(15, height))
fig.suptitle("Lorem ipsum dolor sit amet", y=1-0.2/height)
fig.text(0.1, 0.1/height, "Source: Lorem ipsum", fontsize=8)
fig.subplots_adjust(
    left=0.1, bottom=0.6/height, right=0.9, top=1-0.5/height
)
for i, col in enumerate(df1.columns): 
    df1.loc[:, col].plot(ax=axes[i],
        ylabel="(mm)", xlabel="", grid=True, legend=False,
        style=["o-"], sharex=True)
    axes[i].text(0.45, 0.87, f"{col}", \
        transform=axes[i].transAxes, weight=600,
        bbox=dict(facecolor="white", ec="white"), fontsize=12)
plt.show()  

enter image description here

CodePudding user response:

fig.tight_layout() reduced that space a lot for me:

fig.tight_layout() 
plt.show() 

Result: enter image description here

I placed this as an answer and not only as comment to be able to add the picture. Maybe you can provide more info why fig.tight_layout() didn't provided what you were looking for.

CodePudding user response:

It looks like the underlying problem in my case was where the fig.subplots_adjust() was exactly used in the code. The code started working as I intended when I changed its place to right before plt.show(). Same issue with fig.tight_layout() if it is not placed right before plt.show() (plus fig.tight_layout() does not appear to give me the type of control I need on the figure at least as conveniently as fig.subplots_adjust()).

I checked the Matplotlib documentation for either method again and there does not appear to be an explicit warning on such proper (?) use of the either.

  • Related