diff --git a/.flake8 b/.flake8 index aea286bb027c..b9fa0bf04293 100644 --- a/.flake8 +++ b/.flake8 @@ -81,7 +81,7 @@ per-file-ignores = tutorials/introductory/images.py: E402, E501 tutorials/introductory/pyplot.py: E402, E501 tutorials/introductory/sample_plots.py: E501 - tutorials/introductory/usage.py: E402, E501 + tutorials/introductory/usage.py: E501 tutorials/text/annotations.py: E501 tutorials/text/pgf.py: E501 tutorials/text/text_intro.py: E402 diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 8b737e564f77..386d981cdb9c 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -6778,8 +6778,8 @@ def hist(self, x, bins=None, range=None, density=None, weights=None, return tops, bins, cbook.silent_list('Lists of Patches', patches) @_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None) - def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, - cmin=None, cmax=None, **kwargs): + def hist2d(self, x, y, bins=10, range=None, density=None, weights=None, + cmin=None, cmax=None, normed=None, **kwargs): """ Make a 2D histogram plot. @@ -6812,8 +6812,15 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, xmax], [ymin, ymax]]``. All values outside of this range will be considered outliers and not tallied in the histogram. - normed : bool, optional, default: False - Normalize histogram. + density : boolean, optional + If False, the default, returns the number of samples in each bin. + If True, returns the probability *density* function at the bin, + ``bin_count / sample_count / bin_area``. + + Default is ``None`` for both *normed* and *density*. If either is + set, then that value will be used. If neither are set, then the + args will be treated as ``False``. + If both *density* and *normed* are set an error is raised. weights : array_like, shape (n, ), optional, default: None An array of values w_i weighing each sample (x_i, y_i). @@ -6828,6 +6835,9 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, to none before passing to imshow) and these count values in the return value count histogram will also be set to nan upon return + normed : bool, optional, default: None + Deprecated; use the density keyword argument instead. + Returns ------- h : 2D array @@ -6870,7 +6880,15 @@ def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, in effect to gamma correction) can be accomplished with `.colors.PowerNorm`. """ + if density is not None and normed is not None: + raise ValueError("kwargs 'density' and 'normed' cannot be used " + "simultaneously. Please only use 'density', " + "since 'normed' is deprecated.") + if normed is not None: + cbook.warn_deprecated("2.1", name="'normed'", obj_type="kwarg", + alternative="'density'", removal="3.1") + normed = bool(density) or bool(normed) h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range, normed=normed, weights=weights) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 4a3081ed7ec0..fdcfe4441640 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2403,14 +2403,16 @@ def autoscale_view(self, tight=None, scalex=True, scaley=True): if tight is not None: self._tight = bool(tight) - if self.use_sticky_edges and (self._xmargin or self._ymargin): + if self.use_sticky_edges and ( + (self._xmargin and scalex and self._autoscaleXon) or + (self._ymargin and scaley and self._autoscaleYon)): stickies = [artist.sticky_edges for artist in self.get_children()] - x_stickies = sum([sticky.x for sticky in stickies], []) - y_stickies = sum([sticky.y for sticky in stickies], []) + x_stickies = np.array([x for sticky in stickies for x in sticky.x]) + y_stickies = np.array([y for sticky in stickies for y in sticky.y]) if self.get_xscale().lower() == 'log': - x_stickies = [xs for xs in x_stickies if xs > 0] + x_stickies = x_stickies[x_stickies > 0] if self.get_yscale().lower() == 'log': - y_stickies = [ys for ys in y_stickies if ys > 0] + y_stickies = y_stickies[y_stickies > 0] else: # Small optimization. x_stickies, y_stickies = [], [] diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 8dc6b7c5e624..8504cfbd5c33 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -240,7 +240,8 @@ def tick_values(self, vmin, vmax): vmin = max(vmin, self._colorbar.norm.vmin) vmax = min(vmax, self._colorbar.norm.vmax) ticks = super().tick_values(vmin, vmax) - return ticks[(ticks >= vmin) & (ticks <= vmax)] + rtol = (vmax - vmin) * 1e-10 + return ticks[(ticks >= vmin - rtol) & (ticks <= vmax + rtol)] class _ColorbarAutoMinorLocator(ticker.AutoMinorLocator): @@ -296,7 +297,10 @@ def tick_values(self, vmin, vmax): vmin = self._colorbar.norm.vmin vmax = self._colorbar.norm.vmax ticks = super().tick_values(vmin, vmax) - return ticks[(ticks >= vmin) & (ticks <= vmax)] + rtol = (np.log10(vmax) - np.log10(vmin)) * 1e-10 + ticks = ticks[(np.log10(ticks) >= np.log10(vmin) - rtol) & + (np.log10(ticks) <= np.log10(vmax) + rtol)] + return ticks class ColorbarBase(cm.ScalarMappable): @@ -405,7 +409,6 @@ def __init__(self, ax, cmap=None, else: self.formatter = format # Assume it is a Formatter # The rest is in a method so we can recalculate when clim changes. - self.config_axis() self.draw_all() def _extend_lower(self): @@ -439,6 +442,7 @@ def draw_all(self): # units: X, Y = self._mesh() C = self._values[:, np.newaxis] + self.config_axis() self._config_axes(X, Y) if self.filled: self._add_solids(X, Y, C) @@ -593,6 +597,7 @@ def _config_axes(self, X, Y): ax.set_frame_on(False) ax.set_navigate(False) xy = self._outline(X, Y) + ax.ignore_existing_data_limits = True ax.update_datalim(xy) ax.set_xlim(*ax.dataLim.intervalx) ax.set_ylim(*ax.dataLim.intervaly) @@ -1150,7 +1155,6 @@ def update_bruteforce(self, mappable): self.set_alpha(mappable.get_alpha()) self.cmap = mappable.cmap self.norm = mappable.norm - self.config_axis() self.draw_all() if isinstance(self.mappable, contour.ContourSet): CS = self.mappable diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index f5f62466075c..277c2da9874c 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -685,11 +685,11 @@ def suptitle(self, t, **kwargs): The y location of the text in figure coordinates. horizontalalignment, ha : {'center', 'left', right'}, default: 'center' - The horizontal alignment of the text. + The horizontal alignment of the text relative to (*x*, *y*). verticalalignment, va : {'top', 'center', 'bottom', 'baseline'}, \ default: 'top' - The vertical alignment of the text. + The vertical alignment of the text relative to (*x*, *y*). fontsize, size : default: :rc:`figure.titlesize` The font size of the text. See `.Text.set_size` for possible diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 6ceced49285c..af2c80d1bc3f 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -2379,8 +2379,8 @@ def angle_spectrum( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.annotate) -def annotate(s, xy, *args, **kwargs): - return gca().annotate(s, xy, *args, **kwargs) +def annotate(*args, **kwargs): + return gca().annotate(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2427,12 +2427,10 @@ def axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.bar) -def bar( - x, height, width=0.8, bottom=None, *, align='center', - data=None, **kwargs): +def bar(*args, data=None, **kwargs): return gca().bar( - x, height, width=width, bottom=bottom, align=align, - **({"data": data} if data is not None else {}), **kwargs) + *args, **({"data": data} if data is not None else {}), + **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2444,9 +2442,8 @@ def barbs(*args, data=None, **kw): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.barh) -def barh(y, width, height=0.8, left=None, *, align='center', **kwargs): - return gca().barh( - y, width, height=height, left=left, align=align, **kwargs) +def barh(*args, **kwargs): + return gca().barh(*args, **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2710,8 +2707,8 @@ def magnitude_spectrum( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.margins) -def margins(*margins, x=None, y=None, tight=True): - return gca().margins(*margins, x=x, y=y, tight=tight) +def margins(*args, **kw): + return gca().margins(*args, **kw) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2728,12 +2725,9 @@ def minorticks_on(): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @_autogen_docstring(Axes.pcolor) -def pcolor( - *args, alpha=None, norm=None, cmap=None, vmin=None, - vmax=None, data=None, **kwargs): +def pcolor(*args, data=None, **kwargs): __ret = gca().pcolor( - *args, alpha=alpha, norm=norm, cmap=cmap, vmin=vmin, - vmax=vmax, **({"data": data} if data is not None else {}), + *args, **({"data": data} if data is not None else {}), **kwargs) sci(__ret) return __ret @@ -2741,14 +2735,10 @@ def pcolor( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @_autogen_docstring(Axes.pcolormesh) -def pcolormesh( - *args, alpha=None, norm=None, cmap=None, vmin=None, - vmax=None, shading='flat', antialiased=False, data=None, - **kwargs): +def pcolormesh(*args, data=None, **kwargs): __ret = gca().pcolormesh( - *args, alpha=alpha, norm=norm, cmap=cmap, vmin=vmin, - vmax=vmax, shading=shading, antialiased=antialiased, - **({"data": data} if data is not None else {}), **kwargs) + *args, **({"data": data} if data is not None else {}), + **kwargs) sci(__ret) return __ret @@ -2783,10 +2773,10 @@ def pie( # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.plot) -def plot(*args, scalex=True, scaley=True, data=None, **kwargs): +def plot(*args, data=None, **kwargs): return gca().plot( - *args, scalex=scalex, scaley=scaley, **({"data": data} if data - is not None else {}), **kwargs) + *args, **({"data": data} if data is not None else {}), + **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2823,8 +2813,8 @@ def quiver(*args, data=None, **kw): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.quiverkey) -def quiverkey(Q, X, Y, U, label, **kw): - return gca().quiverkey(Q, X, Y, U, label, **kw) +def quiverkey(*args, **kw): + return gca().quiverkey(*args, **kw) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2893,21 +2883,18 @@ def stackplot(x, *args, data=None, **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.stem) -def stem( - *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, - label=None, data=None): +def stem(*args, data=None, **kwargs): return gca().stem( - *args, linefmt=linefmt, markerfmt=markerfmt, basefmt=basefmt, - bottom=bottom, label=label, **({"data": data} if data is not - None else {})) + *args, **({"data": data} if data is not None else {}), + **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.step) -def step(x, y, *args, where='pre', data=None, **kwargs): +def step(x, y, *args, data=None, **kwargs): return gca().step( - x, y, *args, where=where, **({"data": data} if data is not - None else {}), **kwargs) + x, y, *args, **({"data": data} if data is not None else {}), + **kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @@ -2949,13 +2936,8 @@ def tick_params(axis='both', **kwargs): # Autogenerated by boilerplate.py. Do not edit as changes will be lost. @docstring.copy_dedent(Axes.ticklabel_format) -def ticklabel_format( - *, axis='both', style='', scilimits=None, useOffset=None, - useLocale=None, useMathText=None): - return gca().ticklabel_format( - axis=axis, style=style, scilimits=scilimits, - useOffset=useOffset, useLocale=useLocale, - useMathText=useMathText) +def ticklabel_format(**kwargs): + return gca().ticklabel_format(**kwargs) # Autogenerated by boilerplate.py. Do not edit as changes will be lost. diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index fd2a7d52c7b6..6137da4afdba 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -7,6 +7,7 @@ from matplotlib.colors import BoundaryNorm, LogNorm, PowerNorm from matplotlib.cm import get_cmap from matplotlib.colorbar import ColorbarBase +from matplotlib.ticker import LogLocator, LogFormatter def _get_cmap_norms(): @@ -411,3 +412,27 @@ def test_colorbar_log_minortick_labels(): r'$\mathdefault{4\times10^{4}}$'] for l, exp in zip(lb, expected): assert l.get_text() == exp + + +def test_colorbar_renorm(): + x, y = np.ogrid[-4:4:31j, -4:4:31j] + z = 120000*np.exp(-x**2 - y**2) + + fig, ax = plt.subplots() + im = ax.imshow(z) + cbar = fig.colorbar(im) + + norm = LogNorm(z.min(), z.max()) + im.set_norm(norm) + cbar.set_norm(norm) + cbar.locator = LogLocator() + cbar.formatter = LogFormatter() + cbar.update_normal(im) + assert np.isclose(cbar.vmin, z.min()) + + norm = LogNorm(z.min() * 1000, z.max() * 1000) + im.set_norm(norm) + cbar.set_norm(norm) + cbar.update_normal(im) + assert np.isclose(cbar.vmin, z.min() * 1000) + assert np.isclose(cbar.vmax, z.max() * 1000) diff --git a/tutorials/introductory/usage.py b/tutorials/introductory/usage.py index 3c2835295323..5777a9be6197 100644 --- a/tutorials/introductory/usage.py +++ b/tutorials/introductory/usage.py @@ -603,18 +603,18 @@ def my_plotter(ax, data1, data2, param_dict): # Prior to version 1.0, show() generally could not be called # more than once in a single script (although sometimes one # could get away with it); for version 1.0.1 and above, this -# restriction is lifted, so one can write a script like this: - -import numpy as np -import matplotlib.pyplot as plt - -plt.ioff() -for i in range(3): - plt.plot(np.random.rand(10)) - plt.show() - -############################################################################### -# which makes three plots, one at a time. +# restriction is lifted, so one can write a script like this:: +# +# import numpy as np +# import matplotlib.pyplot as plt +# +# plt.ioff() +# for i in range(3): +# plt.plot(np.random.rand(10)) +# plt.show() +# +# which makes three plots, one at a time. I.e. the second plot will show up, +# once the first plot is closed. # # Summary # -------