Visualization & Export - Black-Lights/planetscope-py GitHub Wiki

Visualization & Export

PlanetScope-py provides enhanced visualization and export capabilities with coordinate system fixes, increased scene footprint limits, and one-line functions for rapid visualization generation.

Enhanced Features

Fixed coordinate system display - No more mirrored/flipped maps
Increased scene footprint limits - 150+ default (up to 1000+)
One-line visualization functions - Individual plot generation
Enhanced ROI clipping - Proper polygon-shaped outputs
Dynamic histogram bins - Automatic bin calculation
Robust GeoTIFF export - With QGIS styling and coordinate fixes

Quick Start

Ultra-Simple Visualization (1-line)

from planetscope_py import quick_planet_analysis

# Complete analysis with enhanced visualization
result = quick_planet_analysis(milan_roi, "last_month")
# Automatically creates 4-panel summary plot with coordinate fixes

One-Line Individual Plots

from planetscope_py import plot_density_map_only, plot_footprints_only, export_geotiff_only

# Just density map (coordinate-corrected)
fig = plot_density_map_only(milan_roi, "last_month", "density.png")

# Just scene footprints (enhanced limits)
fig = plot_footprints_only(milan_roi, "last_month", max_scenes=500)

# Just GeoTIFF export (with QML styling)
success = export_geotiff_only(milan_roi, "last_month", "output.tif")

Enhanced Summary Plot

Four-Panel Layout with Fixes

The enhanced create_summary_plot() generates a comprehensive visualization with coordinate system fixes:

  1. Density Map: Spatial distribution with corrected orientation
  2. Density Distribution: Histogram with dynamic bins
  3. Statistics Summary: Enhanced metrics table
  4. Scene Footprints: Scene boundaries with increased limits (150+)
from planetscope_py.visualization import DensityVisualizer

result = quick_planet_analysis(milan_roi, "last_month")

visualizer = DensityVisualizer()
fig = visualizer.create_summary_plot(
    density_result=result['density_result'],
    roi_polygon=milan_roi,
    save_path="enhanced_summary.png",
    max_scenes_footprint=300,  # Enhanced: increased from 50
    show_plot=True  # Fixed: proper notebook display
)

Enhanced Customization

# Advanced options with coordinate fixes
fig = visualizer.create_summary_plot(
    density_result=result['density_result'],
    roi_polygon=roi,
    scene_polygons=result['scene_polygons'],
    save_path="custom_analysis.png",
    clip_to_roi=True,  # Enhanced: proper polygon clipping
    max_scenes_footprint=500,  # Enhanced: up to 1000+
    show_plot=True
)

Individual Plot Functions

Density Map Only

from planetscope_py import plot_density_map_only

# One-line density map with coordinate fixes
fig = plot_density_map_only(
    milan_roi, "last_month", 
    save_path="density.png",
    resolution=30,
    clip_to_roi=True
)

Scene Footprints Only

from planetscope_py import plot_footprints_only

# Enhanced footprint plot with increased limits
fig = plot_footprints_only(
    milan_roi, "last_month",
    save_path="footprints.png", 
    max_scenes=500  # Enhanced: up to 1000+
)

Histogram Only

from planetscope_py import plot_histogram_only

# Dynamic histogram with proper bins
fig = plot_histogram_only(
    milan_roi, "last_month",
    save_path="histogram.png",
    clip_to_roi=True
)

Enhanced GeoTIFF Export

One-Line Export with Fixes

from planetscope_py import export_geotiff_only

# Enhanced export with coordinate fixes
success = export_geotiff_only(
    milan_roi, "last_month", 
    output_path="density.tif",
    clip_to_roi=True
)

# Automatically creates:
# - density.tif (GeoTIFF with coordinate fixes)
# - density.qml (QGIS style file)

Enhanced File Properties

The exported GeoTIFF includes:

  • Coordinate System: Fixed orientation and proper CRS handling
  • Spatial Reference: WGS84 (EPSG:4326) with PROJ error handling
  • Data Type: 32-bit floating point
  • NoData Value: -9999 for areas outside ROI
  • Compression: LZW compression for smaller files
  • Enhanced Metadata: Method, resolution, coordinate fixes applied

