Issue
I want to draw the boundary of the intersection of a couple of circles that I created. Here is what I have so far:
EDITED
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from matplotlib.patches import PathPatch
from matplotlib.path import Path
import matplotlib.ticker as mticker
import numpy as np
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Mercator())
ax.set_extent([11, 38, 56, 70], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=1)
ax.coastlines(linewidth=1)
# Adding the circles
radius = 120 # km
n_samples = 80 # Number of points on the circle
lons = (21.64, 22.5, 23.82, 24.5, 25.44, 26.32, 26.9, 27.11, 27.38, 29.45, 29.8)
lats = (60.13, 61.81, 63.1, 60.56, 62.3, 64.77, 67.14, 60.9, 62.86, 63.84, 61.91)
for lon, lat in zip(lons,lats):
circle = Geodesic().circle(lon, lat, radius*1000., n_samples=n_samples)
feature = cartopy.feature.ShapelyFeature([Polygon(circle)], ccrs.Geodetic(), fc='orange', alpha=0.4, ec="black", lw=0.5, linestyle="-")
ax.add_feature(feature)
I have searched the web, but could not find a solution for this so far. If someone could help me out, that'd be great :)
Solution
You don't actually mention what the issue is, so it's difficult the answer.
But something that you probably unintentionally do at the moment is mixing different units to create your circles. You define your map as being Orthographic, the center center in lat/lon and the radius in meters. What do you expect the result to be?
Given that you assign the circles having the PlateCarree()
projection, the radius should also be defined as such. In your current code everything works fine, but you set the radius to be 250000 degrees!!
If you for example set the radius to be 2.5 degrees, it looks like the image shown below:
You'll have to decide on whether you want a circle to be a circle on the earth (geodetic), on the map projection or on the image (figure coordinates) etc. And then choose the units accordingly in a consistent manner.
edit:
The Geodetic class is certainly a good choice, the pyproj
package also has functionality for this type of operation.
The union of several circles can be drawn as shown in the example below, it uses Shapely to perform the union.
import matplotlib.pyplot as plt
from cartopy.geodesic import Geodesic
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from shapely.geometry import Polygon
from shapely.ops import unary_union
fig, ax = plt.subplots(figsize=(10, 6), subplot_kw=dict(projection=ccrs.Mercator()))
ax.set_extent([11, 38, 56, 70], crs=ccrs.PlateCarree())
ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=.3)
ax.coastlines(linewidth=.3, resolution="50m")
# Adding the circles
radius = 120 # km
n_samples = 80 # Number of points on the circle
lons = (21.64, 22.5, 23.82, 24.5, 25.44, 26.32, 26.9, 27.11, 27.38, 29.45, 29.8)
lats = (60.13, 61.81, 63.1, 60.56, 62.3, 64.77, 67.14, 60.9, 62.86, 63.84, 61.91)
geo = Geodesic()
circles = [Polygon(geo.circle(lon, lat, radius*1000., n_samples=n_samples)) for lon, lat in zip(lons, lats)]
feature = cfeature.ShapelyFeature(unary_union(circles), ccrs.PlateCarree(), fc='orange', alpha=0.4, ec="k", lw=2, linestyle="-")
# feature = cfeature.ShapelyFeature(circles, ccrs.PlateCarree(), fc='orange', alpha=0.4, ec="k", lw=2, linestyle="-")
ax.add_feature(feature)
Without the union, just plotting circles
it looks like:
Answered By - Rutger Kassies
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.