Jeremy
Jeremy

Reputation: 876

colour map grids based on value in pandas dataframe

I want to fill the gridded map with colors based on the value of interest. A sample data is here:

import pandas as pd

df = pd.DataFrame()
df['lon'] = [100,105,110,115,120,125,130]
df['lat'] = [38,40,42,44,46,48,50]
df['value'] = [1,2,3,4,5,6,7]

Specifically, is it possible to do this with Cartopy? I found a similar question here:https://stackoverflow.com/questions/53412785/plotting-pandas-csv-data-onto-cartopy-map. But that post was to plot scattered points, I need to fill the grids with colors.

I myself tried:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

lon, lat = np.meshgrid(df['lon'], df['lat'])

fig = plt.figure(figsize=[15,15])
ax = plt.axes(projection=ccrs.PlateCarree())
ax.pcolormesh(lon,lat,df['variable'],latlon=True,cmap='jet')

plt.show()

The error is at ax.pcolormesh(...), it says "not enough values to unpack (expected 2, got 1)"

Many thanks for your help.

Upvotes: 1

Views: 769

Answers (1)

swatchai
swatchai

Reputation: 18812

For discrete data you can create rectangular patches for each point. Here is a possible solution for your sample data set. Each row of data (lat, long, value) is used to create a rectangular patch. The value is normalized by dividing with max(value) to enable using colormap for coloring the patches.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.patches as mpatches

def make_rect(clon, clat, dlon, dlat):
    lon_min = clon - dlon/2.
    lat_min = clat - dlat/2.
    lon_max = clon + dlon/2.
    lat_max = clat + dlat/2.
    # clockwise from LL
    #lons = [lon_min, lon_min, lon_max, lon_max, lon_min]
    #lats = [lat_min, lat_max, lat_max, lat_min, lat_min]
    ll = [lon_min,lat_min]
    ul = [lon_min,lat_max]
    ur = [lon_max,lat_max]
    lr = [lon_max,lat_min]
    return [ll, ul, ur, lr, ll]

df = pd.DataFrame()
df['lon'] = [100,105,110,115,120,125,130]
df['lat'] = [38,40,42,44,46,48,50]
df['value'] = [1,2,3,4,5,6,7]   # not suffice for meshgrid plot

# The colormap to use.
cm = plt.cm.get_cmap('jet')

fig = plt.figure(figsize=[8,6])
ax = plt.axes(projection=ccrs.PlateCarree(), extent=[95, 134, 35, 52])

# plot the red dots using the available data
# comment out if not needed
ax.plot(df['lon'], df['lat'], 'ro')

# plot rectangular patches at the data points
dlon, dlat = 5, 2  #spacings between data points
for lon1, lat1, val1 in zip(df['lon'], df['lat'], df['value']):
    pcorners = make_rect(lon1, lat1, dlon, dlat)
    poly = mpatches.Polygon(pcorners, ec='gray', fill=True, lw=0.25, \
           fc=cm(val1 / max(df['value'])), transform=ccrs.PlateCarree())
    ax.add_patch(poly)       

ax.gridlines(draw_labels=True)
plt.show()

The output plot:

enter image description here

Upvotes: 1

Related Questions