Rich output capture automatically detects and captures visual outputs like matplotlib plots, pandas DataFrames, and plotly charts from your code execution.
Prerequisites
Before you begin, make sure you have:
- Active sandbox - A running sandbox (see Creating Sandboxes)
- Understanding of code execution - Familiarity with Synchronous Execution is helpful
- Code that generates visualizations - Code that creates plots, DataFrames, or charts
Overview
When you execute code with run_code(), HopX automatically captures:
- Matplotlib plots → PNG images (base64-encoded)
- Pandas DataFrames → HTML tables
- Plotly charts → HTML interactive visualizations
- JSON outputs → Structured data
Rich output capture is enabled by default in run_code(). All visual outputs are automatically detected and included in the ExecutionResult.rich_outputs array.
Automatic Capture
Rich outputs are captured automatically:
from hopx_ai import Sandbox
sandbox = Sandbox.create(template="code-interpreter")
# Execute code that generates a plot
result = sandbox.run_code('''
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title("Sine Wave")
plt.savefig('/workspace/plot.png')
''')
# Check for rich outputs
print(f"Rich outputs captured: {len(result.rich_outputs)}")
for output in result.rich_outputs:
print(f"Type: {output.type}")
print(f"Data keys: {list(output.data.keys())}")
sandbox.kill()
Matplotlib Plots
Capture matplotlib plots as PNG images:
from hopx_ai import Sandbox
import base64
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import matplotlib.pyplot as plt
import numpy as np
# Create a simple plot
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2, label='sin(x)')
plt.plot(x, np.cos(x), 'r--', linewidth=2, label='cos(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Trigonometric Functions')
plt.legend()
plt.grid(True)
plt.savefig('/workspace/trig_plot.png')
''')
# Access captured plot
for output in result.rich_outputs:
if 'image/png' in output.data:
png_data = output.data['image/png']
print(f"Plot captured: {len(png_data)} bytes")
# png_data is base64-encoded PNG image
sandbox.kill()
Pandas DataFrames
Capture pandas DataFrames as HTML tables:
from hopx_ai import Sandbox
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import pandas as pd
import numpy as np
# Create a DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'Age': [25, 30, 35, 28],
'Score': [85, 92, 78, 95]
}
df = pd.DataFrame(data)
print(df) # DataFrame is automatically captured as HTML
''')
# Access captured DataFrame
for output in result.rich_outputs:
if 'text/html' in output.data:
html_data = output.data['text/html']
print(f"DataFrame captured as HTML: {len(html_data)} chars")
# html_data contains HTML table representation
sandbox.kill()
Plotly Charts
Capture interactive Plotly charts as HTML:
from hopx_ai import Sandbox
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import plotly.graph_objects as go
import numpy as np
# Create interactive plot
x = np.linspace(0, 10, 100)
y = np.sin(x)
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name='sin(x)'))
fig.update_layout(title='Interactive Plot', xaxis_title='x', yaxis_title='y')
fig.write_html('/workspace/plot.html')
''')
# Access captured Plotly chart
for output in result.rich_outputs:
if 'text/html' in output.data:
html_data = output.data['text/html']
print(f"Plotly chart captured: {len(html_data)} chars")
# html_data contains interactive HTML chart
sandbox.kill()
Multiple Rich Outputs
Capture multiple outputs in a single execution:
from hopx_ai import Sandbox
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# Create a plot
plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.savefig('/workspace/plot1.png')
# Create a DataFrame
df = pd.DataFrame({'x': [1, 2, 3], 'y': [4, 5, 6]})
print(df)
# Create another plot
plt.figure()
plt.scatter([1, 2, 3], [4, 5, 6])
plt.savefig('/workspace/plot2.png')
''')
# Access all captured outputs
print(f"Total rich outputs: {len(result.rich_outputs)}")
for i, output in enumerate(result.rich_outputs):
print(f"Output {i+1}: {output.type}")
print(f" Data types: {list(output.data.keys())}")
sandbox.kill()
Rich Output Structure
Each rich output has the following structure:
from hopx_ai import Sandbox
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import matplotlib.pyplot as plt
plt.plot([1, 2, 3])
plt.savefig('/workspace/plot.png')
''')
# Inspect rich output structure
for output in result.rich_outputs:
print(f"Type: {output.type}") # e.g., "image/png", "text/html"
print(f"Data: {type(output.data)}") # Dict[str, str]
# Access specific data format
if 'image/png' in output.data:
png_base64 = output.data['image/png']
# Decode if needed: import base64; image_bytes = base64.b64decode(png_base64)
if 'text/html' in output.data:
html_content = output.data['text/html']
# Use HTML content directly
sandbox.kill()
Complete Example
Here’s a complete example with all rich output types:
from hopx_ai import Sandbox
import base64
sandbox = Sandbox.create(template="code-interpreter")
result = sandbox.run_code('''
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 1. Matplotlib plot
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
plt.title("Sine Wave")
plt.savefig('/workspace/sine.png')
# 2. Pandas DataFrame
df = pd.DataFrame({
'x': x[::10],
'sin(x)': np.sin(x[::10])
})
print(df)
# 3. Multiple plots
plt.figure()
plt.subplot(2, 1, 1)
plt.plot(x, np.sin(x))
plt.title("Sin")
plt.subplot(2, 1, 2)
plt.plot(x, np.cos(x))
plt.title("Cos")
plt.savefig('/workspace/multiplot.png')
''')
# Process all rich outputs
print(f"Captured {len(result.rich_outputs)} rich outputs\n")
for i, output in enumerate(result.rich_outputs, 1):
print(f"Output {i}:")
print(f" Type: {output.type}")
if 'image/png' in output.data:
png_data = output.data['image/png']
print(f" PNG size: {len(png_data)} bytes (base64)")
if 'text/html' in output.data:
html_data = output.data['text/html']
print(f" HTML size: {len(html_data)} chars")
sandbox.kill()
Best Practices
1. Save Files Explicitly
Always save plots to files (e.g., plt.savefig()) to ensure they’re captured. Rich output capture works best when files are explicitly saved.
2. Use Appropriate Formats
- Matplotlib: Save as PNG for best compatibility
- Pandas: Print DataFrames to trigger HTML capture
- Plotly: Use
write_html() for interactive charts
3. Check Output Count
Use len(result.rich_outputs) to verify all expected outputs were captured.
4. Handle Base64 Encoding
PNG images are base64-encoded. Decode them before displaying or saving locally.
5. Multiple Outputs
You can capture multiple plots/DataFrames in a single execution. All will be included in rich_outputs.
Next Steps