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

Appearance settings

Commit 09321e4

Browse filesBrowse files
authored
Merge pull request #13593 from anntzer/lazy-autoscale
Only autoscale_view() when needed, not after every plotting call.
2 parents 79c296c + 160de56 commit 09321e4
Copy full SHA for 09321e4

File tree

Expand file treeCollapse file tree

9 files changed

+148
-72
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+148
-72
lines changed
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Autoscaling changes
2+
```````````````````
3+
4+
Matplotlib used to recompute autoscaled limits after every plotting
5+
(``plot()``, ``bar()``, etc.) call. It now only does so when actually
6+
rendering the canvas, or when the user queries the Axes limits. This is a
7+
major performance improvement for plots with a large number of artists.
8+
9+
In particular, this means that artists added manually with `Axes.add_line`,
10+
`Axes.add_patch`, etc. will be taken into account by the autoscale, even
11+
without an explicit call to `Axes.autoscale_view`.
12+
13+
In some cases, this can result in different limits being reported. If this is
14+
an issue, consider triggering a draw with `fig.canvas.draw`.
15+
16+
LogLocator.nonsingular now maintains the orders of its arguments
17+
````````````````````````````````````````````````````````````````
18+
19+
It no longer reorders them in increasing order. The new behavior is consistent
20+
with MaxNLocator.

‎lib/matplotlib/axes/_axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes/_axes.py
+26-28Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
863863
trans = self.get_yaxis_transform(which='grid')
864864
l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs)
865865
self.add_line(l)
866-
self.autoscale_view(scalex=False, scaley=scaley)
866+
self._request_autoscale_view(scalex=False, scaley=scaley)
867867
return l
868868

869869
@docstring.dedent_interpd
@@ -932,7 +932,7 @@ def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
932932
trans = self.get_xaxis_transform(which='grid')
933933
l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs)
934934
self.add_line(l)
935-
self.autoscale_view(scalex=scalex, scaley=False)
935+
self._request_autoscale_view(scalex=scalex, scaley=False)
936936
return l
937937

938938
@docstring.dedent_interpd
@@ -988,7 +988,7 @@ def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
988988
p = mpatches.Polygon(verts, **kwargs)
989989
p.set_transform(trans)
990990
self.add_patch(p)
991-
self.autoscale_view(scalex=False)
991+
self._request_autoscale_view(scalex=False)
992992
return p
993993

994994
def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
@@ -1053,7 +1053,7 @@ def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
10531053
p = mpatches.Polygon(verts, **kwargs)
10541054
p.set_transform(trans)
10551055
self.add_patch(p)
1056-
self.autoscale_view(scaley=False)
1056+
self._request_autoscale_view(scaley=False)
10571057
return p
10581058

10591059
@_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"],
@@ -1128,7 +1128,7 @@ def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
11281128
corners = (minx, miny), (maxx, maxy)
11291129

11301130
self.update_datalim(corners)
1131-
self.autoscale_view()
1131+
self._request_autoscale_view()
11321132

11331133
return lines
11341134

@@ -1205,7 +1205,7 @@ def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
12051205

12061206
corners = (minx, miny), (maxx, maxy)
12071207
self.update_datalim(corners)
1208-
self.autoscale_view()
1208+
self._request_autoscale_view()
12091209

12101210
return lines
12111211

@@ -1421,7 +1421,7 @@ def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
14211421
else: # "horizontal", None or "none" (see EventCollection)
14221422
corners = (minpos, minline), (maxpos, maxline)
14231423
self.update_datalim(corners)
1424-
self.autoscale_view()
1424+
self._request_autoscale_view()
14251425

14261426
return colls
14271427

@@ -1665,7 +1665,7 @@ def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs):
16651665
lines = [*self._get_lines(*args, data=data, **kwargs)]
16661666
for line in lines:
16671667
self.add_line(line)
1668-
self.autoscale_view(scalex=scalex, scaley=scaley)
1668+
self._request_autoscale_view(scalex=scalex, scaley=scaley)
16691669
return lines
16701670

16711671
@_preprocess_data(replace_names=["x", "y"], label_namer="y")
@@ -1741,7 +1741,7 @@ def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
17411741

17421742
ret = self.plot(x, y, fmt, **kwargs)
17431743

1744-
self.autoscale_view()
1744+
self._request_autoscale_view()
17451745

17461746
return ret
17471747

@@ -2453,7 +2453,7 @@ def bar(self, x, height, width=0.8, bottom=None, *, align="center",
24532453
ymin = ymin - np.max(yerr)
24542454
ymin = max(ymin * 0.9, 1e-100)
24552455
self.dataLim.intervaly = (ymin, ymax)
2456-
self.autoscale_view()
2456+
self._request_autoscale_view()
24572457

24582458
bar_container = BarContainer(patches, errorbar, label=label)
24592459
self.add_container(bar_container)
@@ -2649,7 +2649,7 @@ def broken_barh(self, xranges, yrange, **kwargs):
26492649

26502650
col = mcoll.BrokenBarHCollection(xranges_conv, yrange_conv, **kwargs)
26512651
self.add_collection(col, autolim=True)
2652-
self.autoscale_view()
2652+
self._request_autoscale_view()
26532653

26542654
return col
26552655

@@ -3462,7 +3462,7 @@ def extract_err(err, data):
34623462
for l in caplines:
34633463
self.add_line(l)
34643464

3465-
self.autoscale_view()
3465+
self._request_autoscale_view()
34663466
errorbar_container = ErrorbarContainer((data_line, tuple(caplines),
34673467
tuple(barcols)),
34683468
has_xerr=(xerr is not None),
@@ -4130,7 +4130,7 @@ def dopatch(xs, ys, **kwargs):
41304130
axis.set_major_formatter(formatter)
41314131
formatter.seq = [*formatter.seq, *datalabels]
41324132

4133-
self.autoscale_view(
4133+
self._request_autoscale_view(
41344134
scalex=self._autoscaleXon, scaley=self._autoscaleYon)
41354135

41364136
return dict(whiskers=whiskers, caps=caps, boxes=boxes,
@@ -4501,7 +4501,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
45014501
self.set_ymargin(0.05)
45024502

45034503
self.add_collection(collection)
4504-
self.autoscale_view()
4504+
self._request_autoscale_view()
45054505

45064506
return collection
45074507

@@ -4841,9 +4841,7 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
48414841

48424842
corners = ((xmin, ymin), (xmax, ymax))
48434843
self.update_datalim(corners)
4844-
collection.sticky_edges.x[:] = [xmin, xmax]
4845-
collection.sticky_edges.y[:] = [ymin, ymax]
4846-
self.autoscale_view(tight=True)
4844+
self._request_autoscale_view(tight=True)
48474845

48484846
# add the collection last
48494847
self.add_collection(collection, autolim=False)
@@ -5013,7 +5011,7 @@ def quiver(self, *args, **kw):
50135011
q = mquiver.Quiver(self, *args, **kw)
50145012

50155013
self.add_collection(q, autolim=True)
5016-
self.autoscale_view()
5014+
self._request_autoscale_view()
50175015
return q
50185016
quiver.__doc__ = mquiver.Quiver.quiver_doc
50195017

@@ -5029,7 +5027,7 @@ def barbs(self, *args, **kw):
50295027

50305028
b = mquiver.Barbs(self, *args, **kw)
50315029
self.add_collection(b, autolim=True)
5032-
self.autoscale_view()
5030+
self._request_autoscale_view()
50335031
return b
50345032

50355033
# Uses a custom implementation of data-kwarg handling in
@@ -5084,7 +5082,7 @@ def fill(self, *args, data=None, **kwargs):
50845082
for poly in self._get_patches_for_fill(*args, data=data, **kwargs):
50855083
self.add_patch(poly)
50865084
patches.append(poly)
5087-
self.autoscale_view()
5085+
self._request_autoscale_view()
50885086
return patches
50895087

50905088
@_preprocess_data(replace_names=["x", "y1", "y2", "where"])
@@ -5265,7 +5263,7 @@ def get_interp_point(ind):
52655263
self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits,
52665264
updatex=False, updatey=True)
52675265
self.add_collection(collection, autolim=False)
5268-
self.autoscale_view()
5266+
self._request_autoscale_view()
52695267
return collection
52705268

52715269
@_preprocess_data(replace_names=["y", "x1", "x2", "where"])
@@ -5445,7 +5443,7 @@ def get_interp_point(ind):
54455443
self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits,
54465444
updatex=True, updatey=False)
54475445
self.add_collection(collection, autolim=False)
5448-
self.autoscale_view()
5446+
self._request_autoscale_view()
54495447
return collection
54505448

54515449
#### plotting z(x,y): imshow, pcolor and relatives, contour
@@ -5944,7 +5942,7 @@ def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
59445942
collection.sticky_edges.y[:] = [miny, maxy]
59455943
corners = (minx, miny), (maxx, maxy)
59465944
self.update_datalim(corners)
5947-
self.autoscale_view()
5945+
self._request_autoscale_view()
59485946
return collection
59495947

59505948
@_preprocess_data()
@@ -6156,7 +6154,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
61566154
collection.sticky_edges.y[:] = [miny, maxy]
61576155
corners = (minx, miny), (maxx, maxy)
61586156
self.update_datalim(corners)
6159-
self.autoscale_view()
6157+
self._request_autoscale_view()
61606158
return collection
61616159

61626160
@_preprocess_data()
@@ -6342,22 +6340,22 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
63426340
ret.sticky_edges.x[:] = [xl, xr]
63436341
ret.sticky_edges.y[:] = [yb, yt]
63446342
self.update_datalim(np.array([[xl, yb], [xr, yt]]))
6345-
self.autoscale_view(tight=True)
6343+
self._request_autoscale_view(tight=True)
63466344
return ret
63476345

63486346
@_preprocess_data()
63496347
def contour(self, *args, **kwargs):
63506348
kwargs['filled'] = False
63516349
contours = mcontour.QuadContourSet(self, *args, **kwargs)
6352-
self.autoscale_view()
6350+
self._request_autoscale_view()
63536351
return contours
63546352
contour.__doc__ = mcontour.QuadContourSet._contour_doc
63556353

63566354
@_preprocess_data()
63576355
def contourf(self, *args, **kwargs):
63586356
kwargs['filled'] = True
63596357
contours = mcontour.QuadContourSet(self, *args, **kwargs)
6360-
self.autoscale_view()
6358+
self._request_autoscale_view()
63616359
return contours
63626360
contourf.__doc__ = mcontour.QuadContourSet._contour_doc
63636361

@@ -6872,7 +6870,7 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
68726870

68736871
self.set_autoscalex_on(_saved_autoscalex)
68746872
self.set_autoscaley_on(_saved_autoscaley)
6875-
self.autoscale_view()
6873+
self._request_autoscale_view()
68766874

68776875
if label is None:
68786876
labels = [None]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.