How to Create a Line Chart in Matplotlib

Matplotlib is Python's foundational plotting library, and line charts are its bread and butter. If you're visualizing trends over time, tracking continuous measurements, or comparing sequential data,...

Key Insights

  • Matplotlib’s plot() function creates line charts with just two lines of code, but mastering customization options transforms basic visualizations into publication-ready graphics
  • Multiple datasets on a single chart require careful attention to colors, line styles, and legends to maintain clarity—avoid plotting more than 4-5 lines on one axes
  • Professional line charts need proper axis labels, appropriate figure sizing (10-12 inches wide for presentations), and explicit DPI settings (300+ for print) rather than relying on defaults

Introduction to Matplotlib Line Charts

Matplotlib is Python’s foundational plotting library, and line charts are its bread and butter. If you’re visualizing trends over time, tracking continuous measurements, or comparing sequential data, line charts are your go-to tool. They excel at showing patterns, trajectories, and relationships in ordered datasets—think stock prices, temperature readings, or user growth metrics.

The pyplot module provides a MATLAB-like interface that makes creating charts straightforward. Here’s what you need to get started:

import matplotlib.pyplot as plt
import numpy as np

That’s it. Two imports give you everything needed for sophisticated line visualizations. NumPy isn’t strictly required, but you’ll use it constantly for generating sample data and manipulating arrays.

Creating Your First Line Chart

The plot() function does the heavy lifting. Pass it x-coordinates and y-coordinates, then call show() to display the result:

import matplotlib.pyplot as plt

# Simple data
x = [1, 2, 3, 4, 5, 6, 7]
y = [2, 4, 3, 7, 5, 8, 6]

# Create the line chart
plt.plot(x, y)
plt.show()

This produces a basic line chart with default styling—a solid blue line connecting your data points. The x-axis automatically scales from 1 to 7, and the y-axis adjusts to fit your y-values.

If you only provide one array, Matplotlib treats it as y-values and generates sequential integers for x-values:

# Just y-values
sales = [120, 135, 128, 145, 160, 155, 170]
plt.plot(sales)
plt.show()

This works fine for quick exploratory analysis, but explicit x-values make your intent clearer and avoid confusion.

Customizing Line Appearance

Default blue lines get boring fast. Matplotlib offers extensive customization through additional parameters to plot():

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 50)
y = np.sin(x)

# Customize line style, color, width, and markers
plt.plot(x, y, 
         linestyle='--',      # Dashed line
         color='red',         # Red color
         linewidth=2,         # Thicker line
         marker='o',          # Circle markers
         markersize=4,        # Marker size
         markerfacecolor='yellow',  # Marker fill
         markeredgecolor='red')     # Marker outline

plt.show()

Common line styles:

  • '-' or 'solid': Solid line (default)
  • '--' or 'dashed': Dashed line
  • '-.' or 'dashdot': Dash-dot pattern
  • ':' or 'dotted': Dotted line

Colors accept names ('red', 'blue'), hex codes ('#FF5733'), or RGB tuples ((0.1, 0.2, 0.5)). For markers, try 'o' (circles), 's' (squares), '^' (triangles), or '*' (stars).

You can also use format strings for concise styling:

plt.plot(x, y, 'r--')  # Red dashed line
plt.plot(x, y, 'go-')  # Green line with circle markers
plt.plot(x, y, 'b^:')  # Blue dotted line with triangle markers

Adding Labels and Titles

Unlabeled charts are useless in professional contexts. Always add descriptive labels and titles:

import matplotlib.pyplot as plt
import numpy as np

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
revenue = [45000, 52000, 48000, 61000, 58000, 67000]

plt.plot(months, revenue, marker='o', linewidth=2, color='#2E86AB')

# Add labels and title
plt.xlabel('Month', fontsize=12)
plt.ylabel('Revenue ($)', fontsize=12)
plt.title('Q1-Q2 Revenue Trend', fontsize=14, fontweight='bold')

# Add grid for readability
plt.grid(True, alpha=0.3, linestyle='--')

plt.show()

The grid() function adds reference lines that help readers extract values. Set alpha below 1.0 to make grid lines subtle rather than distracting.

Plotting Multiple Lines

Comparing datasets requires multiple lines on the same axes. Call plot() multiple times before show():

import matplotlib.pyplot as plt

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
product_a = [45000, 52000, 48000, 61000, 58000, 67000]
product_b = [38000, 41000, 43000, 47000, 52000, 54000]
product_c = [29000, 31000, 35000, 38000, 42000, 48000]

plt.plot(months, product_a, marker='o', label='Product A', linewidth=2)
plt.plot(months, product_b, marker='s', label='Product B', linewidth=2)
plt.plot(months, product_c, marker='^', label='Product C', linewidth=2)

plt.xlabel('Month', fontsize=12)
plt.ylabel('Sales ($)', fontsize=12)
plt.title('Product Sales Comparison', fontsize=14, fontweight='bold')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

plt.show()

The label parameter in each plot() call defines legend text. Call legend() to display it—loc controls placement ('upper left', 'lower right', 'best' for automatic positioning).

Limit yourself to 4-5 lines maximum. Beyond that, charts become cluttered and hard to interpret. Consider faceting (multiple subplots) or filtering your data instead.

Advanced Formatting

Professional visualizations require attention to sizing, resolution, and axis formatting:

import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime, timedelta

# Generate date range
start_date = datetime(2024, 1, 1)
dates = [start_date + timedelta(days=i*7) for i in range(26)]
values = np.random.randn(26).cumsum() + 100

# Set figure size and DPI
plt.figure(figsize=(12, 6), dpi=100)

plt.plot(dates, values, linewidth=2.5, color='#A23B72', marker='o', markersize=5)

plt.xlabel('Date', fontsize=13)
plt.ylabel('Metric Value', fontsize=13)
plt.title('Weekly Performance Metrics - 2024', fontsize=15, fontweight='bold', pad=20)

# Format date axis
plt.gcf().autofmt_xdate()  # Rotate date labels

# Set axis limits
plt.ylim(bottom=95)  # Start y-axis at 95

plt.grid(True, alpha=0.3, linestyle='--')
plt.tight_layout()  # Prevent label cutoff

# Save to file
plt.savefig('performance_chart.png', dpi=300, bbox_inches='tight')
plt.show()

Key parameters:

  • figsize=(width, height): Dimensions in inches (10-12 wide for presentations)
  • dpi: Dots per inch (100 for screen, 300+ for print)
  • tight_layout(): Automatically adjusts spacing to prevent overlapping elements
  • savefig(): Exports to PNG, PDF, SVG, or other formats

For date axes, gcf().autofmt_xdate() rotates labels to prevent overlap. You can also use matplotlib.dates for fine-grained date formatting.

Practical Example: Website Traffic Analysis

Here’s a complete example analyzing website traffic over a quarter:

import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime, timedelta

# Generate realistic traffic data
np.random.seed(42)
start_date = datetime(2024, 1, 1)
dates = [start_date + timedelta(days=i) for i in range(90)]

# Simulate traffic with weekly patterns and growth trend
base_traffic = 5000
weekly_pattern = np.tile([1.0, 0.95, 0.9, 0.85, 0.9, 1.2, 1.3], 13)[:90]
growth = np.linspace(1.0, 1.4, 90)
noise = np.random.normal(0, 200, 90)
daily_visitors = base_traffic * weekly_pattern * growth + noise

# Calculate 7-day moving average
moving_avg = np.convolve(daily_visitors, np.ones(7)/7, mode='valid')
moving_avg_dates = dates[6:]  # Align dates with moving average

# Create professional chart
plt.figure(figsize=(14, 7), dpi=100)

plt.plot(dates, daily_visitors, linewidth=1, alpha=0.4, 
         color='#3498db', label='Daily Visitors')
plt.plot(moving_avg_dates, moving_avg, linewidth=2.5, 
         color='#e74c3c', label='7-Day Moving Average')

plt.xlabel('Date', fontsize=13, fontweight='bold')
plt.ylabel('Unique Visitors', fontsize=13, fontweight='bold')
plt.title('Website Traffic - Q1 2024', fontsize=16, fontweight='bold', pad=20)

plt.legend(loc='upper left', fontsize=11, framealpha=0.9)
plt.grid(True, alpha=0.3, linestyle='--', linewidth=0.5)
plt.gcf().autofmt_xdate()

# Format y-axis with thousands separator
ax = plt.gca()
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{int(x):,}'))

plt.tight_layout()
plt.savefig('website_traffic_q1.png', dpi=300, bbox_inches='tight')
plt.show()

This example demonstrates best practices:

  • Clear visual hierarchy: Raw data in light color, trend line prominent
  • Meaningful aggregation: Moving average smooths daily noise
  • Professional formatting: Thousands separators, rotated dates, proper sizing
  • Export-ready: High DPI, tight bounding box for clean exports

Line charts are deceptively simple but endlessly configurable. Master these fundamentals—basic plotting, styling, labeling, and multi-line comparisons—and you’ll handle 90% of real-world visualization needs. The remaining 10% is knowing when to use a different chart type entirely.

Liked this? There's more.

Every week: one practical technique, explained simply, with code you can use immediately.