<jupyter_start><jupyter_text>**HoloViews encapsulates your continuous or discrete data into storable, composable, sliceable objects, leveraging matplotlib or Bokeh for visualization and IPython/Jupyter Notebook for maximum productivity.**Main features:* Preserves your raw data while allowing rapid, interactive exploratory analysis.* Builds even complex, composite visualizations that are easily customized.* Succinct, declarative style allows you to keep all the necessary code visible, ensuring your workflow is transparent and fully reproducible.* You can select, slice, or transform only the relevant data that is currently of interest.* You can store your raw data as HoloViews objects via pickling, for later analysis or visualization even without the code that generated it.* Strong support for the IPython/Jupyter Notebook, including tab-completion throughout and convenient IPython magics (with all functionality available from pure Python as well).* Seamless (optional) interaction with Pandas Dataframes.* [And much, much more!](http://holoviews.org/features.html)The [IPython/Jupyter notebook](http://ipython.org/notebook/) environment and [matplotlib](http://matplotlib.org) or [bokeh](http://bokeh.pydata.org) allow you to do interactive exploration and analysis of your data and measurements, using the rich [ecosystem of tools available in Python](http://scipy.org).  However, your notebooks can very quickly fill up with verbose, specialized plotting code whenever you want to visualize your data, which is often.  To make all this practical, you can use HoloViews to greatly improve your productivity, requiring orders of magnitude fewer lines of code and letting you focus on your data itself, not on writing code to visualize and display it.Here we will show some of the main features of HoloViews, focusing on why it is useful for scientists and engineers.<jupyter_code>import holoviews as hv
import numpy as np
hv.notebook_extension()<jupyter_output><empty_output><jupyter_text>A simple function First, let us define a mathematical function to explore, using the Numpy array library:<jupyter_code>def sine(x, phase=0, freq=100):
    return np.sin((freq * x + phase))<jupyter_output><empty_output><jupyter_text>We will examine the effect of varying phase and frequency:<jupyter_code>phases = np.linspace(0,2*np.pi,11) # Explored phases
freqs = np.linspace(50,150,5)      # Explored frequencies<jupyter_output><empty_output><jupyter_text>Over a specific spatial area, sampled on a grid:<jupyter_code>dist = np.linspace(-0.5,0.5,202)   # Linear spatial sampling
x,y = np.meshgrid(dist, dist)
grid = (x**2+y**2)                 # 2D spatial sampling<jupyter_output><empty_output><jupyter_text>Compact data visualization With HoloViews, we can immediately view our simple function by creating ``Image`` and ``Curve`` objects to visualize the 2D arrays and 1D cross-sections generated by the ``sine`` function, respectively:<jupyter_code>freq1 = hv.Image(sine(grid, freq=50))  + hv.Curve(zip(dist, sine(dist**2, freq=50)))
freq2 = hv.Image(sine(grid, freq=200)) + hv.Curve(zip(dist, sine(dist**2, freq=200)))
(freq1 + freq2).cols(2)<jupyter_output><empty_output><jupyter_text>As you can see, ``Image`` takes a 2D numpy array as input and ``Curve`` accepts a list of ``(x,y)`` points. With the ``+`` operator we can lay these elements out together and with ``.cols(2)`` we can arrange them into two columns.HoloViews objects like ``Image`` and ``Curve`` are a great way to work with your data, because they display so easily and flexibly, yet preserve the raw data (the Numpy array in this case) in the ``.data`` attribute. [Calling matplotlib directly](http://matplotlib.org/examples/pylab_examples/multi_image.html) to generate such a figure would take much, much more code, e.g., to label each of the axes, to create a figure with subfigures, etc.  Moreover, such code would be focused on the plotting, whereas with HoloViews you can focus directly on what matters: your data, letting it plot itself.  Because the HoloViews code is so succinct, you don't need to hide it away in some difficult-to-maintain external script; you can simply type what you want to see right in the notebook, changing it at will and being able to come back to your analysis just as you left it.Only two element types are shown above, but HoloViews supports many other types of element that behave in the same way: **scatter points, histograms, tables, vectorfields, RGB images, 3D plots, annotations**, and ***many more*** as shown in the [Elements overview](Elements.ipynb).  All of these can be combined easily to create even quite complex plots with a minimum of code to write or maintain.  Interactive exploration We can interactively explore this simple function if we declare the dimensions of the parameter space to be explored (``dimensions``) as well as the specific samples to take in this parameter space (``keys``):<jupyter_code>dimensions = ['Phase', 'Frequency']
keys = [(p,f) for p in phases for f in freqs]<jupyter_output><empty_output><jupyter_text>Now we create a high-dimensional [``HoloMap``](Exploring_Data.ipynb) to explore: The tuple keys are the points in the parameter space, and the values are the corresponding ``Image`` objects:<jupyter_code>items = [(k, hv.Image(sine(grid, *k), vdims=['Amplitude'])) for k in keys]
circular_wave = hv.HoloMap(items, kdims=dimensions)
circular_wave<jupyter_output><empty_output><jupyter_text>You can still compose as many visualization elements as you wish together. Here is a demonstration of how to generate the horizontal cross-section of the circular wave using ``Curve`` elements. This is then positioned next to our circular wave:<jupyter_code>items = [(k, hv.Curve(zip(dist, sine(dist**2, *k)))) for k in keys]
sections = hv.HoloMap(items, kdims=dimensions)
circular_wave + sections<jupyter_output><empty_output><jupyter_text>You can then easily [export](Exporting.ipynb) your ``HoloMap`` objects to an interactive notebook, video formats, or GIF animations to use on a web page.  Succinct Analysis HoloViews is focused on making your data readily available, both for visualization and for numerical analysis.  Because HoloViews objects preserve your raw data, you can use any Python analysis tools you wish, such as those in the [SciPy](http://scipy.org) library.  We also support some very general-purpose data analysis and manipulation operations directly in HoloViews, exploiting the generality of the HoloViews data structures to simplify common tasks. Here, we pick a point on the circular wave at ``(0,0.25)`` and plot the amplitude value as a function of phase. The circular wave is shown annotated with a point at the chosen position. Note how we can still interactively explore the remaining dimensions, namely ``Frequency``.<jupyter_code>sample_pos = (0,0.25)
annotated = circular_wave * hv.Points([sample_pos])
sample = circular_wave.sample(samples=[sample_pos]).to.curve('Phase', 'Amplitude', ['Frequency'])
annotated + sample<jupyter_output><empty_output><jupyter_text>Note that the spatial frequency of our curve plot is *not* affected by the frequency of our wave. That is because the phase always spans exactly one cycle at any of the chosen frequencies. Here is the circular wave annotated with contours at the 0.5 level, followed by a thresholded version of the same wave, and then the gradient of this pattern, along with a histogram of the gradient values:<jupyter_code>%output holomap='gif'<jupyter_output><empty_output><jupyter_text>Note that GIF support requires [ImageMagick](http://www.imagemagick.org/) which is installed by default on many Linux installations and may be installed on OSX using [brew](http://brew.sh/). For more information on how to install ImageMagick (including Windows instructions) see the [installation page](http://www.imagemagick.org/script/binary-releases.php).<jupyter_code>%%opts Image (cmap='gray') Contours (color='r')
from holoviews.operation import contours, threshold, gradient
m = hv.HoloMap([(p, hv.Image(sine(grid, phase=p))) for p in phases], kdims=['Phase'])
contours(m, levels=[0.5]) + threshold(m, level=0.5) + gradient(m).hist(bin_range=(0,0.7))<jupyter_output><empty_output><jupyter_text>(The ``%%`` syntax for specifying options will be briefly explained in the next section below.)  You can see that this data is shown as an animation, because the data covers multiple phases; each frame of the animation shows the result from one phase.  To get a static plot, just select one phase out of this space instead of a whole list of phases as done here.  Throughout HoloViews, if there are more dimensions of data than will fit into the plot as it has been laid out, they will simply be displayed as an animation or using slider bars.  Supplied operations include **gradient, fft_power, convolve, histogram** and other common general-purpose analysis tools.  Flexible display system Remember the initial test of the ``sine`` function? Those two composite objects are still in the namespace and even though the objects have already been created, we can still style the display in any way we like.  This styling is done separately from specifying your data, so that your data's specification is always clearly visible, independently of how it is being viewed:<jupyter_code>%%opts Image (cmap='RdYlGn') Curve (color='g')
(freq1 + freq2).cols(2)<jupyter_output><empty_output><jupyter_text>For convenience, the IPython-magic syntax for [setting options](Options.ipynb) like ``%%opts`` is used throughout these tutorials.  However, you can use pure Python code to control the options in a similar way, e.g. from within an external non-IPython program where you want to render a HoloViews plot straight to a file, though it requires a few more curly brackets and quote marks:<jupyter_code>red_wave = circular_wave(options={'Image':{'style':{'cmap':'RdGy'}}})
red_wave<jupyter_output><empty_output><jupyter_text>Understanding your data HoloViews is designed to make it easy to understand your data. For instance, consider two circular waves with very different amplitudes:<jupyter_code>comparison = hv.Image(sine(grid)) + hv.Image(sine(grid, phase=np.pi)*0.02)<jupyter_output><empty_output><jupyter_text>HoloViews ensures that these differences are visible by default, by normalizing across any elements of the same type that are displayed together, and even across the frames of an animation:<jupyter_code>%%opts Image (cmap='gray')
comparison = hv.Image(sine(grid)) + hv.Image(sine(grid, phase=np.pi)*0.02)
comparison<jupyter_output><empty_output><jupyter_text>This default visualization makes it clear that the two patterns differ greatly in amplitude. However, it is difficult to see the structure of the low-amplitude wave in **B**.  If you wish to focus on the spatial structure rather than the amplitude, you can instruct HoloViews to normalize data in different axes separately:<jupyter_code>%%opts Image {+axiswise} (cmap='gray')
comparison<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08343179132963738, 'fraction_numerical': 0.006634554212487503, 'mean_word_length': 5.85607476635514, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '100815', 'license': 'MIT', 'n_tokens_mistral': 3090, 'n_tokens_neox': 2968, 'n_words': 1365, 'path': 'Recommender-Source-Code/JupyterNotebook/notebooks/Showcase.ipynb', 'repo_name': 'Xiyao-Cheng/OnTimeEvidence', 'size': '11003'}