QGIS Integration with Enhanced Styling

# Advanced export with custom styling
from planetscope_py.visualization import DensityVisualizer

result = quick_planet_analysis(milan_roi, "last_month")

visualizer = DensityVisualizer()
visualizer.export_density_geotiff_with_style(
    density_result=result['density_result'],
    output_path="enhanced_density.tif",
    roi_polygon=milan_roi,
    clip_to_roi=True,  # Enhanced: proper polygon clipping
    colormap="viridis"
)

Advanced Visualization

Access from Analysis Results

# Use enhanced visualization functions with results
result = quick_planet_analysis(milan_roi, "last_month")

from planetscope_py.visualization import plot_density_only, plot_footprints_only

# Individual plots from results (coordinate-corrected)
plot_density_only(result['density_result'], milan_roi, "density.png")
plot_footprints_only(result['scene_polygons'], milan_roi, "footprints.png", max_scenes=300)

Enhanced Statistical Plots

# Enhanced histogram with dynamic bins
from planetscope_py.visualization import DensityVisualizer

visualizer = DensityVisualizer()
fig = visualizer.plot_density_histogram(
    density_result=result['density_result'],
    roi_polygon=milan_roi,
    clip_to_roi=True,  # Enhanced: ROI clipping
    bins=None  # Enhanced: automatic bin calculation
)

Comparison Visualizations

# Enhanced method comparison
methods = ['rasterization', 'vector_overlay']
results = {}

for method in methods:
    results[method] = quick_planet_analysis(
        milan_roi, "last_month", 
        method=method,
        max_scenes_footprint=200
    )

# Compare with coordinate fixes
fig, axes = plt.subplots(1, len(methods), figsize=(15, 6))
for i, (method, result) in enumerate(results.items()):
    # Enhanced visualization with coordinate fixes
    plot_density_only(result['density_result'], milan_roi, show_plot=False)

Enhanced Export Formats

Robust GeoTIFF Export

# Enhanced export with error handling
def robust_export(density_result, output_path, roi_polygon=None):
    """Enhanced export with coordinate fixes and error handling."""
    from planetscope_py.workflows import export_density_geotiff_robust
    
    success = export_density_geotiff_robust(
        density_result, output_path,
        roi_polygon=roi_polygon,
        clip_to_roi=True
    )
    
    if success:
        print(f"Enhanced GeoTIFF exported: {output_path}")
        print(f"QML style file: {output_path.replace('.tif', '.qml')}")
    
    return success

Enhanced Metadata Export

# Export enhanced statistics
import pandas as pd

result = quick_planet_analysis(milan_roi, "last_month")

# Enhanced statistics DataFrame
stats_df = pd.DataFrame([{
    'method': 'enhanced_rasterization',
    'coordinate_fixes_applied': True,
    'resolution_m': result['summary']['analysis_resolution_m'],
    'scenes_found': result['scenes_found'],
    'mean_density': result['summary']['mean_density'],
    'max_density': result['summary']['max_density'],
    'computation_time_s': result['summary']['computation_time_s'],
    'max_scenes_displayed': result['summary']['max_scenes_displayed']
}])

stats_df.to_csv('enhanced_analysis_stats.csv', index=False)

Batch Visualization

Enhanced Batch Processing

from planetscope_py.visualization import batch_plot_generation

# Enhanced batch visualization with increased limits
results_list = [result1, result2, result3]
roi_list = [roi1, roi2, roi3]

plot_paths = batch_plot_generation(
    results_list, roi_list,
    output_dir="./enhanced_batch_plots",
    max_scenes_per_plot=300,  # Enhanced: increased from 50
    clip_to_roi=True,
    coordinate_fixes=True
)

Quality Control

Enhanced Validation

# Enhanced validation with coordinate system checks
def validate_enhanced_results(result, milan_roi):
    """Validate results with coordinate system checks."""
    
    # Check coordinate system fixes
    if hasattr(result['density_result'], 'coordinate_fixes_applied'):
        print("✓ Coordinate system fixes applied")
    
    # Check scene footprint limits
    scenes_displayed = result['summary'].get('max_scenes_displayed', 0)
    if scenes_displayed >= 150:
        print(f"✓ Enhanced scene limits: {scenes_displayed} scenes")
    
    # Check ROI clipping
    if result['summary'].get('coordinate_system_corrected', False):
        print("✓ Enhanced ROI clipping applied")
    
    return True

# Validate results
validate_enhanced_results(result, milan_roi)

Performance Tips

Enhanced Performance Guidelines

Visualization Type Enhanced Method Performance
Quick summary quick_planet_analysis() 1-line execution
Individual plots One-line functions Optimized rendering
Large scene counts max_scenes=1000 Enhanced limits
High resolution Coordinate fixes Corrected display
Batch processing Enhanced batch functions Parallel processing

Memory Optimization

# Enhanced memory-efficient visualization
result = quick_planet_analysis(
    large_roi, "last_month",
    resolution=100.0,  # Coarser resolution for large areas
    max_scenes_footprint=300,  # Reasonable scene limit
    clip_to_roi=True  # Enhanced: reduce memory usage
)

Troubleshooting

Common Issues and Enhanced Solutions

# Issue: Coordinate system display problems
# Solution: Enhanced coordinate fixes are automatic

# Issue: Too many scenes to display
# Solution: Enhanced scene limits (up to 1000+)
fig = plot_footprints_only(roi, "last_month", max_scenes=1000)

# Issue: PROJ database errors
# Solution: Enhanced error handling in GeoTIFF export
success = export_geotiff_only(roi, "last_month", "output.tif")
# Automatically handles PROJ compatibility issues

# Issue: Histogram showing fixed ranges
# Solution: Enhanced dynamic bin calculation (automatic)

Configuration Reference

DensityVisualizer Configuration

from planetscope_py.visualization import DensityVisualizer

# Initialize with custom settings
visualizer = DensityVisualizer(
    figsize=(12, 8)                           # Figure size in inches (default: (12, 8))
)

# Matplotlib style configuration (automatic)
# plt.rcParams["figure.dpi"] = 100           # Display DPI (default: 100)
# plt.rcParams["savefig.dpi"] = 300          # Save DPI (default: 300)  
# plt.rcParams["font.size"] = 10             # Font size (default: 10)

Plot Method Parameters

# Density map configuration
density_options = {
    'roi_polygon': roi,                       # ROI polygon (optional)
    'title': 'Scene Density Map',            # Plot title (default: auto-generated)
    'colormap': 'viridis',                    # Colormap (default: 'viridis')
    'save_path': 'density.png',              # Save path (optional)
    'show_stats': True,                       # Show statistics (default: True)
    'clip_to_roi': True,                      # Clip to ROI (default: True)
    'show_plot': True                         # Display plot (default: True)
}

# Histogram configuration
histogram_options = {
    'bins': None,                             # Number of bins (default: auto-calculated)
    'title': 'Density Distribution',         # Plot title
    'save_path': 'histogram.png',            # Save path (optional)
    'clip_to_roi': True,                      # Clip data to ROI (default: True)
    'show_plot': True                         # Display plot (default: True)
}

# Scene footprints configuration
footprints_options = {
    'title': 'Scene Footprints',             # Plot title
    'max_scenes': 300,                        # Max scenes to display (default: 150)
    'save_path': 'footprints.png',           # Save path (optional)
    'show_intersecting_only': True,          # Only ROI-intersecting scenes (default: True)
    'show_all_if_requested': False,          # Show all if reasonable (default: False)
    'show_plot': True                         # Display plot (default: True)
}

# Summary plot configuration
summary_options = {
    'save_path': 'summary.png',              # Save path (optional)
    'clip_to_roi': True,                      # Clip outputs to ROI (default: True)
    'max_scenes_footprint': 300,             # Max scenes in footprint panel (default: 150)
    'show_plot': True                         # Display plot (default: True)
}

One-Line Function Parameters

# plot_density_map_only parameters
density_params = {
    'time_period': "last_month",              # Time period (default: "last_month")
    'save_path': None,                        # Save path (optional)
    'resolution': 30.0,                       # Grid resolution (default: 30.0)
    'cloud_cover_max': 0.2,                  # Max cloud cover (default: 0.2)
    'clip_to_roi': True,                      # Clip to ROI (default: True)
    'colormap': 'viridis'                     # Colormap (default: 'viridis')
}

# plot_footprints_only parameters
footprints_params = {
    'time_period': "last_month",              # Time period (default: "last_month")
    'save_path': None,                        # Save path (optional)
    'max_scenes': 300,                        # Max scenes (default: 300)
    'show_intersecting_only': True           # Only intersecting scenes (default: True)
}

# export_geotiff_only parameters
export_params = {
    'time_period': "last_month",              # Time period (default: "last_month")
    'output_path': "density.tif",            # Output path (default: "density.tif")
    'clip_to_roi': True,                      # Clip to ROI (default: True)
    'resolution': 30.0,                       # Grid resolution (default: 30.0)
    'colormap': 'viridis'                     # QML colormap (default: 'viridis')
}

GeoTIFF Export Configuration

# Enhanced GeoTIFF export options
export_config = {
    'output_path': 'density.tif',            # Output file path
    'roi_polygon': roi,                       # ROI for clipping (optional)
    'clip_to_roi': True,                      # Clip to ROI shape (default: True)
    'colormap': 'viridis',                    # QGIS style colormap (default: 'viridis')
    'compress': 'lzw',                        # Compression method (default: 'lzw')
    'no_data_value': -9999.0,                # NoData value (default: -9999.0)
    'create_qml': True                        # Create QML style file (default: True)
}

# File properties (automatic)
file_properties = {
    'driver': 'GTiff',                        # File format
    'dtype': 'float32',                       # Data type
    'crs': 'EPSG:4326',                      # Coordinate system (with fallbacks)
    'tiled': True,                           # Tiled format for large files
    'blocksize': 512                         # Tile size in pixels
}

Batch Processing Configuration

# batch_plot_generation parameters
batch_config = {
    'output_dir': "./batch_plots",            # Output directory (default: "./batch_plots")
    'max_scenes_per_plot': 300,               # Max scenes per plot (default: 200)
    'clip_to_roi': True,                      # Clip all outputs (default: True)
    'coordinate_fixes': True,                 # Apply coordinate fixes (default: True)
    'parallel_processing': True               # Parallel generation (default: True)
}

Configuration Tables

Visualization Parameters

Parameter Type Default Options Description
figsize tuple (12, 8) Any tuple Figure size in inches
colormap str "viridis" matplotlib colormaps Color scheme
title str Auto Any string Plot title
save_path str None File path Save location
show_stats bool True True/False Display statistics
clip_to_roi bool True True/False Clip to ROI shape
show_plot bool True True/False Display in notebook
max_scenes int 150-300 1-1000+ Max scenes in footprint plots

Export Parameters

Parameter Type Default Options Description
output_path str Required File path Output file location
clip_to_roi bool True True/False Clip to ROI polygon
colormap str "viridis" matplotlib colormaps QML style colormap
compress str "lzw" lzw/deflate/none Compression method
no_data_value float -9999.0 Any float NoData value
create_qml bool True True/False Create QGIS style file

Enhanced Scene Limits

Function Default Limit Maximum Enhanced Feature
plot_footprints_only 300 1000+ Increased from 50
create_summary_plot 150 1000+ Configurable limits
batch_plot_generation 200 1000+ Per-plot limits
Scene discovery No limit API limits All available scenes

Time Period Options

Format Example Description
Shortcuts "last_month" Previous 30 days
Shortcuts "last_3_months" Previous 90 days
Date range "2025-01-01/2025-01-31" Custom date range
Tuple ("2025-01-01", "2025-01-31") Date tuple

Error Handling Configuration

# Error handling options (automatic)
error_config = {
    'proj_fallback': True,                    # Handle PROJ errors (default: True)
    'coordinate_validation': True,            # Validate coordinates (default: True)
    'memory_monitoring': True,                # Monitor memory usage (default: True)
    'geometry_validation': True,              # Validate geometries (default: True)
    'graceful_degradation': True              # Fallback options (default: True)
}

Next Steps