1

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.

Jeremy
  • 849
  • 6
  • 15
  • But your grid is not continuous. What's your expectation from the included data? – Quang Hoang Jun 25 '20 at 20:46
  • Yes, the grids may not always be continuous. The real work behind this sample is the satellite observations, which has random data gaps. – Jeremy Jun 25 '20 at 20:47

1 Answers1

1

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

swatchai
  • 17,400
  • 3
  • 39
  • 58
  • I succeeded in applying this to my real work task! Thanks! – Jeremy Jun 26 '20 at 10:36
  • Thanks for the answer! But in this way, how can I add the colorbar? because in my codes there is one line: ```sc = ax.scatter(...); cbar = fig.colorbar(sc, cax=cbar_ax, extend=extend_subplot)```, now since ```ax``` is in the loop, and there is no ```sc``` returned back... – Xu Shan May 10 '22 at 09:46