QWARD Architecture¶
This document outlines the architecture of the QWARD library and provides usage examples.
Overview¶
QWARD is designed with a clear separation between execution and analysis components. The architecture consists of four main components and follows the Strategy pattern for extensible metric calculation, enhanced with Pydantic-based schema validation for data integrity and type safety.
Simplified Architecture¶
This simplified view shows the core Strategy pattern implementation in QWARD, focusing on the essential components and their relationships.
classDiagram
%% Simplified Strategy Pattern for QWARD with Schema Validation
class Scanner {
<<Context>>
+circuit: QuantumCircuit
+calculators: List[MetricCalculator]
+add(strategy, **kwargs) Scanner
+scan(include_all_pre_runtime) ScanResult
+calculate_metrics() Dict[str, DataFrame]
}
class ScanResult {
<<Value Object>>
+summary() ScanResult
+visualize() ScanResult
+to_dict() Dict[str, DataFrame]
}
class MetricCalculator {
<<Strategy Interface>>
+get_metrics() BaseModel
}
class QiskitMetrics {
<<Concrete Strategy>>
+circuit: QuantumCircuit
+get_metrics() QiskitMetricsSchema
+is_ready() bool
}
class ComplexityMetrics {
<<Concrete Strategy>>
+get_metrics() ComplexityMetricsSchema
}
class CircuitPerformanceMetrics {
<<Concrete Strategy>>
+get_metrics() CircuitPerformanceSchema
}
class SchemaModule {
<<Validation Layer>>
+QiskitMetricsSchema
+ComplexityMetricsSchema
+CircuitPerformanceSchema
+validate_data()
+generate_json_schema()
+to_flat_dict()
}
%% Strategy Pattern Relationships
Scanner --> MetricCalculator : uses strategies
Scanner --> ScanResult : produces
%% Strategy Interface Implementation
MetricCalculator <|.. QiskitMetrics : implements
MetricCalculator <|.. ComplexityMetrics : implements
MetricCalculator <|.. CircuitPerformanceMetrics : implements
%% Schema Integration
QiskitMetrics --> SchemaModule : validates with
ComplexityMetrics --> SchemaModule : validates with
CircuitPerformanceMetrics --> SchemaModule : validates with
%% Pattern Notes
note for Scanner "Context: Orchestrates metric calculation and returns dictionary of DataFrames"
note for MetricCalculator "Strategy Interface: Common interface returning validated schema objects"
note for QiskitMetrics "Returns validated Qiskit-native metrics with type safety"
note for ComplexityMetrics "Returns validated complexity analysis metrics with constraints"
note for CircuitPerformanceMetrics "Returns validated execution performance metrics with cross-field validation"
note for SchemaModule "Pydantic-based validation with automatic type checking and JSON schema generation"
Key Points¶
Scanner (Context): Maintains metric calculators and delegates calculation work
MetricCalculator (Interface): Defines common interface returning validated schema objects
Concrete Strategies: Each implements different metric calculation algorithms with validation
Schema Validation: Pydantic-based data validation ensures type safety and constraint checking
Unified API: All metric classes use
get_metrics()to return schema objects directlyScanner Integration: Scanner automatically calls
to_flat_dict()for DataFrame conversionPre-runtime helper:
get_all_pre_runtime_strategies()provides all pre-runtime strategy classesStrategy Pattern Benefits: Runtime strategy switching, extensibility, separation of concerns
Schema-Based Data Validation¶
QWARD includes comprehensive schema-based validation using Pydantic, providing:
classDiagram
%% Schema Validation Architecture
class BaseModel {
<<Pydantic Base>>
+model_validate()
+model_json_schema()
+model_dump()
+to_flat_dict()
}
class QiskitMetricsSchema {
+basic_metrics: BasicMetricsSchema
+instruction_metrics: InstructionMetricsSchema
+scheduling_metrics: SchedulingMetricsSchema
+to_flat_dict() Dict[str, Any]
+from_flat_dict() QiskitMetricsSchema
}
class ComplexityMetricsSchema {
+gate_based_metrics: GateBasedMetricsSchema
+entanglement_metrics: EntanglementMetricsSchema
+standardized_metrics: StandardizedMetricsSchema
+advanced_metrics: AdvancedMetricsSchema
+derived_metrics: DerivedMetricsSchema
+to_flat_dict() Dict[str, Any]
+from_flat_dict() ComplexityMetricsSchema
}
class CircuitPerformanceSchema {
+success_metrics: SuccessMetricsSchema
+statistical_metrics: StatisticalMetricsSchema
+validate_error_rate()
+validate_successful_shots()
+to_flat_dict() Dict[str, Any]
}
%% Inheritance
BaseModel <|-- QiskitMetricsSchema
BaseModel <|-- ComplexityMetricsSchema
BaseModel <|-- CircuitPerformanceSchema
%% Validation Features
note for QiskitMetricsSchema "Validates circuit metrics with type checking and constraints"
note for ComplexityMetricsSchema "Validates complexity metrics with range and cross-field validation"
note for CircuitPerformanceSchema "Validates performance metrics with rate consistency checks and statistical constraints"
Schema Benefits¶
Type Safety: Automatic type checking and validation
Constraint Validation: Range checks, cross-field validation, and business rules
IDE Support: Full autocomplete and type hints
API Documentation: Automatic JSON schema generation
DataFrame Compatibility: Easy conversion to/from flat dictionaries via
to_flat_dict()Error Prevention: Catch data inconsistencies early
Detailed Architecture¶
The complete architecture with all implementation details:
classDiagram
%% Complete QWARD Architecture with Schema Validation
class Scanner {
<<Context>>
+circuit: QuantumCircuit
+job: Union[AerJob, QiskitJob]
+strategies: List[MetricCalculator]
+__init__(circuit, job, strategies)
+add_strategy(metric_calculator)
+add(strategy, **kwargs) Scanner
+scan(include_all_pre_runtime) ScanResult
+calculate_metrics() Dict[str, DataFrame]
+set_circuit(circuit)
+set_job(job)
}
class ScanResult {
<<Value Object>>
+summary() ScanResult
+visualize() ScanResult
+to_dict() Dict[str, DataFrame]
}
class MetricCalculator {
<<Strategy Interface>>
#circuit: QuantumCircuit
#_metric_type: MetricsType
#_id: MetricsId
+__init__(circuit)
+metric_type: MetricsType
+id: MetricsId
+name: str
+circuit: QuantumCircuit
+_get_metric_type()* MetricsType
+_get_metric_id()* MetricsId
+is_ready()* bool
+get_metrics()* BaseModel
+_ensure_schemas_available()
}
class QiskitMetrics {
<<Concrete Strategy>>
+__init__(circuit)
+_get_metric_type() MetricsType
+_get_metric_id() MetricsId
+is_ready() bool
+get_metrics() QiskitMetricsSchema
+get_basic_metrics() BasicMetricsSchema
+get_instruction_metrics() InstructionMetricsSchema
+get_scheduling_metrics() SchedulingMetricsSchema
}
class ComplexityMetrics {
<<Concrete Strategy>>
+__init__(circuit)
+_get_metric_type() MetricsType
+_get_metric_id() MetricsId
+is_ready() bool
+get_metrics() ComplexityMetricsSchema
+get_gate_based_metrics() GateBasedMetricsSchema
+get_entanglement_metrics() EntanglementMetricsSchema
+get_standardized_metrics() StandardizedMetricsSchema
+get_advanced_metrics() AdvancedMetricsSchema
+get_derived_metrics() DerivedMetricsSchema
}
class CircuitPerformanceMetrics {
<<Concrete Strategy>>
#_job: Optional[JobType]
#_jobs: List[JobType]
#success_criteria: Callable[[str], bool]
+__init__(circuit, job, jobs, success_criteria)
+_get_metric_type() MetricsType
+_get_metric_id() MetricsId
+is_ready() bool
+get_metrics() CircuitPerformanceSchema
+get_success_metrics() SuccessMetricsSchema
+get_statistical_metrics() StatisticalMetricsSchema
+add_job(job)
+_default_success_criteria() Callable[[str], bool]
}
class MetricsType {
<<enumeration>>
PRE_RUNTIME
POST_RUNTIME
}
class MetricsId {
<<enumeration>>
QISKIT
COMPLEXITY
CIRCUIT_PERFORMANCE
}
%% Strategy Pattern Relationships
Scanner --> MetricCalculator : uses strategies
Scanner --> ScanResult : produces
%% Strategy Interface Implementation
MetricCalculator <|.. QiskitMetrics : implements
MetricCalculator <|.. ComplexityMetrics : implements
MetricCalculator <|.. CircuitPerformanceMetrics : implements
%% Strategy Interface Dependencies
MetricCalculator --> MetricsType : defines type
MetricCalculator --> MetricsId : defines identifier
%% Notes about Enhanced Architecture
note for Scanner "Context: Maintains references to metric calculators and delegates work. Returns dictionary of DataFrames for analysis."
note for ScanResult "Fluent wrapper around calculated metric DataFrames."
note for MetricCalculator "Strategy Interface: Common interface returning validated schema objects. Includes schema availability checking."
note for QiskitMetrics "Concrete Strategy: Qiskit-native metrics with validated schema output"
note for ComplexityMetrics "Concrete Strategy: Comprehensive complexity analysis with validated schemas and constraint checking"
note for CircuitPerformanceMetrics "Concrete Strategy: Circuit performance analysis with validated schema output and custom criteria"
Folder Structure¶
The QWARD library is organized into the following folder structure:
/qward/
├── __init__.py # Main package initialization
├── scanner.py # Scanner class implementation
├── runtime/
│ └── __init__.py
├── metrics/
│ ├── __init__.py
│ ├── base_metric.py # Base MetricCalculator class
│ ├── types.py # MetricsType and MetricsId enums
│ ├── defaults.py # Default metric configurations│
│ ├── qiskit_metrics.py # QiskitMetrics implementation
│ ├── complexity_metrics.py # ComplexityMetrics implementation
│ ├── circuit_performance.py # CircuitPerformanceMetrics implementation
│ ├── behavioral_metrics.py # BehavioralMetrics implementation
│ ├── structural_metrics.py # StructuralMetrics implementation
│ ├── element_metrics.py # ElementMetrics implementation
│ └── quantum_specific_metrics.py # QuantumSpecificMetrics implementation
├── visualization/
│ ├── __init__.py
│ ├── base.py # VisualizationStrategy base class and PlotConfig
│ ├── visualizer.py # Unified Visualizer class
│ ├── qiskit_metrics_visualizer.py # QiskitVisualizer implementation
│ ├── complexity_metrics_visualizer.py # ComplexityVisualizer implementation
│ └── circuit_performance_visualizer.py # CircuitPerformanceVisualizer implementation
│ ├── behavioral_metrics_visualizer.py # BehavioralVisualizer implementation
│ ├── element_metrics_visualizer.py # StructuralVisualizer implementation
│ ├── quantum_specific_metrics_visualizer.py # ElementVisualizer implementation
│ └── structural_metrics_visualizer.py # QuantumSpecificVisualizer implementation
├── utils/
│ ├── __init__.py
│ ├── flatten.py # Utility for flattening nested lists
│ └── helpers.py # Utility functions
└── examples/
│ ├── __init__.py
│ ├── utils.py # Utilities for examples
│ ├── schema_demo.py # Schema validation demonstration
│ ├── circuit_performance_demo.py # Circuit performance metrics demonstration
│ ├── run_on_aer.ipynb # Example notebook for running on Aer simulator
│ ├── aer.py # Example Aer simulator usage
│ ├── example_visualizer.py # Comprehensive visualization examples
│ ├── visualization_demo.py # CircuitPerformanceVisualizer demo
│ ├── direct_strategy_example.py # Direct strategy usage examples
│ └── visualization_quickstart.py # Quick visualization example
└── schemas/ # Pydantic schema definitions
├── behavioral_metrics_schema.py
├── circuit_performance_schema.py
├── complexity_metrics_schema.py
├── element_metrics_schema.py
├── legacy_schemas.py
├── loc_metrics_schema.py
├── qiskit_metrics_schema.py
├── quantum_specific_metrics_schema.py
└── structural_metrics_schema.py
This structure provides a clean organization for the code, with:
Main Package: Core classes at the top level for easy imports
Runtime Module: Handles execution of quantum circuits
Metrics Module: Contains all metric implementations and schema definitions
Visualization Module: Contains all visualization strategies and unified visualizer
Utils Module: Helper functions and utilities
Examples Module: Working code examples demonstrating library usage including schema validation and visualization
Components¶
Scanner¶
The Scanner class is the main entry point for analyzing quantum circuits. It can be initialized with a quantum circuit, job, and an optional list of metric classes or instances. It allows users to add further metrics and calculate them, returning results as a dictionary of DataFrames for easy analysis.
MetricCalculator¶
The MetricCalculator class is an abstract base class that defines the interface for all metrics. It includes the circuit attribute, properties for metric type and ID, and abstract methods for metric calculation. All concrete implementations return validated schema objects directly through get_metrics(). Default metric classes can be obtained using the get_default_strategies() function from the qward.metrics.defaults module.
Schema Validation¶
The schema validation system provides:
Type Safety: Automatic validation of data types and constraints
Business Rules: Cross-field validation (e.g., error_rate = 1 - success_rate)
Range Validation: Ensures values are within expected bounds
Documentation: Automatic JSON schema generation for API documentation
IDE Support: Full autocomplete and type hints for better developer experience
QiskitMetrics¶
The QiskitMetrics class extracts metrics directly from QuantumCircuit objects, including basic metrics (depth, width, gate counts), instruction metrics (connectivity, factors), and scheduling metrics (timing information). It returns a validated QiskitMetricsSchema object with type-safe access to all metric categories.
ComplexityMetrics¶
The ComplexityMetrics class calculates comprehensive circuit complexity metrics based on research literature, including gate-based metrics, entanglement metrics, standardized metrics, advanced metrics, and derived metrics. All metrics are validated through a ComplexityMetricsSchema with appropriate constraints and cross-field validation.
CircuitPerformanceMetrics¶
The CircuitPerformanceMetrics class calculates performance metrics for quantum circuits, such as success rate and error rate. It supports both single job and multiple job analysis with customizable success criteria. The class returns a validated CircuitPerformanceSchema object with validation for both individual job metrics and aggregate statistics across multiple jobs.
ElementMetrics¶
The ElementMetrics class analyzes the fundamental building blocks of a quantum circuit, including gate usage, operator frequencies, and parameterized operations. It provides fine-grained insight into gate composition and operand interactions. All results are returned through a validated ElementMetricsSchema for safe and structured access.
StructuralMetrics¶
The StructuralMetrics class captures the architectural shape of a quantum circuit, including depth, width, layering structure, and graph-based connectivity. It measures topological and resource-oriented properties that reflect the circuit’s structural complexity. The class returns a validated StructuralMetricsSchema containing all structural indicators.
BehavioralMetrics¶
The BehavioralMetrics class evaluates how a circuit behaves during execution or simulation, analyzing state evolution, probability distributions, and interference patterns. It provides metrics that reflect the dynamic behavior of the algorithm rather than its static structure. All outputs are validated through a BehavioralMetricsSchema.
QuantumSpecificMetrics¶
The QuantumSpecificMetrics class computes metrics that capture uniquely quantum properties, such as entanglement, interference, non-classicality, and resource-theoretic indicators. These measures quantify the quantum nature and computational potential of a circuit. The class returns a validated QuantumSpecificMetricsSchema containing all quantum-specific metrics.
Usage Examples¶
Basic Circuit Analysis with Schema Validation¶
from qiskit import QuantumCircuit
from qward import Scanner
from qward.metrics import QiskitMetrics
# Create a quantum circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
# Create a scanner with the circuit
scanner = Scanner(circuit=circuit)
# Add a metric
scanner.add_strategy(QiskitMetrics(circuit))
# Calculate metrics (Scanner returns dictionary of DataFrames)
results = scanner.calculate_metrics()
# Use schema-based metrics directly
qiskit_metrics = QiskitMetrics(circuit)
metrics = qiskit_metrics.get_metrics() # Returns QiskitMetricsSchema
# Access validated data with full type safety
print(f"Circuit depth: {metrics.basic_metrics.depth}")
print(f"Gate count: {metrics.basic_metrics.size}")
print(f"Number of qubits: {metrics.basic_metrics.num_qubits}")
Comprehensive Analysis with Multiple Metrics¶
from qward import Scanner
from qward.metrics import QiskitMetrics, ComplexityMetrics, CircuitPerformanceMetrics
# Create a scanner with multiple metrics
scanner = Scanner(circuit=circuit)
scanner.add_strategy(QiskitMetrics(circuit))
scanner.add_strategy(ComplexityMetrics(circuit))
# For circuit performance, you need job execution results
if job: # Assuming you have a job from circuit execution
scanner.add_strategy(CircuitPerformanceMetrics(circuit, job=job))
# Calculate all metrics (returns dictionary of DataFrames)
results = scanner.calculate_metrics()
# Access schema-based metrics for detailed analysis
complexity_metrics = ComplexityMetrics(circuit)
complexity_schema = complexity_metrics.get_metrics()
print(f"Gate Count: {complexity_schema.gate_based_metrics.gate_count}")
print(f"Gate Density: {complexity_schema.standardized_metrics.gate_density}")
print(f"Parallelism Efficiency: {complexity_schema.advanced_metrics.parallelism_efficiency}")
Circuit Performance Analysis with Custom Criteria¶
from qward.metrics import CircuitPerformanceMetrics
# Define custom success criteria
def bell_state_success(result: str) -> bool:
clean_result = result.replace(" ", "")
return clean_result in ["0000", "1111"] # |00⟩ or |11⟩ states
# Create circuit performance metric with custom criteria
circuit_performance = CircuitPerformanceMetrics(
circuit=circuit,
job=job,
success_criteria=bell_state_success
)
# Get validated schema with automatic constraint checking
metrics = circuit_performance.get_metrics()
print(f"Success Rate: {metrics.success_metrics.success_rate:.3f}")
print(f"Error Rate: {metrics.success_metrics.error_rate:.3f}") # Automatically validated
Schema Validation and JSON Generation¶
from qward.metrics.schemas import ComplexityMetricsSchema
import json
# Generate JSON schema for API documentation
complexity_metrics = ComplexityMetrics(circuit)
schema_obj = complexity_metrics.get_metrics()
# Get JSON schema for documentation
json_schema = ComplexityMetricsSchema.model_json_schema()
print(json.dumps(json_schema, indent=2))
# Convert to flat dictionary for DataFrame compatibility
flat_dict = schema_obj.to_flat_dict()
print(f"Flattened metrics: {list(flat_dict.keys())}")
# Validate data integrity
try:
# This will raise ValidationError if data is invalid
validated_schema = ComplexityMetricsSchema.model_validate(schema_obj.model_dump())
print("✅ Data validation passed")
except Exception as e:
print(f"❌ Validation error: {e}")
Using Custom Metrics with Schema Support¶
from qward.metrics.base_metric import MetricCalculator
from qward.metrics.types import MetricsType, MetricsId
from qiskit import QuantumCircuit
from pydantic import BaseModel
class MyCustomMetricsSchema(BaseModel):
custom_complexity: float
circuit_signature: str
class MyCustomMetric(MetricCalculator):
def __init__(self, circuit: QuantumCircuit):
super().__init__(circuit)
def _get_metric_type(self) -> MetricsType:
return MetricsType.PRE_RUNTIME
def _get_metric_id(self) -> MetricsId:
return MetricsId.QISKIT # Or define a new ID
def is_ready(self) -> bool:
return self.circuit is not None
def get_metrics(self) -> MyCustomMetricsSchema:
# Custom metric calculation
custom_value = self.circuit.depth() * self.circuit.num_qubits
return MyCustomMetricsSchema(
custom_complexity=custom_value,
circuit_signature=f"{self.circuit.num_qubits}q_{self.circuit.depth()}d"
)
# Usage
scanner = Scanner(circuit=circuit)
scanner.add_strategy(MyCustomMetric(circuit))
results = scanner.calculate_metrics()
Best Practices¶
Circuit Analysis
Use the Scanner class for all circuit analysis
Add metrics before calculating results
Consider using multiple metrics for comprehensive analysis
All metrics return validated schema objects by default
Schema Usage
All metric classes return schema objects directly via
get_metrics()Take advantage of IDE autocomplete with schema objects
Use
to_flat_dict()when you need dictionary format for DataFramesLeverage JSON schema generation for API documentation
Execution
Handle job and result errors appropriately
Use appropriate Qiskit runtime services for backend execution
Validate success criteria for CircuitPerformanceMetrics metrics
Data Management
Use consistent naming conventions for analysis results
Schema validation ensures data integrity automatically
Scanner handles schema-to-DataFrame conversion seamlessly
Custom Metrics
Inherit from the MetricCalculator base class
Implement the required abstract methods
Return validated schema objects from
get_metrics()Document metric calculation methodology
Consider adding custom Pydantic schemas for validation
Performance
Schema validation adds minimal overhead but provides significant benefits
Scanner automatically handles
to_flat_dict()conversion for DataFramesAll validation happens at metric calculation time
Visualization System¶
QWARD includes a comprehensive visualization system for analyzing and presenting quantum circuit metrics. The visualization module follows a structured approach that integrates seamlessly with the metric calculation system and provides a modern, type-safe API.
New API Features (v0.9.0)¶
🎯 Type-Safe Constants System¶
Metricsconstants:Metrics.QISKIT,Metrics.COMPLEXITY,Metrics.CIRCUIT_PERFORMANCEPlotsconstants:Plots.QISKIT.CIRCUIT_STRUCTURE,Plots.COMPLEXITY.COMPLEXITY_RADAR, etc.IDE Autocompletion: Full IntelliSense support for all plot names
Error Prevention: Compile-time detection of typos in metric and plot names
🔍 Rich Plot Metadata System¶
Plot Descriptions: Detailed information about what each plot shows
Plot Types: Categorized as bar charts, radar charts, line plots, etc.
Dependencies: Information about required data columns
Categories: Organized by analysis type (structure, performance, complexity)
⚡ Granular Plot Control¶
Single Plot Generation:
generate_plot(metric, plot_name)Selected Plots:
generate_plots({metric: [plot1, plot2]})All Plots:
generate_plots({metric: None})Memory Efficient: Default
save=False, show=Falsefor batch processing
Architecture Overview¶
The visualization system is built on the following key components:
PlotConfig: A dataclass holding all plot appearance and saving configurations.VisualizationStrategy: An abstract base class for all visualizers with plot registry system. It handles common setup (output directory, styling viaPlotConfig) and provides utility methods likesave_plot/show_plot, data validation, and plot creation helpers. Subclasses must implement plot registry and new API methods.Individual Visualizers: Three concrete visualizers inheriting from
VisualizationStrategy:QiskitVisualizer: Visualizes circuit structure and instruction metrics (4 plots)ComplexityVisualizer: Visualizes complexity analysis with radar charts and efficiency metrics (3 plots)CircuitPerformanceVisualizer: Visualizes performance metrics with success rates, shot distributions, and aggregate summaries (3 plots)
Visualizer: A unified entry point that automatically detects available metrics and provides type-safe visualization capabilities.
classDiagram
class VisualizationStrategy {
<<abstract>>
+output_dir: str
+config: PlotConfig
+PLOT_REGISTRY: Dict[str, PlotMetadata]
+save_plot(fig, filename)
+show_plot(fig)
+get_available_plots()* List[str]
+get_plot_metadata(plot_name)* PlotMetadata
+generate_plot(plot_name, save, show)* Figure
+generate_plots(plot_names, save, show)* List[Figure]
+generate_all_plots(save, show) List[Figure]
+create_dashboard(save, show)*
+_validate_required_columns()
+_extract_metrics_from_columns()
+_create_bar_plot_with_labels()
+_setup_plot_axes()
+_finalize_plot()
}
class PlotConfig {
+figsize: Tuple[int, int]
+dpi: int
+style: str
+color_palette: List[str]
+save_format: str
+grid: bool
+alpha: float
+__post_init__()
}
class PlotMetadata {
+name: str
+method_name: str
+description: str
+plot_type: PlotType
+filename: str
+dependencies: List[str]
+category: str
}
class QiskitVisualizer {
+PLOT_REGISTRY: Dict[str, PlotMetadata]
+generate_plot(plot_name, save, show)
+get_available_plots() List[str]
+get_plot_metadata(plot_name) PlotMetadata
+plot_circuit_structure()
+plot_gate_distribution()
+plot_instruction_metrics()
+plot_circuit_summary()
+create_dashboard()
}
class ComplexityVisualizer {
+PLOT_REGISTRY: Dict[str, PlotMetadata]
+generate_plot(plot_name, save, show)
+get_available_plots() List[str]
+get_plot_metadata(plot_name) PlotMetadata
+plot_gate_based_metrics()
+plot_complexity_radar()
+plot_efficiency_metrics()
+create_dashboard()
}
class CircuitPerformanceVisualizer {
+PLOT_REGISTRY: Dict[str, PlotMetadata]
+generate_plot(plot_name, save, show)
+get_available_plots() List[str]
+get_plot_metadata(plot_name) PlotMetadata
+plot_success_error_comparison()
+plot_shot_distribution()
+plot_aggregate_summary()
+create_dashboard()
}
class Visualizer {
+scanner: Optional[Scanner]
+metrics_data: Dict[str, DataFrame]
+registered_strategies: Dict[str, Type[VisualizationStrategy]]
+get_available_plots() Dict[str, List[str]]
+get_plot_metadata(metric, plot_name) PlotMetadata
+generate_plot(metric, plot_name, save, show) Figure
+generate_plots(selections, save, show) Dict[str, List[Figure]]
+create_dashboard(save, show) Dict[str, Figure]
+register_strategy()
+get_available_metrics()
+get_metric_summary()
+print_available_metrics()
}
VisualizationStrategy <|-- QiskitVisualizer
VisualizationStrategy <|-- ComplexityVisualizer
VisualizationStrategy <|-- CircuitPerformanceVisualizer
VisualizationStrategy --> PlotConfig : uses
VisualizationStrategy --> PlotMetadata : defines
Visualizer --> VisualizationStrategy : manages
Visualizer --> Scanner : optional integration
note for VisualizationStrategy "Abstract base class with plot registry and metadata system"
note for QiskitVisualizer "4 plots: circuit_structure, gate_distribution, instruction_metrics, circuit_summary"
note for ComplexityVisualizer "3 plots: gate_based_metrics, complexity_radar, efficiency_metrics"
note for CircuitPerformanceVisualizer "3 plots: success_error_comparison, shot_distribution, aggregate_summary"
note for Visualizer "Unified entry point with type-safe constants and granular control"
Key Components¶
VisualizationStrategy¶
Abstract base class providing core visualization functionality with new API:
Output Management: Handles output directory creation and file path management
Plot Configuration: Integrates with
PlotConfigfor consistent stylingPlot Registry: Each visualizer defines a
PLOT_REGISTRYwith rich metadataNew API Methods:
get_available_plots(),get_plot_metadata(),generate_plot(),generate_plots(),generate_all_plots()Common Utilities: Provides reusable methods for data validation, plot creation, and formatting
Save/Show Operations: Provides
save_plot()andshow_plot()methodsAbstract Interface: Defines
create_dashboard()method that subclasses must implement
Individual Visualizers¶
Three specialized visualizers for different metric types with plot registries:
QiskitVisualizer: Handles circuit structure and instruction analysis (4 plots)circuit_structure: Basic circuit metrics (depth, width, size, qubits)gate_distribution: Gate type analysis and instruction distributioninstruction_metrics: Instruction-related metrics and connectivity analysiscircuit_summary: Derived metrics and summary information
ComplexityVisualizer: Handles complexity analysis visualization (3 plots)gate_based_metrics: Gate counts, depth, T-gates, and CNOT gatescomplexity_radar: Radar chart for normalized complexity indicatorsefficiency_metrics: Parallelism efficiency and circuit efficiency analysis
CircuitPerformanceVisualizer: Handles execution performance visualization (3 plots)success_error_comparison: Success vs error rate comparisons across jobsshot_distribution: Distribution of successful vs failed shotsaggregate_summary: Statistical summary across multiple jobs
Visualizer (Unified Entry Point)¶
Main class that provides a single interface for all visualizations with new API:
Type-Safe Constants: Works with
MetricsandPlotsconstants for error preventionAuto-Detection: Automatically detects available metrics and registers appropriate visualizers
Granular Control: Generate single plots, selected plots, or all plots with precise control
Rich Metadata: Access detailed information about each plot’s purpose and requirements
Flexible Input: Works with Scanner instances or custom metrics data
Memory Efficient: Default
save=False, show=Falsefor batch processing
PlotConfig¶
Configuration dataclass for plot appearance and behavior:
Appearance: Figure size, DPI, color palettes, transparency
Styling: Plot styles (default, quantum, minimal)
Output: Save format (PNG, SVG), grid settings
Extensible: Easy to customize for different visualization needs
Integration with Scanner (New API)¶
The visualization system seamlessly integrates with the Scanner output using the new type-safe API:
from qward.visualization.constants import Metrics, Plots
# Calculate metrics
scanner = Scanner(circuit=circuit)
scanner.add_strategy(QiskitMetrics(circuit))
scanner.add_strategy(ComplexityMetrics(circuit))
scanner.add_strategy(CircuitPerformanceMetrics(circuit=circuit, job=job))
metrics_dict = scanner.calculate_metrics()
# Option 1: Use unified Visualizer with type-safe constants (recommended)
visualizer = Visualizer(scanner=scanner)
# NEW API: Generate specific plots with type-safe constants
selected_plots = visualizer.generate_plots({
Metrics.QISKIT: [
Plots.QISKIT.CIRCUIT_STRUCTURE,
Plots.QISKIT.GATE_DISTRIBUTION
],
Metrics.COMPLEXITY: [
Plots.COMPLEXITY.COMPLEXITY_RADAR
]
}, save=True, show=False)
# NEW API: Generate all plots for specific metrics
all_qiskit_plots = visualizer.generate_plots({
Metrics.QISKIT: None # None = all plots
}, save=True, show=False)
# NEW API: Generate single plot
single_plot = visualizer.generate_plot(
Metrics.CIRCUIT_PERFORMANCE,
Plots.CIRCUIT_PERFORMANCE.SUCCESS_ERROR_COMPARISON,
save=True,
show=False
)
# NEW API: Explore available plots and metadata
available_plots = visualizer.get_available_plots()
for metric_name, plot_names in available_plots.items():
print(f"\n{metric_name} ({len(plot_names)} plots):")
for plot_name in plot_names:
metadata = visualizer.get_plot_metadata(metric_name, plot_name)
print(f" - {plot_name}: {metadata.description} ({metadata.plot_type.value})")
# Create comprehensive dashboards (unchanged)
dashboards = visualizer.create_dashboard(save=True, show=False)
# Option 2: Use individual visualizers directly with new API
from qward.visualization import QiskitVisualizer, ComplexityVisualizer, CircuitPerformanceVisualizer
qiskit_viz = QiskitVisualizer({Metrics.QISKIT: metrics_dict[Metrics.QISKIT]})
# NEW API: Generate specific plots
qiskit_viz.generate_plot(Plots.QISKIT.CIRCUIT_STRUCTURE, save=True, show=False)
# NEW API: Generate selected plots
selected_figures = qiskit_viz.generate_plots([
Plots.QISKIT.CIRCUIT_STRUCTURE,
Plots.QISKIT.GATE_DISTRIBUTION
], save=True, show=False)
# NEW API: Generate all plots
all_figures = qiskit_viz.generate_all_plots(save=True, show=False)
# NEW API: Get plot metadata
metadata = qiskit_viz.get_plot_metadata(Plots.QISKIT.CIRCUIT_STRUCTURE)
print(f"Plot description: {metadata.description}")
print(f"Plot type: {metadata.plot_type.value}")
print(f"Dependencies: {metadata.dependencies}")
Extensibility¶
The visualization system is designed for easy extension with the new plot registry system:
Custom Visualizers: Create new visualizers by inheriting from
VisualizationStrategyand defining aPLOT_REGISTRYPlot Metadata: Rich metadata system provides detailed information about each plot
Type Safety: Constants system prevents errors and provides IDE autocompletion
Custom Plot Types: Add new visualization methods with proper metadata registration
Custom Styling: Define new
PlotConfigpresets for different use casesRegistration System: Register custom visualizers with the unified
Visualizerclass
Benefits of New API¶
Type Safety: Constants prevent typos and provide IDE autocompletion
Rich Metadata: Detailed information about each plot’s purpose and requirements
Granular Control: Generate exactly the plots you need
Memory Efficient: Default parameters optimized for batch processing
Error Prevention: Validation of metric and plot combinations
Discoverability: Easy exploration of available plots and their capabilities
Future-Proof: Extensible design for adding new visualization types
For detailed usage and examples, see the Visualization Guide and explore the comprehensive examples in qward/examples/.