https://podaac.jpl.nasa.gov/dataset/OSCAR_L4_OC_third-deg

import xarray as xr
# Open the dataset
ds = xr.open_dataset("local_folder/oscar_vel2022.nc")

Plate carrée projection

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import os

dec = 2 # decimation

# Create a directory for the images if it doesn't exist
output_dir = "oscar_images"
os.makedirs(output_dir, exist_ok=True)

for t in range(len(ds.time)):
    plt.figure(figsize=(18, 9))
    ax = plt.axes(projection=ccrs.PlateCarree()) # plate carrée projection
    
    lon = ds.longitude.values[::dec]
    lon[lon > 180] = lon[lon > 180] - 360
    
    plt.streamplot(
        lon,
        ds.latitude.values[::dec],
        ds.u.values[t, 0, ::dec, ::dec],
        ds.v.values[t, 0, ::dec, ::dec],
        8,
        transform = ccrs.PlateCarree()
    )
    
    ax.coastlines()

    # Create a title using the time dimension
    plt.title(f'Sea surface currents derived from oscar_vel2022.nc, Time: {ds.time.values[t]}')

    # Save the figure with a filename based on the time step
    plt.savefig(f"{output_dir}/oscar_vel2022_t{t}.png", dpi=150)

    # Close the figure to free up memory
    plt.close()
#!/bin/bash

# Define total number of time steps
N=72

# Define output directory
output_dir="ffmpeg"

# Create output directory if it doesn't exist
mkdir -p $output_dir

# Define width and height
width=2700
height=1350

# Define progress bar height
progress_height=80

# Create N images with increasing filled progress bars
for i in $(seq 1 $N); do
    progress=$((i*width/N))  # proportionally increase size
    convert -size ${width}x${progress_height} xc:grey50 -fill "rgb(0,0,0)" -draw "rectangle 0,0 $progress,${progress_height}" ${output_dir}/progress_${i}.png
done

# Overlay progress bar onto each image, create new image
for i in $(seq 1 $N); do
    # Calculate progress bar position
    y_offset=$(( height-progress_height-10 ))  # place the progress bar at the bottom, with 10 pixels padding

    # Overlay progress bar and save as new image
    convert oscar_vel2022_t${i}.png ${output_dir}/progress_${i}.png -geometry +0+${y_offset} -composite ${output_dir}/oscar_vel2022_progress_t${i}.png
done

# Create video using ffmpeg
ffmpeg -framerate 5 -i "${output_dir}/oscar_vel2022_progress_t%d.png" -c:v libx264 -r 30 -pix_fmt yuv420p ${output_dir}/oscar_vel2022.mp4

# Clean up progress bar and composite images
rm ${output_dir}/progress_*.png
rm ${output_dir}/oscar_vel2022_progress_t*.png

Video.js Options Reference

ffmpeg -i ffmpeg/oscar_vel2022.mp4 -vf "fps=3,scale=1000:-1:flags=lanczos" -c:v gif ffmpeg/oscar_vel2022.gif

OSCAR SSV 2022 GIF

Peters projection

import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import os

dec = 2 # decimation

# Create a directory for the images if it doesn't exist
output_dir = "output_Peters"
os.makedirs(output_dir, exist_ok=True)

for t in range(len(ds.time)):
    plt.figure(figsize=(18, 9))
    ax = plt.axes(projection=ccrs.EqualEarth()) # Equal Earth (similar to Peters) projection
    
    lon = ds.longitude.values[::dec]
    lon[lon > 180] = lon[lon > 180] - 360
    
    plt.streamplot(
        lon,
        ds.latitude.values[::dec],
        ds.u.values[t, 0, ::dec, ::dec],
        ds.v.values[t, 0, ::dec, ::dec],
        8,
        transform = ccrs.PlateCarree()
    )
    
    ax.coastlines()

    # Create a title using the time dimension
    plt.title(f'Sea surface currents derived from oscar_vel2022.nc, Time: {ds.time.values[t]}')

    # Save the figure with a filename based on the time step
    plt.savefig(f"{output_dir}/oscar_vel2022_t{t}.png", dpi=150)

    # Close the figure to free up memory
    plt.close()
#!/bin/bash

# Define total number of time steps
N=72

# Define output directory
output_dir="ffmpeg_Peters"

# Create output directory if it doesn't exist
mkdir -p $output_dir

# Define width and height
width=2700
height=1350

# Define progress bar height
progress_height=80

# Create N images with increasing filled progress bars
for i in $(seq 1 $N); do
    progress=$((i*width/N))  # proportionally increase size
    convert -size ${width}x${progress_height} xc:grey50 -fill "rgb(0,0,0)" -draw "rectangle 0,0 $progress,${progress_height}" ${output_dir}/progress_${i}.png
done

# Overlay progress bar onto each image, create new image
for i in $(seq 1 $N); do
    # Calculate progress bar position
    y_offset=$(( height-progress_height-10 ))  # place the progress bar at the bottom, with 10 pixels padding

    # Overlay progress bar and save as new image
    convert oscar_vel2022_t${i}.png ${output_dir}/progress_${i}.png -geometry +0+${y_offset} -composite ${output_dir}/oscar_vel2022_progress_t${i}.png
done

# Create video using ffmpeg
ffmpeg -framerate 5 -i "${output_dir}/oscar_vel2022_progress_t%d.png" -c:v libx264 -r 30 -pix_fmt yuv420p oscar_vel2022.mp4

# Clean up progress bar and composite images
rm ${output_dir}/progress_*.png
rm ${output_dir}/oscar_vel2022_progress_t*.png

Video.js Options Reference

ffmpeg -i oscar_vel2022_peters.mp4 -vf "fps=3,scale=1000:-1:flags=lanczos" -c:v gif oscar_vel2022_peters.gif

OSCAR SSV 2022 GIF