Plot Pandas DataFrames Using AI Assistants

Tested prompts for ai tool to plot pandas dataframe compared across 5 leading AI models.

BEST BY JUDGE SCORE Claude Haiku 4.5 8/10

The prompt we tested

You are a Python data visualization assistant that helps users plot pandas DataFrames. Given the user's DataFrame description and visualization goal below, produce ready-to-run Python code using pandas and matplotlib (or seaborn/plotly when clearly better) to create the requested plot.

Respond in under 250 words. Output must include exactly one fenced ```python code block that runs end-to-end assuming the user's DataFrame is named `df`, with clear axis labels, a title, and plt.show() at the end. Keep prose concise and avoid unnecessary data-cleaning steps unless the user's input requires them.

User's DataFrame and plotting request:
I have a pandas DataFrame called df with columns 'date' (datetime), 'product', and 'revenue'. It covers 3 products over 12 months of 2024. I want to visualize monthly revenue trends per product so I can compare which product is growing fastest.

Return: (1) a brief recommendation of the best chart type for this data, (2) a complete, copy-pasteable Python code block including imports and sample df.head() assumptions, (3) short notes explaining key styling choices (labels, title, figure size, color) and one suggested variation.

Model comparison

ModelQualityCostLatencyTokens
Claude Opus 4.7 8 $0.0589 10.2s 399 / 705
Claude Haiku 4.5 8 $0.0028 5.8s 273 / 513
GPT-5.4 7 $0.0057 7.7s 252 / 339
Gemini 2.5 Pro 7 $0.0032 17.9s 261 / 568
Grok 4.1 Fast Reasoning 7 $0.0002 12.7s 399 / 302

Outputs

Claude Opus 4.7 8/10
**Recommendation:** A multi-line chart with one line per product is ideal here—it makes trend direction and relative growth rates easy to compare at a glance.

```python
import pandas as pd
import matplotlib.pyplot as plt

# Assumes df.head() looks like:
#         date   product  revenue
# 0 2024-01-01        A     1200
# 1 2024-01-01        B      950
# 2 2024-01-01        C      780

# Aggregate to monthly revenue per product
df['date'] = pd.to_datetime(df['date'])
monthly = (df.groupby([pd.Grouper(key='date', freq='MS'), 'product'])['revenue']
             .sum()
             .unstack('product'))

# Plot
fig, ax = plt.subplots(figsize=(10, 6))
monthly.plot(ax=ax, marker='o', linewidth=2, colormap='tab10')

ax.set_title('Monthly Revenue Trends by Product (2024)', fontsize=14, fontweight='bold')
ax.set_xlabel('Month')
ax.set_ylabel('Revenue')
ax.legend(title='Product', frameon=False)
ax.grid(True, linestyle='--', alpha=0.5)
fig.autofmt_xdate()
plt.tight_layout()
plt.show()
```

**Styling notes:**
- **Figure size (10×6):** wide enough to space out 12 monthly ticks without crowding.
- **Markers + lines:** markers highlight discrete monthly points while lines convey trend.
- **`tab10` colormap:** categorically distinct colors for 3 products, colorblind-friendlier than defaults.
- **Dashed grid at low alpha:** aids reading values without dominating the chart.
- **Bold title, clean legend (no frame):** keeps focus on the data.

**Variation:** To compare *growth rates* directly rather than absolute levels, normalize each product to its January value (`monthly / monthly.iloc[0] * 100`) and plot as an indexed trend — the fastest grower will have the steepest line.
Judge notes: The output is production-ready and complete, but the prose slightly exceeds necessity and the variation note, while useful, is described but not shown as runnable code, leaving a small gap between promise and delivery.
Claude Haiku 4.5 8/10
## Recommendation

A **line plot** is ideal here—it clearly shows revenue trends over time and makes growth rates easy to compare across products.

## Code

```python
import pandas as pd
import matplotlib.pyplot as plt

# Sample DataFrame structure (adjust if needed)
df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=36, freq='MS'),
    'product': ['A']*12 + ['B']*12 + ['C']*12,
    'revenue': [10000 + i*500 for i in range(12)] + 
               [12000 + i*800 for i in range(12)] + 
               [8000 + i*300 for i in range(12)]
})

# Pivot for easier plotting
pivot_df = df.pivot_table(values='revenue', index='date', columns='product')

# Create line plot
plt.figure(figsize=(10, 6))
for product in pivot_df.columns:
    plt.plot(pivot_df.index, pivot_df[product], marker='o', label=product, linewidth=2)

plt.xlabel('Date', fontsize=11, fontweight='bold')
plt.ylabel('Revenue ($)', fontsize=11, fontweight='bold')
plt.title('Monthly Revenue Trends by Product (2024)', fontsize=13, fontweight='bold')
plt.legend(title='Product', frameon=True, shadow=True)
plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```

## Key Styling Notes

- **Line markers** ('o') highlight individual months for precision
- **Legend with shadow** makes product identification clear
- **Grid lines** (alpha=0.3) aid value reading without clutter
- **Bold labels/title** improve readability
- **Rotated x-axis** prevents date overlap

## Suggested Variation

Replace the line plot with a **stacked area chart** (`pivot_df.plot(kind='area', stacked=True)`) to emphasize total revenue composition, though this sacrifices easy individual product comparison.
Judge notes: Fully production-ready with clean code, clear structure, and useful variation, but minor nitpick: the sample data construction uses a workaround (repeated lists) rather than a cleaner `np.tile`/`pd.concat` approach, and the legend shadow styling is a trivial flourish that slightly oversells polish.
GPT-5.4 7/10
A multi-line time series chart is the best fit: it shows month-to-month revenue trends clearly and makes growth-rate comparisons across products easy.

```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Assumes df has columns: 'date' (datetime), 'product', 'revenue'
print(df.head())

# Ensure datetime and aggregate to monthly revenue per product
df['date'] = pd.to_datetime(df['date'])
monthly = (
    df.groupby([pd.Grouper(key='date', freq='MS'), 'product'], as_index=False)['revenue']
      .sum()
)

# Plot
sns.set_style("whitegrid")
plt.figure(figsize=(10, 6))

sns.lineplot(
    data=monthly,
    x='date',
    y='revenue',
    hue='product',
    marker='o',
    linewidth=2.5,
    palette='tab10'
)

plt.title('Monthly Revenue Trends by Product (2024)')
plt.xlabel('Month')
plt.ylabel('Revenue')
plt.xticks(monthly['date'].sort_values().unique(), rotation=45)
plt.legend(title='Product')
plt.tight_layout()
plt.show()
```

Notes:
- Labels and title make the chart immediately interpretable.
- A 10×6 figure keeps 12 monthly points readable without crowding.
- Distinct colors plus markers help compare products and spot growth patterns quickly.
- `whitegrid` improves readability for trend comparisons.

Suggested variation:
- If you want to emphasize overall change from January to December, try a slope chart or normalize each product to January = 100 for relative growth comparison.
Judge notes: The output is solid and mostly production-ready, but the `plt.xticks()` line using `.unique()` on sorted dates may produce inconsistent tick rendering, and the prompt explicitly asked for a sample `df.head()` assumption with actual sample data in the code (not just a print statement), making it not fully copy-pasteable without a pre-existing `df`.
Gemini 2.5 Pro 7/10
A line chart is the best choice here. It excels at showing trends over time for different categories, making it simple to compare the growth trajectories of your products on the same axes.

The code below uses seaborn's `lineplot`, which automatically groups the data by the 'product' column and assigns a unique color to each, creating a clear and comparative visualization.

```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# --- Sample DataFrame Creation ---
# This code simulates a DataFrame with your described structure.
dates = pd.to_datetime(pd.date_range(start='2024-01-01', periods=12, freq='MS'))
products = ['Product A', 'Product B', 'Product C']
data = []
for product in products:
    # Simulate different growth trends for visualization
    base_revenue = np.random.randint(800, 1500)
    growth_factor = 1 + np.random.uniform(0.05, 0.2)
    for i, date in enumerate(dates):
        revenue = base_revenue * (growth_factor ** (i/12)) + np.random.uniform(-50, 50)
        data.append([date, product, revenue])
df = pd.DataFrame(data, columns=['date', 'product', 'revenue'])

# --- Plotting Code ---
plt.style.use('seaborn-v0_8-whitegrid')
plt.figure(figsize=(12, 6))

# Create a line plot with a distinct line for each product
sns.lineplot(
    data=df,
    x='date',
    y='revenue',
    hue='product', # Automatically groups and colors by product
    marker='o'
)

# Add title and labels for clarity
plt.title('Monthly Revenue Trends by Product (2024)', fontsize=16)
plt.xlabel('Month', fontsize=12)
plt.ylabel('Revenue', fontsize=12)

plt.tight_layout()
plt.show()
```

**Notes:**
*   **Styling:** The `figsize` provides ample space for 12 months of data. The `hue` parameter is key, as it automatically handles the color-coding and legend. A title and axis labels are included for context.
*   **Variation:** You could create a bar chart grouped by month (`seaborn.barplot`) to compare exact revenue figures more directly for specific months, rather than focusing on the trend.
Judge notes: The output delivers a functional, well-structured response but falls short on two points: the sample DataFrame uses randomized data with non-reproducible results (missing `np.random.seed()`), and the "Notes" section is slightly thin—it doesn't explain the `marker='o'` choice or mention legend placement, which a demanding user would expect.
Grok 4.1 Fast Reasoning 7/10
1. **Best chart**: Seaborn lineplot (hue=product) – ideal for comparing multi-series time trends with smooth lines and markers.

```python
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Sample df.head() assumption:
#           date product  revenue
# 0 2024-01-15  ProductA    1000
# 1 2024-01-20  ProductB     800
# ... (datetime, 3 products, 12 months)

df['month'] = df['date'].dt.to_period('M')
monthly_df = df.groupby(['month', 'product'])['revenue'].sum().reset_index()

plt.figure(figsize=(12, 6))
sns.lineplot(data=monthly_df, x='month', y='revenue', hue='product', marker='o', linewidth=2.5)
plt.title('Monthly Revenue Trends by Product (2024)')
plt.xlabel('Month')
plt.ylabel('Total Revenue ($)')
plt.xticks(rotation=45)
plt.legend(title='Product')
plt.tight_layout()
plt.show()
```

3. **Notes**: Figsize=(12,6) for wide view; marker='o', linewidth=2.5 for emphasis; seaborn palette auto-assigns distinct colors (e.g., blue/orange/green); descriptive labels/title. **Variation**: Add `sns.lineplot(..., ci=None)` to disable confidence intervals if data is aggregated totals. (148 words)
Judge notes: The code has a subtle bug: `x='month'` passes Period objects to seaborn, which can cause axis label rendering issues (e.g., showing ordinal integers instead of readable month labels) without converting to string or datetime first, making the code not fully copy-paste reliable.

Related queries