(self, XY, U, V, angles)
| 658 | # XY is stacked [X, Y]. |
| 659 | # See quiver() doc for meaning of X, Y, U, V, angles. |
| 660 | def _make_verts(self, XY, U, V, angles): |
| 661 | uv = (U + V * 1j) |
| 662 | str_angles = angles if isinstance(angles, str) else '' |
| 663 | if str_angles == 'xy' and self.scale_units == 'xy': |
| 664 | # Here eps is 1 so that if we get U, V by diffing |
| 665 | # the X, Y arrays, the vectors will connect the |
| 666 | # points, regardless of the axis scaling (including log). |
| 667 | angles, lengths = self._angles_lengths(XY, U, V, eps=1) |
| 668 | elif str_angles == 'xy' or self.scale_units == 'xy': |
| 669 | # Calculate eps based on the extents of the plot |
| 670 | # so that we don't end up with roundoff error from |
| 671 | # adding a small number to a large. |
| 672 | eps = np.abs(self.axes.dataLim.extents).max() * 0.001 |
| 673 | angles, lengths = self._angles_lengths(XY, U, V, eps=eps) |
| 674 | |
| 675 | if str_angles and self.scale_units == 'xy': |
| 676 | a = lengths |
| 677 | else: |
| 678 | a = np.abs(uv) |
| 679 | |
| 680 | if self.scale is None: |
| 681 | sn = max(10, math.sqrt(self.N)) |
| 682 | if self.Umask is not ma.nomask: |
| 683 | amean = a[~self.Umask].mean() |
| 684 | else: |
| 685 | amean = a.mean() |
| 686 | # crude auto-scaling |
| 687 | # scale is typical arrow length as a multiple of the arrow width |
| 688 | scale = 1.8 * amean * sn / self.span |
| 689 | |
| 690 | if self.scale_units is None: |
| 691 | if self.scale is None: |
| 692 | self.scale = scale |
| 693 | widthu_per_lenu = 1.0 |
| 694 | else: |
| 695 | if self.scale_units == 'xy': |
| 696 | dx = 1 |
| 697 | else: |
| 698 | dx = self._dots_per_unit(self.scale_units) |
| 699 | widthu_per_lenu = dx / self._trans_scale |
| 700 | if self.scale is None: |
| 701 | self.scale = scale * widthu_per_lenu |
| 702 | length = a * (widthu_per_lenu / (self.scale * self.width)) |
| 703 | X, Y = self._h_arrows(length) |
| 704 | if str_angles == 'xy': |
| 705 | theta = angles |
| 706 | elif str_angles == 'uv': |
| 707 | theta = np.angle(uv) |
| 708 | else: |
| 709 | theta = ma.masked_invalid(np.deg2rad(angles)).filled(0) |
| 710 | theta = theta.reshape((-1, 1)) # for broadcasting |
| 711 | xy = (X + Y * 1j) * np.exp(1j * theta) * self.width |
| 712 | XY = np.stack((xy.real, xy.imag), axis=2) |
| 713 | if self.Umask is not ma.nomask: |
| 714 | XY = ma.array(XY) |
| 715 | XY[self.Umask] = ma.masked |
| 716 | # This might be handled more efficiently with nans, given |
| 717 | # that nans will end up in the paths anyway. |
no test coverage detected