Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcce31fa

Browse files
committed
Don't let margins expand polar plots to negative radii by default.
This is implemented by altering the semantics of sticky edges asdocumented in the changelog. As it turns out, this change also improvesconsistency for streamplot():- in test_streamplot.py::test_{linewidth,mask_and_nans}, the change is necessary because the axes limits would now be (-3, 3) (matching the vector field limits), whereas they were previously xlim=(-3.0, 2.9999999999999947), ylim=(-3.0000000000000004, 2.9999999999999947) (they can be inspected with `plt.gcf().canvas.draw(); print(plt.gca().get_xlim(), plt.gca().get_ylim())`).- in test_streamplot.py::test_maxlength, note that the previous version expanded the axes limits *beyond* (-3, 3), whereas the current doesn't do so anymore. It doesn't actually make much sense if the vector field limits are applied if the streamplot goes all the way to the edges, but are ignored otherwise.
1 parent79ccf53 commitcce31fa

File tree

5 files changed

+66
-24
lines changed

5 files changed

+66
-24
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Change in the application of ``Artist.sticky_edges``
2+
````````````````````````````````````````````````````
3+
4+
Previously, the ``sticky_edges`` attribute of artists was a list of values such
5+
that if an axis limit coincides with a sticky edge, it would not be expanded by
6+
the axes margins (this is the mechanism that e.g. prevents margins from being
7+
added around images).
8+
9+
``sticky_edges`` now have an additional effect on margins application: even if
10+
an axis limit did not coincide with a sticky edge, it cannot *cross* a sticky
11+
edge through margin application -- instead, the margins will only expand the
12+
axis limit until it bumps against the sticky edge.
13+
14+
This change improves the margins of axes displaying a `~Axes.streamplot`:
15+
16+
- if the streamplot goes all the way to the edges of the vector field, then the
17+
axis limits are set to match exactly the vector field limits (whereas they
18+
would be sometimes be off by a small floating point error previously).
19+
- if the streamplot does not reach the edges of the vector field (e.g., due to
20+
the use of ``start_points`` and ``maxlength``), then margins expansion will
21+
not cross the the vector field limits anymore.
22+
23+
This change is also used internally to ensure that polar plots don't display
24+
negative *r* values unless the user really passes in a negative value.

‎lib/matplotlib/axes/_base.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,14 +2402,14 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True):
24022402
(self._xmarginandscalexandself._autoscaleXon)or
24032403
(self._ymarginandscaleyandself._autoscaleYon)):
24042404
stickies= [artist.sticky_edgesforartistinself.get_children()]
2405-
x_stickies=np.array([xforstickyinstickiesforxinsticky.x])
2406-
y_stickies=np.array([yforstickyinstickiesforyinsticky.y])
2407-
ifself.get_xscale().lower()=='log':
2408-
x_stickies=x_stickies[x_stickies>0]
2409-
ifself.get_yscale().lower()=='log':
2410-
y_stickies=y_stickies[y_stickies>0]
24112405
else:# Small optimization.
2412-
x_stickies,y_stickies= [], []
2406+
stickies= []
2407+
x_stickies=np.sort([xforstickyinstickiesforxinsticky.x])
2408+
y_stickies=np.sort([yforstickyinstickiesforyinsticky.y])
2409+
ifself.get_xscale().lower()=='log':
2410+
x_stickies=x_stickies[x_stickies>0]
2411+
ifself.get_yscale().lower()=='log':
2412+
y_stickies=y_stickies[y_stickies>0]
24132413

24142414
defhandle_single_axis(scale,autoscaleon,shared_axes,interval,
24152415
minpos,axis,margin,stickies,set_bound):
@@ -2450,29 +2450,35 @@ def handle_single_axis(scale, autoscaleon, shared_axes, interval,
24502450
locator=axis.get_major_locator()
24512451
x0,x1=locator.nonsingular(x0,x1)
24522452

2453+
# Prevent margin addition from crossing a sticky value. Small
2454+
# tolerances (whose values come from isclose()) must be used due to
2455+
# floating point issues with streamplot.
2456+
rtol=1e-5
2457+
atol=1e-8
2458+
# Index of largest element < x0 + tol, if any.
2459+
i0=stickies.searchsorted(x0+rtol*abs(x0)+atol)-1
2460+
x0bound=stickies[i0]ifi0!=-1elseNone
2461+
# Index of smallest element > x1 - tol, if any.
2462+
i1=stickies.searchsorted(x1-rtol*abs(x1)-atol)
2463+
x1bound=stickies[i1]ifi1!=len(stickies)elseNone
2464+
24532465
# Add the margin in figure space and then transform back, to handle
24542466
# non-linear scales.
24552467
minpos=getattr(bb,minpos)
24562468
transform=axis.get_transform()
24572469
inverse_trans=transform.inverted()
2458-
# We cannot use exact equality due to floating point issues e.g.
2459-
# with streamplot.
2460-
do_lower_margin=notnp.any(np.isclose(x0,stickies))
2461-
do_upper_margin=notnp.any(np.isclose(x1,stickies))
24622470
x0,x1=axis._scale.limit_range_for_scale(x0,x1,minpos)
24632471
x0t,x1t=transform.transform([x0,x1])
2464-
2465-
ifnp.isfinite(x1t)andnp.isfinite(x0t):
2466-
delta= (x1t-x0t)*margin
2467-
else:
2468-
# If at least one bound isn't finite, set margin to zero
2469-
delta=0
2470-
2471-
ifdo_lower_margin:
2472-
x0t-=delta
2473-
ifdo_upper_margin:
2474-
x1t+=delta
2475-
x0,x1=inverse_trans.transform([x0t,x1t])
2472+
delta= (x1t-x0t)*margin
2473+
ifnotnp.isfinite(delta):
2474+
delta=0# If a bound isn't finite, set margin to zero.
2475+
x0,x1=inverse_trans.transform([x0t-delta,x1t+delta])
2476+
2477+
# Apply sticky bounds.
2478+
ifx0boundisnotNone:
2479+
x0=max(x0,x0bound)
2480+
ifx1boundisnotNone:
2481+
x1=min(x1,x1bound)
24762482

24772483
ifnotself._tight:
24782484
x0,x1=locator.view_limits(x0,x1)

‎lib/matplotlib/tests/test_axes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,12 @@ def test_polar_rlim_bottom(fig_test, fig_ref):
797797
ax.set_rmin(.5)
798798

799799

800+
deftest_polar_rlim_zero():
801+
ax=plt.figure().add_subplot(projection='polar')
802+
ax.plot(np.arange(10),np.arange(10)+.01)
803+
assertax.get_ylim()[0]==0
804+
805+
800806
@image_comparison(baseline_images=['axvspan_epoch'])
801807
deftest_axvspan_epoch():
802808
fromdatetimeimportdatetime

‎lib/matplotlib/tests/test_streamplot.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ def test_linewidth():
5555
X,Y,U,V=velocity_field()
5656
speed=np.hypot(U,V)
5757
lw=5*speed/speed.max()
58-
df=25/30# Compatibility factor for old test image
58+
# Compatibility for old test image
59+
df=25/30
60+
plt.gca().set(xlim=(-3.0,2.9999999999999947),
61+
ylim=(-3.0000000000000004,2.9999999999999947))
5962
plt.streamplot(X,Y,U,V,density=[0.5*df,1.*df],color='k',
6063
linewidth=lw)
6164

@@ -69,6 +72,9 @@ def test_masks_and_nans():
6972
mask[40:60,40:60]=1
7073
U[:20, :20]=np.nan
7174
U=np.ma.array(U,mask=mask)
75+
# Compatibility for old test image
76+
plt.gca().set(xlim=(-3.0,2.9999999999999947),
77+
ylim=(-3.0000000000000004,2.9999999999999947))
7278
withnp.errstate(invalid='ignore'):
7379
plt.streamplot(X,Y,U,V,color=U,cmap=plt.cm.Blues)
7480

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp