```python
import matplotlib.pyplot as plt
import numpy as np
# Sample quarterly sales data (in thousands of USD) for three products
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
widget_a = [45, 52, 61, 70]
widget_b = [38, 41, 55, 63]
widget_c = [30, 48, 50, 58]
# Color-blind friendly palette (from Wong, 2011 / Okabe-Ito)
colors = ['#0072B2', # blue
'#E69F00', # orange
'#009E73'] # green
# Set up bar positions
x = np.arange(len(quarters)) # label locations
width = 0.25 # width of each bar
# Create the figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Plot each product's bars, offset by width
bars_a = ax.bar(x - width, widget_a, width, label='Widget A', color=colors[0])
bars_b = ax.bar(x, widget_b, width, label='Widget B', color=colors[1])
bars_c = ax.bar(x + width, widget_c, width, label='Widget C', color=colors[2])
# Helper function to annotate each bar with its value
def add_value_labels(bars):
for bar in bars:
height = bar.get_height()
ax.annotate(f'{height}',
xy=(bar.get_x() + bar.get_width() / 2, height),
xytext=(0, 3), # 3 points vertical offset
textcoords='offset points',
ha='center', va='bottom',
fontsize=9)
# Apply labels to all bar groups
add_value_labels(bars_a)
add_value_labels(bars_b)
add_value_labels(bars_c)
# Titles, axis labels, ticks, legend, and styling
ax.set_title('Quarterly Sales Comparison by Product', fontsize=14, fontweight='bold')
ax.set_xlabel('Quarter', fontsize=12)
ax.set_ylabel('Sales (in thousands of USD)', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(quarters)
ax.legend(title='Product', loc='upper left')
ax.yaxis.grid(True, linestyle='--', alpha=0.6)
ax.set_axisbelow(True)
# Add a little headroom so labels don't get clipped
ax.set_ylim(0, max(max(widget_a), max(widget_b), max(widget_c)) * 1.15)
plt.tight_layout()
plt.show()
```
Generate Python Matplotlib Visualizations with AI
Tested prompts for ai generate matplotlib chart code compared across 5 leading AI models.
You have data. You know matplotlib can visualize it. But writing the chart code from scratch means digging through documentation, fighting with axis labels, and debugging subplot layouts. AI models can generate the full matplotlib code block in seconds when you describe what you want in plain English.
This page tests exactly that workflow: a specific prompt asking an AI to generate matplotlib chart code, run against four different models. You get the raw outputs, a head-to-head comparison, and the editorial context to know which output to trust and why.
The practical value here is speed and correctness. A well-prompted AI will produce runnable matplotlib code with proper imports, labeled axes, a title, and sensible styling. You paste it into your notebook, adjust the data source, and move on. The work below shows you what that output actually looks like and where each model stumbles.
When to use this
This approach fits best when you know what chart type you need and can describe your data structure clearly. If you can say 'I have a pandas DataFrame with monthly revenue by region and I want a grouped bar chart with a legend,' an AI can generate the matplotlib code faster than you can locate the right Stack Overflow answer.
- Rapid prototyping a visualization before cleaning your full dataset
- Generating boilerplate chart code for a chart type you rarely use, like violin plots or hexbin plots
- Converting a chart description from a stakeholder or product spec into working code
- Learning matplotlib syntax by reading generated code and modifying it
- Reproducing a chart style you saw elsewhere without knowing the exact matplotlib calls
When this format breaks down
- When your data structure is complex or nested and you cannot describe it precisely in the prompt, the generated code will make wrong assumptions about column names or array shapes and will fail silently or throw KeyErrors.
- When you need pixel-perfect, brand-compliant chart styling with custom fonts, specific hex colors, and exact spacing, AI output will get you 70% there but the remaining 30% requires manual matplotlib tuning that takes as long as writing it yourself.
- When the chart logic depends on conditional business rules, like coloring bars red only if they exceed a dynamic threshold pulled from another table, the generated code will need substantial rewriting and may introduce subtle logic errors.
- When you are working in a regulated environment where all code must be reviewed line by line before use, the time saved by generation gets consumed by mandatory audit, eliminating the productivity benefit.
The prompt we tested
You are an expert Python developer specializing in data visualization with Matplotlib. Generate clean, runnable Matplotlib code based on the user's chart description below. Instructions: Return a single, complete Python code block that imports all required libraries (matplotlib.pyplot, numpy/pandas as needed), includes realistic sample data if none is provided, applies clear titles, axis labels, legends, and styling, and ends with plt.show(). Add brief inline comments explaining each major step, and keep the code self-contained so it runs without modification. User's chart request: I need a grouped bar chart comparing quarterly sales (Q1-Q4) for three products: Widget A, Widget B, and Widget C. Use a color-blind friendly palette and add value labels on top of each bar. Produce the complete Python code now.
Model comparison
| Model | Quality | Cost | Latency | Tokens |
|---|---|---|---|---|
| Claude Opus 4.7 | 9 | $0.0713 | 9.8s | 277 / 895 |
| Claude Haiku 4.5 | 9 | $0.0042 | 8.6s | 180 / 813 |
| GPT-5.4 | 9 | $0.0075 | 5.9s | 167 / 474 |
| Gemini 2.5 Pro | 5 | $0.0035 | 15.9s | 171 / 661 |
| Grok 4.1 Fast Reasoning | 8 | $0.0003 | 8.5s | 315 / 539 |
Outputs
```python
import matplotlib.pyplot as plt
import numpy as np
# Sample data: quarterly sales for three products
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
widget_a = [45000, 52000, 48000, 61000]
widget_b = [38000, 41000, 55000, 59000]
widget_c = [52000, 48000, 51000, 54000]
# Color-blind friendly palette (Okabe-Ito)
colors = ['#E69F00', '#56B4E9', '#009E73']
# Set up the figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Define bar positions
x = np.arange(len(quarters))
bar_width = 0.25
# Create grouped bars
bars1 = ax.bar(x - bar_width, widget_a, bar_width, label='Widget A', color=colors[0])
bars2 = ax.bar(x, widget_b, bar_width, label='Widget B', color=colors[1])
bars3 = ax.bar(x + bar_width, widget_c, bar_width, label='Widget C', color=colors[2])
# Function to add value labels on top of each bar
def add_value_labels(bars):
for bar in bars:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width() / 2, height,
f'${height:,.0f}',
ha='center', va='bottom', fontsize=9, fontweight='bold')
# Add value labels to all bar groups
add_value_labels(bars1)
add_value_labels(bars2)
add_value_labels(bars3)
# Customize the chart
ax.set_xlabel('Quarter', fontsize=12, fontweight='bold')
ax.set_ylabel('Sales ($)', fontsize=12, fontweight='bold')
ax.set_title('Quarterly Sales Comparison by Product', fontsize=14, fontweight='bold', pad=20)
ax.set_xticks(x)
ax.set_xticklabels(quarters)
ax.legend(loc='upper left', frameon=True, shadow=True)
# Format y-axis to display currency
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'${x/1000:.0f}K'))
# Add grid for better readability
ax.grid(axis='y', alpha=0.3, linestyle='--')
ax.set_axisbelow(True)
# Adjust layout to prevent label cutoff
plt.tight_layout()
# Display the chart
plt.show()
```
This code creates a professional grouped bar chart with the following features:
- **Grouped bars**: Three bars per quarter for easy side-by-side comparison
- **Color-blind friendly palette**: Uses the Okabe-Ito color scheme (orange, blue, green) that's accessible to people with color vision deficiency
- **Value labels**: Dollar amounts displayed on top of each bar for precise reading
- **Professional styling**: Includes grid lines, formatted y-axis with currency symbols, bold labels, and a legend
- **Sample data**: Realistic quarterly sales figures for three widget products
- **Self-contained**: Runs immediately without external data files
```python
import matplotlib.pyplot as plt
import numpy as np
# Sample quarterly sales data
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
widget_a = [120, 135, 150, 165]
widget_b = [100, 145, 140, 155]
widget_c = [90, 110, 130, 145]
# Set up bar positions
x = np.arange(len(quarters))
bar_width = 0.24
# Create the figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Color-blind friendly palette (Okabe-Ito inspired)
colors = ['#0072B2', '#E69F00', '#009E73']
# Plot grouped bars
bars_a = ax.bar(x - bar_width, widget_a, width=bar_width, label='Widget A', color=colors[0])
bars_b = ax.bar(x, widget_b, width=bar_width, label='Widget B', color=colors[1])
bars_c = ax.bar(x + bar_width, widget_c, width=bar_width, label='Widget C', color=colors[2])
# Add titles and labels
ax.set_title('Quarterly Sales Comparison by Product', fontsize=14, pad=12)
ax.set_xlabel('Quarter', fontsize=12)
ax.set_ylabel('Sales (Units)', fontsize=12)
ax.set_xticks(x)
ax.set_xticklabels(quarters)
ax.legend()
# Add a light horizontal grid for readability
ax.yaxis.grid(True, linestyle='--', alpha=0.4)
ax.set_axisbelow(True)
# Function to add value labels above each bar
def add_value_labels(bars):
for bar in bars:
height = bar.get_height()
ax.text(
bar.get_x() + bar.get_width() / 2,
height + 2,
f'{int(height)}',
ha='center',
va='bottom',
fontsize=10
)
# Apply value labels to each product's bars
add_value_labels(bars_a)
add_value_labels(bars_b)
add_value_labels(bars_c)
# Adjust layout to prevent clipping
plt.tight_layout()
# Display the chart
plt.show()
```
```python
import matplotlib.pyplot as plt
import numpy as np
# --- 1. Sample Data ---
# Define the categories (quarters) and the data for each product.
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
sales_data = {
'Widget A': [250, 265, 280, 290],
'Widget B': [220, 230, 245, 270],
'Widget C': [180, 200, 210, 240],
}
products = list(sales_data.keys())
product_sales = np.array(list(sales_data.values()))
# --- 2. Setup for Plotting ---
# Calculate the position for each group of bars on the x-axis.
x = np.arange(len(quarters)) # The label locations [0, 1, 2, 3]
bar_width = 0.25 # The width of each individual bar
spacing = 0.05 # A small space between bars in a group
# Create the figure and axes objects for the plot.
# Using layout='constrained' helps automatically adjust plot elements.
fig, ax = plt.subplots(figsize=(12, 7), layout='constrained')
# --- 3. Color Palette ---
# Use a color-blind friendly palette (from Paul Tol's "Vibrant" scheme).
colors = ['#0077BB', '#EE7733', '#009988']
# --- 4. Plotting the Bars ---
# Loop through each product to plot its bars.
for i, product in enumerate(products):
# Calculate the offset for each bar within a group.
# The central bar is at x, others are offset by bar_width + spacing.
offset = bar_width * (i - 1) + spacing * (i - 1)
# Plot the bars for the current product.
rects = ax.bar(x + offset, product_sales[i], bar_width, label=product, color=colors[i])
# Add value labels on top of each bar.
ax.bar_label(rects, padding=3, fmt='%d', fontsize=9)
# --- 5. Customization and Styling ---
# Add a descriptive title and clear axis labels.
ax.set_title('Quarterly Sales Comparison by Product', fontsize=16, fontweight='bold')
ax.set_xlabel('Quarter', fontsize=12)
ax.set_ylabel('Sales (in thousands)', fontsize=12)
# Set the x-axis ticks to be in the center of each group of bars.
ax.set_xticks(x, quarters)
# Add a legend to identify the products.
ax.legend(loc='upper left', ncols
```python
import matplotlib.pyplot as plt
import numpy as np
# Define quarters and realistic sample sales data (in thousands of units)
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
sales_a = [100, 120, 110, 130] # Widget A
sales_b = [90, 100, 95, 105] # Widget B
sales_c = [80, 90, 85, 100] # Widget C
# Color-blind friendly palette (blue, orange, green)
colors = ['#0072B2', '#D55E00', '#009E73']
# Set up the bar positions and width for grouping
x = np.arange(len(quarters))
width = 0.25 # Width of each bar
# Create figure and axis
fig, ax = plt.subplots(figsize=(10, 6))
# Plot grouped bars for each product
bars_a = ax.bar(x - width, sales_a, width, label='Widget A', color=colors[0])
bars_b = ax.bar(x, sales_b, width, label='Widget B', color=colors[1])
bars_c = ax.bar(x + width, sales_c, width, label='Widget C', color=colors[2])
# Add value labels on top of each bar
for i, v in enumerate(sales_a):
ax.text(i - width, v + 2, f'{v}', ha='center', va='bottom', fontweight='bold')
for i, v in enumerate(sales_b):
ax.text(i, v + 2, f'{v}', ha='center', va='bottom', fontweight='bold')
for i, v in enumerate(sales_c):
ax.text(i + width, v + 2, f'{v}', ha='center', va='bottom', fontweight='bold')
# Customize the plot: titles, labels, legend, grid, and styling
ax.set_xlabel('Quarters', fontsize=12, fontweight='bold')
ax.set_ylabel('Sales (thousands of units)', fontsize=12, fontweight='bold')
ax.set_title('Quarterly Sales Comparison for Widgets A, B, and C', fontsize=14, fontweight='bold', pad=20)
ax.set_xticks(x)
ax.set_xticklabels(quarters)
ax.legend(loc='upper left')
ax.grid(axis='y', linestyle='--', alpha=0.7)
# Adjust layout to prevent label cutoff
plt.tight_layout()
# Display the plot
plt.show()
```
What makes these work
-
01Describe your data structure explicitly
Vague prompts like 'make a bar chart of sales data' produce generic placeholder code with fake variable names that you have to rewire anyway. Tell the AI the exact column names, data types, and whether you are working with a list, numpy array, or pandas DataFrame. The more specific the data description, the more directly usable the output.
-
02Specify style requirements in the prompt
Matplotlib's defaults are ugly and inconsistent. Include your style preferences in the prompt: grid visibility, spine removal, font size, figure size in inches, and color choices. An AI will apply these if asked but will not invent good defaults on its own. Requesting plt.style.use or specific rcParams in the prompt costs you five words and saves you ten minutes of cleanup.
-
03Ask for runnable standalone code
Explicitly request that the output include all imports and sample data so you can run it immediately without modification. This forces the model to produce a complete, self-contained script rather than a code snippet that assumes context you have to supply. Once it runs, replacing the sample data with your real data source is a two-line change.
-
04Request inline comments for unfamiliar chart types
If you are generating code for a chart type you rarely write, add 'include brief comments explaining each major step' to your prompt. This turns the output into a learning artifact you can modify confidently rather than opaque code you are afraid to touch. It also makes debugging faster when something does not render as expected.
More example scenarios
Generate matplotlib code for a horizontal bar chart showing monthly sales totals for 6 months: Jan 42000, Feb 38000, Mar 51000, Apr 47000, May 63000, Jun 58000. Use a blue color palette, add value labels at the end of each bar, include a title 'Monthly Sales H1 2024', and set clean gridlines on the x-axis only.
The AI should produce a complete script with explicit month labels and values defined as lists, plt.barh for horizontal bars, a loop using ax.text to place value annotations at bar ends, ax.xaxis.grid with alpha styling, spines removed for a clean look, and plt.tight_layout before plt.show. All imports included at the top.
Write matplotlib code for a multi-line chart. I have three models tracked over 10 training epochs. Model A accuracy: [0.55, 0.61, 0.67, 0.72, 0.76, 0.79, 0.81, 0.83, 0.84, 0.85]. Model B: [0.60, 0.65, 0.70, 0.74, 0.77, 0.79, 0.80, 0.81, 0.81, 0.82]. Model C: [0.50, 0.58, 0.65, 0.71, 0.76, 0.80, 0.83, 0.85, 0.87, 0.88]. Add a legend, label axes, and highlight the best-performing epoch for each model with a marker.
The AI should produce code using plt.plot three times with distinct linestyles or colors, np.argmax to find peak epoch per model, ax.scatter or ax.plot with a star marker at that point, a labeled legend, x-axis ticks set to epoch numbers 1 through 10, and appropriate axis labels and title.
Generate matplotlib code for a scatter plot showing ad spend vs revenue. Use randomly seeded sample data with 50 points where revenue roughly correlates with spend. Add a linear regression line using numpy polyfit, color the scatter points by a third variable called 'channel' with three categories, include a colorbar or legend, and label the axes clearly.
The AI should use np.random.seed for reproducibility, create a channel category array, use a loop or scatter with c parameter and a categorical colormap, call np.polyfit and np.poly1d to compute and plot the regression line, add a legend mapping colors to channel names, and include axis labels with units in parentheses.
Write matplotlib code to create a heatmap using imshow. I have a 5x4 matrix of feature engagement scores for 5 user segments across 4 product features. Use a diverging colormap centered at 50, add text annotations showing the value in each cell, label the x-axis with feature names and y-axis with segment names, and include a colorbar.
The AI should define a 5x4 numpy array with sample values, use ax.imshow with a diverging colormap like RdYlGn and vmin/vmax set to 0 and 100, loop over the matrix to place ax.text annotations in each cell with contrasting color logic, set x and y tick labels from provided name lists, add plt.colorbar, and handle tight layout.
Generate matplotlib code for a histogram of daily stock returns. Simulate 500 daily returns from a normal distribution with mean 0.001 and std 0.02. Overlay a fitted normal distribution curve, add vertical dashed lines at the 5th and 95th percentiles, shade the tails red, and include a title and axis labels. Use a clean minimal style.
The AI should use np.random.normal to generate data, plt.hist with density equals True and an alpha fill, scipy.stats.norm to fit and plot the PDF overlay, np.percentile to compute cutoffs, ax.axvline for dashed percentile lines, ax.fill_betweenx or histogram bin shading for red tails, and plt.style.use with a minimal style like seaborn-v0_8-whitegrid.
Common mistakes to avoid
-
Omitting data shape from the prompt
If you say 'I have sales data' without specifying rows, columns, and types, the model will invent a structure. The generated code will use column names like 'sales' or 'value' that do not match your actual DataFrame. You then spend more time debugging than you would have spent writing the code yourself.
-
Assuming the code runs without testing it
AI-generated matplotlib code almost always needs at least one small fix, a missing import, a deprecated function call, or a version-specific method difference. Copy it into a live environment and run it before embedding it in any production notebook or report pipeline. Never forward generated code to a colleague as verified without running it first.
-
Using vague color or style instructions
Prompts like 'make it look professional' or 'use nice colors' produce inconsistent results across models. Specify exact hex codes, named matplotlib colors, or a named style sheet. Vague aesthetic instructions waste one prompt iteration that forces you to re-prompt with specifics anyway.
-
Ignoring matplotlib version differences
Some AI models were trained on older matplotlib documentation and will generate code using deprecated APIs, like plt.set_cmap or certain seaborn integration patterns, that raise warnings or errors in current versions. If you hit an error, add your matplotlib version to the prompt and ask the model to regenerate using the current API.
-
Asking for too many chart types in one prompt
Prompting for a dashboard with four different subplot types in a single request often produces code where the subplot layout logic is wrong or the axes objects get confused. Generate each chart type separately, confirm it runs, then ask a follow-up prompt to combine them into a plt.subplots grid. This produces cleaner, debuggable code.
Related queries
Frequently asked questions
Which AI model is best for generating matplotlib chart code?
GPT-4 class models and Claude tend to produce the most complete and runnable matplotlib code out of the box, with correct imports and working subplot logic. Smaller or older models often produce syntactically correct but logically incomplete code, missing axis labels or using wrong method signatures. The comparison table on this page shows the specific differences across four tested models.
Can AI generate matplotlib code from a pandas DataFrame?
Yes, and it works well when you describe the DataFrame schema in the prompt. Include the column names, the data types, and whether the DataFrame is wide or long format. Tell the AI whether you want it to call df.plot with matplotlib backend or use pure matplotlib with df column access. These distinctions produce meaningfully different code.
How do I get AI to generate matplotlib code that uses my actual data?
Paste a small representative sample of your data directly into the prompt, or describe the exact structure with column names and sample values. The AI cannot access your files, so you have to supply the schema. For large DataFrames, describe the columns and types rather than pasting thousands of rows. Once the generated code runs on sample data, replacing it with your real data source is straightforward.
Can I use AI to convert a matplotlib chart to Plotly or Seaborn?
Yes, conversion prompts work reasonably well. Provide the existing matplotlib code and ask the model to rewrite it using the target library. Results are most reliable for standard chart types like bar, line, and scatter. Complex custom matplotlib code with many manual patches, annotations, or figure artists may not translate cleanly and will require manual adjustment.
Why does the AI-generated matplotlib code sometimes produce a blank chart?
Blank charts usually come from mismatched data shapes, an empty array being plotted, or plt.show being called before data is assigned to the axes. Check that the sample data in the generated code is structured the way the plot function expects. If you replaced the sample data with your own, confirm the shape matches what the original code assumed.
Can AI generate matplotlib subplots with multiple chart types?
It can, but prompt clarity matters significantly here. Specify the grid layout explicitly, such as 'a 2x2 subplot grid where the top-left is a bar chart, top-right is a line chart, bottom-left is a scatter plot, and bottom-right is a histogram.' When the layout instruction is vague, models frequently mix up axes object assignments and the chart types end up in the wrong positions.
Try it with a real tool
Run this prompt in one of these tools. Affiliate links help keep Gridlyx free.