quiver plot does not adjust to arrow extent

62 Views Asked by At

As visible for example here: How to turn off matplotlib quiver scaling?

when using matplotlib.pyplots's quiver to draw arrows, the arrows often point out of the image. It seems like the plot adjusts only to the starting point (X, Y arguments to quiver()) and does not take into account the extent of the actual arrows. Is there an easy way to rescale the axes to include the entire arrow?

I'm aware of plt.xlim(..., ...) , plt.ylim(..., ...), or Axes.set_xlim / Axes.set_ylim; I thought maybe there is a global command (like the tight layout command) to include all points into the visible part of the plot (all plots at once, potentially)?


Update, since someone was not happy about the question: Trying to add to the example I linked, what @Mathieu suggested in the comments (constrained layout), does not appear to work:

import matplotlib.pyplot as plt
import numpy as np

pts = np.array([[1, 2], [3, 4]])
end_pts = np.array([[2, 4], [6, 8]])
diff = end_pts - pts

plt.quiver(pts[:,0], pts[:,1], diff[:,0], diff[:,1],
           angles='xy', scale_units='xy', scale=1.)

We get an image with one arrow pointing out of the image: enter image description here

Enabling constrained layout:

import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['figure.constrained_layout.use'] = True

pts = np.array([[1, 2], [3, 4]])
end_pts = np.array([[2, 4], [6, 8]])
diff = end_pts - pts

plt.quiver(pts[:,0], pts[:,1], diff[:,0], diff[:,1],
           angles='xy', scale_units='xy', scale=1.)

This results in smaller margins, but has no effect on axis ranges: enter image description here

1

There are 1 best solutions below

0
dasWesen On

It seems you can add invisible endpoints with plt.scatter(). This is not a "global" option but for me it also does the job (I don't have to take a max, so it's one step less than ylim/xlim).

import matplotlib.pyplot as plt
import numpy as np

pts = np.array([[1, 2], [3, 4]])
end_pts = np.array([[2, 4], [6, 8]])
diff = end_pts - pts

plt.scatter(end_pts[:, 0], end_pts[:, 1], s=0)
plt.quiver(pts[:,0], pts[:,1], diff[:,0], diff[:,1],
           angles='xy', scale_units='xy', scale=1.)

This gives the following image:

nicer arrow plot