0
votes

I'm trying to plot circles on a miller projection map using a center latitude, longitude and radius. I can't get the circles to show up on the map projection. I've tried plotting them using different techniques as shown in the links.

How to plot a circle in basemap or add artiste

How to make smooth circles on basemap projections

Here is my code:

def plot_notams(dict_of_filtered_notams):

''' Create a map of the US and plot all NOTAMS from a given time period.'''

'''Create the map'''
fig = plt.figure(figsize=(8,6), dpi=200)
ax = fig.add_subplot(111)
m = Basemap(projection='mill',llcrnrlat=20, urcrnrlat=55, llcrnrlon=-135, urcrnrlon=-60, resolution='h')
m.drawcoastlines()
m.drawcountries(linewidth=2)
m.drawstates()
m.fillcontinents(color='coral', lake_color='aqua')
m.drawmapboundary(fill_color='aqua')
m.drawmeridians(np.arange(-130, -65, 10), labels=[1,0,0,1], textcolor='black')
m.drawparallels(np.arange(20, 60, 5), labels=[1,0,0,1], textcolor='black')

''' Now add the NOTAMS to the map '''

notam_data = dict_of_filtered_notams['final_notam_list']

for line in notam_data:
    notam_lat = float(line.split()[0])
    notam_lon = float(line.split()[1])
    coords = convert_coords(notam_lon, notam_lat)
    notam_lon, notam_lat = coords[0], coords[1]
    FL400_radius = np.radians(float(line.split()[2]))
    x,y = m(notam_lon, notam_lat)
    print("notam_lon = ",notam_lon, "notam_lat = ", notam_lat,"\n")
    print("x,y values = ",'%.3f'%x,",",'%.3f'%y,"\n")
    print("FL400_radius = ",('% 3.2f' % FL400_radius))
    print("")
    cir = plt.Circle((x,y), FL400_radius, color="white", fill=False)
    ax.add_patch(cir)

(The convert_coords function is simply formatting the notam_lon/notam_lat values into a usable format as shown in the data below.)

Here is what my data looks like (you can see where it's being printed in the code above):

notam_lon = -117.7839 notam_lat = 39.6431

x,y values = 1914342.075 , 2398770.441

FL400_radius = 6.98

Here's an image of what my code above produces: My map projection

I also tried using the map.plot() function (specifically, m.plot(x,y, "o")) in place of "ax.add_patch(cir)." That worked but plotted points or "o's," of course. Here's the image produced by replacing "ax.add_patch(cir)" with "m.plot(x,y, "o")."
Plot using map.plot() function in place of ax.add_patch()

And as a final note, I'm using basemap 1.2.0-1 and matplotlib 3.0.3. I haven't found any indication that these versions are incompatible. Also, this inability to plot a circle wasn't an issue 2 months ago when I did this last. I'm at a loss here. I appreciate any feedback. Thank you.

1
could be a zorder problem. try cir = plt.Circle((x,y), FL400_radius, color="white", fill=False, zorder=10) - Jonas
Hmm. That didn't work but thanks for the input. - Brandon

1 Answers

1
votes

To plot circles on a map, you need appropriate locations (x,y) and radius. Here is a working code and resulting plot.

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np

# make up 10 data points for location of circles
notam_lon = np.linspace(-117.7839, -100, 10)
notam_lat = np.linspace(39.6431, 52, 10)

# original radius of circle is too small
FL400_radius = 6.98   # what unit?

fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
m = Basemap(projection='mill', llcrnrlat=20, urcrnrlat=55, llcrnrlon=-135, urcrnrlon=-60, resolution='l')

# radiusm = (m.ymax-m.ymin)/10. is good for check plot
radiusm = FL400_radius*10000  # meters, you adjust as needed here

for xi,yi in zip(notam_lon, notam_lat):
    # xy=m(xi,yi): conversion (long,lat) to (x,y) on map
    circle1 = plt.Circle(xy=m(xi,yi), radius=radiusm, \
                         edgecolor="blue", facecolor="yellow", zorder=10)
    #ax.add_patch(circle1)  # deprecated
    ax.add_artist(circle1)  # use this instead

m.drawcoastlines()
m.drawcountries(linewidth=2)
m.drawstates()
m.fillcontinents(color='coral', lake_color='aqua')

# m.drawmapboundary(fill_color='aqua') <-- causes deprecation warnings
# use this instead:
rect = plt.Rectangle((m.xmin,m.ymin), m.xmax-m.xmin, m.ymax-m.ymin, facecolor="aqua", zorder=-10)
ax.add_artist(rect)

m.drawmeridians(np.arange(-130, -65, 10), labels=[1,0,0,1], textcolor='black')
m.drawparallels(np.arange(20, 60, 5), labels=[1,0,0,1], textcolor='black')

plt.show()

The output map:

enter image description here

Hope this is useful.