Skip to content
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

[Bug]: Spurious lines added with some manually add contour labels #27333

Closed
kafitzgerald opened this issue Nov 15, 2023 · 5 comments · Fixed by #27334
Closed

[Bug]: Spurious lines added with some manually add contour labels #27333

kafitzgerald opened this issue Nov 15, 2023 · 5 comments · Fixed by #27334
Milestone

Comments

@kafitzgerald
Copy link

Bug summary

With Matplotlib 3.8+ I'm seeing spurious lines that get added with manually labeled contours via clabel.

It seems to only happen in locations where the contours are more complex or near those areas, but I haven't been able to track down why this happens.

Code for reproduction

Example code (here working with Matplotlib <3.8): https://geocat-examples.readthedocs.io/en/latest/gallery/Contours/NCL_coneff_8.html

I'll work on stripping down this example though.

Actual outcome

when run in a script that provided a manual list of contour label locations:
Screen Shot 2023-11-15 at 3 17 14 PM

when locations were manually clicked:
Screen Shot 2023-11-15 at 3 21 19 PM

Expected outcome

similar, but without the spurious straight lines.

Additional information

What are the conditions under which this bug happens?

  • happens with both "clicked" and specified manual contour labels in certain locations
  • seems to happen only near areas with more complex contours
  • interestingly, this also happens when you specify contour label locations this way on a cartopy map and the specified points are not on the projected map. however, this is not the case here.
    Has this worked in earlier versions?
  • worked prior to 3.8
    Do you know why this bug is happening?
  • unfortunately, no. will look into it a bit more though.

Operating system

OS/X

Matplotlib Version

3.8.1

Matplotlib Backend

MacOSX

Python version

Python 3.11.6

Jupyter version

4.0.8

Installation

conda

@ksunden
Copy link
Member

ksunden commented Nov 16, 2023

Do you have a minimal (i.e. mpl + numpy only, preferably) reproducer of this?

I know that there were some issues in 3.8.0 that seem similar at least, but I thought I fixed them for 3.8.1 in #27045. Are you sure they persist in 3.8.1?

@kafitzgerald
Copy link
Author

Sorry about that.

Here you go:

from matplotlib import pyplot as plt
import numpy as np

lat = [-87.8638  , -85.09653 , -82.31291 , -79.525604, -76.7369  , -73.94752 ,
       -71.15775 , -68.36776 , -65.57761 , -62.787354, -59.99702 , -57.20663 ,
       -54.4162  , -51.625732, -48.83524 , -46.044727, -43.254196, -40.46365 ,
       -37.673088, -34.882523, -32.091946, -29.30136 , -26.510769, -23.720175,
       -20.929575, -18.138971, -15.348365, -12.557756,  -9.767145,  -6.976533]
