🔍 Code Extractor

class IllustrationGenerator

Maturity: 49

A class that generates educational illustrations and technical drawings for mathematical and scientific concepts using matplotlib and programmatic rendering.

File:
/tf/active/vicechatdev/e-ink-llm/graphics_generator.py
Lines:
375 - 527
Complexity:
moderate

Purpose

The IllustrationGenerator class is responsible for creating visual educational content including mathematical function plots, scientific diagrams (like atomic structures), and generic illustrations. It provides a unified interface for generating different types of educational graphics based on specifications, with fallback error handling. The class uses matplotlib for rendering and returns base64-encoded PNG images suitable for embedding in documents or web pages.

Source Code

class IllustrationGenerator:
    """Generates educational illustrations and technical drawings"""
    
    def __init__(self, api_key: str):
        self.client = OpenAI(api_key=api_key)
    
    async def generate_illustration(self, spec: GraphicSpec) -> GraphicSpec:
        """Generate an illustration using AI or programmatic methods"""
        params = spec.parameters
        concept = params.get('concept', spec.description)
        style = params.get('style', 'educational')
        
        try:
            # For educational concepts, try programmatic generation first
            if 'mathematical' in style or 'math' in concept:
                return self._create_math_illustration(spec)
            elif 'scientific' in style or 'science' in concept:
                return self._create_science_illustration(spec)
            else:
                # For complex illustrations, could use DALL-E (if needed)
                return self._create_generic_illustration(spec)
                
        except Exception as e:
            print(f"Error generating illustration: {e}")
            return self._create_error_illustration(spec, f"Illustration generation failed: {e}")
    
    def _create_math_illustration(self, spec: GraphicSpec) -> GraphicSpec:
        """Create mathematical concept illustrations"""
        params = spec.parameters
        concept = params.get('concept', 'function').lower()
        
        fig, ax = plt.subplots(figsize=(8, 6))
        
        if 'function' in concept or 'quadratic' in concept:
            # Draw a quadratic function
            x = np.linspace(-5, 5, 100)
            y = x**2
            ax.plot(x, y, 'black', linewidth=2)
            ax.axhline(y=0, color='black', linewidth=0.5)
            ax.axvline(x=0, color='black', linewidth=0.5)
            ax.grid(True, alpha=0.3)
            ax.set_title('Quadratic Function: y = x²', fontsize=14, fontweight='bold')
            
        elif 'derivative' in concept:
            # Show function and its derivative
            x = np.linspace(-3, 3, 100)
            y = x**2
            dy = 2*x
            ax.plot(x, y, 'black', linewidth=2, label='f(x) = x²')
            ax.plot(x, dy, 'gray', linewidth=2, linestyle='--', label="f'(x) = 2x")
            ax.legend()
            ax.grid(True, alpha=0.3)
            ax.set_title('Function and its Derivative', fontsize=14, fontweight='bold')
            
        else:
            # Generic mathematical illustration
            ax.text(0.5, 0.5, f'Mathematical Concept:\n{concept}', 
                   ha='center', va='center', transform=ax.transAxes,
                   fontsize=14, bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgray"))
        
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        plt.tight_layout()
        
        spec.image_data = self._fig_to_base64(fig)
        spec.width = 800
        spec.height = 600
        plt.close(fig)
        return spec
    
    def _create_science_illustration(self, spec: GraphicSpec) -> GraphicSpec:
        """Create scientific concept illustrations"""
        params = spec.parameters
        concept = params.get('concept', 'atoms').lower()
        
        fig, ax = plt.subplots(figsize=(8, 6))
        
        if 'atom' in concept:
            # Draw simple atomic structure
            center = Circle((0.5, 0.5), 0.1, facecolor='gray', edgecolor='black')
            ax.add_patch(center)
            
            # Electron orbits
            for radius in [0.2, 0.3, 0.4]:
                orbit = Circle((0.5, 0.5), radius, fill=False, edgecolor='black', linestyle='--')
                ax.add_patch(orbit)
            
            ax.set_xlim(0, 1)
            ax.set_ylim(0, 1)
            ax.set_title('Atomic Structure', fontsize=14, fontweight='bold')
            
        else:
            # Generic scientific illustration
            ax.text(0.5, 0.5, f'Scientific Concept:\n{concept}', 
                   ha='center', va='center', transform=ax.transAxes,
                   fontsize=14, bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgray"))
        
        ax.axis('off')
        plt.tight_layout()
        
        spec.image_data = self._fig_to_base64(fig)
        spec.width = 800
        spec.height = 600
        plt.close(fig)
        return spec
    
    def _create_generic_illustration(self, spec: GraphicSpec) -> GraphicSpec:
        """Create a generic illustration placeholder"""
        fig, ax = plt.subplots(figsize=(8, 6))
        
        ax.text(0.5, 0.5, f'Illustration:\n{spec.description}', 
               ha='center', va='center', transform=ax.transAxes,
               fontsize=14, bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgray"))
        
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 1)
        ax.axis('off')
        ax.set_title(spec.description, fontsize=14, fontweight='bold')
        
        plt.tight_layout()
        
        spec.image_data = self._fig_to_base64(fig)
        spec.width = 800
        spec.height = 600
        plt.close(fig)
        return spec
    
    def _fig_to_base64(self, fig) -> str:
        """Convert matplotlib figure to base64 encoded image"""
        buffer = io.BytesIO()
        fig.savefig(buffer, format='png', dpi=150, bbox_inches='tight',
                   facecolor='white', edgecolor='none')
        buffer.seek(0)
        image_data = buffer.getvalue()
        buffer.close()
        
        return base64.b64encode(image_data).decode('utf-8')
    
    def _create_error_illustration(self, spec: GraphicSpec, error_msg: str) -> GraphicSpec:
        """Create an error placeholder illustration"""
        fig, ax = plt.subplots(figsize=(6, 4))
        ax.text(0.5, 0.5, f"Error: {error_msg}", ha='center', va='center',
               transform=ax.transAxes, fontsize=12,
               bbox=dict(boxstyle="round,pad=0.3", facecolor="lightgray"))
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 1)
        ax.axis('off')
        
        spec.image_data = self._fig_to_base64(fig)
        spec.width = 600
        spec.height = 400
        plt.close(fig)
        return spec

Parameters

Name Type Default Kind
bases - -

Parameter Details

api_key: OpenAI API key string used to initialize the OpenAI client. Required for instantiation even though current implementation primarily uses programmatic generation rather than AI-based image generation. This suggests the class may be designed to support DALL-E integration for complex illustrations in the future.

Return Value

Instantiation returns an IllustrationGenerator object. The main method generate_illustration() returns a GraphicSpec object with populated image_data (base64-encoded PNG), width, and height attributes. All internal methods also return modified GraphicSpec objects with generated illustration data.

Class Interface

Methods

__init__(self, api_key: str)

Purpose: Initialize the IllustrationGenerator with an OpenAI API key

Parameters:

  • api_key: OpenAI API key string for client initialization

Returns: None (constructor)

async generate_illustration(self, spec: GraphicSpec) -> GraphicSpec

Purpose: Main entry point to generate an illustration based on the provided specification, routing to appropriate generation method based on style and concept

Parameters:

  • spec: GraphicSpec object containing description and parameters dictionary with 'concept' and 'style' keys

Returns: Modified GraphicSpec object with populated image_data (base64 PNG), width, and height attributes

_create_math_illustration(self, spec: GraphicSpec) -> GraphicSpec

Purpose: Create mathematical concept illustrations including quadratic functions, derivatives, and generic math concepts

Parameters:

  • spec: GraphicSpec object with parameters containing 'concept' key (e.g., 'function', 'quadratic', 'derivative')

Returns: GraphicSpec object with generated mathematical illustration as base64-encoded PNG

_create_science_illustration(self, spec: GraphicSpec) -> GraphicSpec

Purpose: Create scientific concept illustrations including atomic structures and generic science concepts

Parameters:

  • spec: GraphicSpec object with parameters containing 'concept' key (e.g., 'atom', 'atoms')

Returns: GraphicSpec object with generated scientific illustration as base64-encoded PNG

_create_generic_illustration(self, spec: GraphicSpec) -> GraphicSpec

Purpose: Create a generic placeholder illustration with the description text displayed

Parameters:

  • spec: GraphicSpec object with description to be displayed in the illustration

Returns: GraphicSpec object with generic placeholder illustration as base64-encoded PNG

_fig_to_base64(self, fig) -> str

Purpose: Convert a matplotlib figure object to a base64-encoded PNG string

Parameters:

  • fig: matplotlib.figure.Figure object to be converted

Returns: Base64-encoded string representation of the figure as PNG image

_create_error_illustration(self, spec: GraphicSpec, error_msg: str) -> GraphicSpec

Purpose: Create an error placeholder illustration displaying the error message

Parameters:

  • spec: GraphicSpec object to be populated with error illustration
  • error_msg: Error message string to display in the illustration

Returns: GraphicSpec object with error placeholder illustration as base64-encoded PNG

Attributes

Name Type Description Scope
client OpenAI OpenAI client instance initialized with the provided API key, potentially for future DALL-E integration instance

Dependencies

  • openai
  • matplotlib
  • numpy
  • io
  • base64

Required Imports

from openai import OpenAI
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import numpy as np
import io
import base64

Conditional/Optional Imports

These imports are only needed under specific conditions:

from matplotlib.patches import Circle

Condition: only needed when generating scientific illustrations with atomic structures

Required (conditional)

Usage Example

from openai import OpenAI
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
import numpy as np
import io
import base64
from dataclasses import dataclass
from typing import Dict, Any, Optional

@dataclass
class GraphicSpec:
    description: str
    parameters: Dict[str, Any]
    image_data: Optional[str] = None
    width: int = 0
    height: int = 0

# Instantiate the generator
generator = IllustrationGenerator(api_key='your-openai-api-key')

# Create a math illustration
math_spec = GraphicSpec(
    description='Quadratic function',
    parameters={'concept': 'quadratic function', 'style': 'mathematical'}
)
result = await generator.generate_illustration(math_spec)
print(f'Generated image size: {result.width}x{result.height}')

# Create a science illustration
science_spec = GraphicSpec(
    description='Atomic structure',
    parameters={'concept': 'atom model', 'style': 'scientific'}
)
result = await generator.generate_illustration(science_spec)

# Create a generic illustration
generic_spec = GraphicSpec(
    description='Custom concept',
    parameters={'concept': 'custom educational concept'}
)
result = await generator.generate_illustration(generic_spec)

Best Practices

  • Always await the generate_illustration() method as it is async
  • Ensure GraphicSpec objects have properly formatted parameters dictionary with 'concept' and 'style' keys
  • The class automatically closes matplotlib figures to prevent memory leaks
  • Use 'mathematical' or 'math' in style/concept for math illustrations, 'scientific' or 'science' for science illustrations
  • The returned GraphicSpec object contains base64-encoded PNG data in the image_data attribute
  • Error handling is built-in; failed generations return error placeholder illustrations rather than raising exceptions
  • The OpenAI client is initialized but not currently used in the implementation; this may be for future DALL-E integration
  • All generated images are 800x600 pixels by default (600x400 for error illustrations)
  • Images are rendered at 150 DPI with white background and tight bounding boxes

Similar Components

AI-powered semantic similarity - components with related functionality:

  • class GraphicsGenerator 73.0% similar

    GraphicsGenerator is a coordinator class that orchestrates the generation of different types of graphics (charts, diagrams, illustrations, and sketches) by delegating to specialized generator classes.

    From: /tf/active/vicechatdev/e-ink-llm/graphics_generator.py
  • class DiagramGenerator 69.8% similar

    A class that generates various types of diagrams including flowcharts, process flows, and network diagrams using matplotlib and networkx, returning base64-encoded PNG images.

    From: /tf/active/vicechatdev/e-ink-llm/graphics_generator.py
  • class ChartGenerator 67.1% similar

    A class that generates various types of charts (bar, line, pie, scatter) optimized for e-ink displays with high contrast and clear visibility.

    From: /tf/active/vicechatdev/e-ink-llm/graphics_generator.py
  • function demo_graphics_generation 61.8% similar

    Demonstrates the generation of three types of graphics (bar chart, process diagram, and mathematical illustration) using the GraphicsGenerator class with e-ink optimized styling.

    From: /tf/active/vicechatdev/e-ink-llm/demo_hybrid_mode.py
  • class SignatureGenerator 59.4% similar

    A class that generates signature-like images from text names using italic fonts and decorative flourishes.

    From: /tf/active/vicechatdev/document_auditor/src/utils/signature_generator.py
← Back to Browse