So i tried to use plt.quiver, but i couldn't align the vectors to the grids. When I try to use angles = "xy" it flattens the vectors. When i use angles = "uv" its not aligned.
Here is my code:
import matplotlib.pyplot as plt
import numpy as np
v1 = np.array([[2],[2]])
V = 0
U = 0
fig = plt.figure(figsize=(5,10))
ax1 = plt.subplot(2,1,1)
ax1.quiver(V, U, v1[0], v1[1], scale = 1, units= "xy",angles = "uv")
ax1.set_ylim(-3,3)
ax1.set_xlim(-3,3)
ax1.grid()
ax2 = plt.subplot(2,1,2)
ax2.quiver(V, U, v1[0], v1[1], scale = 1, units= "xy",angles = "uv")
ax2.set_ylim(-3,3)
ax2.set_xlim(-3,3)
ax2.grid()
plt.show()
Error code when using angles ="xy":
The error code : ...\Python\Python310\lib\site-packages\matplotlib\quiver.py:609: RuntimeWarning: invalid value encountered in true_divide lengths = np.hypot(*dxy.T) / eps
The plot:
When angles = "xy": https://i.stack.imgur.com/6DFd9.png
When angles = "uv": https://i.stack.imgur.com/dB5dv.png
I'm a little bit new to the quiver function and I'm not sure how could i solve this.
CodePudding user response:
This appears to be an artifact (bug?) of how matplotlib is trying to scale the arrows.
In the source of Quiver
, here there is the following lines:
if str_angles == 'xy' and self.scale_units == 'xy':
# Here eps is 1 so that if we get U, V by diffing
# the X, Y arrays, the vectors will connect the
# points, regardless of the axis scaling (including log).
angles, lengths = self._angles_lengths(U, V, eps=1)
elif str_angles == 'xy' or self.scale_units == 'xy':
# Calculate eps based on the extents of the plot
# so that we don't end up with roundoff error from
# adding a small number to a large.
eps = np.abs(self.axes.dataLim.extents).max() * 0.001
angles, lengths = self._angles_lengths(U, V, eps=eps)
The key line being eps = np.abs(self.axes.dataLim.extents).max() * 0.001
inside the second if block, which is what applies to your call to quiver(...)
.
All of your data is located at (0,0), which means self.axes.dataLim.extents
are zero, and so eps
is in turn zero.
The error:
RuntimeWarning: invalid value encountered in true_divide lengths = np.hypot(*dxy.T) / eps
you see is because of a division by zero later on, which tries to use that eps
value as a denominator.
You can work-around this either by passing scale_units="xy"
to the quiver(...)
call, or by calling update_datalim on your axes. E.g.
ax1.update_datalim([(-3, -3), (3, 3)]) # Force axis datalimits to include area we want to view.
or
ax1.quiver(V, U, v1[0], v1[1], scale=1, units="xy", angles="uv", scale_units="xy")