Hi Steve,
In my Met Data app I use the geometry attribute from the GeoDataFrame to get the x & y coords of each data point and then call chart.annotate() to draw the text values at a suitable offset.
Here is the method I use:
def plotData(self, data_frame, data_type, points):
"""Plot the data on the map.
:param data_frame: pandas.DataFrame containing the data.
:param data_type: string, the type of data to be plotted.
:param points: list of Point objects
"""
columns = MetDataModel.CHART_DATA_COLUMNS[data_type]
# Convert the DataFrame to a GeoDataFrame
self.reports_gdf = gpd.GeoDataFrame(data_frame, crs=WGS84_EPSG_STR, geometry=points)
if data_type == "Wind Arrows":
self.axes.barbs(self.reports_gdf.geometry.x,
self.reports_gdf.geometry.y,
self.reports_gdf['u_comp'],
self.reports_gdf['v_comp'],
length=6,
linewidth=.7)
else:
# Add dots to mark the sites
chart = self.reports_gdf.plot(ax=self.map_plot, color='grey', markersize=8)
# Annotate map with the data values
x_off = 3
for i, column in enumerate(columns):
y_off = 2 - (i * 8)
for x, y, value in zip(self.reports_gdf.geometry.x,
self.reports_gdf.geometry.y,
self.reports_gdf[column]):
# Only plot values that are not 'nan'
if not math.isnan(value):
if data_type in ("Wind Speeds", "Present Weather"):
value = int(value)
chart.annotate(value,
xy=(x, y),
xytext=(x_off, y_off),
textcoords="offset points",
size=7,
color=DATA_COLOURS[i])
self.map_plot.set_aspect(DEFAULT_ASPECT)
self.canvas.draw()
The calling method contains the following segment:
# Extract the list of Points from the DataFrame
points = gpd.points_from_xy(data_frame.Longitude, data_frame.Latitude)
if points:
# Plot the met data on the map
self.plotData(data_frame, self.data_type, points)
else:
self.map_plot.set_aspect(DEFAULT_ASPECT)
msg = "There is no data for %s" % dt_str
# Plot message near the centre of the map
self.map_plot.text(0.5, 0.4, msg, fontsize=12,
transform=self.axes.transAxes,
ha="center", va="center", color='red',
bbox=dict(boxstyle="round, pad=0.4",
facecolor="antiquewhite"))
Hopefully you will be able adapt parts of this code to suit your application.
Edit: here is the definition of MetDataModel.CHART_DATA_COLUMNS
CHART_DATA_COLUMNS = OrderedDict([
(TEMPERATURES_CHART, ("dry_bulb", "dew_point")),
(WIND_ARROWS_CHART, ("wind_dir", "wind_speed")),
(WIND_SPEEDS_CHART, ("wind_speed", "wind_gust_10")),
(PRESENT_WEATHER_CHART, ("present_wx",)),
(MSLP_CHART, ("msl_pressure",)),
])