quivermc is an adapted version of Andrew Roberts' ncquiverref. Dr. Roberts' function and this function fix a couple of problems with Matlab's quiverm function. The two primary reasons you should never use quiverm are as follows:
1. Matlab's quiverm confoundingly mixes up u and v. By convention in the Earth sciences, u is the zonal component where eastward is positive and v is the meridional component where northward is positive. Matlab gets this wrong, but the quivermc function described here gets it right.
2. For reasons related to ship travel and some old legacy code from Navy guys decades ago, Matlab's quiverm scales vectors in a strange way that depends on latitude. If you're plotting some absolute field like wind vectors, there is no physical reason that you would want to scale vectors in such a way that their zonal components shrink to zero at the poles.
In addition to fixing the problems described above, quivermc also allows a few extra options including color settings, arrow density, and options for displaying converging or diverging flow.
descriptions says quivermc(lat,lon,u,v) plots 'vectors' of zonal and meridional components u and v at locations given by lat and lon, but asks for grid.
I guess the problem is that my "grids" are not regular spaced and this function only support regular spaced grids.
I am having some trouble plotting from data, where lat, lon,u and v are row vectors. With quiver() and quiverm() this is possible by converting the row vectors to grids by doing [lat;lat], [lon;lon], [u;u] and [v;v]. But when I do this with quivermc() it does not plot anything and does not raise any errors.
Thanks for any help!
Why does this function only accept grids? What if I want to plot only 1 vector arrow? The original quiverm accepts singular inputs.
Thank you for the code, it does indeed work a lot better than quiverm. I do run into one repeated error when I try to create a reference vector. When I try to specify the units of the reference vector, I get an error message that states that:
Error using text
First two or three arguments must be numeric doubles.
Error in quivermc (line 417)
Has this error come up before and do you perhaps have a solution to it? As far as I'm aware, this is the correct way of trying to plot the reference vector correct?
I hope you can point out the error, otherwise the function still does a good job for the rest.
Thank you very much for this great function! It really helped me a lot!
I do have found a tiny problem, though, which could be fixed very easily. If I set the location of the colormap to be 'horizontal', it doesn't work and shows error.
I notice that in the code (line 183) you replace 'horizontal' with 'SouthOutside', and in one line above (line 182) you replace 'on' with 'EastOutside'. However, 'horizontal' itself contains 'on' so it will end up with 'horiEastOutsidetal' and there goes the error.
So if you exchange the position of those two lines, i.e. replace 'horizontal' with 'SouthOutside' before replacing 'on' with 'EastOutside', it should be good to go.
Thanks for the feedback. For your situation I'd recommend setting everything you don't want to plot to NaN before using quivermc. For example, if only want to plot data north of 70N, this should work:
Just a quick question. I love the function. When I plot the quiver arrows over a stereographic map of the Arctic, I get a large number of arrows that project off of the projection. Any way to work out this? Basically, I would just like to set the map latitude limits and plot the data within those limits instead of the whole dataset.
The "Undefined function..." error message almost always means Matlab can't find the function. Make sure you download, unzip, and put quivermc somewhere Matlab can find it.
Dear Chad i test your code without changing any thing but i get " Undefined function or method 'quivermc' for input arguments of type 'double'.
Error in ==> Untitled at 108
i wanna know what's the problem?
Thanks for bringing this to my attention. I have never worked with orthographic projections before, but you are exactly right. I wish I could offer some elegant solution, but nothing immediately comes to mind, unless you can figure out which vectors are on the other side of the globe and NaN-out those values.
On a philosophical note, an orthographic projection may not be the best choice for showing vector fields. The vector field is plotted in 2D space where equal length is given to equal vector magnitudes everywhere in the map, whereas orthographic projections are distorted toward the horizon of the globe. Mixing and undistorted vector fields with distorted space may be confusing for the viewer to interpret.
Nonetheless, if you find a good solution to the problem of quivermc plotting on all sides of an orthographic projection, please let me know.
Thanks for this nice routine.
One problem: When you set axesm('ortho') quivermc also draws "hidden" vectors (on the backside of the hemisphere).
Do you have any suggestions for improving this?
Thanks in advance for any comments!
Thank u for your answer.
I get your point of the first question .
I must draw all the arrows,and my u,v have lots of NaN,so each arrow will not only be about a pixel in width. Why can I draw all arrows using quiverm although they look not good.
I tried to delete all NaN ,and reshape u,v,lon,lat,and I can use your function to draw all arrows,but there is another question,the number of NaN is not the same when I have many different u,v.
Matlab's quiverm mixes up u and v because by convention in Earth Science, u is the zonal component and v is the meridional component. However, Matlab's quiverm goes against convention and defines u as the meridional component and v as the zonal. Matlab's quiverm also scales the arrows by latitude, but that's a different problem.
You probably do not want to plot all 608x896 arrows in your field for two reasons:
1. Plotting over half a million arrows hogs computational resources.
2. More importantly, what are the dimensions of your figure? If your figure is 1000 pixels wide, that means each arrow can only be about a pixel in width. A one-pixel arrow will not look like an arrow, it will look like a tiny dot.
Thank u for sharing your code.I want to ask you some questions.
First,you say matlab's quiverm confoundingly mixes up u and v. But I use quiverm to draw arrows correctly.Why did you think matlab is wrong?
Second,my u matrix is 608*896,how can I get the full arrows.I tried to modify your code,changed the defaultWidth 50 to 1000,and changed DensityVal 100 to 1000.But the output is wrong.Hope to get your precious answer.
Thanks in advance for any help,
That's a great question worth clarifying. Inputs lat and lon can only have units of degrees, but u and v can have just about any units *except* degrees. So u and v in meters per second or miles per hour or angstroms per fortnight are perfect for quivermc.
I wrote quivermc because Matlab's inbuilt quiverm function only accepts velocities in degrees, which is absolutely nonsensical for most real-world applications. You can absolutely use quivermc for wind data without needing to do any silly latitude-dependent scaling.
There are a couple of examples in the html documentation file (the light bulb icon on this page) that show how you can even label a reference arrow with any units you'd like.
Let me know if you have any more questions.
Thanks for the awesome submission.
I have a question about the format of the input arguments u and u.
I am trying to overlay wind vectors on a map (generated with geoshow), with the wind vector locations given by lat and lon matrices (in degrees) and the u and v components given in meters per second.
The ncquiverref function requires that the location matrices for the vectors be in the same units as the u and v component (i.e. if the locations of the vectors are in degrees, the u and v components have to be in degrees, whereas if the locations are in Cartesian units the u and v components must be in Cartesian units).
Do the u and v inputs for quivermc have to be in degrees lon and degrees lat per unit time (respectively), as the location inputs are in degrees? I see in your conversation with Gino below that the coordinates (I'm assuming this is just the location matrices?) cannot be in Cartesian units, but I was not able to find anywhere in the documentation that u and v had to be in any particular units.
Thanks in advance for any help,
Quivermc needs to know where every arrow should be placed. You seem to have information about the size and direction of 144 x ? arrows, but your missing information about where those arrows belong. I wish I could be more helpful, but it sounds like your dataset is incomplete. It is difficult to know without any more information.
Many thanks for sharing this routine!It is great.
I have a question.
Error using quivermc (line 143)
Dimensions of lat, lon, u, and v must agree.
In my case, lon, u and v have the same lenght 144. But the lat has 73. What can I do to solve that?
Any help or suggestion will be greatly appreciated.
It looks like you are plotting in cartesian coordinates. quivermc is for map coordinates. If you have the mapping toolbox, initialize a map first with the worldmap function. If you do not have the Mapping Toolbox, I think you'll need to use one of the other quiver functions on the File Exchange site. Good luck!
Great addition to ncquiverref, thanks !!!
I have a question regarding an error I keep getting:
??? Error using ==> quivermc at 247
Current axes must be map axes.
I'm plotting WRF wind vectors. The WRF data is on a Lambert conformal conic projection. I'm using the function toposurf (http://mooring.ucsd.edu/software/matlab/doc/map/toposurf.html) to plot a map of 2 meters air temperature and trying to plot the wind vectors on top. I've being using ncquiverref to plot the wind vectors with success, but I need to make the arrows a thicker and the "divergent" option will help better display my data.
Any help or suggestion will greatly appreciated.
Thanks, this is excellent.
Leyon, that is an excellent suggestion. I've now included some options for colorbars. Thanks for the tip!
Very nice function. A suggestion to improve your function is to scale the colorbar xticks based on the reference value rather than 0:1. It would eliminate the need for the user to do the multiplication.
Here is the snippet of code I use to do such a task:
set(cb, 'xticklabel', get(cb, 'xtick') * refval);
cb is a handle to the colorbar or in your case can be turned on if the option colormap is defined in line 331.
Good quiver plot function with excellent range of options.
Typo fix in example file.
Now includes options for colorbar formatting, made possible in part by John Barber's calcticks function.
Now includes linewidth option and more arrow size scaling options.
Removed 'refvec' 'on' or 'off' style. Now a reference vector is printed only when units are declared.