WeatherNext 3 forecast data is available in [Google Earth
Engine](https://earthengine.google.com/) as an `ImageCollection` across two
public catalog listings: the [0.1° Gridded Collection](https://developers.google.com/earth-engine/datasets/catalog/projects_gcp-public-data-weathernext_assets_weathernext_3_0_0_0p1deg)
and the [0.05° Stations Collection](https://developers.google.com/earth-engine/datasets/catalog/projects_gcp-public-data-weathernext_assets_weathernext_3_0_0_0p05deg).
Earth Engine provides precomputed ensemble statistics for surface weather
variables, optimized for planetary-scale raster computation, geospatial
overlays, and interactive mapping.

> [!NOTE]
> To request access to WeatherNext Earth Engine assets, submit the
> [WeatherNext
> Data Request form](https://docs.google.com/forms/d/e/1FAIpQLSeCf1JY8G78UDWzbm0ly9kJxfSjUIJT5WyMR_HiNqCm-IHIBg/viewform). Requests are typically approved within 5--7 business
> days.

## What is Earth Engine?

[Google Earth Engine](https://earthengine.google.com/) is a cloud platform for
petabyte-scale scientific analysis and visualization of geospatial datasets.
Computations run in parallel across Google's infrastructure, making it ideal for
combining weather forecasts with satellite imagery, land cover, and custom
vector boundaries.

## Available datasets \& collections

Earth Engine provides optimized surface forecast ImageCollections with
precomputed distribution statistics. The data is split into two collections
by **spatial grid resolution**:

| Collection | Earth Engine Asset ID | Grid Resolution | Variables \& Scope |
| [0.1° Gridded](https://developers.google.com/earth-engine/datasets/catalog/projects_gcp-public-data-weathernext_assets_weathernext_3_0_0_0p1deg) | `projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p1deg` | 0.1° | - 19 gridded surface variables across six precomputed statistical metrics---specifically mean, p10, p25, p50, p75, and p90 (total of 114 metrics, including total precipitation and solar radiation). - Hourly timesteps across all inits. - 24 inits per day from 2026 to present; 8 per day for 2024--2025. |
| [0.05° Stations](https://developers.google.com/earth-engine/datasets/catalog/projects_gcp-public-data-weathernext_assets_weathernext_3_0_0_0p05deg) | `projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p05deg` | 0.05° | - High-resolution station head forecasts for 2m temperature and dew point across six precomputed statistical metrics---specifically mean, p10, p25, p50, p75, and p90 (total of 12 metrics). - Hourly timesteps across all inits. - 24 inits per day from 2026 to present; 8 per day for 2024--2025. |
|---|---|---|---|

*(For the raw 64-member ensemble and 3D atmospheric pressure levels, use [Google
Cloud Storage (Zarr)](https://developers.google.com/weathernext/guides/gcs)).*

### Image structure and properties

In Earth Engine, each forecast run produces a series of `ee.Image` assets
representing lead time steps for a given initialization run:

| Property | Type | Description |
|---|---|---|
| `start_time` | String | Initialization timestamp of the model run in UTC ISO 8601 format (e.g., `2026-05-01T00:00:00Z`). |
| `end_time` | String | Valid timestamp for the forecast (`start_time + forecast_hour`). |
| `forecast_hour` | Integer | Lead time in hours from initialization (1 to 360 for 6-hourly inits, 1 to 48 for interim inits). |
| `system:time_start` | Long | Valid time in milliseconds since the Unix epoch. |
| `ingestion_time_utc` | Double | Timestamp when the forecast data became available in Earth Engine. |
| `B_` | String | The band names in order, starting from B0 to B11 for the 0.05° station collection and B0 to B113 for the 0.1° gridded collection. |

> [!NOTE]
> **Forecast Horizons:**
>
> - **6-hourly initialization runs (00, 06, 12, 18 UTC):** 360-hour (15-day) forecast horizon.
> - **Interim initialization runs:** 48-hour forecast horizon.
>   - 2026 to present: every hour (01--05, 07--11, 13--17, 19--23 UTC)
>   - 2024--2025: 03, 09, 15, 21 UTC only

### Bands \& ensemble statistics

Each base weather variable is provided across **6 ensemble statistics** :
`_mean`, `_p10`, `_p25`, `_p50` (median), `_p75`, and `_p90` (for example,
`temperature_2m_mean`, `temperature_2m_p50`, `u_component_of_wind_10m_mean`,
`total_precipitation_1hr_mean`).

*** ** * ** ***

## Common query recipes

Explore common Earth Engine Python API workflows for WeatherNext image collections:

### 1. Load the latest forecast run

Initialize the Earth Engine Python API and filter the collection by
initialization timestamp:

<br />

**Python**

<br />

    import ee

    ee.Initialize(project="YOUR_PROJECT_ID")

    collection_id = "projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p1deg"
    col = ee.ImageCollection(collection_id)

    # Filter for a specific forecast initialization run (e.g., 2026-05-01 00:00 UTC)
    forecast_run = col.filter(
        ee.Filter.eq("start_time", "2026-05-01T00:00:00Z")
    )

    # Total hourly forecast images (up to 360 lead times)
    print(f"Hourly steps in run: {forecast_run.size().getInfo()}")

<br />

<br />

### 2. Time series extraction and plotting (0.1° gridded collection)

Extract an hourly temperature forecast time series (mean, 10th, and 90th
percentile bands) over a region:

<br />

**Python**

<br />

    import ee
    import matplotlib.dates as mdates
    import matplotlib.pyplot as plt
    import pandas as pd
    import seaborn as sns

    ee.Initialize(project="YOUR_PROJECT_ID")

    collection_id = "projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p1deg"
    col = ee.ImageCollection(collection_id)

    # Define NYC bounding box (west, south, east, north)
    ny_geom = ee.Geometry.BBox(-74.26, 40.50, -73.70, 40.90)

    # Filter for initialization run and first 24 hours
    ny_temps_ee = (col
        .filter(ee.Filter.eq("start_time", "2026-05-01T00:00:00Z"))
        .filter(ee.Filter.lte("forecast_hour", 24))
        .filterBounds(ny_geom)
        .select(["temperature_2m_mean", "temperature_2m_p10", "temperature_2m_p90"]))

    # Convert ImageCollection into Pandas DataFrame using covering grid
    def convert_to_dataframe(image_collection, geometry, bands_to_reducer):
      covering_grid = geometry.coveringGrid(
          image_collection.first().projection(),
          image_collection.first().projection().nominalScale()
      )
      def convert_to_feature_collection(image):
        def get_feature_for_cell(cell_polygon):
          feature_dict = {
              "time": image.get("end_time"),
              "init_time": image.get("start_time"),
              "forecast_hour": image.get("forecast_hour"),
          }
          for band_id, reducer in bands_to_reducer.items():
            val = image.reduceRegion(
                reducer=reducer,
                geometry=cell_polygon.geometry(),
                scale=image.projection().nominalScale()
            ).get(band_id)
            feature_dict[band_id] = val
          return ee.Feature(cell_polygon.geometry(), feature_dict)
        return covering_grid.map(get_feature_for_cell)

      features = image_collection.map(convert_to_feature_collection).flatten()
      df = ee.data.computeFeatures({
          "expression": features,
          "fileFormat": "PANDAS_DATAFRAME"
      })
      df["time"] = pd.to_datetime(df["time"])
      df["init_time"] = pd.to_datetime(df["init_time"])
      return df

    ny_temps = convert_to_dataframe(
        ny_temps_ee,
        ny_geom,
        {
            "temperature_2m_mean": ee.Reducer.mean(),
            "temperature_2m_p10": ee.Reducer.mean(),
            "temperature_2m_p90": ee.Reducer.mean(),
        }
    )

    # Plot hourly mean with 10th-90th percentile envelope
    ny_temps_agg = ny_temps.groupby("time", as_index=False)[
        ["temperature_2m_mean", "temperature_2m_p10", "temperature_2m_p90"]
    ].mean()

    temp_mean_c = ny_temps_agg["temperature_2m_mean"] - 273.15
    temp_p10_c = ny_temps_agg["temperature_2m_p10"] - 273.15
    temp_p90_c = ny_temps_agg["temperature_2m_p90"] - 273.15
    times = ny_temps_agg["time"]

    plt.figure(figsize=(12, 6))
    sns.set_theme(style="whitegrid")
    plt.fill_between(times, temp_p10_c, temp_p90_c, color="lightcoral", alpha=0.35, label="10th-90th Percentile Range")
    plt.plot(times, temp_mean_c, marker="o", markersize=4, color="firebrick", linewidth=2, label="Ensemble Mean")
    plt.xlabel("Valid Time (UTC)", fontsize=12)
    plt.ylabel("2m Temperature (°C)", fontsize=12)
    plt.title("1-Day Temperature Forecast for New York", fontsize=14)
    plt.legend(loc="upper right", fontsize=11)
    plt.tight_layout()
    plt.show()

<br />

<br />

### 3. Interactive map visualization with geemap

Display global forecast ensemble means onto an interactive map:

<br />

**Python**

<br />

    import ee
    import geemap.core as geemap

    ee.Initialize(project="YOUR_PROJECT_ID")

    collection_id = "projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p1deg"
    col = ee.ImageCollection(collection_id)

    variable = "temperature_2m_mean"
    palette = "coolwarm"

    # Select single forecast valid step
    world_avgs = (col
        .filter(ee.Filter.eq("start_time", "2026-04-30T18:00:00Z"))
        .filter(ee.Filter.eq("end_time", "2026-05-01T00:00:00Z"))
        .select(variable)
        .first())

    # Compute global min and max for color normalization
    min_max = world_avgs.reduceRegion(
        reducer=ee.Reducer.minMax(),
        geometry=ee.Geometry.BBox(-180, -90, 180, 90),
        scale=world_avgs.projection().nominalScale(),
        maxPixels=1e13
    )

    vis_params = {
        "bands": [variable],
        "min": min_max.get(f"{variable}_min"),
        "max": min_max.get(f"{variable}_max"),
        "palette": palette,
    }

    m = geemap.Map(center=[35, 0], zoom=2)
    m.add_layer(world_avgs, vis_params, f"{variable} average", True, 0.5)
    m

<br />

<br />

### 4. High-resolution station forecast query (0.05° collection)

Query the station-calibrated collection for fine-scale point and region
forecasting:

<br />

**Python**

<br />

    import ee

    ee.Initialize(project="YOUR_PROJECT_ID")

    stations_col = ee.ImageCollection("projects/gcp-public-data-weathernext/assets/weathernext_3_0_0_0p05deg")

    # Define NYC bounding box (west, south, east, north)
    ny_geom = ee.Geometry.BBox(-74.26, 40.50, -73.70, 40.90)

    station_run = (stations_col
        .filter(ee.Filter.eq("start_time", "2026-05-01T00:00:00Z"))
        .filterBounds(ny_geom)
        .select(["station_head_temperature_2m_mean", "station_head_dewpoint_temperature_2m_mean"]))

<br />

<br />

*** ** * ** ***

## Best practices

- **Filter before reducing:** Apply `filterBounds()` and `filter(ee.Filter.lte('forecast_hour', ...))` early to limit the images evaluated on Google infrastructure.
- **Leverage precomputed stats:** Use the precomputed statistical bands (`_mean`, `_p10`, `_p25`, `_p50`, `_p75`, `_p90`) directly instead of attempting to calculate custom reductions over raw members.
- **Specify nominal scale:** Set `scale=5000` for surface temperature and dew point in the 0.05° collection, and `scale=10000` for 0.1° surface fields when calling `reduceRegion`.

*** ** * ** ***

## Starter guides

For interactive Colab notebooks with complete workflows and geemap tutorials:

- [WeatherNext 3 Starter Guide - Earth Engine (0.1°)](https://storage.googleapis.com/weathernext-public/colabs/WeatherNext_3_Starter_Guide_Earth_Engine_0p1deg.ipynb)
- [WeatherNext 3 Starter Guide - Earth Engine (0.05°)](https://storage.googleapis.com/weathernext-public/colabs/WeatherNext_3_Starter_Guide_Earth_Engine_0p05deg.ipynb)

*** ** * ** ***

## Terms of use

- **Real-Time Data (data relating to less than 1 hour ago and the future):** Governed by the [GDM Real-Time Weather Forecasting Experimental Data Terms of
  Use](https://storage.googleapis.com/weathernext-public/terms-of-use.pdf).
- **Historical Data (data relating to 1 hour ago or more):** Licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).

For more details, see
[Terms of Service and Disclaimers](https://developers.google.com/weathernext/guides/disclaimers).