Generate charts and visualizations
On this page
Updated November 2, 2026 based on OpenAI documentation: the Code Interpreter tool now requires a
containerparameter (added to all examples), text input parts use theinput_texttype, and web search uses theweb_searchtool (web_search_previewis now a legacy tool without domain filters). Generated files are retrieved using thefichiers_generesandtelechargerfunctions from Lesson 10. Files attached to messages are uploaded with theuser_datapurpose, which OpenAI recommends for model inputs (File inputs). Sources: Code Interpreter · Web search.
Generate charts and visualizations
A chart produced by Code Interpreter isn’t a generated image: it’s the rendering of an actual matplotlib script executed on your real data. This distinction matters—axes are accurate, values match the file, and you can request the code to reproduce it locally.
Three libraries coexist in the container, each serving a different purpose. matplotlib handles everything but can be verbose. seaborn adds a statistical layer that makes distributions and correlations readable in a single line. plotly produces interactive HTML, best reserved for deliverables you’ll explore with a mouse. Name the one you want in your prompt; without instructions, the model defaults to matplotlib.
Simple charts with matplotlib
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6-terra",
input="Create a bar chart showing monthly sales: "
"Jan=120, Feb=98, Mar=145, Apr=167, May=189, Jun=210, "
"Jul=195, Aug=178, Sep=220, Oct=245, Nov=267, Dec=312. "
"Professional style, blue colors, title and labels.",
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions="Use matplotlib with a professional style. "
"Sans-serif font, light grid, no top or right spines."
)
# Retrieve the generated image
for ann in fichiers_generes(response):
telecharger(client, ann, "monthly_sales.png")
Charts from file data
This is the most common use case, and where the value is clearest: you upload the file, describe the chart you want, and the model handles reading, column typing, and plotting. No manual preparation steps, and crucially, no manual transcription of numbers—so no copy-paste errors.
with open("team_performance.csv", "rb") as f:
file_obj = client.files.create(file=f, purpose="user_data")
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": (
"From this file, create a dashboard with 4 charts: "
"1. Monthly revenue evolution (line chart) "
"2. Breakdown by product category (pie chart) "
"3. Top 10 clients by revenue (horizontal bar chart) "
"4. Correlation between quantity and amount (scatter plot) "
"Arrange the 4 charts in a 2x2 grid."
)},
{"type": "input_file", "file_id": file_obj.id}
]
}],
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions="Create a matplotlib figure with 4 subplots. "
"Use a consistent color palette. "
"Resolution 1920x1080, DPI 150. "
"Export as high-quality PNG."
)
Statistical visualizations with seaborn
seaborn shines when the question concerns a distribution or a relationship rather than a series of values. A box plot by category or a correlation matrix reveals at a glance what a table of numbers only shows after careful reading—and that’s exactly what a chart should do.
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": (
"Visual statistical analysis of this data: "
"1. Heatmap of the correlation matrix "
"2. Distribution of each numerical variable (histograms + KDE) "
"3. Boxplots by category to identify outliers "
"4. Pairplot of the 5 main variables"
)},
{"type": "input_file", "file_id": file_obj.id}
]
}],
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions="Use seaborn with the 'whitegrid' theme. "
"Annotate values in the heatmap. "
"Use the 'coolwarm' palette for correlations."
)
Interactive charts with plotly
plotly changes the nature of the deliverable: instead of a static image, you get a standalone HTML file where you can zoom, hover, and filter. It’s the right choice for a dashboard someone will explore, but the wrong choice for a figure destined for a printed document or email.
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": (
"Create an interactive plotly chart showing sales evolution with: "
"- Zoom and date range selection "
"- Hover tooltips with details "
"- Buttons to filter by category "
"- Export as standalone HTML file"
)},
{"type": "input_file", "file_id": file_obj.id}
]
}],
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}]
)
# Retrieve the interactive HTML file
for ann in fichiers_generes(response):
if ann.filename.endswith(".html"):
telecharger(client, ann, "interactive_dashboard.html")
Advanced customization
Corporate style guide
A default-generated chart is immediately recognizable and looks amateurish in a corporate document. Passing your colors, fonts, and conventions in instructions is enough to produce consistent figures from one report to the next—and since these instructions are reusable, you only make the effort once.
STYLE_GUIDE = """
Visualization rules:
- Primary color: #1E3A5F (navy blue)
- Secondary color: #E74C3C (red)
- Accent color: #F39C12 (orange)
- Background: white (#FFFFFF)
- Font: sans-serif
- No borders around charts
- Light gray grid (#E0E0E0)
- Bold title, size 14
- Axis labels size 11
- Legend at bottom right
- Always include data source at bottom left
- Minimum resolution: 1200x800 pixels
"""
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": "Create a quarterly revenue evolution chart"},
{"type": "input_file", "file_id": file_obj.id}
]
}],
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions=STYLE_GUIDE
)
Pattern: visual report generator
def generate_visual_report(
file_path: str,
report_title: str,
sections: list[str]
) -> list[str]:
"""Generate a report with charts from data."""
with open(file_path, "rb") as f:
file_obj = client.files.create(file=f, purpose="user_data")
images = []
for i, section in enumerate(sections):
response = client.responses.create(
model="gpt-5.6-terra",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": f"Section {i+1} of report '{report_title}': {section}"},
{"type": "input_file", "file_id": file_obj.id}
]
}],
tools=[{"type": "code_interpreter", "container": {"type": "auto"}}],
instructions=(
"Create a professional chart for this section. "
"Include a descriptive title and relevant annotations. "
"Export as PNG 1200x800 DPI 150."
)
)
for ann in fichiers_generes(response):
name = f"report_section_{i+1}.png"
telecharger(client, ann, name)
images.append(name)
return images
# Usage
charts = generate_visual_report(
"annual_sales.csv",
"2025 Sales Report",
[
"Monthly revenue evolution with trend",
"Sales breakdown by region (map or treemap)",
"Performance comparison by sales rep (grouped bars)",
"Forecasts for the next 3 months (with confidence interval)"
]
)
Tips for quality charts
quality_instructions = """
For each chart:
- Choose the chart type best suited to the data
- Use accessible colors (sufficient contrast)
- Avoid 3D charts unless explicitly requested
- Limit pie charts to 6 categories maximum
- Add annotations for important points
- Use appropriate scales (no truncated zero unless justified)
- Always export in high resolution
"""
Key takeaways
- matplotlib, seaborn, and plotly are available in the sandbox
- Pass your data via
input_filefor charts based on real files - Define a style guide in
instructionsfor consistency - Retrieve generated images from
container_file_citationannotations, then download them via the container API (functionsfichiers_generesandtelechargerfrom Lesson 10) - Plotly lets you generate interactive HTML dashboards