"""Export utilities for saving visualizations in various formats.
This module provides functions to export visualizations to different formats
including high-resolution images, PDFs, and web-ready formats.
"""
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from matplotlib.figure import Figure
import plotly.graph_objects as go
[docs]
def save_for_publication(
fig: Figure,
filename: str,
width: float = 7,
height: float = 5,
dpi: int = 600,
) -> str:
"""Save figure with publication-quality settings.
Exports a figure with settings optimized for academic publication
or professional reports.
Args:
fig: Matplotlib figure
filename: Output filename (without extension)
width: Figure width in inches
height: Figure height in inches
dpi: Resolution (600 for print quality)
Returns:
Path to saved PDF file
Examples:
>>> fig, ax = plt.subplots()
>>> ax.plot([1, 2, 3], [1, 4, 2])
>>> save_for_publication(fig, "figure_1")
'figure_1.pdf'
"""
# Resize figure to exact dimensions
fig.set_size_inches(width, height)
# Save as PDF (vector format preferred for publication)
output_path = f"{filename}.pdf"
fig.savefig(
output_path,
format="pdf",
dpi=dpi,
bbox_inches="tight",
transparent=False,
metadata={
"Title": filename,
"Producer": "Ergodic Insurance Analysis",
},
)
# Also save high-res PNG for review
fig.savefig(
f"{filename}.png",
format="png",
dpi=dpi,
bbox_inches="tight",
transparent=False,
)
return output_path
[docs]
def save_for_presentation(
fig: Union[Figure, go.Figure],
filename: str,
width: int = 1920,
height: int = 1080,
) -> str:
"""Save figure optimized for presentations.
Exports a figure with settings optimized for PowerPoint or
other presentation software.
Args:
fig: Matplotlib or Plotly figure
filename: Output filename (without extension)
width: Width in pixels
height: Height in pixels
Returns:
Path to saved file
Examples:
>>> fig, ax = plt.subplots()
>>> ax.plot([1, 2, 3], [1, 4, 2])
>>> save_for_presentation(fig, "slide_1")
'slide_1.png'
"""
output_path = f"{filename}.png"
if isinstance(fig, Figure):
# Calculate DPI to achieve desired pixel dimensions
fig_width, fig_height = fig.get_size_inches()
dpi_x = width / fig_width
dpi_y = height / fig_height
dpi = min(dpi_x, dpi_y)
fig.savefig(
output_path,
format="png",
dpi=dpi,
bbox_inches="tight",
transparent=True, # Transparent for slide backgrounds
)
elif isinstance(fig, go.Figure):
try:
fig.write_image(
output_path,
width=width,
height=height,
scale=1,
)
except Exception as e:
print(f"Warning: Could not save plotly figure: {e}")
print("Install kaleido for static image export: pip install kaleido")
# Fallback to HTML
output_path = f"{filename}.html"
fig.write_html(output_path)
return output_path
[docs]
def save_for_web(
fig: Union[Figure, go.Figure],
filename: str,
optimize: bool = True,
) -> Dict[str, str]:
"""Save figure optimized for web display.
Creates web-optimized versions of the figure including responsive
formats and multiple resolutions.
Args:
fig: Matplotlib or Plotly figure
filename: Base filename (without extension)
optimize: Whether to optimize file sizes
Returns:
Dictionary of format to file path mappings
Examples:
>>> fig, ax = plt.subplots()
>>> ax.plot([1, 2, 3], [1, 4, 2])
>>> files = save_for_web(fig, "chart")
>>> print(files)
{'thumbnail': 'chart_thumb.png', 'full': 'chart.png', 'svg': 'chart.svg'}
"""
saved_files = {}
if isinstance(fig, Figure):
# Save thumbnail (low res for quick loading)
thumb_path = f"{filename}_thumb.png"
fig.savefig(thumb_path, dpi=72, bbox_inches="tight")
saved_files["thumbnail"] = thumb_path
# Save full resolution PNG
full_path = f"{filename}.png"
fig.savefig(full_path, dpi=150, bbox_inches="tight")
saved_files["full"] = full_path
# Save SVG for scalable graphics
svg_path = f"{filename}.svg"
fig.savefig(svg_path, format="svg", bbox_inches="tight")
saved_files["svg"] = svg_path
elif isinstance(fig, go.Figure):
# Save interactive HTML
html_path = f"{filename}.html"
fig.write_html(
html_path,
include_plotlyjs="cdn", # Use CDN for smaller file
config={"displayModeBar": False} if optimize else None,
)
saved_files["html"] = html_path
# Try to save static versions
try:
# Thumbnail
thumb_path = f"{filename}_thumb.png"
fig.write_image(thumb_path, width=400, height=300)
saved_files["thumbnail"] = thumb_path
# Full size
full_path = f"{filename}.png"
fig.write_image(full_path, width=1200, height=800)
saved_files["full"] = full_path
except Exception:
pass # Kaleido not installed
return saved_files
[docs]
def batch_export(
figures: Dict[str, Union[Figure, go.Figure]],
output_dir: str,
formats: Optional[List[str]] = None,
dpi: int = 300,
) -> Dict[str, List[str]]:
"""Export multiple figures in batch.
Saves multiple figures to a directory with consistent settings.
Args:
figures: Dictionary mapping names to figures
output_dir: Output directory path
formats: List of formats to save each figure
dpi: Resolution for raster formats
Returns:
Dictionary mapping figure names to lists of saved files
Examples:
>>> fig1, ax1 = plt.subplots()
>>> fig2, ax2 = plt.subplots()
>>> figures = {"chart1": fig1, "chart2": fig2}
>>> batch_export(figures, "output/", formats=["png"])
"""
if formats is None:
formats = ["png", "pdf"]
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
all_saved = {}
for name, fig in figures.items():
output_base = output_path / name
saved = save_figure(
fig,
str(output_base),
dpi=dpi,
formats=formats,
)
all_saved[name] = saved
return all_saved