banner



How Do You Animate A Dot Moving From Point To Point On A Map

At that place are a couple of approaches to this.

The matplotlib approach

I'll showtime with perchance the near basic if y'all are familiar with matplotlib, but this approach suffers from indirectly using cartopy's functionality, and is therefore harder to configure/extend.

There is a private _get_transformed_path method on a Line2D object (the thing that is returned from plt.plot). The resulting TransformedPath object has a get_transformed_path_and_affine method, which basically will give united states the projected line (in the coordinate system of the Axes being fatigued).

          In [i]: import cartopy.crs as ccrs  In [three]: import matplotlib.pyplot as plt  In [four]: ax = plt.axes(projection=ccrs.Robinson())  In [6]: ny_lon, ny_lat = -75, 43  In [seven]: delhi_lon, delhi_lat = 77.23, 28.61  In [eight]: [line] = plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],    ...:          color='blue', linewidth=2, marking='o',    ...:          transform=ccrs.Geodetic(),    ...:          )  In [9]: t_path = line._get_transformed_path()  In [10]: path_in_data_coords, _ = t_path.get_transformed_path_and_affine()  In [xi]: path_in_data_coords.vertices Out[xi]:  array([[-6425061.82215208,  4594257.92617961],        [-5808923.84969279,  5250795.00604155],        [-5206753.88613758,  5777772.51828996],        [-4554622.94040482,  6244967.03723341],        [-3887558.58343227,  6627927.97123701],        [-3200922.19194864,  6932398.19937816],        [-2480001.76507805,  7165675.95095855],        [-1702269.5101901 ,  7332885.72276795],        [ -859899.12295981,  7431215.78426759],        [   23837.23431173,  7453455.61302756],        [  889905.10635756,  7397128.77301289],        [ 1695586.66856764,  7268519.87627204],        [ 2434052.81300274,  7073912.54130764],        [ 3122221.22299409,  6812894.40443648],        [ 3782033.80448001,  6478364.28561403],        [ 4425266.18173684,  6062312.15662039],        [ 5049148.25986903,  5563097.6328901 ],        [ 5616318.74912886,  5008293.21452795],        [ 6213232.98764984,  4307186.23400115],        [ 6720608.93929235,  3584542.06839575],        [ 7034261.06659143,  3059873.62740856]])                  

We tin can pull this together with matplotlib'southward animation functionality to exercise as requested:

          import cartopy.crs as ccrs import matplotlib.animation as animation import matplotlib.pyplot every bit plt  ax = plt.axes(projection=ccrs.Robinson()) ax.stock_img()  ny_lon, ny_lat = -75, 43 delhi_lon, delhi_lat = 77.23, 28.61  [line] = plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],          color='blueish', linewidth=2, marker='o',          transform=ccrs.Geodetic(),          )  t_path = line._get_transformed_path() path_in_data_coords, _ = t_path.get_transformed_path_and_affine()   # Depict the point that nosotros want to animate. [point] = plt.plot(ny_lon, ny_lat, marker='o', transform=ax.projection)  def animate_point(i):     verts = path_in_data_coords.vertices     i = i % verts.shape[0]     # Set the coordinates of the line to the coordinate of the path.     point.set_data(verts[i, 0], verts[i, one])  ani = blitheness.FuncAnimation(     ax.figure, animate_point,     frames= path_in_data_coords.vertices.shape[0],     interval=125, repeat=Truthful)  ani.save('point_ani.gif', writer='imagemagick') plt.show()                  

The matplotlib way

The cartopy approach

Under the hood, cartopy's matplotlib implementation (as used above), is calling the project_geometry method. We may as well make use of this directly as it is often more than convenient to be using Shapely geometries than it is matplotlib Paths.

With this approach, we simply define a shapely geometry, and so construct the source and target coordinate reference systems that nosotros want to catechumen the geometry from/to:

          target_cs.project_geometry(geometry, source_cs)                  

The just thing we have to lookout out for is that the event can be a MultiLineString (or more mostly, whatsoever Multi- geometry type). However, in our simple example, we don't need to bargain with that (incidentally, the same was true of the simple Path returned in the beginning example).

