Last active
April 27, 2021 21:20
-
-
Save jdbcode/a33e21d2c8eaf5ee52bde090593bd15f to your computer and use it in GitHub Desktop.
Earth Engine PDSI data reduction plotted with Altair and ggplot2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "ee_pdsi_chart_altair_ggplot2.ipynb", | |
"provenance": [], | |
"collapsed_sections": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/jdbcode/a33e21d2c8eaf5ee52bde090593bd15f/ee_pdsi_chart_altair_ggplot2.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "vTL0i0GkRBx0" | |
}, | |
"source": [ | |
"# Setup" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "SvSPxYYwpVyC" | |
}, | |
"source": [ | |
"import ee\n", | |
"ee.Authenticate()\n", | |
"ee.Initialize()" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "phryoeEgp5rH" | |
}, | |
"source": [ | |
"import pandas as pd\n", | |
"import altair as alt" | |
], | |
"execution_count": 2, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "G-2BwN5PRFhD" | |
}, | |
"source": [ | |
"A function to return a pandas dataframe for a mapped region reduction on an image collection." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "0fxbsgpy8n4C" | |
}, | |
"source": [ | |
"def reduce_col_to_df(col, reduce_params):\n", | |
" def create_reduce_region_function(reduce_params):\n", | |
" def reduce_region_function(img):\n", | |
" stat = img.reduceRegion(**reduce_params)\n", | |
" return (ee.Feature(None, stat)\n", | |
" .set({'millis': img.date().millis()}))\n", | |
" return reduce_region_function\n", | |
" \n", | |
" reduce = create_reduce_region_function(reduce_params)\n", | |
" fc = ee.FeatureCollection(col.map(reduce))\n", | |
" prop_names = fc.first().propertyNames()\n", | |
" prop_lists = fc.reduceColumns(\n", | |
" reducer=ee.Reducer.toList().repeat(prop_names.size()),\n", | |
" selectors=prop_names).get('list')\n", | |
"\n", | |
" return pd.DataFrame(ee.Dictionary.fromLists(prop_names, prop_lists).getInfo())" | |
], | |
"execution_count": 3, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "cOiMl6-AqpEb" | |
}, | |
"source": [ | |
"# Get drought data (PDSI)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "zIflx14uQhYZ" | |
}, | |
"source": [ | |
"Define collection ('GRIDMET/DROUGHT') and region of interest (Monterey country, CA)." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "LS0KsCvjqRau" | |
}, | |
"source": [ | |
"date_range = ['2010-01-01', '2021-05-01']\n", | |
"pdsi = (ee.ImageCollection('GRIDMET/DROUGHT')\n", | |
" .filterDate(date_range[0], date_range[1])\n", | |
" .select('pdsi'))\n", | |
"\n", | |
"aoi = (ee.FeatureCollection('TIGER/2018/Counties')\n", | |
" .filter(ee.Filter.eq('NAME', 'Monterey'))\n", | |
" .geometry())" | |
], | |
"execution_count": 4, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "9TKL3Vi1QlGR" | |
}, | |
"source": [ | |
"Get a pandas dataframe that contains the median regional PDSI per observation." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 424 | |
}, | |
"id": "42WCwHKz-SJg", | |
"outputId": "9e23a766-a676-4387-ec88-0a9094dc6fe0" | |
}, | |
"source": [ | |
"reduce_params = {\n", | |
" 'geometry': aoi,\n", | |
" 'reducer': ee.Reducer.median(),\n", | |
" 'scale': 4000,\n", | |
" 'crs': 'EPSG:3310'\n", | |
"}\n", | |
"pdsi_df = reduce_col_to_df(pdsi, reduce_params)\n", | |
"display(pdsi_df)" | |
], | |
"execution_count": 5, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>millis</th>\n", | |
" <th>pdsi</th>\n", | |
" <th>system:index</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>1262671200000</td>\n", | |
" <td>1.018947</td>\n", | |
" <td>20100105</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>1263103200000</td>\n", | |
" <td>0.922500</td>\n", | |
" <td>20100110</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>1263535200000</td>\n", | |
" <td>0.797780</td>\n", | |
" <td>20100115</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>1263967200000</td>\n", | |
" <td>0.800977</td>\n", | |
" <td>20100120</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>1264399200000</td>\n", | |
" <td>0.857332</td>\n", | |
" <td>20100125</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>...</th>\n", | |
" <td>...</td>\n", | |
" <td>...</td>\n", | |
" <td>...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>819</th>\n", | |
" <td>1616738400000</td>\n", | |
" <td>-2.828437</td>\n", | |
" <td>20210326</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>820</th>\n", | |
" <td>1617170400000</td>\n", | |
" <td>-2.855532</td>\n", | |
" <td>20210331</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>821</th>\n", | |
" <td>1617602400000</td>\n", | |
" <td>-2.889107</td>\n", | |
" <td>20210405</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>822</th>\n", | |
" <td>1618034400000</td>\n", | |
" <td>-2.950056</td>\n", | |
" <td>20210410</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>823</th>\n", | |
" <td>1618466400000</td>\n", | |
" <td>-3.048842</td>\n", | |
" <td>20210415</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>824 rows × 3 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" millis pdsi system:index\n", | |
"0 1262671200000 1.018947 20100105\n", | |
"1 1263103200000 0.922500 20100110\n", | |
"2 1263535200000 0.797780 20100115\n", | |
"3 1263967200000 0.800977 20100120\n", | |
"4 1264399200000 0.857332 20100125\n", | |
".. ... ... ...\n", | |
"819 1616738400000 -2.828437 20210326\n", | |
"820 1617170400000 -2.855532 20210331\n", | |
"821 1617602400000 -2.889107 20210405\n", | |
"822 1618034400000 -2.950056 20210410\n", | |
"823 1618466400000 -3.048842 20210415\n", | |
"\n", | |
"[824 rows x 3 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "qE8ypAGIQ4cz" | |
}, | |
"source": [ | |
"Clean up the dataframe." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 424 | |
}, | |
"id": "4xBchcpTAXGG", | |
"outputId": "7a583df8-e5cf-4fe2-d0d1-94af72b1083d" | |
}, | |
"source": [ | |
"pdsi_df['Datetime'] = pd.to_datetime(pdsi_df['millis'], unit='ms')\n", | |
"pdsi_df = pdsi_df.rename(columns={\n", | |
" 'pdsi': 'PDSI'\n", | |
"}).drop(columns=['millis', 'system:index'])\n", | |
"display(pdsi_df)" | |
], | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>PDSI</th>\n", | |
" <th>Datetime</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>1.018947</td>\n", | |
" <td>2010-01-05 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>0.922500</td>\n", | |
" <td>2010-01-10 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>0.797780</td>\n", | |
" <td>2010-01-15 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>0.800977</td>\n", | |
" <td>2010-01-20 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>0.857332</td>\n", | |
" <td>2010-01-25 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>...</th>\n", | |
" <td>...</td>\n", | |
" <td>...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>819</th>\n", | |
" <td>-2.828437</td>\n", | |
" <td>2021-03-26 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>820</th>\n", | |
" <td>-2.855532</td>\n", | |
" <td>2021-03-31 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>821</th>\n", | |
" <td>-2.889107</td>\n", | |
" <td>2021-04-05 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>822</th>\n", | |
" <td>-2.950056</td>\n", | |
" <td>2021-04-10 06:00:00</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>823</th>\n", | |
" <td>-3.048842</td>\n", | |
" <td>2021-04-15 06:00:00</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>824 rows × 2 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" PDSI Datetime\n", | |
"0 1.018947 2010-01-05 06:00:00\n", | |
"1 0.922500 2010-01-10 06:00:00\n", | |
"2 0.797780 2010-01-15 06:00:00\n", | |
"3 0.800977 2010-01-20 06:00:00\n", | |
"4 0.857332 2010-01-25 06:00:00\n", | |
".. ... ...\n", | |
"819 -2.828437 2021-03-26 06:00:00\n", | |
"820 -2.855532 2021-03-31 06:00:00\n", | |
"821 -2.889107 2021-04-05 06:00:00\n", | |
"822 -2.950056 2021-04-10 06:00:00\n", | |
"823 -3.048842 2021-04-15 06:00:00\n", | |
"\n", | |
"[824 rows x 2 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "fV1DUIklQWZ_" | |
}, | |
"source": [ | |
"# Plot with Altair" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 368 | |
}, | |
"id": "fs4i_O0mApBe", | |
"outputId": "76a284f8-bc33-4efa-e6f5-3f75b662f453" | |
}, | |
"source": [ | |
"alt.Chart(pdsi_df).mark_bar(size=3).encode(\n", | |
" x='Datetime:T',\n", | |
" y='PDSI:Q',\n", | |
" color=alt.Color(\n", | |
" 'PDSI:Q', scale=alt.Scale(scheme='redblue', domain=(-5, 5))),\n", | |
" tooltip=[\n", | |
" alt.Tooltip('Datetime:T', title='Date'),\n", | |
" alt.Tooltip('PDSI:Q', title='PDSI')\n", | |
" ]).properties(width=1000, height=300).interactive()" | |
], | |
"execution_count": 7, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "3Hq1d_JpQSUy" | |
}, | |
"source": [ | |
"# Plot with ggplot2" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "jAobEE5iBaNN" | |
}, | |
"source": [ | |
"Load R." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "jF0HZLDgBZOu" | |
}, | |
"source": [ | |
"%load_ext rpy2.ipython" | |
], | |
"execution_count": 8, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "3mHhmhsIFVZh" | |
}, | |
"source": [ | |
"Transfer pandas DF to R kernel." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "mxearcMdEmzb" | |
}, | |
"source": [ | |
"%R -i pdsi_df" | |
], | |
"execution_count": 9, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "cEklpbXqP0K3" | |
}, | |
"source": [ | |
"Load R libraries." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "UwrCV8q4BhAN" | |
}, | |
"source": [ | |
"%%R\n", | |
"\n", | |
"library('ggplot2')\n", | |
"library(scales)" | |
], | |
"execution_count": 10, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "j0SQhkx4QMH_" | |
}, | |
"source": [ | |
"Plot PDSI using ggplot2." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 497 | |
}, | |
"id": "xXWBfD7ZCOwE", | |
"outputId": "180e7919-33a7-4b04-ade8-fab21a5fa39d" | |
}, | |
"source": [ | |
"%%R\n", | |
"\n", | |
"ggplot(pdsi_df, aes(Datetime, PDSI)) +\n", | |
" geom_col(aes(fill = PDSI)) +\n", | |
" scale_fill_distiller(\n", | |
" palette = \"RdBu\", limits = c(-5, 5), direction = 1, oob=squish) +\n", | |
" theme_bw()" | |
], | |
"execution_count": 11, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment