Generate Python Matplotlib Visualizations with AI

Tested prompts for ai generate matplotlib chart code compared across 5 leading AI models.

BEST BY JUDGE SCORE Claude Haiku 4.5 9/10

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

ModelQualityCostLatencyTokens
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

Claude Opus 4.7 9/10
```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()
```
Judge notes: Nearly flawless—correct color-blind palette with proper attribution, clean helper function, all required elements present; the only minor nitpick is the bars could include edge colors or slight styling enhancements for publication quality.
Claude Haiku 4.5 9/10
```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
Judge notes: Nearly flawless — the only minor nitpick is that the y-axis K-format and the bar labels showing full dollar amounts (e.g., $45,000) create a slight inconsistency in unit representation, but this is trivial.
GPT-5.4 9/10
```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()
```
Judge notes: Nearly flawless and production-ready; the only minor nitpick is that `bar_width=0.24` leaves a small gap between bars that could be `0.25` for perfectly flush grouping, but this is trivial.
Gemini 2.5 Pro 5/10
```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
Judge notes: The output is truncated mid-line (`ax.legend(loc='upper left', ncols`), making the code non-runnable as delivered, which is a critical failure for a "complete, self-contained" code generation task.
Grok 4.1 Fast Reasoning 8/10
```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()
```
Judge notes: Fully functional and well-structured, but uses a manual value-label loop instead of the more concise `ax.bar_label()` method, and could use `zip` or a loop to avoid repeating bar/label code three times.

What makes these work

  1. 01
    Describe 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.

  2. 02
    Specify 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.

  3. 03
    Ask 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.

  4. 04
    Request 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

#01 · Sales performance bar chart for a retail analyst
Input
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.
Expected output
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.
#02 · Time series line chart for a data scientist tracking model accuracy
Input
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.
Expected output
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.
#03 · Scatter plot with regression line for a marketing analyst
Input
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.
Expected output
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.
#04 · Heatmap for a product team reviewing feature engagement
Input
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.
Expected output
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.
#05 · Distribution histogram for a finance analyst reviewing return data
Input
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.
Expected output
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.