The code to produce a similar plot to above:

          import cartopy.crs as ccrs import matplotlib.blitheness equally animation import matplotlib.pyplot as plt import numpy as np import shapely.geometry as sgeom   ax = plt.axes(project=ccrs.Robinson()) ax.stock_img()  ny_lon, ny_lat = -75, 43 delhi_lon, delhi_lat = 77.23, 28.61   line = sgeom.LineString([[ny_lon, ny_lat], [delhi_lon, delhi_lat]])  projected_line = ccrs.PlateCarree().project_geometry(line, ccrs.Geodetic())  # We only animate along one of the projected lines. if isinstance(projected_line, sgeom.MultiLineString):     projected_line = projected_line.geoms[0]  ax.add_geometries(     [projected_line], ccrs.PlateCarree(),     edgecolor='blueish', facecolor='none')  [point] = plt.plot(ny_lon, ny_lat, marker='o', transform=ccrs.PlateCarree())   def animate_point(i):     verts = np.array(projected_line.coords)     i = i % verts.shape[0]     # Set the coordinates of the line to the coordinate of the path.     signal.set_data(verts[i, 0], verts[i, i])  ani = animation.FuncAnimation(     ax.figure, animate_point,     frames=len(projected_line.coords),     interval=125, repeat=True)  ani.salvage('projected_line_ani.gif', writer='imagemagick') plt.show()                  

The cartopy way

Final remaaaaarrrrrrks....

The approach naturally generalises to animating whatsoever type of matplotlib Arrrrtist.... in this case, I took a flake more than control over the slap-up circle resolution, and I blithe an image along the great circle:

          import cartopy.crs as ccrs import matplotlib.animation equally animation import matplotlib.pyplot as plt import numpy as np import shapely.geometry every bit sgeom   ax = plt.axes(projection=ccrs.Mercator()) ax.stock_img()  line = sgeom.LineString([[-5.9845, 37.3891], [-82.3666, 23.1136]])   # Higher resolution version of Mercator. Same workaround equally found in # https://github.com/SciTools/cartopy/problems/viii#issuecomment-326987465. class HighRes(ax.projection.__class__):     @belongings     def threshold(self):         return super(HighRes, self).threshold / 100   projected_line = HighRes().project_geometry(line, ccrs.Geodetic())  # Nosotros only animate along one of the projected lines. if isinstance(projected_line, sgeom.MultiLineString):     projected_line = projected_line.geoms[0]  # Add the projected line to the map. ax.add_geometries(     [projected_line], ax.projection,     edgecolor='blueish', facecolor='none')   def ll_to_extent(10, y, ax_size=(4000000, 4000000)):     """     Render an image extent in centered on the given     point with the given width and height.      """     return [x - ax_size[0] / 2, x + ax_size[0] / ii,             y - ax_size[1] / 2, y + ax_size[1] / 2]   # Image from https://pixabay.com/en/sailing-ship-gunkhole-sail-pirate-28930/. pirate = plt.imread('pirates.png') img = ax.imshow(pirate, extent=ll_to_extent(0, 0), transform=ax.projection, origin='upper')  ax.set_global()   def animate_ship(i):     verts = np.array(projected_line.coords)     i = i % verts.shape[0]      # Prepare the extent of the epitome to the coordinate of the path.     img.set_extent(ll_to_extent(verts[i, 0], verts[i, i]))   ani = animation.FuncAnimation(     ax.figure, animate_ship,     frames=len(projected_line.coords),     interval=125, repeat=False)  ani.save('arrrr.gif', writer='imagemagick') plt.prove()                  

Arrrr, here be pirates!

All code and images for this answer can be found at https://gist.github.com/pelson/618a5f4ca003e56f06d43815b21848f6.

Source: https://stackoverflow.com/questions/51482082/animate-a-point-moving-along-path-between-two-points

Posted by: pettitsuded1943.blogspot.com

0 Response to "How Do You Animate A Dot Moving From Point To Point On A Map"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel