问题
I've been trying for a while now to plot vector field with uncertainty ellipses in Cartopy. The idea is that if I have a location (lat/lon) and a vector (wind speed, for example), but that vector has an uncertainty (measured in standard deviation, for example), then I'd like to plot an ellipses around the tip of the arrow indicating that uncertainty. In GMT, psvelo
does the trick, my goal is something like this.
This is the same question as has been asked before here - I'm reopening it because I think that if someone can help me understand transforms better and I can find the location of the tip of the arrow, I can plot the error ellipse myself. Plus, some Matplotlib/Cartopy functionality might have changed in the last 4 years.
So, here's what I tried so far:
Making a map, using quiver to plot the vectors, and then trying to access some sort of scale parameter in the returned
Quiver
object. I couldn't find anything useful, and even though thescale
attribute looked like it would've been the right thing, it turned out never to be set unless I set it myself.If I do set the scaling myself, I don't know how to do this if my location and vector have different units, and both are obviously not related to the axis width. For example, if I decided that I want to have a 50 m/s long vector at 10°E, 40°N, to be a certain fraction of the width of the axis, what would my
scale
parameter be? Me trying out random combinations of transformations has not gotten any results. (The idea here then being, if I can figure out that relation, then I am one step closer to knowing where to put the ellipse.)I've tried to figure out
quiver
's autoscaling to see how I can "predict" what it's going to do internally, and then use that to know where the tip of the arrow is. Sadly, it's not as straightforward as the Matlab variant, so I failed at that as well.Lastly, I also don't understand why I can't use
cartopy.crs.Geodetic()
as my source coordinate system. The error I get isinvalid transform: Spherical quiver is not supported - consider using PlateCarree/RotatedPole.
From reading the Cartopy documentation, wouldn't that be the appropriate one if my vector's location is measured in latitude, longitude and altitude?
Here's an MWE:
# imports
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
# data
lon, lat = np.array([10, 10.5]), np.array([40, 40])
east, north = np.array([0, 50]), np.array([50, 0])
# map
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Mercator()})
ax.set_extent([7, 13, 38, 42], ccrs.Geodetic())
ax.coastlines("50m")
q = ax.quiver(lon, lat, east, north, transform=ccrs.PlateCarree())
plt.show()
I really think this is a feature that Cartopy should have, as it is one of the biggest hurdles I've encountered so far when using Python for geoscience applications. Currently, the only approach I know is to write a GMT script file from within my Python program, and run GMT with a Python system call, and that's really a pain.
I know that GMT is developing their own Python interface, but they haven't even incorporated all the basic functionality, so it's anyone's guess when they will get to psvelo
...
Thanks for all your help and tips,
PBB
回答1:
Well the hard part about this is the matplotlib part. If I were trying to make this, I'd focus on that before making it work in Cartopy. Technically, the point you need is somewhere in the set of paths generated by the quiver
command (located in q._paths
in your MWE). A simpler solution would be to use pivot='tip'
so that the point of the arrow is always located at the (x,y)
point.
The error you're getting from Cartopy when you try to use Geodetic
is because doing everying correctly when working on a sphere involves more complicated math--thus not everything works with Geodetic
. If instead you use PlateCarree
, it will treat lon/lat as Cartesian coordinates on a plane.
来源:https://stackoverflow.com/questions/60679029/cartopy-cant-plot-vector-field-with-uncertainties-and-related-questions