How to Create a Treemap in Plotly

Treemaps visualize hierarchical data using nested rectangles, where each rectangle's size represents a quantitative value. Unlike traditional tree diagrams that emphasize structure, treemaps...

Key Insights

  • Treemaps excel at visualizing hierarchical data with proportional rectangles, making them ideal for budget breakdowns, file systems, and portfolio analysis where you need to show both hierarchy and relative size at a glance
  • Plotly’s treemap() function requires just three core parameters—labels, parents, and values—but the parent-child relationship structure is critical and the most common source of errors
  • Real-world treemap success depends on proper data preparation: ensure every child has exactly one parent, use empty string for root nodes, and validate there are no circular references before plotting

Introduction to Treemaps

Treemaps visualize hierarchical data using nested rectangles, where each rectangle’s size represents a quantitative value. Unlike traditional tree diagrams that emphasize structure, treemaps prioritize efficient space usage and make it easy to spot proportional relationships at every level of the hierarchy.

You’ll find treemaps particularly useful for disk space analyzers (showing which folders consume the most storage), financial dashboards (displaying budget allocation across departments and projects), market analysis (visualizing market cap by sector and company), and sales reporting (breaking down revenue by region, product category, and individual SKU).

Plotly stands out as an excellent choice for treemap creation because it provides interactive features out of the box—hover tooltips, zoom capabilities, and click events—without requiring additional JavaScript. The library handles the complex rectangle packing algorithm automatically, and you can create publication-ready visualizations with minimal code.

Setting Up Your Environment

Install Plotly using pip. You’ll also want pandas for data manipulation, though it’s not strictly required for basic treemaps.

pip install plotly pandas

Verify your installation with a quick import test:

import plotly.express as px
import plotly.graph_objects as go
import pandas as pd

print(f"Plotly version: {px.__version__}")

If you’re working in a Jupyter notebook, treemaps will render inline automatically. For Python scripts, Plotly will open visualizations in your default browser.

Creating a Basic Treemap

The fundamental requirement for any treemap is hierarchical data structured as parent-child relationships. You need three essential lists: labels (node names), parents (each node’s parent), and values (the size of each rectangle).

Here’s a straightforward example showing a company’s departmental budget allocation:

import plotly.express as px

labels = [
    "Company", 
    "Engineering", "Product", "Sales",
    "Backend Team", "Frontend Team", "Mobile Team",
    "Design", "Research",
    "Enterprise", "SMB"
]

parents = [
    "",  # Company is the root
    "Company", "Company", "Company",
    "Engineering", "Engineering", "Engineering",
    "Product", "Product",
    "Sales", "Sales"
]

values = [
    0,  # Root node typically has 0
    450, 280, 320,
    200, 150, 100,
    180, 100,
    200, 120
]

fig = px.treemap(
    labels=labels,
    parents=parents,
    values=values
)

fig.show()

The parent-child relationship is crucial: “Company” has an empty string as its parent (making it the root), “Engineering” has “Company” as its parent, and “Backend Team” has “Engineering” as its parent. This creates a three-level hierarchy. The root node should have a value of 0 since its size is determined by its children.

Customizing Treemap Appearance

Basic treemaps work, but customization makes them compelling. You can control colors, hover information, text display, and borders to create professional visualizations.

import plotly.express as px

labels = [
    "Company", 
    "Engineering", "Product", "Sales",
    "Backend Team", "Frontend Team", "Mobile Team",
    "Design", "Research",
    "Enterprise", "SMB"
]

parents = [
    "", 
    "Company", "Company", "Company",
    "Engineering", "Engineering", "Engineering",
    "Product", "Product",
    "Sales", "Sales"
]

values = [
    0,
    450, 280, 320,
    200, 150, 100,
    180, 100,
    200, 120
]

# Add efficiency metric for color coding
efficiency = [
    0,
    0.92, 0.85, 0.78,
    0.95, 0.90, 0.88,
    0.87, 0.82,
    0.80, 0.75
]

fig = px.treemap(
    labels=labels,
    parents=parents,
    values=values,
    color=efficiency,
    color_continuous_scale='RdYlGn',
    hover_data={'efficiency': ':.2%'}
)

fig.update_traces(
    textposition="middle center",
    textfont_size=14,
    marker=dict(line=dict(width=2, color='white'))
)

fig.update_layout(
    title="Company Budget Allocation by Department",
    font=dict(size=12),
    margin=dict(t=50, l=0, r=0, b=0)
)

fig.show()

This enhanced version uses a color scale to represent efficiency metrics, with green indicating high efficiency and red showing areas needing improvement. The white borders clearly delineate sections, and the hover data provides additional context beyond what’s visible in the rectangles.

Working with Real-World Data

Real-world data rarely arrives in the perfect format for treemaps. You’ll typically start with a DataFrame and need to construct the parent-child relationships.

Here’s a practical example using sales data:

import pandas as pd
import plotly.express as px

# Simulate sales data
sales_data = pd.DataFrame({
    'Region': ['North', 'North', 'North', 'South', 'South', 'South'],
    'Category': ['Electronics', 'Electronics', 'Furniture', 'Electronics', 'Furniture', 'Furniture'],
    'Product': ['Laptop', 'Phone', 'Desk', 'Tablet', 'Chair', 'Table'],
    'Revenue': [45000, 32000, 18000, 28000, 15000, 22000]
})

# Build hierarchical structure
labels = ['Total']
parents = ['']
values = [0]

# Add regions
for region in sales_data['Region'].unique():
    labels.append(region)
    parents.append('Total')
    region_revenue = sales_data[sales_data['Region'] == region]['Revenue'].sum()
    values.append(region_revenue)

# Add categories within regions
for region in sales_data['Region'].unique():
    region_data = sales_data[sales_data['Region'] == region]
    for category in region_data['Category'].unique():
        label = f"{region} - {category}"
        labels.append(label)
        parents.append(region)
        category_revenue = region_data[region_data['Category'] == category]['Revenue'].sum()
        values.append(category_revenue)

# Add products within categories
for _, row in sales_data.iterrows():
    labels.append(row['Product'])
    parents.append(f"{row['Region']} - {row['Category']}")
    values.append(row['Revenue'])

fig = px.treemap(
    labels=labels,
    parents=parents,
    values=values,
    title="Sales Revenue by Region, Category, and Product"
)

fig.update_traces(textinfo="label+value")
fig.show()

The key challenge is ensuring every label is unique and every parent reference matches an existing label exactly. Notice how category labels include the region prefix to maintain uniqueness.

Advanced Features

Plotly treemaps support custom data fields that appear in hover tooltips but don’t affect the visualization structure:

import plotly.graph_objects as go

labels = ["Company", "Engineering", "Backend", "Frontend", "Product", "Design"]
parents = ["", "Company", "Engineering", "Engineering", "Company", "Product"]
values = [0, 450, 200, 150, 280, 180]
employees = [0, 45, 20, 15, 28, 18]
growth = [0, 15, 20, 12, 8, 5]

fig = go.Figure(go.Treemap(
    labels=labels,
    parents=parents,
    values=values,
    customdata=list(zip(employees, growth)),
    hovertemplate='<b>%{label}</b><br>Budget: $%{value}k<br>Employees: %{customdata[0]}<br>Growth: %{customdata[1]}%<extra></extra>',
    texttemplate='<b>%{label}</b><br>$%{value}k',
    marker=dict(
        colorscale='Blues',
        cmid=300
    )
))

fig.update_layout(title="Department Overview with Metrics")
fig.show()

Using graph_objects instead of express gives you finer control over hover templates and custom data. The customdata parameter accepts any additional information you want available in tooltips, and hovertemplate defines exactly how that information displays.

Best Practices and Troubleshooting

Choose hierarchies that make intuitive sense to your audience. Generally, limit depth to 3-4 levels—deeper hierarchies become difficult to navigate visually. Order matters: place your most important categories first in your data structure for better visual prominence.

For large datasets with hundreds of nodes, consider filtering to show only the top N items by value, or allow users to drill down interactively rather than displaying everything at once. Treemaps with more than 100 leaf nodes become cluttered.

The most common error is “parent not found” which occurs when a parent reference doesn’t match any label exactly. Check for typos, extra spaces, and case sensitivity. Use this validation function before creating your treemap:

def validate_treemap_data(labels, parents):
    label_set = set(labels)
    for i, parent in enumerate(parents):
        if parent != "" and parent not in label_set:
            print(f"Error: Parent '{parent}' for label '{labels[i]}' not found")
            return False
    return True

# Usage
if validate_treemap_data(labels, parents):
    fig = px.treemap(labels=labels, parents=parents, values=values)
    fig.show()

Circular dependencies (where A is a parent of B, and B is a parent of A) will cause infinite loops. Ensure your hierarchy is a true tree structure with a single root and no cycles.

For performance optimization with large datasets, consider aggregating small values into an “Other” category, or use branchvalues="total" to show cumulative values at each branch level rather than calculating from children.

Treemaps transform complex hierarchical data into instantly understandable visualizations. Master the parent-child relationship structure, validate your data before plotting, and customize thoughtfully to create treemaps that reveal insights your audience would otherwise miss.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.