diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 # Matplotlib for Haskell
 
-[![Build Status](https://img.shields.io/circleci/project/github/abarbu/matplotlib-haskell.svg)](https://circleci.com/gh/abarbu/matplotlib-haskell)
+[![Build Status](https://github.com/abarbu/matplotlib-haskell/actions/workflows/CI.yaml/badge.svg)](https://github.com/abarbu/matplotlib-haskell/actions/workflows/CI.yaml)
 [![Hackage](https://img.shields.io/hackage/v/matplotlib.svg)](https://hackage.haskell.org/package/matplotlib)
 
 Haskell bindings to Python's Matplotlib. It's high time that Haskell had a
diff --git a/matplotlib.cabal b/matplotlib.cabal
--- a/matplotlib.cabal
+++ b/matplotlib.cabal
@@ -1,5 +1,5 @@
 name:                matplotlib
-version:             0.7.5
+version:             0.7.6
 synopsis:            Bindings to Matplotlib; a Python plotting library
 description:
     Matplotlib is probably the most full featured plotting library out there.
diff --git a/src/Graphics/Matplotlib.hs b/src/Graphics/Matplotlib.hs
--- a/src/Graphics/Matplotlib.hs
+++ b/src/Graphics/Matplotlib.hs
@@ -46,7 +46,7 @@
 --  the appropriate datatype. Strings become python strings, bools become bools,
 --  etc. If you want to insert code verbatim into an option use 'lit'. If you
 --  want to have a raw string with no escapes use 'raw'.
---  [@'o2'@] A keyword option. The key is awlays a string, the value is treated
+--  [@'o2'@] A keyword option. The key is always a string, the value is treated
 --  the same way that the option in 'o1' is treated.
 --
 -- Right now there's no easy way to bind to an option other than the last one
@@ -86,6 +86,10 @@
 file :: [Char] -> Matplotlib -> IO (Either String String)
 file filename m = withMplot m (\s -> python $ pyIncludes (pyBackend "agg") ++ s ++ pyFigure filename)
 
+-- | Get the SVG for a figure
+toSvg :: Matplotlib -> IO (Either String String)
+toSvg m = withMplot m (\s -> python $ pyIncludes "" ++ s ++ pySVG)
+
 -- * Useful plots
 
 -- | Plot the cross-correlation and autocorrelation of several variables. TODO Due to
@@ -414,7 +418,7 @@
 
 -- | Enable 3D projection
 axis3DProjection :: Matplotlib
-axis3DProjection = mp # "ax = plot.gca(projection='3d')"
+axis3DProjection = mp # "ax = plot.gca() if plot.gca().name == '3d' else plot.subplot(projection='3d')"
 
 -- | Label and set limits of a set of 3D axis
 -- TODO This is a mess, does both more and less than it claims.
diff --git a/src/Graphics/Matplotlib/Internal.hs b/src/Graphics/Matplotlib/Internal.hs
--- a/src/Graphics/Matplotlib/Internal.hs
+++ b/src/Graphics/Matplotlib/Internal.hs
@@ -344,10 +344,17 @@
                      ,"import numpy as np"
                      ,"from scipy import interpolate"
                      ,"import os"
+                     ,"import io"
                      ,"import sys"
                      ,"import json"
                      ,"import random, datetime"
                      ,"from matplotlib.dates import DateFormatter, WeekdayLocator"
+                     -- We set this rcParams due to:
+                     --     bivariateNormal:    /run/user/1000/code12548-89.py:30: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3.  Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading'].  This will become an error two minor releases later.
+                     --   plot.sci(ax.pcolor(np.array(data[0]),np.array(data[1]),np.array(data[2]),cmap=r'PuBu_r'))
+                     -- /run/user/1000/code12548-89.py:36: MatplotlibDeprecationWarning: shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3.  Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto', 'nearest' or 'gouraud', or set rcParams['pcolor.shading'].  This will become an error two minor releases later.
+                     --   plot.sci(ax.pcolor(np.array(data[0]),np.array(data[1]),np.array(data[2]),norm=mcolors.LogNorm(vmin=1.964128034639681e-6, vmax=7.963602137747198),cmap=r'PuBu_r'))
+                     ,"plot.rcParams['pcolor.shading'] ='auto'"
                      ,"fig = plot.gcf()"
                      ,"axes = [plot.gca()]"
                      ,"ax = axes[0]"]
@@ -379,6 +386,13 @@
 -- | Python code that saves a figure
 pyFigure :: [Char] -> [[Char]]
 pyFigure output = ["plot.savefig('" ++ escapeSlashes output ++ "')"]
+
+-- | Python code that returns SVG for a figure
+pySVG :: [[Char]]
+pySVG =
+  ["i = io.StringIO()"
+  ,"plot.savefig(i, format='svg')"
+  ,"print(i.getvalue())"]
 
 -- | Create a positional option
 o1 x = P $ toPythonOpt x
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -610,9 +610,9 @@
 mgriddata = readData (x, y, z, xi, yi)
   -- TODO This requires a lot of manual indexing. Next big API change will be to
   -- have references to loaded data.
-  % mp # "data.append(interpolate.griddata((data[0], data[1]), data[2], tuple(np.meshgrid(data[3], data[4])), method='cubic', rescale=True))"
-  % mp # "plot.sci(ax.contour(data[3], data[4], data[5], 15, linewidths=0.5, colors='k'))"
-  % mp # "plot.sci(ax.contourf(data[3], data[4], data[5], 15, vmax=abs(data[5]).max(), vmin=-abs(data[5]).max()))"
+  % mp # "data.append(interpolate.griddata((data[0], data[1]), data[2], tuple(np.meshgrid(data[3], data[4])), method='linear', rescale=True))"
+  % mp # "plot.contour(data[3], data[4], data[5], 15, linewidths=0.5, colors='k')"
+  % mp # "plot.contourf(data[3], data[4], data[5], 15, extend='both')"
   % colorbar
   % scatter x y @@ [o2 "marker" "o", o2 "s" 5, o2 "zorder" 10]
   % xlim (-2) 2
