Expand description
§Plotly Static Image Export
A Rust library for exporting Plotly plots to static images using headless browsers via WebDriver.
This library provides a interface for converting Plotly plots provided as JSON values into various static image formats (PNG, JPEG, WEBP, SVG, PDF) using WebDriver and headless browsers.
§Features
- Async/Sync API Support: Support for both async and sync contexts
- Multiple Formats: Support for PNG, JPEG, WEBP, SVG, and PDF export
- Headless Rendering: Uses headless browsers for rendering
- WebDriver Support: Supports both Chrome (chromedriver) and Firefox (geckodriver)
- Configurable: Customizable dimensions, scale, and browser capabilities
- Offline Mode: Can work with offline bundled JavaScript libraries
- Automatic Management: Handles WebDriver process lifecycle and cleanup
- Parallelism: Designed for use in parallel environments (tests, etc.)
- Logging Support: Integrated logging with
env_logger
support
§Quick Start
// This example requires a WebDriver-compatible browser (Chrome/Firefox).
// It cannot be run as a doc test.
use plotly_static::{StaticExporterBuilder, ImageFormat};
use serde_json::json;
use std::path::Path;
// Create a simple plot
let plot = json!({
"data": [{
"type": "scatter",
"x": [1, 2, 3, 4],
"y": [10, 11, 12, 13]
}],
"layout": {
"title": "Simple Scatter Plot"
}
});
// Build and use StaticExporter
let mut exporter = StaticExporterBuilder::default()
.build()
.expect("Failed to build StaticExporter");
// Export to PNG
exporter.write_fig(
Path::new("my_plot"),
&plot,
ImageFormat::PNG,
800,
600,
1.0
).expect("Failed to export plot");
§Features and Dependencies
§Required Features
You must enable one of the following features:
chromedriver
: Use Chrome/Chromium for renderinggeckodriver
: Use Firefox for rendering
§Optional Features
webdriver_download
: Automatically download WebDriver binaries at build time
§Example Cargo.toml
[dependencies]
plotly_static = { version = "0.1", features = ["chromedriver", "webdriver_download"] }
§Async Support
The library supports async operations. To use the async API you need to call
build_async
instead of build
on the StaticExporterBuilder
. This will
return an AsyncStaticExporter
instance where the write_fig
and
write_to_string
methods are async.
use plotly_static::StaticExporterBuilder;
let exporter = StaticExporterBuilder::default()
.build_async()
.expect("Failed to build AsyncStaticExporter");
Never use the sync
API in async contexts. The sync
API wraps the async
API and uses a tokio::runtime::Runtime
instance internally. Using the
sync
API in an async context will cause runtime errors such as e.g.,
“Cannot drop a runtime in a context where blocking is not allowed. This
happens when a runtime is dropped from within an asynchronous context.” or
similar ones.
§Advanced Usage
§Custom Configuration
// This example requires a running WebDriver (chromedriver/geckodriver) and a browser.
// It cannot be run as a doc test.
use plotly_static::StaticExporterBuilder;
let exporter = StaticExporterBuilder::default()
.webdriver_port(4444)
.webdriver_url("http://localhost")
.spawn_webdriver(true)
.offline_mode(true)
.webdriver_browser_caps(vec![
"--headless".to_string(),
"--no-sandbox".to_string(),
"--disable-gpu".to_string(),
])
.build()
.expect("Failed to build StaticExporter");
§Browser Binary Configuration
You can specify custom browser binaries using environment variables:
# For Chrome/Chromium
export BROWSER_PATH="/path/to/chrome"
# For Firefox
export BROWSER_PATH="/path/to/firefox"
The library will automatically use these binaries when creating WebDriver sessions.
§String Export
// This example requires a running WebDriver (chromedriver/geckodriver) and a browser.
// It cannot be run as a doc test.
use plotly_static::{StaticExporterBuilder, ImageFormat};
use serde_json::json;
let plot = json!({
"data": [{"type": "scatter", "x": [1,2,3], "y": [4,5,6]}],
"layout": {}
});
let mut exporter = StaticExporterBuilder::default()
.build()
.expect("Failed to build StaticExporter");
let svg_data = exporter.write_to_string(
&plot,
ImageFormat::SVG,
800,
600,
1.0
).expect("Failed to export plot");
// svg_data contains SVG markup that can be embedded in HTML
§Logging Support
The library supports logging via the log
crate. Enable it with
env_logger
:
use plotly_static::StaticExporterBuilder;
// Initialize logging (typically done once at the start of your application)
env_logger::init();
// Set log level via environment variable
// RUST_LOG=debug cargo run
let mut exporter = StaticExporterBuilder::default()
.build()
.expect("Failed to build StaticExporter");
§Parallel Usage
The library is designed to work safely in parallel environments:
use plotly_static::{StaticExporterBuilder, ImageFormat};
use std::sync::atomic::{AtomicU32, Ordering};
// Generate unique ports for parallel usage
static PORT_COUNTER: AtomicU32 = AtomicU32::new(4444);
fn get_unique_port() -> u32 {
PORT_COUNTER.fetch_add(1, Ordering::SeqCst)
}
// Each thread/process should use a unique port
let mut exporter = StaticExporterBuilder::default()
.webdriver_port(get_unique_port())
.build()
.expect("Failed to build StaticExporter");
§WebDriver Management
The library automatically manages WebDriver processes:
- Automatic Detection: Detects if WebDriver is already running on the specified port
- Process Spawning: Automatically spawns WebDriver if not already running
- Connection Reuse: Reuses existing WebDriver sessions when possible
- External Sessions: Can connect to externally managed WebDriver sessions
Due to the underlying WebDriver implementation, the library cannot
automatically close WebDriver processes when StaticExporter
is dropped.
You must call close
manually to ensure proper cleanup.
§WebDriver Configuration
Set the WEBDRIVER_PATH
environment variable to specify a custom WebDriver
binary location (should point to the full executable path):
export WEBDRIVER_PATH=/path/to/chromedriver
cargo run
Or use the webdriver_download
feature for automatic download at build
time.
§Error Handling
The library uses anyhow::Result
for error handling. Common errors include:
- WebDriver not available or not running
- Invalid Plotly JSON format
- File system errors
- Browser rendering errors
§Browser Support
- Chrome/Chromium: Full support via chromedriver
- Firefox: Full support via geckodriver
- Safari: Not currently supported
- Edge: Not currently supported
§Performance Considerations
- Reuse Exporters: Reuse
StaticExporter
instances for multiple exports - Parallel Usage: Use unique ports for parallel operations
- WebDriver Reuse: The library automatically reuses WebDriver sessions when possible
§Comparison with Kaleido
- No custom Chromium/Chrome external dependency: Uses standard WebDriver instead of proprietary Kaleido
- Better Browser Support: Works with any WebDriver-compatible browser: Chrome/Chromium,Firefox,Brave
- Extensible: Easy to control browser capabilities and customize the StaticExporter instance
§Limitations
- Requires a WebDriver-compatible browser
- PDF export uses browser JavaScript
html2pdf
(not native Plotly PDF) - EPS is no longer supported and will be removed
- Slightly slower than Kaleido
§License
MIT License - see LICENSE file for details.
Structs§
- Async
Static Exporter - Async StaticExporter for async contexts. Keeps the same API as the sync StaticExporter for compatibility.
- Static
Exporter - Synchronous exporter for exporting Plotly plots to static images.
- Static
Exporter Builder - Builder for configuring and creating a
StaticExporter
instance.
Enums§
- Image
Format - Supported image formats for static image export.