-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[Annotations] ValueError: lines do not intersect when computing tight bounding box containing arrow with filled paths #12820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
fyi @thempel |
bisects to #11801. |
that was quick! |
Since I have currently no idea at which point in the code this needs to be fixed, a workaround is to not use parallel lines,
|
I would like to report that I got this error also when doing animation with matplotlib and this particular error did not occur in 2017. I only ran into it after updating matplotlib. I found that I would not run into this error if I disable a certain line in the animation. Also found out that if I downgrade to ver 2.3.3, then it works. |
I also would like to report getting this error. I am on Matplotlib |
@darienmorrow do you have a more minimal example that reproduces this? |
I was working with @darienmorrow on his figure, I was unable to reproduce on current master (9895288) |
Can you try with the v3.2.0 rc ( |
Okay, so it is backend dependent (I have not done an exhaustive search, but there is something weird going on, that I cannot replicate all behavior in a clean venv) So (@darienmorrow uses conda on his main machine, for what it is worth, unless otherwise noted, packages are from conda-forge): In his base venv, the figure fails to build under Agg and Qt5Agg, but succeeds under TkAgg All other configurations I have tried fail only under Qt5Agg (having tested Agg, Qt5Agg, TkAgg). This includes clean venv installs only, but including Qt (installed the conda forge matplotlib full package, not just matplotlib-base):
Unfortunately, this figure is burried in a fairly long script, and attempts to break out only the failing parts have not triggered the error. I may have another go at it, though. |
Okay, I have a simplified script. It seems to be a very unlucky rounding condition. import matplotlib as mpl
mpl.use("qt5agg")
import matplotlib.pyplot as plt
import pathlib
print(mpl.get_backend())
fig_type = '.png'
here = pathlib.Path(__file__).parent
save=True
nrows =4
ncols = 4
hspace = wspace = 0.09523809523809526
fig = plt.figure(figsize=[6.5, 6.5])
fig.subplots_adjust(1/6.5, 1/6.5, 1-1/6.5, 1-1/6.5)
gs = mpl.gridspec.GridSpec(nrows, ncols, hspace=hspace, wspace=wspace)
axstark = plt.subplot(gs[2:4,0:2])
axstarkins = axstark.inset_axes([0.0,0.0,0.8,1])
ax = axstarkins
# plot states
y0 = [0.2, .8]
x0 = [.2,.45]
y0p = [.3,.7]
# pump arrows
x = (x0[1] - x0[0]) / 2 + x0[0]
arrowprops={"width":1, "headwidth":7, "headlength":7}
ax.annotate(s='', xy=(x-.04,y0p[1]), xytext=(x-.04, y0[0]), arrowprops=arrowprops)
ax.annotate(s='', xy=(x+.04,y0p[0]), xytext=(x+.04, y0[1]), arrowprops=arrowprops)
# finish up
if save:
p = "intro_fig"+fig_type
plt.savefig(here / p) Some notes:
Also, the figure script is why I opened up #15049, just noticed that we are still explicitly passing |
Yikes, thanks for running this to ground @ksunden ! From a very cursory investigation it looks like we have one part of the code that is checking "are you parallel" using one threshold and then calling code that checks "are you not parallel" using a slightly different threshold. |
Per @tacaswell's comment, the following patch appears to fix the issue: diff --git i/lib/matplotlib/bezier.py w/lib/matplotlib/bezier.py
index 9e347ce87..8cec64f15 100644
--- i/lib/matplotlib/bezier.py
+++ w/lib/matplotlib/bezier.py
@@ -389,23 +389,23 @@ def get_parallels(bezier2, width):
# find cm_left which is the intersecting point of a line through
# c1_left with angle t1 and a line through c2_left with angle
# t2. Same with cm_right.
- if parallel_test != 0:
- # a special case for a straight line, i.e., angle between two
- # lines are smaller than some (arbitrary) value.
- cmx_left, cmy_left = (
- 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left)
- )
- cmx_right, cmy_right = (
- 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right)
- )
- else:
+ try:
cmx_left, cmy_left = get_intersection(c1x_left, c1y_left, cos_t1,
sin_t1, c2x_left, c2y_left,
cos_t2, sin_t2)
-
cmx_right, cmy_right = get_intersection(c1x_right, c1y_right, cos_t1,
sin_t1, c2x_right, c2y_right,
cos_t2, sin_t2)
+ except ValueError:
+ # Special case straight lines, i.e., angle between two lines is
+ # less than the threshold used by get_intersection (we don't use
+ # check_if_parallel as the threshold is not the same).
+ cmx_left, cmy_left = (
+ 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left)
+ )
+ cmx_right, cmy_right = (
+ 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right)
+ )
# the parallel Bezier lines are created with control points of
# [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right] Just needs a test, yada yada. |
That is a test which fails (raises ValueError) on current master (8ac3ea1), but passes with the above patch applied. We could add checks that it gives expected results, but really all that we are looking for is that it doesn't error out. Unless I am mistaken, there are no unit tests targeting only |
I don't think we should worry about such a case; clearly we should be able to pick whatever threshold for parallel-checking makes sense for us (in a sense get_parallels should be private API). |
I agree with @anntzer . We don't usually consider tweaking floating point thresholds an API change. |
Fair enough, then it is unclear to me that there are any actual tests required in this instance. |
This is the diff provided by @anntzer [here](matplotlib#12820 (comment)) Closes matplotlib#12820
Uh oh!
There was an error while loading. Please reload this page.
Bug report
During computation of tight_layout of subplots containing a histogram one gets a ValueError in bezier.py:35: Given lines do not intersect. Please verify that the angles are not equal or differ by 180 degrees.
Could be related to #6076
See the attached script and csv files to reproduce the bug. I have marked three FIXME code lines, that are all conditions for the bug to be triggered.
This seems to be a regression in matplotlib 3, since the LTS version is running fine.
test files: files.zip
leads to
Expected outcome
It works, if the arrowprops are omitted, which means not to draw an arrow.
Matplotlib version
print(matplotlib.get_backend())
): module://backend_interaggInstalled with conda from conda-forge.
The text was updated successfully, but these errors were encountered: