Pandas: Data Visualization
Last updated: 2026-08-26
Nobody wants to stare at raw numbers -- your boss wants charts, reports need charts, and slide decks need charts. Pandas' df.plot generates a chart in a single line, powered by the Matplotlib engine under the hood. This section covers the 8 most commonly used chart types, subplot layouts, and style customization so you can quickly turn any DataFrame into a visual report.
⚠️ Note: The code below must be run in a local Python environment with matplotlib installed.
1. What You Will Learn
- ❶ df.plot basics
- ❷ Chart types (line/bar/hist/box/scatter/pie/area/kde)
- ❸ subplots layout
- ❹ Style customization
- ❺ Saving and exporting
2. Bob's Sales Visualization Report
(1) The Problem: Nobody Reads Tables
Bob presents monthly sales to his boss, but nobody bothers looking at plain tables.
(2) The Solution: One-Line Charts with df.plot
▶ Example: df.plot Basics (Difficulty ⭐)
PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Sample data
df = pd.DataFrame({
'month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
'sales': [3200, 3500, 3800, 3600, 4100, 4500],
'cost': [2000, 2200, 2400, 2300, 2600, 2800]
})
df = df.set_index('month')
# Line chart — one line of code!
df['sales'].plot(kind='line', title='Monthly Sales Trend', figsize=(8, 4))
plt.ylabel('Sales ($)')
plt.tight_layout()
# plt.savefig('sales_trend.png', dpi=150)
# plt.show()
print("Line chart created!")
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
3. Chart Type Quick Reference
(1) 8 Common Chart Types
| kind | Chart | Use Case |
|---|---|---|
| line | Line chart | Time trends |
| bar | Bar chart | Category comparison |
| barh | Horizontal bar chart | Categories with long labels |
| hist | Histogram | Distribution |
| box | Box plot | Distribution + outliers |
| scatter | Scatter plot | Correlation |
| pie | Pie chart | Proportions |
| area | Area chart | Cumulative trends |
| kde | Kernel density | Smooth distribution |
▶ Example
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
: Multiple Chart Types (Difficulty ⭐⭐)
PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
df = pd.DataFrame({
'category': ['Electronics', 'Clothing', 'Home', 'Sports', 'Books'],
'sales': [5000, 3000, 2000, 1500, 800],
'avg_price': [299, 55, 75, 45, 15],
'rating': [4.5, 4.2, 3.9, 4.0, 4.3]
})
# Bar chart — category comparison
df.plot(kind='bar', x='category', y='sales', title='Sales by Category', figsize=(8, 4))
# plt.show()
# Horizontal bar — better for long labels
df.plot(kind='barh', x='category', y='sales')
# plt.show()
# Pie chart — proportions
df.set_index('category')['sales'].plot(kind='pie', autopct='%1.1f%%', figsize=(6, 6))
# plt.show()
# Histogram — distribution
prices = pd.Series(np.random.normal(100, 30, 500))
prices.plot(kind='hist', bins=20, title='Price Distribution')
# plt.show()
# Box plot — distribution + outliers
scores = pd.DataFrame({
'Math': np.random.normal(75, 10, 100),
'English': np.random.normal(80, 12, 100),
'Science': np.random.normal(70, 15, 100)
})
scores.plot(kind='box', title='Score Distribution by Subject')
# plt.show()
# Scatter — correlation
df.plot(kind='scatter', x='avg_price', y='rating', title='Price vs Rating', s=100)
# plt.show()
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
4. Subplot Layout
▶ Example
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
: subplots Multi-Chart Layout (Difficulty ⭐⭐)
PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
df = pd.DataFrame({
'A': np.random.randn(50).cumsum(),
'B': np.random.randn(50).cumsum(),
'C': np.random.randn(50).cumsum(),
'D': np.random.randn(50).cumsum()
})
# Each column in its own subplot
df.plot(subplots=True, layout=(2, 2), figsize=(10, 8), sharey=True)
plt.suptitle('4 Series Trend')
plt.tight_layout()
# plt.show()
# Custom layout
df[['A', 'B']].plot(subplots=True, layout=(1, 2), figsize=(12, 4))
# plt.show()
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
5. Style Customization
▶ Example
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
: Style Customization (Difficulty ⭐⭐)
PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
df = pd.DataFrame({
'sales': np.random.randint(100, 500, 12),
'profit': np.random.randint(10, 150, 12)
}, index=pd.date_range('2024-01', periods=12, freq='MS').strftime('%b'))
# Custom colors, markers, line style
ax = df.plot(
kind='line',
style=['o-', 's--'], # markers + line style
color=['#2196F3', '#FF5722'], # custom colors
figsize=(10, 5),
title='Monthly Sales & Profit',
xlabel='Month',
ylabel='Amount ($)',
grid=True,
alpha=0.8
)
# Add annotations
ax.axhline(y=df['sales'].mean(), color='gray', linestyle=':', label='Avg Sales')
ax.legend(loc='upper left')
plt.tight_layout()
# plt.show()
print("Styled chart created!")
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
6. Pandas vs Matplotlib
| Feature | df.plot | Matplotlib |
|---|---|---|
| Lines of code | 1 | 5-15 |
| Flexibility | Medium | High |
| Learning curve | Low | High |
| Customization | Basic | Unlimited |
| Relationship | Wraps Matplotlib | Underlying engine |
💡 Tip: df.plot returns a Matplotlib Axes object, so you can keep refining it with Matplotlib methods. Strategy: use df.plot for a quick draft, then fine-tune details via the Axes object.
7. Complete Example: E-Commerce Sales Visualization Report
(4) ▶ Chart Selection Decision Tree
graph TB
A[What do you want to show?] --> B{Trend over time?}
B -->|Yes| C[Line chart]
B -->|No| D{Category comparison?}
D -->|Yes| E[Bar chart]
D -->|No| F{Data distribution?}
F -->|Yes| G[Histogram hist / Box plot]
F -->|No| H{Correlation?}
H -->|Yes| I[Scatter plot]
H -->|No| J{Proportions?}
J -->|Yes| K[Pie chart]
J -->|No| L[Area chart]
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
▶ Example
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
: Full Visualization Report Workflow (Difficulty ⭐⭐⭐)
PYTHON
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# ============================================
# Comprehensive example: E-commerce sales
# visualization report with multiple charts
# ============================================
np.random.seed(42)
df = pd.DataFrame({
'month': pd.date_range('2024-01', periods=12, freq='MS'),
'Electronics': np.random.randint(3000, 8000, 12),
'Clothing': np.random.randint(1000, 4000, 12),
'Home': np.random.randint(500, 2500, 12),
'Sports': np.random.randint(300, 1500, 12)
})
df = df.set_index('month')
# 1. Line: monthly trend
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
df.plot(ax=axes[0, 0], kind='line', title='Monthly Sales by Category')
axes[0, 0].set_ylabel('Sales ($)')
# 2. Bar: total by category
df.sum().plot(ax=axes[0, 1], kind='bar', title='Annual Sales by Category', color='steelblue')
axes[0, 1].set_ylabel('Total Sales ($)')
# 3. Pie: market share
df.sum().plot(ax=axes[1, 0], kind='pie', autopct='%1.1f%%', title='Market Share')
# 4. Area: cumulative trend
df.plot(ax=axes[1, 1], kind='area', alpha=0.5, title='Cumulative Sales Trend')
axes[1, 1].set_ylabel('Sales ($)')
plt.suptitle('2024 E-Commerce Sales Report', fontsize=16)
plt.tight_layout()
# plt.savefig('sales_report.png', dpi=150, bbox_inches='tight')
print("4-chart report created!")
TEXT
📖 Display only
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed -- please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
❓ FAQ
Q What is the relationship between Pandas plot and Matplotlib?
A df.plot is a high-level wrapper around Matplotlib -- it calls matplotlib.pyplot under the hood and returns an Axes object. Use df.plot for simple charts (one line does the job), and Matplotlib for complex customization (start with df.plot for the base chart, then refine with Axes methods). The two work together seamlessly.
Q What values does the kind parameter accept?
A line (line chart/default), bar (bar chart), barh (horizontal bar), hist (histogram), box (box plot), kde/density (kernel density), area (area chart), pie (pie chart), scatter (scatter plot), hexbin (hexagonal binning). The most commonly used are: line/bar/hist/scatter.
Q How do I arrange subplots?
A subplots=True gives each column its own subplot, and layout=(rows, cols) specifies the grid. For example, layout=(2,2) creates a 2x2 grid. sharex/sharey=True shares axes across subplots. You can also do it manually:
fig, axes = plt.subplots(2,2) then df.plot(ax=axes[0,0]) to place charts in specific positions.Q How do I save a chart as an image?
A Use
plt.savefig('filename.png', dpi=150, bbox_inches='tight'). The dpi parameter controls resolution (150 = medium, 300 = high quality). bbox_inches='tight' prevents labels from being clipped. Supported formats include png/jpg/svg/pdf. Do not call plt.show() before saving (show clears the figure).Q How do I fix garbled Chinese characters?
A Two options: (1)
plt.rcParams['font.sans-serif'] = ['SimHei'] to set a Chinese font (Windows); (2) use English for titles and labels (recommended, avoids font compatibility issues). Option 2 is more universal -- it works cross-platform without depending on font files.Q How do I add a color mapping to a scatter plot?
A Use the c parameter to specify a color column:
df.plot(kind='scatter', x='price', y='rating', c='sales', cmap='viridis', colorbar=True). The cmap parameter sets the colormap (viridis/coolwarm/RdYlGn), and colorbar displays the legend. The s parameter controls marker size.Q How do I overlay plots on the same axes?
A Use the ax parameter:
ax1 = df1.plot() then df2.plot(ax=ax1). The second plot overlays on the first, sharing the same axes. This is great for comparing multiple datasets. Set label and legend to distinguish them.📖 Summary
- df.plot(kind=...) creates a chart in one line, powered by Matplotlib under the hood
- 8 chart types: line (trends) / bar (comparison) / hist (distribution) / box (distribution + outliers) / scatter (correlation) / pie (proportions) / area (cumulative) / kde (density)
- subplots=True for multiple subplots, layout=(r,c) for grid arrangement
- Style customization: style/color/figsize/title/grid/alpha/axhline
- df.plot returns an Axes object -- keep refining with Matplotlib methods
- Saving: plt.savefig(path, dpi, bbox_inches)
- Strategy: df.plot for a quick draft, then Matplotlib for fine-tuning details
📝 Exercises
- Basic (Difficulty ⭐): Create a monthly sales DataFrame and display it using line, bar, and pie charts. Compare how each chart type presents the same data.
- Intermediate (Difficulty ⭐⭐): Create a multi-column DataFrame and use subplots=True to draw a 2x2 grid of subplots (line/bar/box/hist). Add titles and gridlines.
- Challenge (Difficulty ⭐⭐⭐): Simulate 12 months of sales data across 4 product categories. Create a 4-chart report: a trend line chart, an annual bar chart, a proportion pie chart, and a price-vs-rating scatter plot. Save the result as a PNG file.
← Previous: Window Functions · Next: Performance Optimization →