Python вывод анимации matplotlib отличается от отображаемого рисунка - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь создать видео, используя matplotlib.animation для фигуры с подзадачами. Один из подзаговоров использует cartopy для отображения карты.

Код, который я написал:

import pandas as pd
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
import matplotlib as mpl
import matplotlib.animation as animation
from IPython.display import HTML


data = pd.DataFrame({'data': np.sin(np.arange(0, 2, 0.2))}, index=pd.date_range(start='1/1/2018', periods=10))

extent = [-16, 10, 36, 48] 

#create the figure
fig = plt.figure(figsize=(7,12))

#add subplots
ax = plt.subplot(211, projection=ccrs.PlateCarree())
ax_t = plt.subplot(212)

ax.coastlines(resolution='50m')
ax.add_feature(cfeature.BORDERS.with_scale('50m'))
ax.set_extent(extent, ccrs.PlateCarree())

sm = plt.cm.ScalarMappable(cmap=mpl.cm.Reds,norm=plt.Normalize(0,1))
sm._A = []
cb = plt.colorbar(sm, ax=ax, fraction=0.022, pad=0.02)
cb.set_label('Values')

color = (1.0, 1.0, 1.0)
hpoint = ax.plot(-3, 40, color=color, linewidth=2, marker='o', markersize=30, transform=ccrs.PlateCarree() ) 

#ax_t.plot(meanRMS)
data.plot(ax=ax_t)
ax_t.margins(x=0, tight=True)
ax_t.grid(True)

box1 = ax.get_position()
box2 = ax_t.get_position()
deltaheigh = box2.height * 0.3
ax_t.set_position([box1.x0, box1.y0 - deltaheigh*1.1 , box1.width  , deltaheigh])

Этот код дает вывод, который я хочу и ожидаю:

изображение на выходе

при создании видео анимации:

frames = 1
iter_data = data.iterrows()
ndays = data.shape[0]

def makemap(n):
    if n % frames == 0:
        time, val = next(iter_data)
        color = (1.0, 1.0-val[0], 1.0-val[0])
        hpoint[0].set_color(color)
        ax.set_title(time.strftime("%d %b %Y"), fontsize=20)




ani = animation.FuncAnimation(fig, makemap, frames=frames*(ndays-2), interval=100)


HTML(ani.to_html5_video())

Я получаю видео с другой формой / форматом (больший белый холст с изображением, даже не отцентрированным): введите описание изображения здесь

Как я могу исправить этот неожиданный результат?

1 Ответ

0 голосов
/ 16 апреля 2020

Похоже, вы работаете с ноутбуком Jupyter. В блокноте, когда рисунки matplotlib отображаются встроенными, они сохраняют изображения с помощью опции bbox_inches='tight'. Это можно увидеть на примере matplotlib . К сожалению, этот параметр не совместим с сохранением анимации, поскольку он может изменять размер кадров анимации от изображения к изображению.

Чтобы решить эту проблему, нужно вручную настроить размеры фигуры и осей, а не полагаться на плотная коробка для устранения пробелов для вас. Вы можете проверить, как будет выглядеть отдельный кадр, сохранив рисунок вручную, а не полагаясь на встроенный дисплей Jupyter, например:

fig.savefig('myfig.png')
...