Plotting with Matplotlib

The default plotting extension for HoloViews until a 2.0 release is Matplotlib when HoloViews will start defaulting to Bokeh (see the Plotting with Bokeh user guide).

While the 'bokeh' backend provides many useful interactive features, the 'matplotlib' plotting extension is well suited to static exports for printed figures and because matplotlib is very full featured allows. To enable the 'matplotlib' backend, we can initialize the Holoviews notebook extension:

In [1]:
import numpy as np
import holoviews as hv
from holoviews import opts

hv.extension('matplotlib')

Working with matplotlib directly

When HoloViews outputs matplotlib plots it creates and manipulates a matplotlib Figure, axes and artists in the background. If at any time you need access to the underlying matplotlib representation of an object you can use the hv.render function to convert it. For example let us convert a HoloViews Image to a matplotlib Figure, which will let us access and modify every aspect of the plot:

In [2]:
img = hv.Image(np.random.rand(10, 10))

fig = hv.render(img)

print('Figure: ', fig)
print('Axes:   ', fig.axes)
Figure:  Figure(400x400)
Axes:    [<matplotlib.axes._subplots.AxesSubplot object at 0x11d478470>]

Static file format

Matplotlib supports a wide range of export formats suitable for both web and print publishing. During interactive exploration in the Notebook, your results are always visible within the notebook itself, and usually png plots are good enough. To switch the default file format you can use the hv.output utility and control set fig option, supported formats include:

['png', 'svg', 'pdf']

however pdf output is not supported in the notebook. To demonstrate let us switch output to SVG:

In [3]:
hv.output(fig='svg')

Now when we create a plot in the notebook the output will be rendered as SVGs:

In [4]:
from holoviews.operation import contours

x = y = np.arange(-3.0, 3.0, 0.1)
X, Y = np.meshgrid(x, y) 

def g(x,y,c):
    return 2*((x-y)**2/(x**2+y**2)) + np.exp(-(np.sqrt(x**2+y**2)-c)**2)

img = hv.Image(g(X,Y,2))
filled_contours = contours(img, filled=True)

filled_contours
Out[4]:

The hv.save function allows exporting plots to all supported formats simply by changing the file extension. Certain formats support additional options, e.g. for png export we can also specify the dpi (dots per inch):

In [5]:
hv.save(filled_contours, 'contours.png', dpi=144)

To confirm the plot was exported correctly we can load it back in using IPython's Image object:

In [6]:
from IPython.display import Image
Image('contours.png', width=400)
Out[6]:

For a publication, you will usually want to select SVG format by changing the file extension, because this vector format preserves the full resolution of all text and drawing elements. SVG files can be be used in some document preparation programs directly (e.g. LibreOffice ), and can easily be converted using e.g. Inkscape to PDF for use with PDFLaTeX or to EMF for use with Microsoft Word. They can also be edited using Inkscape or other vector drawing programs to move graphical elements around, add arbitrary text, etc., if you need to make final tweaks before using the figures in a document. You can also embed them within other SVG figures in such a drawing program, e.g. by creating a larger figure as a template that automatically incorporates multiple SVG files you have exported separately.

Animation support

The 'matplotlib' backend supports animated outputs either as video (using mp4 or webm formats) or as animated GIFS. This is useful for output to web pages that users can view without needing to interact with. It can also be useful for creating descriptive pages for HoloViews constructs that require a live Python/Jupyter server rather than just a web page - see for example DynamicMap .

GIF

In recent versions of matplotlib (>=2.2.0) GIF output can also be generated using pillow , which is what HoloViews uses by default. The pillow dependency can be installed using conda or pip using: conda install pillow or pip install pillow .

To display a plot The speed of the animation is controlled using the fps (frames per second):

In [7]:
holomap = hv.HoloMap([(t, hv.Image(g(X,Y, 4 * np.sin(np.pi*t)))) for t in np.linspace(0,1,21)]).opts(
    cmap='fire', colorbar=True, show_title=False, xaxis='bare', yaxis='bare')

contour_hmap = contours(holomap, filled=True)

hv.output(contour_hmap, holomap='gif', fps=5)
INFO:matplotlib.animation:Animation.save using <class 'matplotlib.animation.PillowWriter'>