0

我想用更长的标题和子标题在 Python 中为图片制作动画。不幸的是,图表正在向上移动,从而丢失了额外的间距。

#%% Import packages

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from matplotlib.animation import FuncAnimation

#%% Get data

x = pd.date_range('2015-12-31','2020-10-31',freq='B')
y0 = np.exp(np.random.normal(loc=0.05/260, scale=0.15/16, size=len(x)).cumsum())
y1 = 100+(np.random.binomial(2,0.5,size=len(x))-1).cumsum()
df_plot0 = pd.DataFrame(index=x, data=y0)
df_plot1 = pd.DataFrame(index=x, data=y1)

#%% Init und Animate
   
def init():
    return line0, line1

def animate(iTime):
    line0.set_xdata(df_plot0.index[:iTime])
    line0.set_ydata(df_plot0.iloc[:iTime])
    line1.set_xdata(df_plot1.index[:iTime])
    line1.set_ydata(df_plot1.iloc[:iTime])
    return line0, line1

#%% Draw once
    
sns.set_context('notebook')
plt.rcParams['figure.constrained_layout.use'] = True
fig = plt.figure(num='figPort', figsize=(8,4.5),dpi=240, constrained_layout=True)
g_spec = gridspec.GridSpec(ncols=1, nrows=2, figure=fig, height_ratios=[2,2], width_ratios=[1])
sns.set_style('ticks', rc={'axes.grid': True, 'axes.spines.right': False, 'axes.spines.top': False, 'grid.color': 'lightgrey', 'grid.linestyle': 'dotted'})

ax0 = fig.add_subplot(g_spec[0,0])
line0 = ax0.plot(df_plot0, axes=ax0)[0]

ax1 = fig.add_subplot(g_spec[1,0])
line1 = ax1.plot(df_plot1, axes=ax1)[0]

sns.despine(ax=ax0, offset={'left':10, 'bottom':10})
sns.despine(ax=ax1, left=False, bottom=True, top=False,offset={'left':10, 'top':10})
title_main = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor'
title_sub = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna\naliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea\ntakimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy.\n'
ax0.annotate(title_main, xy=(0.025, 0.99), xycoords=('figure fraction'), size=12, ha='left', va='top')  #<-- if 1.01 instead of 0.99, then the height of axes goes to zero
ax0.annotate(title_sub, xy=(0.025, 0.955), xycoords='figure fraction', size=10, ha='left', va='top')

init()
iTime = np.int(df_plot1.shape[0]*3/4)
animate(iTime)

plt.show()

#%%  Animation
anim = FuncAnimation(fig=fig, func=animate, frames=range(100), interval=4, repeat=False, blit=True)
anim.save('test.mp4', fps=60)

任何帮助如何正确放置标题和副标题?

如果我使用 .title 或 .suptitle,我无法正确放置标题。

如果我使用 .annotate(),那么轴将接管整个图形,这样我就不会再正确地看到标题了。

如果我将文本放在 1 以上,例如 1.01 而不是 1 以下,例如 0.99,那么轴将缩小到零高度 - 请参阅代码中的注释。

我确实收到以下错误消息:“用户警告:这个数字使用了 constrained_layout==True,但这与 subplots_adjust 和/或tight_layout 不兼容:设置 constrained_layout==False。”

4

1 回答 1

0

解决了。

在第一个情节之后,在运行动画之前,我使用了 ax.get_position() 和 ax.set_position() 。

for ax in [ax0, ax1]:
    print(ax.get_position())

factor = 0.9
box1 = ax1.get_position()
box0 = ax0.get_position()
ax0.set_position([box0.x0, box0.y0 - (1-factor)*box1.height, box0.width, factor*box0.height])
ax1.set_position([box1.x0, box1.y0 , box1.width, factor * box1.height])

for ax in [ax0, ax1]:
    print(ax.get_position())

@Diziet Asahi 这如何转化为 fig.subplots_adjust(top = ?, bottom = ?) 我是否需要针对不同的轴 ax0 和 ax1 进行不同的调整?

于 2020-11-03T20:43:03.633 回答