Claude
Skills
Sign in
Back

data-visualization

Included with Lifetime
$97 forever

Master advanced declarative visualization with HoloViews. Use this skill when creating complex multi-dimensional visualizations, composing overlays and layouts, implementing interactive streams and selection, building network or hierarchical visualizations, or exploring data with dynamic maps and faceted displays.

General

What this skill does


# Data Visualization Skill

## Overview

Master advanced declarative visualization with HoloViews and composition patterns. This skill covers sophisticated visualization techniques for complex data exploration and presentation.

## Dependencies

- holoviews >= 1.18.0
- pandas >= 1.0.0
- numpy >= 1.15.0
- bokeh >= 3.0.0
- networkx >= 2.0.0 (for network visualizations)

## Core Capabilities

### 1. Advanced Element Composition

HoloViews allows sophisticated composition of visualization elements:

```python
import holoviews as hv
from holoviews import opts
import pandas as pd
import numpy as np

# Create overlaid elements
curve = hv.Curve(df, 'x', 'y', label='Measured')
scatter = hv.Scatter(df_with_noise, 'x', 'y', label='Noisy')
overlay = curve * scatter  # Multiplication overlays

# Create layouts
col_layout = hv.Column(plot1, plot2, plot3)
row_layout = hv.Row(plot1, plot2, plot3)
grid_layout = hv.GridMatrix(data_dict)

# Faceted displays
faceted = hv.Curve(df, 'date', 'value').facet('category')

# Nested layouts
complex_layout = hv.Column(
    hv.Row(plot1, plot2),
    hv.Row(plot3, plot4),
    hv.Row(plot5, plot6)
)
```

### 2. Interactive Streams and Selection

Create responsive visualizations with interactive selection:

```python
from holoviews import streams

# Selection stream
range_stream = streams.RangeXY()
scatter = hv.Scatter(df, 'x', 'y').opts(tools=['box_select'])

@hv.transform
def selected_data(data):
    if range_stream.selection:
        x0, x1 = range_stream.selection[0], range_stream.selection[1]
        y0, y1 = range_stream.selection[2], range_stream.selection[3]
        mask = (data['x'] >= x0) & (data['x'] <= x1) & \
               (data['y'] >= y0) & (data['y'] <= y1)
        return data[mask]
    return data

histogram = selected_data.to(hv.Histogram)
scatter_with_hist = scatter + histogram
```

### 3. Dynamic Maps for Responsive Visualization

```python
# Dynamic updating based on parameters
from holoviews import DynamicMap, streams

def plot_by_category(category):
    data = df[df['category'] == category]
    return hv.Scatter(data, 'x', 'y', title=f'Category: {category}')

category_stream = streams.Stream.define('category', category='A')
dmap = DynamicMap(plot_by_category, streams=[category_stream])

# Parameterized dynamic map
def plot_with_params(threshold=0.5):
    filtered = df[df['value'] > threshold]
    return hv.Scatter(filtered, 'x', 'y')

dmap_param = DynamicMap(
    plot_with_params,
    streams=[streams.Stream.define('threshold', threshold=0.5)]
)
```

### 4. Network and Hierarchical Visualizations

```python
import networkx as nx

# Network graph
G = nx.karate_club_graph()
pos = nx.spring_layout(G)
edges = [(u, v) for u, v in G.edges()]
nodes = list(G.nodes())

# Create nodes and edges visualization
edge_plot = hv.Segments(edges, kdims=['source', 'target'])
node_plot = hv.Scatter(
    [(pos[n][0], pos[n][1], n) for n in nodes],
    kdims=['x', 'y', 'node']
)
network = (edge_plot * node_plot).opts(
    opts.Scatter(size=100, color='red'),
    opts.Segments(color='gray')
)

# Treemap for hierarchical data
treemap = hv.TreeMap(
    hierarchical_data,
    label='Organization'
).opts(tools=['hover'])
```

### 5. Statistical and Aggregate Visualizations

```python
# Aggregate with Rasterize
from holoviews.operation import datashader as dshade

# Box plot for comparison
box_plot = hv.BoxWhisker(df, kdims=['category'], vdims=['value'])

# Violin plot
violin = hv.Violin(df, kdims=['category'], vdims=['value'])

# Distribution comparison
dist_layout = hv.Column(*[
    df[df['category'] == cat]['value'].hvplot.hist()
    for cat in df['category'].unique()
])
```

### 6. Multi-Dimensional Data Exploration

```python
# HoloMap for multi-dimensional data
def plot_by_params(category, metric):
    data = df[(df['category'] == category) & (df['metric'] == metric)]
    return hv.Scatter(data, 'x', 'y', title=f'{category} - {metric}')

hmap = hv.HoloMap(
    {(cat, met): plot_by_params(cat, met)
     for cat in categories for met in metrics},
    kdims=['Category', 'Metric']
)

# NdLayout for structured multi-dimensional display
ndlayout = hv.NdLayout({
    (cat, met): plot_by_params(cat, met)
    for cat in categories for met in metrics
}, kdims=['Category', 'Metric'])
```

## Advanced Styling and Theming

### 1. Global Options

```python
# Set global defaults
opts.defaults(
    opts.Curve(width=700, height=400, responsive=True),
    opts.Scatter(size=100, alpha=0.5),
    opts.Image(cmap='viridis')
)

# Apply to multiple elements
styled_plots = [
    plot.opts(
        title='Styled Plot',
        xlabel='X Axis',
        ylabel='Y Axis',
        toolbar='right',
        active_tools=['pan', 'wheel_zoom']
    )
    for plot in plots
]
```

### 2. Custom Styling

```python
# Element-specific styling
plot = hv.Scatter(df, 'x', 'y').opts(
    color=hv.dim('category').categorize({
        'A': '#FF6B6B',
        'B': '#4ECDC4',
        'C': '#45B7D1'
    }),
    size=hv.dim('value').norm(min=10, max=100),
    selection_color='red',
    nonselection_alpha=0.1
)

# Conditional formatting
plot.opts(
    color=hv.dim('status').categorize({
        'good': 'green',
        'warning': 'orange',
        'error': 'red'
    })
)
```

### 3. Interactive Legends and Annotations

```python
# Annotations
annotated_plot = hv.Curve(df, 'x', 'y')
annotations = [
    hv.Text(x, y, text, fontsize=10)
    for x, y, text in annotations_data
]
plot_with_annotations = annotated_plot * hv.Overlay(annotations)

# Custom legend
plot = hv.Overlay([
    hv.Curve(df1, label='Series 1'),
    hv.Curve(df2, label='Series 2'),
    hv.Curve(df3, label='Series 3')
]).opts(
    legend_position='top_left',
    legend_muted_alpha=0.2
)
```

## Best Practices

### 1. Performance with Large Datasets
```python
# Use rasterize for dense plots
from holoviews.operation import rasterize

large_scatter = hv.Scatter(large_df, 'x', 'y')
rasterized = rasterize(large_scatter, pixel_ratio=2)

# Use aggregation
aggregated = df.groupby('category')['value'].mean().hvplot.bar()

# Use datashader for massive datasets (>100M points)
from holoviews.operation.datashader import datashade
dshaded = datashade(large_scatter)
```

### 2. Responsive and Accessible Plots
```python
# Responsive sizing
plot = hv.Scatter(df, 'x', 'y').opts(
    responsive=True,
    sizing_mode='stretch_width'
)

# Accessible color palettes
plot = hv.Scatter(df, 'x', 'y').opts(
    color=hv.dim('value').norm(),
    cmap='cet_gray_r'  # Perceptually uniform
)

# Clear labels
plot.opts(
    title='Clear Title',
    xlabel='Independent Variable (units)',
    ylabel='Dependent Variable (units)',
    fontsize=14
)
```

### 3. Composition Patterns

```python
# Avoid deep nesting
# Bad: ((a + (b + (c + d)))
# Good: a + b + c + d

# Create helper functions
def create_comparison_layout(data_dict):
    plots = [hv.Scatter(v, label=k) for k, v in data_dict.items()]
    return hv.Column(*plots)

# Modular composition
sidebar = hv.Column(title_text, filter_widget)
main = hv.Row(plot1, plot2)
app = hv.Column(sidebar, main)
```

## Common Patterns

### Pattern 1: Linked Brushing
```python
def create_linked_views(df):
    scatter = hv.Scatter(df, 'x', 'y').opts(tools=['box_select'])

    def get_histogram(selection):
        if selection:
            selected_df = df.iloc[selection.event.inds]
        else:
            selected_df = df
        return hv.Histogram(selected_df['x'], bins=20)

    return scatter + DynamicMap(get_histogram, streams=[streams.Selection1D()])
```

### Pattern 2: Multi-Scale Exploration
```python
def create_zoomable_view(df):
    scatter = hv.Scatter(df, 'x', 'y')
    zoomed = scatter.opts(
        xlim=(0, 10),
        ylim=(0, 10)
    )
    return hv.Column(scatter, zoomed)
```

### Pattern 3: Faceted Analysis
```python
def create_faceted_analysis(df, facet_col):
    return df.hvplot.scatter(
        x='x',
        y='y',
        by=facet_col,
        subplots=True,
        layout='vertical'
    )
```

Related in General