plev = [100000,  85000,  70000,  50000,  40000,  30000,  25000,  20000]
u = np.array([[ 5.281284  ,  5.281284  ,  5.281284  ,  5.281284  ,  5.281284  ,
         5.281284  ,  5.281284  ,  5.281284  ,  5.281284  ,  5.281284  ,
         5.281284  ,  5.281284  ,  5.281284  ,  5.281284  ,  4.5694838 ,
         8.355004  ,  8.594497  ,  7.364512  ,  5.3017035 ,  2.8804004 ,
         0.5346078 , -1.9970245 , -4.043903  , -5.495614  , -6.4742966 ,
        -6.86549   , -6.916672  , -6.6135497 , -5.824724  , -4.929174  ],
       [-7.8476605 , -7.8476605 , -7.8476605 , -4.9444113 , -4.6574264 ,
        -4.4306536 , -1.0847874 ,  0.23506624,  2.1887915 ,  6.6546087 ,
        10.182983  , 12.602904  , 14.024249  , 14.453691  , 14.11188   ,
        13.432743  , 12.298697  , 10.441111  ,  8.136927  ,  5.701264  ,
         3.1575031 ,  0.8824925 , -0.8204733 , -2.142562  , -3.2946696 ,
        -4.214696  , -5.014298  , -5.75503   , -5.797411  , -4.7429767 ],
       [-4.7934184 , -3.987672  , -3.880484  , -3.8545942 , -3.400934  ,
        -2.1740034 , -1.4144217 ,  1.8231349 ,  5.741105  ,  9.357849  ,
        12.589281  , 15.095114  , 16.566757  , 17.07177   , 16.893904  ,
        16.211683  , 15.016567  , 13.3146    , 11.277677  ,  9.180042  ,
         7.2710013 ,  5.7038155 ,  4.5025063 ,  3.3811352 ,  1.9761666 ,
         0.17865679, -1.848804  , -3.5658486 , -4.2557425 , -3.6108153 ],
       [-0.6427475 , -1.3300483 , -1.8785819 , -1.8878341 , -1.1554126 ,
         0.2460148 ,  2.640771  ,  5.841252  ,  9.352374  , 12.879071  ,
        16.21606   , 19.04898   , 20.9498    , 21.753773  , 21.649551  ,
        20.907742  , 19.693817  , 18.178251  , 16.707623  , 15.646201  ,
        15.057117  , 14.641205  , 13.846154  , 12.143323  ,  9.386396  ,
         5.9252477 ,  2.368536  , -0.5125828 , -2.0722165 , -2.2778945 ],
       [-0.58929294, -1.2046508 , -1.4544653 , -1.0103273 ,  0.15982199,
         1.9466033 ,  4.447282  ,  7.6771903 , 11.419675  , 15.136187  ,
        18.620575  , 21.717804  , 23.922436  , 24.840185  , 24.701748  ,
        23.987408  , 22.880804  , 21.526987  , 20.463743  , 20.20535   ,
        20.610573  , 20.982576  , 20.493448  , 18.504211  , 14.933222  ,
        10.389049  ,  5.7908807 ,  2.0268278 , -0.2654018 , -1.0479335 ],
       [-0.4088514 , -0.7439224 , -0.6603948 ,  0.0878893 ,  1.6308761 ,
         3.7945688 ,  6.51758   , 10.002526  , 14.048776  , 18.030323  ,
        21.763384  , 25.12306   , 27.494097  , 28.48131   , 28.469887  ,
        27.976196  , 27.148748  , 26.233028  , 25.929998  , 26.776876  ,
        28.395657  , 29.60503   , 29.1222    , 26.262024  , 21.399248  ,
        15.65298   , 10.07546   ,  5.45065   ,  2.312821  ,  0.5890202 ],
       [-0.30047217, -0.4094708 , -0.09946479,  0.78269076,  2.5223484 ,
         4.950463  ,  7.8729997 , 11.537473  , 15.756553  , 19.893959  ,
        23.728504  , 27.066483  , 29.343843  , 30.36043   , 30.488892  ,
        30.099907  , 29.479034  , 29.078144  , 29.513182  , 31.190378  ,
        33.604244  , 35.186615  , 34.35078   , 30.635078  , 24.895414  ,
        18.486992  , 12.361381  ,  7.0874414 ,  3.166243  ,  0.7561427 ],
       [-0.11722137,  0.06281883,  0.64088964,  1.7681435 ,  3.7674735 ,
         6.47419   ,  9.705322  , 13.647254  , 18.064777  , 22.31285   ,
        26.111181  , 29.2265    , 31.215776  , 32.078777  , 32.2106    ,
        31.913328  , 31.606083  , 31.906605  , 33.293755  , 35.880253  ,
        38.87251   , 40.392326  , 38.82986   , 34.17306   , 27.61663   ,
        20.4983    , 13.791601  ,  8.023929  ,  3.5063663 ,  0.5009983 ]])

contours = plt.contour(lat,plev,u,
                             levels=13,
                             vmin=-8,
                             vmax=40,
                             colors='black',
                             linewidths=0.5,
                             linestyles='solid')

# Label the contours
manual = [(-70, 55000), (-80, 26000), (-58, 30000), (-25, 42000),
          (-45, 69500), (-40, 34000), (-12, 39000), (-37, 75000),
          (-72, 22500)]

clabels = plt.clabel(contours,
                     fontsize=12,
                     colors="black",
                     fmt="%.0f",
                     manual=manual)

There were some similar issues in maptlotlib 3.8 that seem to have cleared up now, but this is with 3.8.1

@ksunden
Copy link
Member

ksunden commented Nov 16, 2023

Okay, what is happening here is that the "nearest contour" logic is picking the point along the MOVETO line (which isn't drawn), and needs to filter out results with codes=MOVETO)

The above with a few things drawn:

path = contours.get_paths()[2]
fullpath = path.deepcopy()
fullpath.codes[1:] = 2
plt.gca().add_artist(mpatches.PathPatch(path, facecolor="none", edgecolor="C0", lw=4))
plt.gca().add_artist(mpatches.PathPatch(fullpath, facecolor="none", edgecolor="C3", lw=2))

plt.plot([-72], [22500], "C1o")

Shows that the offending point lies right on the omitted line.

Blue is the 0 contour, red is the 0 contour with all "LINETO" codes in the path (After the first point), orange dot is the requested manual position for the offending contour.

Figure_1

Should be relatively easy to fix, I think...

@ksunden
Copy link
Member

ksunden commented Nov 16, 2023

@kafitzgerald I opened a draft PR that I think should solve it, if you could to run it through the more intense gauntlet to make sure it fully resolves the issue, that would be appreciated.

I intend to write an ever further pared-down test case and add a unit test prior to getting it merged, but I thought I'd get the code out there first.

ksunden added a commit to ksunden/matplotlib that referenced this issue Nov 16, 2023
@kafitzgerald
Copy link
Author

Thanks!

I'd have gotten back sooner, but was struggling a bit with my dev env. For whatever reason my editable install of matplotlib wasn't working. Got a regular install to work though with the fix.

And it works great on the larger cases I had (both with specified label locations and manual clicks).

Thanks for getting this sorted so quickly!

@QuLogic QuLogic added this to the v3.8.2 milestone Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants