# Options ¶

HoloViews is designed to be both highly customizable, allowing you to control how your visualizations appear, but also to enforce a strong separation between your data (with any semantically associated metadata, like type, dimension names, and description) and all options related purely to visualization. This separation allows HoloViews objects to be generated easily by external programs, without giving them a dependency on any plotting or windowing libraries. It also helps make it completely clear which parts of your code deal with the actual data, and which are just about displaying it nicely, which becomes very important for complex visualizations that become more complicated than your data itself.

To achieve this separation, HoloViews stores visualization options independently from your data, and applies the options only when rendering the data to a file on disk, a GUI window, or an IPython notebook cell.

This tutorial gives an overview of the different types of options available, how to find out more about them, and how to set them in both regular Python and using the IPython magic interface that is shown elsewhere in the tutorials.

## Example objects ¶

First, we'll create some HoloViews data objects ready to visualize:

In [1]:
import numpy as np
import holoviews as hv
hv.notebook_extension()

x,y = np.mgrid[-50:51, -50:51] * 0.1
image = hv.Image(np.sin(x**2+y**2), group="Function", label="Sine")

coords = [(0.1*i, np.sin(0.1*i)) for i in range(100)]
curve = hv.Curve(coords)

curves = {phase: hv.Curve([(0.1*i, np.sin(phase+0.1*i)) for i in range(100)])
for phase in [0, np.pi/2, np.pi, np.pi*3/2]}

waves = hv.HoloMap(curves)

layout = image + curve


## Rendering and saving objects from Python ¶

To illustrate how to do plotting independently of IPython, we'll generate and save a plot directly to disk. First, let's create a  renderer  object that will render our files to SVG (for static figures) or GIF (for animations):

In [2]:
renderer = hv.Store.renderers['matplotlib'].instance(fig='svg', holomap='gif')


We could instead have used the default  Store.renderer  , but that would have been PNG format. Using this renderer, we can save any HoloViews object as SVG or GIF:

In [3]:
renderer.save(layout, 'example_I')


That's it! The renderer builds the figure in matplotlib, renders it to SVG, and saves that to "example_I.svg" on disk. Everything up to this point would have worked the same in IPython or in regular Python, even with no display available. But since we're in IPython Notebook at the moment, we can check whether the exporting worked, by loading the file back into the notebook:

In [4]:
from IPython.display import SVG
SVG(filename='example_I.svg')

Out[4]:

You can use this workflow for generating HoloViews visualizations directly from Python, perhaps as a part of a set of scripts that you run automatically, e.g. to put your results up on a web server as soon as data is generated. But so far, this plot just uses all the default options, with no customization. How can we change how the plot will appear when we render it?

## HoloViews visualization options ¶

HoloViews provides three categories of visualization options that can be set by the user. In this section we will first describe the different kinds of options, then later sections show you how to list the supported options of each type for a given HoloViews object or class, and how to change them in Python or IPython.

####  style  options: ¶

 style  options are passed directly to the underlying rendering backend that actually draws the plots, allowing you to control the details of how it behaves. The default backend is matplotlib, but there are other backends either using matplotlib's options (e.g.  mpld3  ), or their own sets of options (e.g.  bokeh  ).

For whichever backend has been selected, HoloViews can tell you which options are supported, but you will need to see the plotting library's own documentation (e.g. matplotlib , bokeh ) for the details of their use.

HoloViews has been designed to be easily extensible to additional backends in the future, such as Plotly , Cairo, VTK, or D3.js, and if one of those backends were selected then the supported style options would differ.

####  plot  options: ¶

Each of the various HoloViews plotting classes declares various Parameters that control how HoloViews builds the visualization for that type of object, such as plot sizes and labels. HoloViews uses these options internally; they are not simply passed to the underlying backend. HoloViews documents these options fully in its online help and in the Reference Manual . These options may vary for different backends in some cases, depending on the support available both in that library and in the HoloViews interface to it, but we try to keep any options that are meaningful for a variety of backends the same for all of them.

####  norm  options: ¶

 norm  options are a special type of plot option that are applied orthogonally to the above two types, to control normalization. Normalization refers to adjusting the properties of one plot relative to those of another. For instance, two images normalized together would appear with relative brightness levels, with the brightest image using the full range black to white, while the other image is scaled proportionally. Two images normalized independently would both cover the full range from black to white. Similarly, two axis ranges normalized together will expand to fit the largest range of either axis, while those normalized separately would cover different ranges.

There are currently only two  norm  options supported,  axiswise  and  framewise  , but they can be applied to any of the various object types in HoloViews to specify a huge range of different normalization options.

For a given category or group of HoloViews objects, if  axiswise  is True, normalization will be computed independently for all items in that category that have their own axes, such as different  Image  plots or  Curve  plots. If  axiswise  is False, all such objects are normalized together.

For a given category or group of HoloViews objects, if  framewise  is True, normalization of any  HoloMap  objects included is done independently per frame rendered -- each frame will appear as it would if it were extracted from the  HoloMap  and plotted separately. If  framewise  is False (the default), all frames in a given  HoloMap  are normalized together, so that you can see strength differences over the course of the animation.

As described below, these options can be controlled precisely and in any combination to make sure that HoloViews displays the data of most interest, ignoring irrelevant differences and highlighting important ones.

## Finding out which options are available for an object ¶

For the  norm  options, no further online documentation is provided, because all of the various visualization classes support only the two options described above. But there are a variety of ways to get the list of supported  style  options and detailed documentation for the  plot  options for a given component.

First, for any Python class or object in HoloViews, you can use  holoviews.help(  object-or-class  , visualization=False)  to find out about its parameters. For instance, these parameters are available for our  Image  object, shown with their current value (or default value, for a class), data type, whether it can be changed by the user (if it is constant, read-only, etc.), and bounds if any:

In [5]:
hv.help(image, visualization=False)

To view the visualization options applicable to this object or class, use:

holoviews.help(obj, visualization=True)

Parameters of 'Image' instance
==============================

Parameters changed from their default values are marked in red.
Soft bound values are marked in cyan.

Name                        Value                         Type        Bounds   Mode

cdims                   OrderedDict()                     Dict                 V RW
datatype   ['image', 'grid', 'xarray', 'cube', '...       List      (0, None)  V RW
extents            (None, None, None, None)              Tuple                 V RW
group                     'Function'                     String                C RW
kdims          [Dimension('x'), Dimension('y')]           List        (2, 2)   C RW
label                       'Sine'                       String                C RW
vdims                  [Dimension('z')]                   List        (1, 1)   V RW

Parameter docstrings:
=====================

bounds:   The bounding region in sheet coordinates containing the data.
cdims:    The constant dimensions defined as a dictionary of Dimension:value

Aliased with constant_dimensions.
datatype: A priority list of the data types to be used for storage
on the .data attribute. If the input supplied to the element
constructor cannot be put into the requested format, the next
format listed will be used until a suitable format is found (or
the data fails to be understood).
extents:  Allows overriding the extents
of the Element in 2D space defined as four-tuple
defining the (left, bottom, right and top) edges.
group:    A string describing the data wrapped by the object.
kdims:    The label of the x- and y-dimension of the Raster in form
of a string or dimension object.
label:    Optional label describing the data, typically reflecting where
or how it was measured. The label should allow a specific
measurement or dataset to be referenced for a given group..
vdims:    The dimension description of the data held in the matrix.


This information can be useful, but we have explicitly suppressed information regarding the visualization parameters -- these all report metadata about your data, not about anything to do with plotting directly. That's because the normal HoloViews components have nothing to do with plotting; they are just simple containers for your data and a small amount of metadata.

Instead, the plotting implementation and its associated parameters are kept in completely separate Python classes and objects. To find out about visualizing a HoloViews component like an  Image  , you can simply use the help command  holoviews.help(  object-or-class  )  that looks up the code that plots that particular type of component, and then reports the  style  and  plot  options available for it.

For our  image  example,  holoviews.help  first finds that  image  is of type  Image  , then looks in its database to find that  Image  visualization is handled by the  RasterPlot  class (which users otherwise rarely need to access directly).  holoviews.help  then shows information about what objects are available to customize (either the object itself, or the items inside a container), followed by a brief list of  style  options supported by a  RasterPlot  , and a list of  plot  options (which are all the parameters of a  RasterPlot  ). As this list of  plot  options is very long by default, here is an example that uses the  pattern  argument to limit the results to the options referencing the string  'bounds'  :

In [6]:
hv.help(image, pattern='bounds')

Image: Function Sine

Online example: http://holoviews.org/Tutorials/Elements.html#Image

---------------------
Target Specifications
---------------------

Targets in this object available for customization:

Element: Image.Function.Sine

To see the options info for one of these target specifications,
which are of the form {type}[.{group}[.{label}]], do holoviews.help({type}).

-------------
Style Options
-------------

alpha, clims, cmap, filterrad, interpolation, norm, visible

------------
Plot Options
------------

The plot options are the parameters of the plotting class:

Parameters of 'RasterPlot'
==========================

Parameters changed from their default values are marked in red.
Soft bound values are marked in cyan.

Name                    Value                Type      Bounds  Mode

apply_ranges             True              Boolean     (0, 1)  V RW
fig_bounds     (0.15, 0.15, 0.85, 0.85)  NumericTuple          V RW

Parameter docstrings:
=====================

apply_ranges: Whether to compute the plot bounds from the data itself.
fig_bounds:   The bounds of the overall figure as a 4-tuple of the form
(left, bottom, right, top), defining the size of the border
around the subplots.


The pattern option is particularly useful in conjunction with  recursive=True  which helps when searching for information across the different levels of a composite object. Note that the  pattern  argument supports Python's regular expression syntax and may also be used together with the  visualization=False  option.

#### Supported  style  options ¶

As you can see, HoloViews lists the currently allowed  style  options, but provides no further documentation because these settings are implemented by matplotlib and described at the matplotlib site. Note that matplotlib actually accepts a huge range of additional options, but they are not listed as being allowed because those options are not normally meaningful for this plot type. But if you know of a specific matplotlib option not on the list and really want to use it, you can add it manually to the list of supported options using  Store.add_style_opts(  holoviews-component-class  , ['  matplotlib-option ...  '])  . For instance, if you want to use the  filternorm  parameter with this image object, you would run  Store.add_style_opts(Image, ['filternorm'])  . This will add the new option to the corresponding plotting class  RasterPlot  , ready for use just like any other style option:

In [7]:
hv.Store.add_style_opts(hv.Image, ['filternorm'])
# To check that it worked:
RasterPlot = renderer.plotting_class(hv.Image)
print(RasterPlot.style_opts)

['alpha', 'clims', 'cmap', 'filternorm', 'filterrad', 'interpolation', 'norm', 'visible']


#### Changing  plot  options at the class level ¶

Any parameter in HoloViews can be set on an object or on the class of the object, so any of the above plot options can be set like:

In [8]:
RasterPlot.colorbar=True
RasterPlot.set_param(show_title=False,show_frame=True)


Here  .set_param()  allows you to set multiple parameters conveniently, but it works the same as the single-parameter  .colorbar  example above it. Setting these values at the class level affects all previously created and to-be-created plotting objects of this type, unless specifically overridden via  Store  as described below.

Note that if you look at the source code for a particular plotting class, you will only see some of the parameters it supports. The rest, such as  show_frame  above, are defined in a superclass of the given object. The Reference Manual shows the complete list of parameters available for any given class (those labeled  param  in the manual), but it can be an overwhelming list since it includes all superclasses, all the metadata about each parameter, etc. The  holoviews.help  command with  visualization=True  not only provides a much more concise listing, it can will also provide  style  options not available in the Reference Manual, by using the database to determine which plotting class is associated with this object.

Because setting these parameters at the class level does not provide much control over individual plots, HoloViews provides a much more flexible system using the  OptionTree  mechanisms described below, which can override these class defaults according to the more specific HoloViews object type,  group  , and  label  attributes.

The rest of the sections show how to change any of the above options, once you have found the right one using the suitable call to  holoviews.help  .

## Controlling options from Python ¶

Once you know the name of the option you want to change, and the value you want to change it to, there are a number of ways to customize your plot.

For the Python output to SVG example above, you can specify the options for a given type using keywords supplying a dictionary for any of the above option categories. You can see that the colormap changes when we supply that  style  option and render a new SVG:

In [9]:
renderer.save(layout, 'example_II', style=dict(Image={'cmap':'Blues'}),
plot= dict(Image={'yaxis':None}))
SVG(filename='example_II.svg')

Out[9]:

As before, the SVG call is simply to display it here in the notebook; the actual image is saved on disk and then loaded back in here for display.

You can see that the image now has a colorbar, because we set  colorbar=True  on the  RasterPlot  class, that it has become blue, because we set the matplotlib  cmap  style option in the  renderer.save  call, and that the y axis has been disabled, because we set the  plot  option  yaxis  to  None  (which is normally  'left'  by default, as you can see in the default value for  RasterPlot  's parameter  yaxis  above). Hopefully you can see that once you know the option value you want to use, it can be provided easily.

You can also create a whole set of options separately, perhaps holding a large collection of preferred values, and apply it whenever you wish to save:

In [10]:
options={'Image.Function.Sine': {'plot':dict(fig_size=50), 'style':dict(cmap='jet')}}
renderer.save(layout, 'example_III',options=options)
SVG(filename='example_III.svg')

Out[10]:

Here you can see that the y axis has returned, because our previous setting to turn it off was just for the call to  renderer.save  . But we still have a colorbar, because that parameter was set at the class level, for all future plots of this type. Note that this form of option setting, while more verbose, accepts the full  {type}[.{group}[.{label}]]  syntax, like  'Image.Function.Sine'  or  'Image.Function'  , while the shorter keyword approach above only supports the class, like 'Image'.

Note that for the  options  dictionary, the option nesting is inverted compared to the keyword approach: the outermost dictionary is by key (  Image  , or  Image.Function.Sines  ), with the option categories underneath. You can see that with this mechanism, we can specify the options even for subobjects of a container, as long as we can specify them with an appropriate key.

There's also another way to customize options in Python that lets you build up customizations incrementally. To do this, you can associate a particular set of options persistently with a particular HoloViews object, even if that object is later combined with other objects into a container. Here a new copy of the object is created, with the given set of options (using either the keyword or  options=  format above) bound to it:

In [11]:
green_sine = image(style={'cmap':'Greens'})


Here we could save the object to SVG just as before, but in this case we can skip a step and simply view it directly in the notebook:

In [12]:
green_sine

Out[12]:

To customize options of individual components in composite objects like Overlays or Layouts you can either specify the options on each individual component or specify which object to customize using the  {type}[.{group}[.{label}]]  syntax.

In [13]:
(image + curve)(style={'Image.Function.Sine': dict(cmap='Reds'), 'Curve': dict(color='indianred')})

Out[13]:

Both IPython notebook and  renderer.save()  use the same mechanisms for keeping track of the options, so they will give the same results. Specifically, what happens when you "bind" a set of options to an object is that there is an integer ID stored in the object (  green_sine  in this case), and a corresponding entry with that ID is stored in a database of options called an  OptionTree  (kept in  holoviews.core.options.Store  ). The object itself is otherwise unchanged, but then if that object is later used in another container, etc. it will retain its ID and therefore its customization. Any customization stored in an  OptionTree  will override any class attribute defaults set like  RasterGridPlot.border=5  above. This approach lets HoloViews keep track of any customizations you want to make, without ever affecting your actual data objects.

If the same object is later customized again to create a new customized object, the old customizations will be copied, and then the new customizations applied. The new customizations will thus override the old, while retaining any previous customizations not specified in the new step.

In this way, it is possible to build complex objects with arbitrary customization, step by step. As mentioned above, it is also possible to customize objects already combined into a complex container, just by specifying an option for a suitable key (e.g.  'Image.Function.Sine'  above). This flexible system should allow for any level of customization that is needed.

Finally, there is one more way to apply options that is a mix of the above approaches -- temporarily assign a new ID to the object and apply a set of customizations during a specific portion of the code. To illustrate this, we'll create a new Image object called 'Cosine':

In [14]:
cosine = hv.Image(np.cos(x**2+y**2), group="Function", label="Cosine")

In [15]:
with hv.StoreOptions.options(cosine, options={'Image':{'style':{'cmap':'Reds'}}}):
data, info = renderer(cosine)
print(info)
SVG(data)

{'file-ext': 'svg', 'mime_type': u'image/svg+xml'}

Out[15]:

Here the result is in red as it was generated in the context of a 'Reds' colormap but if we display cosine again outside the scope of the with statement, it retains the default settings:

In [16]:
cosine

Out[16]:

Note that if we want to use this context manager to set new options on the existing green_sine object, you must specify that the options apply to a specific Image by stating the applicable group and label:

In [17]:
with hv.StoreOptions.options(green_sine, options={'Image.Function.Sine':{'style':{'cmap':'Purples'}}}):
data, info = renderer(green_sine)
print(info)
SVG(data)

{'file-ext': 'svg', 'mime_type': u'image/svg+xml'}

Out[17]:

Now the result inside the context is purple but elswhere green_sine remains green. If the group and label had not been specified above, the specific customization applied earlier (setting the green colormap) would take precedence over the general settings of Image. For this reason, it is important to know the appropriate precedence of new customizations, or else you can just always specify the object group and label to make sure the new settings override the old ones.

## Controlling options in IPython using  %%opts  and  %opts  ¶

The above sections describe how to set all of the options using regular Python. Similar functionality is provided in IPython, but with a more convenient syntax based on an IPython magic command:

In [18]:
%%opts Curve style(linewidth=8) Image style(interpolation='bilinear') plot[yaxis=None] norm{+framewise}
layout

Out[18]:

The  %%opts  magic works like the pure-Python option for associating options with an object, except that it works on the item in the IPython cell, and it affects the item directly rather than making a copy or applying only in scope. Specifically, it assigns a new ID number to the object returned from this cell, and makes a new  OptionTree  containing the options for that ID number.

If the same  layout  object is used later in the notebook, even within a complicated container object, it will retain the options set on it.

The options accepted are just the same as for the Python version, but specified more succinctly:

 %%opts  target-specification  style(  styleoption  =  val ...  ) plot[  plotoption  =  val ...  ] norm{+  normoption  -  normoption ...  } 

Here key lets you specify the object type (e.g.  Image  ), and optionally its  group  (e.g.  Image.Function  ) or even both  group  and  label  (e.g.  Image.Function.Sine  ), if you want to control options very precisely. There is also an even further abbreviated syntax, because the special bracket types alone are enough to indicate which category of option is specified:

 %%opts  target-specification  (  styleoption  =  val ...  ) [  plotoption  =  val ...  ] {+  normoption  -  normoption ...  } 

Here parentheses indicate style options, square brackets indicate plot options, and curly brackets indicate norm options (with  +axiswise  and  +framewise  indicating True for those values, and  -axiswise  and  -framewise  indicating False). Additional target-specification s and associated options of each type for that target-specification can be supplied at the end of this line. This ultra-concise syntax is used throughout the other tutorials, because it helps minimize the code needed to specify the plotting options, and helps make it very clear that these options are handled separately from the actual data.

Here we demonstrate the concise syntax by customizing the style and plot options of the  Curve  in the layout:

In [19]:
%%opts Curve (color='r') [fontsize={'xlabel':15, 'ticks':8}]
layout

Out[19]:

The color of the curve has been changed to red and the fontsizes of the x-axis label and all the tick labels have been modified. The  fontsize  is an important plot option, and you can find more information about the available options in the  fontsize  documentation above.

The  %%opts  magic is designed to allow incremental customization, which explains why the curve in the cell above has retained the increased thickness specified earlier. To reset all the customizations that have been applied to an object, you can create a fresh, uncustomized copy as follows:

In [20]:
layout()

Out[20]:

The  %opts  "line" magic (with one  %  ) works just the same as the  %%opts  "cell" magic, but it changes the global default options for all future cells, allowing you to choose a new default colormap, line width, etc.

Apart from its brevity, a big benefit of using the IPython magic syntax  %%opts  or  %opts  is that it is fully tab-completable. Each of the options that is currently available will be listed if you press  <TAB>  when you are ready to write it, which makes it much easier to find the right parameter. Of course, you will still need to consult the full  holoviews.help  documentation (described above) to see the type, allowable values, and documentation for each option, but the tab completion should at least get you started and is great for helping you remember the list of options and see which options are available.

You can even use the succinct IPython-style specification directly in your Python code if you wish, but it requires the external pyparsing library (which is already available if you are using matplotlib):

In [21]:
from holoviews.ipython.parser import OptsSpec
renderer.save(image + waves, 'example_V',
options=OptsSpec.parse("Image (cmap='gray')"))


There is also a special IPython syntax for listing the visualization options for a plotting object in a pop-up window that is equivalent to calling  holoviews.help(  object  )  :

In [22]:
%%output info=True
curve

Out[22]:

The line-magic version of this syntax  %output info=True  is particularly useful for learning about components using the notebook, because it will keep a window open with the available options for each object updated as you do  <shift-Enter>  in each cell. E.g. you can go through each of the components in the  Elements  or  Containers  tutorials in this way, to see what options are offered by each without having to type anything for each one.

## Option inheritance ¶

Since HoloViews objects nest in a variety of ways and you do not want to keep changing the options specification when you compose your object into an  Overlay  or  NdOverlay  , certain  plot  options are inherited. This includes all plot options which control the appearance of the axes, but not those that are specific to the Element. As a simple example let us combine the  Image  from above with some  Bounds  . Even though we apply the  xrotation  and  yticks  options to the  Image  they are inherited by the  Overlay  of the  Image  and  Bounds  .

In [23]:
%%opts Image [xrotation=90 yticks=[-0.5, 0., 0.5]]
image * hv.Bounds((-.25, -.25, .25, .25))

Out[23]: