Connecting to dev server...

Circuitry for Jupyter Notebook Users

If you're coming from Jupyter notebooks, Circuitry offers a familiar yet more powerful approach to data analysis, visualization, and automation. This guide will help you transition from notebook-based workflows to visual workflow automation.

From Notebooks to Visual Workflows

Key Differences

Jupyter NotebooksCircuitry
Linear cell executionVisual node-based workflows
Manual cell-by-cell runsAutomated end-to-end execution
Code in cellsCode in dedicated Code nodes
Individual plotsChart, DataViz, and StatPlot nodes
Manual data passingAutomatic data flow between nodes
Single environmentMultiple execution contexts

Core Concepts for Jupyter Users

1. Code Nodes Replace Cells

Instead of notebook cells, Circuitry uses Code nodes that can execute Python and JavaScript code:

  • Python execution powered by Pyodide WebAssembly runtime
  • Pre-loaded libraries: NumPy, Pandas, Matplotlib, SciPy, Scikit-learn
  • Additional packages via micropip
  • Input/output data automatically available as input_data variable

Example: Converting a Jupyter Cell

Jupyter Notebook:

import pandas as pd
import numpy as np

# Load data
data = pd.read_csv('data.csv')

# Process data
data['processed'] = data['value'] * 2
result = data.groupby('category').mean()
print(result)

Circuitry Code Node:

import pandas as pd
import numpy as np

# Input data flows from previous node
data = pd.DataFrame(input_data) if input_data else pd.read_csv('data.csv')

# Process data
data['processed'] = data['value'] * 2
result = data.groupby('category').mean()

# Return result for next node
result = result.to_dict()

2. Visualization Nodes Replace Inline Plots

Circuitry provides three specialized visualization nodes that replace matplotlib/seaborn plots in notebooks:

Chart Node (Matplotlib-based)

  • Best for: Traditional statistical charts (bar, line, scatter, histogram, pie)
  • Configuration: JSON-based with chart type, data columns, styling
  • Output: Base64 PNG images

DataViz Node (Plotly-based)

  • Best for: Interactive visualizations (heatmaps, 3D plots, dashboards)
  • Configuration: Plotly.js compatible settings
  • Output: Interactive plots and static images

StatPlot Node (Seaborn-based)

  • Best for: Statistical analysis plots (regression, distributions, correlations)
  • Configuration: Seaborn style and palette options
  • Output: Publication-ready statistical plots

3. Data Flow Instead of Variable Passing

In Jupyter, you manually pass variables between cells. In Circuitry, data flows automatically:

Jupyter approach:

# Cell 1
raw_data = load_data()

# Cell 2
cleaned_data = clean_data(raw_data)

# Cell 3
plot_data(cleaned_data)

Circuitry approach:

  • Node 1: Load data → outputs raw_data
  • Node 2: Clean data (receives raw_data as input_data) → outputs cleaned_data
  • Node 3: Plot data (receives cleaned_data as input_data)

Migration Patterns

Pattern 1: Data Loading and Processing

Before (Jupyter):

# Cell 1: Load
import pandas as pd
df = pd.read_csv('sales.csv')

# Cell 2: Clean
df = df.dropna()
df['date'] = pd.to_datetime(df['date'])

# Cell 3: Analyze
monthly_sales = df.groupby(df['date'].dt.month).sum()

After (Circuitry):

  1. HTTP Request Node: Fetch CSV data from API
  2. Code Node (Data Cleaning):
    import pandas as pd
    df = pd.DataFrame(input_data)
    df = df.dropna()
    df['date'] = pd.to_datetime(df['date'])
    result = df.to_dict('records')
    
  3. Code Node (Analysis):
    import pandas as pd
    df = pd.DataFrame(input_data)
    monthly_sales = df.groupby(df['date'].dt.month).sum()
    result = monthly_sales.to_dict()
    

Pattern 2: Visualization Workflows

Before (Jupyter):

# Analysis cell
correlation_matrix = df.corr()

# Plotting cell
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Feature Correlations')
plt.show()

After (Circuitry):

  1. Code Node (Analysis):

    import pandas as pd
    df = pd.DataFrame(input_data)
    correlation_matrix = df.corr()
    result = correlation_matrix.to_dict()
    
  2. StatPlot Node Configuration:

    {
      "plotType": "heatmap",
      "title": "Feature Correlations",
      "width": 10,
      "height": 8,
      "style": "whitegrid",
      "customCode": "sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')"
    }
    

Pattern 3: Machine Learning Pipelines

Before (Jupyter):

# Data prep
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Training
model = RandomForestClassifier()
model.fit(X_train, y_train)

# Evaluation
predictions = model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print(f"Accuracy: {accuracy}")

After (Circuitry):

  1. Code Node (Data Split):

    from sklearn.model_selection import train_test_split
    import pandas as pd
    
    df = pd.DataFrame(input_data)
    X = df.drop('target', axis=1)
    y = df['target']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
    
    result = {
      'X_train': X_train.to_dict('records'),
      'X_test': X_test.to_dict('records'),
      'y_train': y_train.tolist(),
      'y_test': y_test.tolist()
    }
    
  2. Code Node (Training):

    from sklearn.ensemble import RandomForestClassifier
    import pandas as pd
    
    data = input_data
    X_train = pd.DataFrame(data['X_train'])
    y_train = data['y_train']
    
    model = RandomForestClassifier()
    model.fit(X_train, y_train)
    
    # In practice, you'd serialize the model
    result = {
      'model_trained': True,
      'X_test': data['X_test'],
      'y_test': data['y_test']
    }
    
  3. Code Node (Evaluation):

    # Evaluate model and create results
    accuracy = 0.95  # placeholder
    result = {'accuracy': accuracy}
    

Advanced Features for Data Scientists

1. Template Variables

Use {{variable}} syntax to make workflows dynamic:

# Code node with template variables
model_type = "{{model_type}}"  # Set via environment variables
test_size = {{test_size}}      # Numeric templates

if model_type == "random_forest":
    from sklearn.ensemble import RandomForestClassifier
    model = RandomForestClassifier()

2. Conditional Workflows

Use Condition nodes for branching logic:

  • If data quality score > 0.8 → Continue with complex model
  • Else → Use simple baseline model

3. Parallel Processing

Use Fork/Join nodes for parallel execution:

  • Fork: Split data for multiple model training
  • Join: Combine results for ensemble methods

4. Automation

Unlike notebooks, Circuitry workflows can be:

  • Triggered by webhooks for real-time data processing
  • Scheduled for batch processing
  • Chained with other workflows
  • Deployed as APIs

Best Practices for Migration

1. Start Small

  • Begin with simple data loading + visualization workflows
  • Gradually add complexity with conditions and loops
  • Practice data flow concepts before complex logic

2. Leverage Code Nodes

  • Use Code nodes for complex Python logic
  • Keep visualization in Chart/DataViz/StatPlot nodes
  • Break large notebook cells into focused nodes

3. Design for Reusability

  • Create modular workflows that can be called from other workflows
  • Use template variables for configurable parameters
  • Document node purposes with clear names

4. Test Data Flow

  • Use the execution output panel to verify data passing
  • Add debug Code nodes to inspect intermediate results
  • Leverage the visual workflow graph to understand dependencies

5. Optimize for Performance

  • Use Image nodes to display static plots without re-execution
  • Cache expensive computations in separate nodes
  • Consider breaking long-running processes into smaller nodes

Common Gotchas

1. Data Serialization

Circuitry passes data as JSON between nodes. Complex objects need serialization:

# Instead of passing DataFrame directly
result = df  # ❌ Won't work

# Serialize to dict/list
result = df.to_dict('records')  # ✅ Works

2. Library Imports

Some libraries may need micropip installation. Circuitry supports familiar Jupyter syntax:

# Jupyter-style (automatically converted)
!pip install seaborn

# Or use micropip directly
import micropip
await micropip.install('seaborn')
import seaborn as sns

3. File Handling

Browser-based execution has different file access patterns:

# Instead of local file reading
data = pd.read_csv('local_file.csv')  # ❌ May not work

# Use HTTP requests or pass data via workflow
data = pd.DataFrame(input_data)  # ✅ Works

Resources for Learning

  1. Python Support Documentation - Complete Python execution guide
  2. Code Node Guide - Detailed Code node documentation
  3. Template Variables - Dynamic workflow configuration
  4. Workflow Patterns - Common workflow designs

Example Notebooks to Workflows

Data Analysis Workflow

Goal: Analyze sales data and create dashboard

Jupyter: 15+ cells with manual execution Circuitry: 6 connected nodes with automatic execution

  • Data loading → Cleaning → Analysis → Multiple visualizations → Dashboard

ML Model Training

Goal: Train and evaluate classification model

Jupyter: Manual feature engineering, training, evaluation Circuitry: Automated pipeline with parallel model comparison

  • Data prep → Feature engineering → Fork (multiple models) → Join → Best model selection

The transition from Jupyter notebooks to Circuitry workflows opens up new possibilities for automation, collaboration, and production deployment of your data science work.