Issue 1:
Bug report

Bug summary

When plotting something with imshow using LogNorm with more than 17 orders of magnitude, it reports ValueError: minvalue must be positive when it should be -I believe- a precision related error. In the example below it works for 9.9e-16 but not for 1e-17.

Thus, when having data over this kind of range and not specifying limits, it crashes giving the wrong error message.

Code for reproduction

from matplotlib.colors import LogNorm
import matplotlib.pyplot as plt
import numpy as np

a = np.linspace(1,100)
c,_,_ = np.histogram2d(np.log10(a),np.log10(a))
im = plt.imshow(c,norm=LogNorm(vmin=1e-17, vmax=1))

Actual outcome

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~/anaconda3/lib/python3.8/site-packages/IPython/core/formatters.py in __call__(self, obj)
339 pass
340 else:
--> 341 return printer(obj)
342 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)

~/anaconda3/lib/python3.8/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
252 jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', **kwargs))
253 if 'svg' in formats:
--> 254 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg', **kwargs))
255 if 'pdf' in formats:
256 pdf_formatter.for_type(Figure, lambda fig: print_figure(fig, 'pdf', **kwargs))

~/anaconda3/lib/python3.8/site-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
130 FigureCanvasBase(fig)
131
--> 132 fig.canvas.print_figure(bytes_io, **kw)
133 data = bytes_io.getvalue()
134 if fmt == 'svg':

~/anaconda3/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2191 else suppress())
2192 with ctx:
-> 2193 self.figure.draw(renderer)
2194
2195 bbox_inches = self.figure.get_tightbbox(

~/anaconda3/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:

~/anaconda3/lib/python3.8/site-packages/matplotlib/figure.py in draw(self, renderer)
1861
1862 self.patch.draw(renderer)
-> 1863 mimage._draw_list_compositing_images(
1864 renderer, self, artists, self.suppressComposite)
1865

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
129 if not_composite or not has_images:
130 for a in artists:
--> 131 a.draw(renderer)
132 else:
133 # Composite any adjacent images together

~/anaconda3/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:

~/anaconda3/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py in wrapper(*inner_args, **inner_kwargs)
409 else deprecation_addendum,
410 **kwargs)
--> 411 return func(*inner_args, **inner_kwargs)
412
413 return wrapper

~/anaconda3/lib/python3.8/site-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
2745 renderer.stop_rasterizing()
2746
-> 2747 mimage._draw_list_compositing_images(renderer, self, artists)
2748
2749 renderer.close_group('axes')

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
153 image_group.append(a)
154 else:
--> 155 flush_images()
156 a.draw(renderer)
157 flush_images()

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in flush_images()
137 def flush_images():
138 if len(image_group) == 1:
--> 139 image_group[0].draw(renderer)
140 elif len(image_group) > 1:
141 data, l, b = composite_images(image_group, renderer, mag)

~/anaconda3/lib/python3.8/site-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
39 renderer.start_filter()
40
---> 41 return draw(artist, renderer, *args, **kwargs)
42 finally:
43 if artist.get_agg_filter() is not None:

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in draw(self, renderer, *args, **kwargs)
639 renderer.draw_image(gc, l, b, im, trans)
640 else:
--> 641 im, l, b, trans = self.make_image(
642 renderer, renderer.get_image_magnification())
643 if im is not None:

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in make_image(self, renderer, magnification, unsampled)
924 clip = ((self.get_clip_box() or self.axes.bbox) if self.get_clip_on()
925 else self.figure.bbox)
--> 926 return self._make_image(self._A, bbox, transformed_bbox, clip,
927 magnification, unsampled=unsampled)
928

~/anaconda3/lib/python3.8/site-packages/matplotlib/image.py in _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification, unsampled, round_to_pixel_border)
543 vmax=s_vmax,
544 ):
--> 545 output = self.norm(resampled_masked)
546 else:
547 if A.shape[2] == 3:

~/anaconda3/lib/python3.8/site-packages/matplotlib/colors.py in __call__(self, value, clip)
1190
1191 self.autoscale_None(result)
-> 1192 self._check_vmin_vmax()
1193 vmin, vmax = self.vmin, self.vmax
1194 if vmin == vmax:

~/anaconda3/lib/python3.8/site-packages/matplotlib/colors.py in _check_vmin_vmax(self)
1179 raise ValueError("minvalue must be less than or equal to maxvalue")
1180 elif self.vmin <= 0:
-> 1181 raise ValueError("minvalue must be positive")
1182
1183 def __call__(self, value, clip=None):

ValueError: minvalue must be positive

Expected outcome

A plot or a correct error message.

Operating system: Ubuntu 20.04

Matplotlib version: 3.3.2

Matplotlib backend: module://ipykernel.pylab.backend_inline

Python version: 3.8.5

Other libraries: numpy 1.19.2

Issue 2:
Bug report

Bug summary

.imshow() with LogNorm produces incorrect and inconsistent coloring.

Code for reproduction

In this example the same array was plotted twice. The first .imshow() call plots the whole array. The following two plot two halves of the same array separately.

The mpl_toolkits is used only to fix axes and colorbar positioning; problems with coloring remain even without it.

import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

import numpy as np

a = 10. ** np.arange(100)

fig, ax = plt.subplots(1)
norm = mpl.colors.LogNorm(np.min(a), np.max(a))

img1 = ax.imshow(a[None, : ], extent = (0, 100, 0, 10),
cmap = 'gray', norm = norm )
img2 = ax.imshow(a[None, :50], extent = (0, 50, -10, 0),
cmap = 'gray', norm = norm )
img3 = ax.imshow(a[None, 50: ], extent = (50, 100, -10, 0),
cmap = 'gray', norm = norm )

plt.xlim( 0, 100)
plt.ylim(-10, 10)

divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("bottom",
size=0.2,
pad=0.4 )
plt.colorbar(img1, cax = cax, orientation='horizontal')

plt.tight_layout()

plt.show()

Actual outcome

As we can see, left parts of each patch produced by .imshow() is completely black. It seems like rounding occurred somewhere. It also can be seen, that different colors are used to represent the same numbers in different arrays.

Expected outcome

It was expected to see smooth transition from black to white from left to right. It was also expected not to see any difference in colors representing same numbers.

Matplotlib version

Operating system: Linux

Matplotlib version (import matplotlib; print(matplotlib.__version__)): 3.3.3

Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg

Python version: 3.7.3

The matplotlib package was installed with pip.