1
votes

I have a multi-year monthly dataset for water vapour values at a certain altitude. Different timesteps have different min and max values. I'm trying to create an animation using FuncAnimation. So far, I've been able to get the contourf plot right. However, I'm doing something wrong with the colorbar. It's only plotting the colorbar for the starting date.(Probably because I have the plt.colorbar set outside of the animate function loop) However, the colorbar range of the first timestep doesn't contain all the data range for other timesteps. I'm trying to plot a colorbar that contains all the values from the entire dataset and can be used to read all the frames in the animation. Another option could be to create a new colorbar for each timestep, all the while sticking to the same colorbar range (that too, I need help with).

from netCDF4 import Dataset
import xarray as xr
import numpy as np

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import cartopy.crs as ccrs
model = <model name>
period = <time period>
for m in model:
    for p in period:
        infile = xr.open_dataset('/path/to/file.nc')
    
    #read in the variables
    hus = infile.hus
    lat = infile.lat
    lon = infile.lon
    date = infile.time
    
    #convert date to list
    date = date.values
    date = list(date)
    
    #reduce it to 3 dimesions
    phus = hus.sel(plev='50000', method='nearest')
    
    #multi-year monthly mean
    climatology = phus.groupby("time.month").mean("time")
    
    #deseasonalize the dataset
    anom = phus.groupby("time.month") - climatology
    
  
    
    fig, ax = plt.subplots(figsize=(15, 10))
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.coastlines()
    contour_opts = {'cmap':'RdBu'}
    cax = ax.contourf(lon, lat, anom[0], **contour_opts)
    cbar = plt.colorbar(cax)
    cbar.set_label('Water Vapour Anomaly')
    
    

    def animate(i):
        ax.collections = []
        ax.set_title(date[i])
        scat = ax.contourf(lon, lat, anom[i], **contour_opts)
       



    anim = FuncAnimation(fig, animate, timestep, interval=100, repeat=True)
    anim.save('test.gif', writer='pillow')
1
I think you need to evaluate the "global" min/max values of your data (i.e. find the range of the fixed colorbar) and the manually create it similar to the answer in this question - Asmus
FYI: Thoroughly answering questions is time-consuming. If your question is solved, say thank you by accepting the solution that is best for your needs. The is below the / arrow, at the top left of the answer. A new solution can be accepted if a better one shows up. You may also vote on the usefulness of an answer with the / arrow, if you have a 15+ reputation. Leave a comment if a solution doesn't answer the question. What should I do when someone answers my question?. Thank you - Zephyr

1 Answers

0
votes

You should create an axis for the colobar outside the animate function, then you can plot your data with the seaborn package (I think with sns.kdeplot, documentation here, you can replace the plt.contourf) with which you can specify if you want the colorbar and its min and max values.
Read this answer as a reference.