-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
BUGFIX: This change fixes #2475, where contour labels added manually #2843
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
Changes from all commits
5834957
1e0b084
01da70d
23b5240
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -548,9 +548,11 @@ def add_label_clabeltext(self, x, y, rotation, lev, cvalue): | |
def add_label_near(self, x, y, inline=True, inline_spacing=5, | ||
transform=None): | ||
""" | ||
Add a label near the point (x, y) of the given transform. | ||
If transform is None, data transform is used. If transform is | ||
False, IdentityTransform is used. | ||
Add a label near the point (x, y). If transform is None | ||
(default), (x, y) is in data coordinates; if transform is | ||
False, (x, y) is in display coordinates; otherwise, the | ||
specified transform will be used to translate (x, y) into | ||
display coordinates. | ||
|
||
*inline*: | ||
controls whether the underlying contour is removed or | ||
|
@@ -569,19 +571,26 @@ def add_label_near(self, x, y, inline=True, inline_spacing=5, | |
if transform: | ||
x, y = transform.transform_point((x, y)) | ||
|
||
# find the nearest contour _in screen units_ | ||
conmin, segmin, imin, xmin, ymin = self.find_nearest_contour( | ||
x, y, self.labelIndiceList)[:5] | ||
|
||
# The calc_label_rot_and_inline routine requires that (xmin,ymin) | ||
# be a vertex in the path. So, if it isn't, add a vertex here | ||
|
||
# grab the paths from the collections | ||
paths = self.collections[conmin].get_paths() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what if the path object from the collection has a different transform than what we are expecting? Otherwise, this all makes sense, albeit it could use some more commenting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the assumption is that the points in the path are in data space as iirc everything returned by I think the issue you are bring up is if points in the path are not specified in data units so instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is exactly what my concern is. The transforms framework can have a lot of redundant parts, which can mask incorrect usage. We shouldn't assume that we know the transform of the path object, that is known only by the path object itself, so we should use it here. Admittedly, my brain does mini-explosions reading through some of these code parts because I easily lose track of the coder's intent and expectation. |
||
lc = paths[segmin].vertices | ||
if transform: | ||
xcmin = transform.inverted().transform([xmin, ymin]) | ||
else: | ||
xcmin = np.array([xmin, ymin]) | ||
# grab the correct segment | ||
active_path = paths[segmin] | ||
# grab it's verticies | ||
lc = active_path.vertices | ||
# sort out where the new vertex should be added data-units | ||
xcmin = self.ax.transData.inverted().transform_point([xmin, ymin]) | ||
# if there isn't a vertex close enough | ||
if not np.allclose(xcmin, lc[imin]): | ||
# insert new data into the vertex list | ||
lc = np.r_[lc[:imin], np.array(xcmin)[None, :], lc[imin:]] | ||
# replace the path with the new one | ||
paths[segmin] = mpath.Path(lc) | ||
|
||
# Get index of nearest level in subset of levels used for labeling | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import numpy as np | ||
|
||
from matplotlib import mlab | ||
from matplotlib.testing.decorators import cleanup, image_comparison | ||
from matplotlib import pyplot as plt | ||
|
||
|
@@ -183,6 +183,34 @@ def test_given_colors_levels_and_extends(): | |
plt.colorbar() | ||
|
||
|
||
@image_comparison(baseline_images=['contour_test_label_transforms'], | ||
extensions=['png'], remove_text=True) | ||
def test_labels(): | ||
# Adapted from pylab_examples example code: contour_demo.py | ||
# see issues #2475, #2843, and #2818 for explanation | ||
delta = 0.025 | ||
x = np.arange(-3.0, 3.0, delta) | ||
y = np.arange(-2.0, 2.0, delta) | ||
X, Y = np.meshgrid(x, y) | ||
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) | ||
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) | ||
# difference of Gaussians | ||
Z = 10.0 * (Z2 - Z1) | ||
|
||
fig, ax = plt.subplots(1, 1) | ||
CS = ax.contour(X, Y, Z) | ||
disp_units = [(216, 177), (359, 290), (521, 406)] | ||
data_units = [(-2, .5), (0, -1.5), (2.8, 1)] | ||
|
||
CS.clabel() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it be better to leave out this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember there was some reason that I I had this call first, but I don't remember what it was. The test shows the sum of the labels plus the ones added manually. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would also note that the location of the added labels does not overlap with where the default labels are placed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but from simply looking at the plot, or the code, I can't easily see which are which. Since you have verified that everything is in its place, this doesn't matter much; the test will still do its job. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will try to get to this today There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is that the call to |
||
|
||
for x, y in data_units: | ||
CS.add_label_near(x, y, inline=True, transform=None) | ||
|
||
for x, y in disp_units: | ||
CS.add_label_near(x, y, inline=True, transform=False) | ||
|
||
|
||
if __name__ == '__main__': | ||
import nose | ||
nose.runmodule(argv=['-s', '--with-doctest'], exit=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...but this one is good.