Issue 1:
Bug report

Bug summary

When plotting a heatmap using pyplot.imshow(), then exporting the image to svg using savefig, the heatmap is exported as base64-encoded embedded png in the svg file. Although this behaviour is reasonable for an actual image being shown using imshow, it breaks up image scalability (which is often the point for vector graphics) when plotting a heatmap.

Code for reproduction

from matplotlib import pyplot as plt
import numpy as np
import random

BOUND = 100

data = np.zeros((BOUND, BOUND))

for _ in range(BOUND * 1000):
x = random.randint(0, BOUND - 1)
y = random.randint(0, BOUND - 1)
data[x, y] += 1

plt.imshow(data, extent=(0, 5, 0, 5), cmap="Blues", origin="lower")
plt.savefig("test.svg", format="svg", bbox_inches="tight")

Actual outcome

The SVG file contains embedded png; this can be checked with any text editor. Also note that opening this file, then zooming on the squares' boundaries on the heatmap results in a blur; while the axes are not blurred by zooming (being vector images).

Expected outcome

The heatmap part of the svg is actually an "array" or vector squares, without borders, of the desired colour; thus, it is possible to scale it to any extent without blurring.

Alternatives

Exporting the same heatmap to pdf instead of svg leads to a weird, seemingly vector graphic (zoomable without blur) result where each square of the heatmap has a grey border. Somehow, this is not the case with any PDF viewer; for instance, zathura seems to render the pdf image fine. However, such a pdf included in a LaTeX document compiled with xelatex with a regular \includegraphics yields those weird borders.

Matplotlib version

Operating system: ArchLinux Linux 5.11.13-arch1-1 #1 SMP PREEMPT Sat, 10 Apr 2021 20:47:14 +0000 x86_64 GNU/Linux

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

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

Python version: 3.9.3

Jupyter version (if applicable): N/A

Other libraries: N/A

Tested with matplotlib installed both from ArchLinux repositories and pip.

Issue 2:
Bug report

Bug summary

Currently, an image using the (default) setting of interpolation="none" will be written "as-it" by the SVG file; SVG renderers will then render them with interpolation (this is actually recommended by the SVG spec, see e.g. http://tavmjong.free.fr/SVG/IMAGE_RENDERING/index.html).

In order to disable interpolation by the renderer, it is necessary to use the image-rendering CSS property, see https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering (specifically, we want to use the "pixelated" value).

Support for this property is fairly incomplete; however it is at least available under a renderer-specific name for all of inkscape, chromium, firefox, and IE (https://caniuse.com/#search=image-rendering). (Inkscape supports "pixelated" since 0.92.2 (https://git.launchpad.net/inkscape/commit/?id=c3a191e4275ade05cf4bb4aab045ee22d050e703) but has supported "-inkscape-pixelated" for a while already.) It appears possible to just specify a bunch of different values to cover all cases, see e.g. comments in https://css-tricks.com/almanac/properties/i/image-rendering/

Code for reproduction

from pylab import *
plt.imshow([[1, 2], [3, 4]])
plt.savefig("/tmp/test.svg")

Actual outcome

Inkscape/Chromium/Firefox render the SVG as interpolated.

Expected outcome

No interpolation.

Matplotlib version

Operating system: linux

Matplotlib version: master

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

Python version: 3.6

Jupyter version (if applicable):

Other libraries: