A tool to visualize Apache Spark execution plans.
Project description
Spark Plan Viz ⚡
A lightweight, interactive tool to visualize PySpark execution plans using D3.js. It helps developers and data engineers debug complex queries when the textual result of df.explain() is not enough. Perfect for identifying bottlenecks, understanding query execution flow, and optimizing Spark performance.
✨ Features
- 📊 Interactive Visualization: Zoom, pan, and click nodes to explore execution details
- 🎯 Performance Insights: Instantly identify shuffles, broadcast joins, and pushed filters
- 📝 Rich Node Information: See join types, filter conditions, aggregate functions, sort orders, and more
- 🔍 Detailed Side Panel: Click any node to view complete information including output columns and full descriptions
- 📓 Jupyter Integration: Renders directly inside notebooks without external files
- 🌐 Standalone HTML: Export visualizations to share with your team
- 🎨 Smart Coloring: Color-coded nodes by operation type for quick identification
- ⚡ AQE Support: Full support for Adaptive Query Execution details
- 🔄 Execution Flow: Tree layout shows data flow from sources (top) to result (bottom)
🚀 Installation
pip install spark-plan-viz
📖 Usage
In a Jupyter Notebook
from spark_plan_viz import visualize_plan
# Assuming 'df' is your PySpark DataFrame
visualize_plan(df, notebook=True)
Export to HTML
from spark_plan_viz import visualize_plan
# Generates a standalone HTML file and opens it in browser
visualize_plan(df, notebook=False, output_file="my_query_plan.html")
🎨 Reading the Visualization
Node Colors
The visualization uses color coding to help you quickly identify different operation types:
- 🔴 Red (Exchange/Shuffle): Data shuffling across executors - potential performance bottleneck
- 🟣 Purple (Join): Join operations - watch for broadcast vs shuffle joins
- 🟢 Green (Scan): Data source operations - check for pushed filters
- 🟠 Orange (Filter): Filter operations
- 🔵 Blue (Aggregate): Aggregation operations - see grouping keys and functions
- 🟤 Brown (Sort): Sort operations - can be expensive
- ⚫ Gray (Project): Column selection/projection
- 🟦 Teal (Window): Window functions
Tree Layout
- Top: Data sources (table/file scans)
- Middle: Transformations (filters, joins, aggregations)
- Bottom: Final result
- Arrows: Show data flow direction from sources to result
Key Information Displayed on Nodes
Each node shows the most relevant information directly:
- Joins: Type (Inner, Left, etc.), 📡 Broadcast indicator
- Filters: Condition preview
- Scans: Table name, data format (PARQUET, JSON, etc.), ✓ Pushed filters indicator
- Aggregates: Functions used (sum, count, avg), grouping keys
- Shuffles: ⚠️ Warning indicator, partition count, shuffle type
- Sorts: Sort order (ASC/DESC)
- Projects: Selected columns
Performance Optimization Tips
When reviewing your execution plan, look for:
-
⚠️ Shuffle Operations (Red):
- Minimize these as they involve network I/O
- Consider repartitioning or using broadcast joins
-
📡 Broadcast Joins (Purple with 📡):
- Excellent for small tables
- Much faster than shuffle joins
- Verify the smaller table is being broadcast
-
✓ Pushed Filters (Green with ✓):
- Filters applied at the data source level
- Reduces data read from disk
- Ensure filters are pushed when possible
-
Data Format:
- Columnar formats (PARQUET, ORC) are generally faster
- Check if your tables use optimal formats
💡 Example
from pyspark.sql import SparkSession
from pyspark.sql.functions import broadcast
from spark_plan_viz import visualize_plan
spark = SparkSession.builder.appName("Example").getOrCreate()
# Create sample data
orders = spark.createDataFrame([
(1, "Alice", 100),
(2, "Bob", 200),
], ["id", "customer", "amount"])
customers = spark.createDataFrame([
("Alice", "NY"),
("Bob", "CA"),
], ["name", "state"])
# Complex query with broadcast join
result = orders.filter(orders.amount > 50) \
.join(broadcast(customers), orders.customer == customers.name) \
.groupBy("state") \
.agg({"amount": "sum"})
# Visualize the execution plan
visualize_plan(result, notebook=True)
📸 Example Visualization
Here's an example screenshot of the visualization:
📋 Requirements
- Python 3.11+
- PySpark 3.x+
- For notebook mode: IPython/Jupyter
⚠️ Limitations
spark_plan_viz is not available on Databricks Serverless Compute, as it's not possible to access the _jdf object of a Spark Dataframe.
PS: I haven't test it on Personal Compute Clusters as I don't have a Databricks subscription active. If you want to analyze query plan on Databricks you can use the builtin See query profile.
📄 License
MIT License
🤝 Contributing
Contributions are welcome! Feel free to open issues or submit pull requests.
Development Setup
# Clone the repository
git clone https://github.com/montanarograziano/spark_plan_viz.git
cd spark_plan_viz
# Install dependencies
just install
# Install pre commits through prek
just pre-commit
# Test on specific Python version
just test-python 3.12
# Test on all supported Python versions (3.11-3.13)
just test-all
See CONTRIBUTING.md for detailed guidelines.
🙏 Acknowledgments
Built with D3.js for interactive visualizations.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spark_plan_viz-0.2.3.tar.gz.
File metadata
- Download URL: spark_plan_viz-0.2.3.tar.gz
- Upload date:
- Size: 376.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e655fb1b7d5d69292ad5c79e414705662086097301c62f91696d1f0a190a5944
|
|
| MD5 |
f303c837f62de6333182c4001676931f
|
|
| BLAKE2b-256 |
85a06f02179e1e7a6e106b76abbd9fbc273713bd14ea2cc556c38e56b25b3b43
|
File details
Details for the file spark_plan_viz-0.2.3-py3-none-any.whl.
File metadata
- Download URL: spark_plan_viz-0.2.3-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0265b9a478cca61bcc988e3426602e8ff2624863e246d8c3f80dfe13c7590636
|
|
| MD5 |
d67599263983624a0527963017a24da9
|
|
| BLAKE2b-256 |
3573d12a0a7df26646f53715233d29a779959bc010cf0c435a46e53337a2aaad
|