Basic Line Plot¶
The plot() method is the fundamental tool for creating line plots in Matplotlib.
Simplest Line Plot¶
Provide only y-values (x-values are auto-generated as indices):
import matplotlib.pyplot as plt
y = [1, 5, 2]
plt.plot(y)
plt.show()
Providing X and Y Values¶
import matplotlib.pyplot as plt
x = [1, 2, 3]
y = [1, 5, 2]
plt.plot(x, y)
plt.show()
OOP Style¶
Using explicit Figure and Axes objects:
import matplotlib.pyplot as plt
import numpy as np
def main():
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y = np.sin(x)
fig, ax = plt.subplots(figsize=(12, 3))
ax.plot(x, y)
plt.show()
if __name__ == "__main__":
main()
Multiple Lines¶
Plot multiple lines on the same axes:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2*np.pi, 2*np.pi, 100)
y_sin = np.sin(x)
y_cos = np.cos(x)
fig, ax = plt.subplots(figsize=(12, 3))
ax.plot(x, y_sin)
ax.plot(x, y_cos)
plt.show()
Plot Returns Line2D Objects¶
The plot() method returns a list of Line2D objects:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-2*np.pi, 2*np.pi, 10)
y = np.sin(x)
lines = plt.plot(x, y, '--*r', ms=20)
plt.show()
print(type(lines)) # <class 'list'>
print(type(lines[0])) # <class 'matplotlib.lines.Line2D'>
With Labels and Title¶
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
y = x + x**2
fig, ax = plt.subplots(figsize=(12, 3))
ax.plot(x, y, color='g')
ax.set_title('$y = x + x^2$', fontsize=20)
ax.set_xlabel('$x$', fontsize=20)
ax.set_ylabel('$y$', fontsize=20)
plt.show()
Combining Multiple Options¶
Use the set() method for multiple properties at once:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
y = x + x**2
fig, ax = plt.subplots()
ax.plot(x, y, color='g')
ax.set(
title='$y = x + x^2$',
xlabel='$x$',
ylabel='$y$',
xlim=[0, 1],
ylim=(0, 2),
xticks=[0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
yticks=[0.0, 0.5, 1.0, 1.5, 2.0]
)
plt.show()
Practical Example: Financial Data¶
import matplotlib.pyplot as plt
import yfinance as yf
def main():
kospi_ticker = "^KS11"
kospi_data = yf.download(kospi_ticker, start="2023-01-01", end="2024-12-31")
close_prices = kospi_data["Close"]
fig, ax = plt.subplots(figsize=(12, 3))
ax.plot(close_prices, label="KOSPI Close")
ax.set_title("KOSPI Closing Prices")
ax.set_xlabel("Date")
ax.set_ylabel("Closing Price")
ax.legend()
ax.grid(True)
plt.show()
if __name__ == '__main__':
main()
Key Takeaways¶
plt.plot(y)uses indices as x-valuesplt.plot(x, y)specifies both coordinates- Multiple
plot()calls add lines to the same axes plot()returns a list ofLine2Dobjects- Use
ax.set()for multiple properties at once
Runnable Example: complete_guide_plot.py¶
"""
Matplotlib Tutorial - Intermediate Level
========================================
Topic: Complete Guide to plt.plot() - The Most Important Function
Author: Educational Python Course
Level: Intermediate
Learning Objectives:
-------------------
1. Master all parameters and options of plt.plot()
2. Understand line customization in depth
3. Learn marker customization
4. Create professional-quality line plots
5. Understand format strings and explicit parameters
6. Master multiple datasets on same axes
Prerequisites:
-------------
- Completion of all beginner tutorials
- Understanding of both MATLAB and OOP styles
- Basic NumPy knowledge
IMPORTANT:
---------
plt.plot() and ax.plot() have IDENTICAL parameters and behavior.
Everything here applies to both styles!
"""
import matplotlib.pyplot as plt
import numpy as np
# ============================================================================
# SECTION 1: Basic Signature and Return Values
# ============================================================================
if __name__ == "__main__":
"""
Complete Signature:
------------------
plot([x], y, [fmt], **kwargs)
Parameters:
-----------
x : array-like (optional)
X-coordinates. If not provided, uses range(len(y))
y : array-like
Y-coordinates (required)
fmt : str (optional)
Format string: '[marker][line][color]'
Examples: 'ro-', 'b--', 'g^:', 'k*-.'
**kwargs : keyword arguments
Explicit property settings (color, linewidth, marker, etc.)
Returns:
--------
list of Line2D objects
Can be used to modify line properties later
"""
# Example of return value
x = np.linspace(0, 10, 50)
y = np.sin(x)
line_objects = plt.plot(x, y)
print(f"Type of return value: {type(line_objects)}") # list
print(f"Number of Line2D objects: {len(line_objects)}") # 1
print(f"First line object: {line_objects[0]}")
plt.show()
# ============================================================================
# SECTION 2: Different Ways to Call plot()
# ============================================================================
print("=" * 70)
print("DIFFERENT WAYS TO CALL plot()")
print("=" * 70)
# Method 1: Only y values (x is automatically 0, 1, 2, ...)
y = [1, 4, 9, 16, 25]
plt.plot(y)
plt.title('Method 1: Only y values')
plt.xlabel('Index')
plt.ylabel('Value')
plt.show()
# Method 2: x and y values
x = [0, 1, 2, 3, 4]
y = [1, 4, 9, 16, 25]
plt.plot(x, y)
plt.title('Method 2: x and y values')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
# Method 3: x, y, and format string
x = np.linspace(0, 10, 50)
y = np.sin(x)
plt.plot(x, y, 'ro-') # red circles with solid line
plt.title('Method 3: x, y, and format string')
plt.show()
# Method 4: x, y, and keyword arguments
plt.plot(x, y, color='blue', linewidth=2, marker='o', markersize=8)
plt.title('Method 4: x, y, and keyword arguments')
plt.show()
# Method 5: Multiple datasets in one call
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x), x, np.cos(x), x, np.sin(2*x))
plt.title('Method 5: Multiple datasets')
plt.legend(['sin(x)', 'cos(x)', 'sin(2x)'])
plt.show()
# ============================================================================
# SECTION 3: Format Strings - The Compact Way
# ============================================================================
"""
Format String Syntax: '[marker][line][color]'
Order doesn't matter! All of these are equivalent:
- 'ro-' (red circles, solid line)
- 'r-o' (same)
- 'or-' (same)
- '-ro' (same)
Colors:
-------
'b' = blue 'g' = green 'r' = red 'c' = cyan
'm' = magenta 'y' = yellow 'k' = black 'w' = white
Line Styles:
-----------
'-' = solid line
'--' = dashed line
'-.' = dash-dot line
':' = dotted line
Markers:
--------
'.' = point 'o' = circle 's' = square
'^' = triangle up 'v' = triangle down '<' = triangle left
'>' = triangle right '*' = star '+' = plus
'x' = x mark 'D' = diamond 'p' = pentagon
'h' = hexagon '|' = vertical line '_' = horizontal line
"""
# Create a comprehensive example showing different format strings
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
axes = axes.flatten()
x = np.linspace(0, 10, 20)
y = x
format_strings = [
('ro-', 'Red circles, solid'),
('bs--', 'Blue squares, dashed'),
('g^:', 'Green triangles up, dotted'),
('mv-.', 'Magenta triangles down, dash-dot'),
('c*-', 'Cyan stars, solid'),
('yD--', 'Yellow diamonds, dashed'),
('kp:', 'Black pentagons, dotted'),
('r+-.', 'Red plus, dash-dot'),
]
for ax, (fmt, title) in zip(axes, format_strings):
ax.plot(x, y, fmt, markersize=8, linewidth=2)
ax.set_title(title)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# ============================================================================
# SECTION 4: Line Properties - Complete Reference
# ============================================================================
"""
Complete List of Line Properties:
---------------------------------
color / c : color specification
- Color name: 'red', 'blue', 'green', etc.
- Short code: 'r', 'g', 'b', 'c', 'm', 'y', 'k', 'w'
- Hex string: '#FF0000' (red), '#00FF00' (green)
- RGB tuple: (1.0, 0.0, 0.0) for red, values 0-1
- RGBA tuple: (1.0, 0.0, 0.0, 0.5) for semi-transparent red
linestyle / ls : line style
- '-' or 'solid'
- '--' or 'dashed'
- '-.' or 'dashdot'
- ':' or 'dotted'
- '' or ' ' or 'none' (no line)
linewidth / lw : float
- Width of the line in points (default: 1.5)
marker : marker style
- See list above (Section 3)
markersize / ms : float
- Size of markers in points
markerfacecolor / mfc : color
- Fill color of the marker
markeredgecolor / mec : color
- Edge color of the marker
markeredgewidth / mew : float
- Width of marker edge
alpha : float (0.0 to 1.0)
- Transparency (0 = fully transparent, 1 = fully opaque)
label : str
- Label for legend
zorder : int
- Drawing order (higher values drawn on top)
"""
# Demonstrating line properties
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
x = np.linspace(0, 10, 100)
# Different colors
axes[0, 0].plot(x, np.sin(x), color='red', linewidth=2)
axes[0, 0].plot(x, np.sin(x) + 1, color='#00FF00', linewidth=2)
axes[0, 0].plot(x, np.sin(x) + 2, color=(0, 0, 1), linewidth=2)
axes[0, 0].set_title('Different Color Specifications')
axes[0, 0].legend(['Name', 'Hex', 'RGB tuple'])
# Line styles
axes[0, 1].plot(x, np.sin(x), linestyle='-', linewidth=2, label='solid')
axes[0, 1].plot(x, np.sin(x) + 1, linestyle='--', linewidth=2, label='dashed')
axes[0, 1].plot(x, np.sin(x) + 2, linestyle='-.', linewidth=2, label='dashdot')
axes[0, 1].plot(x, np.sin(x) + 3, linestyle=':', linewidth=2, label='dotted')
axes[0, 1].set_title('Line Styles')
axes[0, 1].legend()
# Line widths
axes[0, 2].plot(x, np.sin(x), linewidth=1, label='lw=1')
axes[0, 2].plot(x, np.sin(x) + 1, linewidth=2, label='lw=2')
axes[0, 2].plot(x, np.sin(x) + 2, linewidth=4, label='lw=4')
axes[0, 2].plot(x, np.sin(x) + 3, linewidth=8, label='lw=8')
axes[0, 2].set_title('Line Widths')
axes[0, 2].legend()
# Marker sizes
x_sparse = np.linspace(0, 10, 20)
axes[1, 0].plot(x_sparse, np.sin(x_sparse), 'o-', markersize=4, label='ms=4')
axes[1, 0].plot(x_sparse, np.sin(x_sparse) + 1, 'o-', markersize=8, label='ms=8')
axes[1, 0].plot(x_sparse, np.sin(x_sparse) + 2, 'o-', markersize=12, label='ms=12')
axes[1, 0].set_title('Marker Sizes')
axes[1, 0].legend()
# Marker face and edge colors
axes[1, 1].plot(x_sparse, np.sin(x_sparse), 'o-',
markerfacecolor='red', markeredgecolor='black',
markeredgewidth=2, markersize=10, label='Custom colors')
axes[1, 1].plot(x_sparse, np.sin(x_sparse) + 1, 'o-',
markerfacecolor='none', markeredgecolor='blue',
markeredgewidth=2, markersize=10, label='Hollow markers')
axes[1, 1].set_title('Marker Colors')
axes[1, 1].legend()
# Alpha (transparency)
axes[1, 2].plot(x, np.sin(x), linewidth=8, alpha=1.0, label='alpha=1.0')
axes[1, 2].plot(x, np.sin(x) + 0.5, linewidth=8, alpha=0.7, label='alpha=0.7')
axes[1, 2].plot(x, np.sin(x) + 1.0, linewidth=8, alpha=0.4, label='alpha=0.4')
axes[1, 2].plot(x, np.sin(x) + 1.5, linewidth=8, alpha=0.1, label='alpha=0.1')
axes[1, 2].set_title('Transparency (Alpha)')
axes[1, 2].legend()
plt.tight_layout()
plt.show()
# ============================================================================
# SECTION 5: Advanced Marker Customization
# ============================================================================
"""
Markers can be heavily customized beyond basic properties.
"""
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
x = np.linspace(0, 10, 15)
y = np.sin(x)
# Basic markers
axes[0].plot(x, y, 'o-', markersize=10)
axes[0].set_title('Basic Markers')
axes[0].grid(True, alpha=0.3)
# Customized markers: different face and edge
axes[1].plot(x, y, marker='o', linestyle='-',
color='blue',
markerfacecolor='yellow',
markeredgecolor='red',
markeredgewidth=3,
markersize=12,
linewidth=2)
axes[1].set_title('Custom Marker Colors')
axes[1].grid(True, alpha=0.3)
# Hollow markers with thick edges
axes[2].plot(x, y, marker='s', linestyle='--',
color='green',
markerfacecolor='none',
markeredgecolor='green',
markeredgewidth=2,
markersize=10,
linewidth=1.5)
axes[2].set_title('Hollow Markers')
axes[2].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# ============================================================================
# SECTION 6: Plotting Multiple Lines - Best Practices
# ============================================================================
"""
When plotting multiple datasets, you have several options:
1. Multiple plot() calls (most common)
2. Single plot() call with all data
3. Loop over datasets
"""
x = np.linspace(0, 10, 100)
# Method 1: Multiple plot() calls (RECOMMENDED for clarity)
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, np.sin(x), 'r-', linewidth=2, label='sin(x)')
ax.plot(x, np.cos(x), 'b--', linewidth=2, label='cos(x)')
ax.plot(x, np.sin(2*x), 'g:', linewidth=2, label='sin(2x)')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Method 1: Multiple plot() calls')
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
# Method 2: Single plot() call with all data
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, np.sin(x), 'r-',
x, np.cos(x), 'b--',
x, np.sin(2*x), 'g:',
linewidth=2)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Method 2: Single plot() call')
ax.legend(['sin(x)', 'cos(x)', 'sin(2x)'])
ax.grid(True, alpha=0.3)
plt.show()
# Method 3: Loop over datasets (good for many similar plots)
fig, ax = plt.subplots(figsize=(10, 6))
functions = [
('sin(x)', np.sin(x), 'r-'),
('cos(x)', np.cos(x), 'b--'),
('sin(2x)', np.sin(2*x), 'g:')
]
for label, y_data, fmt in functions:
ax.plot(x, y_data, fmt, linewidth=2, label=label)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Method 3: Loop over datasets')
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()
# ============================================================================
# SECTION 7: Using Line2D Objects to Modify Properties Later
# ============================================================================
"""
plot() returns Line2D objects that you can modify after creation.
This is useful for animations or interactive applications.
"""
x = np.linspace(0, 10, 100)
y = np.sin(x)
# Get the Line2D object
fig, ax = plt.subplots()
line, = ax.plot(x, y, 'r-', linewidth=2) # Note the comma to unpack
# OR: lines = ax.plot(x, y); line = lines[0]
print(f"Line object: {line}")
print(f"Current color: {line.get_color()}")
print(f"Current linewidth: {line.get_linewidth()}")
# Modify properties using setter methods
line.set_color('blue')
line.set_linewidth(4)
line.set_linestyle('--')
line.set_alpha(0.7)
ax.set_title('Line properties modified after creation')
plt.show()
# You can also get multiple line objects
fig, ax = plt.subplots()
line1, line2, line3 = ax.plot(x, np.sin(x), x, np.cos(x), x, np.tan(x))
# Modify each line
line1.set_color('red')
line2.set_color('blue')
line3.set_color('green')
ax.set_ylim(-5, 5)
ax.set_title('Multiple Line2D objects')
plt.show()
# ============================================================================
# SECTION 8: Combining Format Strings with Keyword Arguments
# ============================================================================
"""
You can use BOTH format strings and keyword arguments.
Keyword arguments override format string specifications.
"""
x = np.linspace(0, 10, 50)
y = np.sin(x)
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Only format string
axes[0].plot(x, y, 'ro-')
axes[0].set_title("Format string only: 'ro-'")
# Format string + keyword arguments (keywords override)
axes[1].plot(x, y, 'ro-', color='blue', markersize=10)
axes[1].set_title("'ro-' + color='blue'\n(blue overrides red)")
# Keyword arguments only (most explicit)
axes[2].plot(x, y, color='green', linestyle='--',
marker='s', markersize=8, linewidth=2)
axes[2].set_title('Keyword arguments only')
plt.tight_layout()
plt.show()
# ============================================================================
# SECTION 9: Professional Plot Example
# ============================================================================
"""
Let's create a publication-quality plot using everything we've learned.
"""
# Generate data
x = np.linspace(0, 10, 200)
y1 = np.sin(x)
y2 = np.sin(x) * np.exp(-x/10) # Damped sine
y3 = np.cos(x) * np.exp(-x/10) # Damped cosine
# Create figure with custom size
fig, ax = plt.subplots(figsize=(10, 6))
# Plot with carefully chosen colors and styles
ax.plot(x, y1, color='#1f77b4', linestyle='-', linewidth=2.5,
label='sin(x)', alpha=0.9, zorder=3)
ax.plot(x, y2, color='#ff7f0e', linestyle='--', linewidth=2.5,
label='sin(x)·exp(-x/10)', alpha=0.9, zorder=2)
ax.plot(x, y3, color='#2ca02c', linestyle='-.', linewidth=2.5,
label='cos(x)·exp(-x/10)', alpha=0.9, zorder=1)
# Customize axes
ax.set_xlabel('x', fontsize=14, fontweight='bold')
ax.set_ylabel('y', fontsize=14, fontweight='bold')
ax.set_title('Oscillatory and Damped Functions', fontsize=16, fontweight='bold', pad=20)
# Add grid
ax.grid(True, alpha=0.3, linestyle='--', linewidth=0.5)
# Customize legend
ax.legend(loc='upper right', fontsize=12, framealpha=0.9, shadow=True)
# Set axis limits for better view
ax.set_xlim(0, 10)
ax.set_ylim(-1.2, 1.2)
# Add minor ticks
ax.minorticks_on()
plt.tight_layout()
plt.show()
# ============================================================================
# KEY TAKEAWAYS
# ============================================================================
"""
1. plot(x, y) is the most important matplotlib function
2. Format strings provide compact styling: '[marker][line][color]'
3. Keyword arguments provide explicit control
4. Line properties: color, linestyle, linewidth, marker, markersize, alpha
5. Marker customization: face color, edge color, edge width
6. plot() returns Line2D objects that can be modified later
7. Multiple datasets: use multiple plot() calls for clarity
8. Combine format strings and keywords (keywords override format)
9. Use consistent styling for professional plots
10. Always add labels, title, legend, and grid for publication quality
Common Parameters:
-----------------
- color / c : line color
- linestyle / ls : '-', '--', '-.', ':'
- linewidth / lw : line thickness
- marker : marker style
- markersize / ms : marker size
- markerfacecolor / mfc : marker fill color
- markeredgecolor / mec : marker edge color
- markeredgewidth / mew : marker edge width
- alpha : transparency (0-1)
- label : for legend
"""