How to plot multiple lines in Python
Learn how to plot multiple lines in Python. This guide covers various methods, tips, real-world examples, and common error debugging.

To compare datasets in Python, you often need to plot multiple lines on a single graph. Popular libraries make this process simple, which helps you create clear and effective visualizations.
In this article, you'll explore several techniques and practical tips. We also cover real-world applications and debugging advice to help you confidently create insightful charts for your projects.
Basic multiple line plot with matplotlib
import matplotlib.pyplot as plt
x = range(10)
plt.plot(x, [i for i in x])
plt.plot(x, [i**2 for i in x])
plt.xlabel('X values')
plt.ylabel('Y values')
plt.show()--OUTPUT--(Output: A figure showing two lines - a straight diagonal line and a parabola curve)
The key to creating a multi-line plot is straightforward. You simply call the plot() function for each dataset you want to visualize. matplotlib handles the rest by:
- Adding each new line to the current figure.
- Automatically assigning a unique color for visual distinction.
When you finally call show(), it renders all the layered plots at once. This stateful behavior is what makes comparing multiple datasets on a single chart so intuitive.
Common techniques for multiple line plots
With the fundamentals covered, you can make your charts more informative and visually distinct by customizing line styles, adding legends, and plotting from data arrays.
Using different line styles and colors with plot()
import matplotlib.pyplot as plt
x = range(10)
plt.plot(x, [i for i in x], 'r--', linewidth=2)
plt.plot(x, [i**2 for i in x], 'b-', linewidth=3)
plt.xlabel('X values')
plt.ylabel('Y values')
plt.show()--OUTPUT--(Output: A figure showing a red dashed line for the linear function and a blue solid line for the quadratic function)
You can customize each line's appearance directly within the plot() function. The third argument is a format string that combines color and style codes.
'r--'specifies a red (r) dashed (--) line.'b-'creates a blue (b) solid (-) line.
Additionally, the linewidth parameter lets you adjust the thickness of each line, making certain datasets stand out more than others.
Adding legends to distinguish multiple lines
import matplotlib.pyplot as plt
x = range(10)
plt.plot(x, [i for i in x], label='Linear')
plt.plot(x, [i**2 for i in x], label='Quadratic')
plt.legend()
plt.title('Multiple Lines with Legend')
plt.show()--OUTPUT--(Output: A figure with two lines and a legend box identifying "Linear" and "Quadratic" lines)
When your chart displays multiple lines, a legend is crucial for telling them apart. It acts as a key for your readers. Adding one in matplotlib is a straightforward, two-step process.
- First, you assign a name to each line by passing a string to the
labelparameter within eachplot()call. - Then, you simply call
plt.legend(). This function gathers all the labels and automatically displays them in a box on your chart.
Plotting from data in arrays
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2*np.pi, 100)
plt.plot(x, np.sin(x), x, np.cos(x), x, np.tan(x))
plt.grid(True)
plt.ylim(-3, 3)
plt.show()--OUTPUT--(Output: A figure showing sine, cosine, and tangent curves with a grid background)
You don't always have to call plot() repeatedly. A single call can handle multiple datasets, which is efficient when working with arrays from libraries like numpy. The function just needs a sequence of x, y pairs. In this example, it plots np.sin(x), np.cos(x), and np.tan(x) against the same x array.
plt.grid(True)adds a grid, making the chart easier to read.plt.ylim(-3, 3)constrains the y-axis. This is key for preventing the tangent function's infinite values from distorting the plot.
Advanced multiple line plotting
Now you can move beyond static charts by using pandas to organize complex data and plotly to build powerful, interactive visualizations.
Using pandas DataFrame for multiple line plots
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
'x': range(10),
'linear': range(10),
'quadratic': [i**2 for i in range(10)],
'cubic': [i**3 for i in range(10)]
})
df.set_index('x').plot()
plt.show()--OUTPUT--(Output: A figure with three lines automatically colored and labeled based on the DataFrame columns)
Using a pandas DataFrame streamlines the process of plotting multiple lines, especially when your data is already in a tabular format. The structure is ideal for organizing your datasets before visualization.
- First, you designate a column to serve as the x-axis by calling
set_index('x'). - Then, a single call to the
plot()method is all it takes. It automatically plots every other column as a distinct line and even creates a legend for you from the column names.
Creating subplots for multiple line visualization
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
x = np.linspace(0, 10, 100)
ax1.plot(x, np.sin(x), 'r-', x, np.sin(2*x), 'g--')
ax1.set_title('Sine Waves')
ax2.plot(x, np.cos(x), 'b-', x, np.cos(2*x), 'm--')
ax2.set_title('Cosine Waves')
plt.tight_layout()
plt.show()--OUTPUT--(Output: Two side-by-side plots, each containing two lines - the left with sine waves and the right with cosine waves)
When you need to compare different groups of data side-by-side, subplots are the way to go. The plt.subplots() function creates a figure and a grid of axes. For instance, passing (1, 2) creates a single row with two columns, returning two separate axis objects—ax1 and ax2.
- Instead of calling
plt.plot(), you call theplot()method directly on an axis object, likeax1.plot(), to draw on that specific chart. - Each axis can be customized independently with its own titles and lines.
- Calling
plt.tight_layout()at the end automatically adjusts spacing to prevent the plots from overlapping.
Interactive multiple line plots with plotly
import plotly.graph_objects as go
x = list(range(10))
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=x, mode='lines', name='Linear'))
fig.add_trace(go.Scatter(x=x, y=[i**2 for i in x], mode='lines', name='Quadratic'))
fig.update_layout(title='Interactive Multiple Lines')
fig.show()--OUTPUT--(Output: An interactive plot with two lines that allows zooming, panning, and hovering to see values)
For interactive charts, plotly is a great choice. Unlike matplotlib's stateful approach, you work with a go.Figure object. This object acts as a container for your entire visualization.
- Each line is added as a "trace" using the
fig.add_trace()method. - You use
go.Scatterwithmode='lines'to specify a line plot. - The
nameparameter ingo.Scatterconveniently labels each line in the legend.
The final call to fig.show() renders a fully interactive chart. You can zoom, pan, and hover over data points to inspect their values without any extra code.
Move faster with Replit
Replit is an AI-powered development platform designed to turn your ideas into working software using natural language. You can describe an application, and Replit Agent will build it from the ground up, handling everything from the database to deployment.
You can use it to transform the multi-line plotting concepts from this article into fully functional applications. For example, you could build:
- A financial dashboard that plots and compares multiple stock tickers in real time.
- A server monitoring tool that visualizes CPU, memory, and network usage on a single chart.
- A weather comparison app that graphs temperature and humidity data from different cities over time.
Bring your own data visualization idea to life. Describe your app, and the agent will write, test, and deploy the code for you. Get started with Replit Agent.
Common errors and challenges
Even with powerful tools, you might run into a few common roadblocks when plotting multiple lines, but they're usually simple to fix.
Fixing mismatched data dimensions in plot()
One of the most frequent issues is a ValueError that tells you the x and y arrays have different dimensions. This happens because the plot() function needs a y-coordinate for every x-coordinate to draw a continuous line. To fix it, double-check that your data lists or arrays have the exact same number of elements before passing them to the function.
Dealing with overlapping legends
A legend is essential for clarity, but sometimes it can overlap with your data lines. You can easily reposition it using the loc parameter inside the plt.legend() call. This parameter tells matplotlib where to place the legend box.
- You can use string codes like
'upper left','lower right', or'center'for precise placement. - Setting
loc='best'lets the library automatically find a location with the least overlap.
Fixing incorrect line style syntax
If your line styles aren't showing up as expected, you may have used incorrect syntax in the format string. matplotlib uses abbreviated codes—for example, 'r--' creates a red dashed line, while a string like 'red--' won't work. An invalid format string can either raise a ValueError or cause the function to fall back to the default style, so it's always good to check the official documentation for the correct codes.
Fixing mismatched data dimensions in plot()
This ValueError is a classic roadblock when plotting. It happens because the plot() function needs to pair every x-coordinate with a y-coordinate. If your data arrays don't have the same number of elements, it can't draw the line.
The code below shows exactly how this error occurs. Notice that one of the y-axis arrays is intentionally longer than the x-axis array, which triggers the problem.
import matplotlib.pyplot as plt
x = range(10)
y1 = [i for i in range(10)]
y2 = [i**2 for i in range(12)] # Different length than x
plt.plot(x, y1, label='Linear')
plt.plot(x, y2, label='Quadratic') # This causes an error
plt.legend()
plt.show()
The second plt.plot() call fails because it attempts to map the 10 values in x to the 12 values in y2. This mismatch triggers the error. The corrected code below shows how to resolve this issue.
import matplotlib.pyplot as plt
x = range(10)
y1 = [i for i in range(10)]
y2 = [i**2 for i in range(10)] # Corrected to match x length
plt.plot(x, y1, label='Linear')
plt.plot(x, y2, label='Quadratic')
plt.legend()
plt.show()
The solution is to ensure your data arrays match in length. By changing the creation of the y2 list to use range(10), it now has the same number of elements as the x list. This allows the plot() function to successfully pair each x-coordinate with a y-coordinate and draw the line without error.
- This issue often pops up when you're slicing data or performing calculations that unexpectedly change an array's length before plotting.
Dealing with overlapping legends
When you call plt.legend(), its default placement can sometimes obscure your data. Matplotlib tries to find an open spot, but the legend can end up covering important parts of your plot, making the chart difficult to read. The code below shows this in action.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.figure(figsize=(8, 6))
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.plot(x, np.tan(x), label='tan(x)')
plt.legend() # Default position might overlap with the plot
plt.ylim(-3, 3)
plt.show()
The plt.legend() call automatically places the key, but on a crowded chart like this one, it can easily cover the lines you're trying to show. The corrected code below demonstrates how to fix this.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.figure(figsize=(8, 6))
plt.plot(x, np.sin(x), label='sin(x)')
plt.plot(x, np.cos(x), label='cos(x)')
plt.plot(x, np.tan(x), label='tan(x)')
plt.legend(loc='upper right') # Specify legend location
plt.ylim(-3, 3)
plt.show()
You can solve this by manually placing the legend. The plt.legend() function accepts a loc parameter that lets you specify its position. Using a string like 'upper right' moves the legend box, preventing it from covering your data lines.
- Keep an eye on this when creating busy charts, as the default placement might not always be ideal and can hide important details in your visualization.
Fixing incorrect line style syntax
Using the wrong syntax for line styles in matplotlib is a common hiccup. Instead of getting your custom dashed or solid lines, you might trigger a ValueError or see the plot revert to a default style. This often happens when combining format strings and keyword arguments incorrectly.
The following code shows how this error occurs when you try to pass color and style as separate arguments in the plot() function.
import matplotlib.pyplot as plt
x = range(10)
plt.plot(x, [i for i in x], color='red', '--') # Incorrect syntax
plt.plot(x, [i**2 for i in x], color='blue', '-') # Incorrect syntax
plt.xlabel('X values')
plt.ylabel('Y values')
plt.show()
The plot() function raises a SyntaxError because a positional argument like '--' cannot follow a keyword argument like color='red'. This ordering violates Python's rules. The corrected code below shows how to structure the call properly.
import matplotlib.pyplot as plt
x = range(10)
plt.plot(x, [i for i in x], '--', color='red') # Correct syntax
plt.plot(x, [i**2 for i in x], '-', color='blue') # Correct syntax
plt.xlabel('X values')
plt.ylabel('Y values')
plt.show()
The solution is to follow Python's syntax rules: positional arguments must come before keyword arguments. In the plot() function, this means placing the style string like '--' before a keyword argument like color='red'. Reversing this order triggers a SyntaxError.
- This is a common pitfall when you're mixing shorthand style codes and keyword arguments in the same function call, so always double-check the argument sequence.
Real-world applications
With the fundamentals and fixes covered, you can apply multi-line plotting to real-world scenarios, from tracking financial trends to comparing machine learning models.
Visualizing stock price trends with plot()
Plotting multiple stock prices on a single graph is a classic use case that provides a clear visual comparison of how different companies perform against each other over time.
import matplotlib.pyplot as plt
months = range(1, 13)
apple_prices = [250, 275, 290, 255, 300, 330, 325, 315, 360, 390, 410, 400]
microsoft_prices = [160, 170, 165, 150, 180, 190, 210, 215, 220, 235, 230, 240]
plt.plot(months, apple_prices, 'r-', label='AAPL')
plt.plot(months, microsoft_prices, 'b-', label='MSFT')
plt.title('Stock Price Comparison (2020)')
plt.xlabel('Month of 2020')
plt.ylabel('Price (USD)')
plt.legend()
plt.grid(True)
plt.show()
This code plots two datasets, apple_prices and microsoft_prices, against a shared x-axis representing months. Each call to the plt.plot() function adds a distinct line to the same figure, making it easy to layer data.
- The format strings
'r-'and'b-'define the appearance, setting the lines to red and blue. - The
labelparameter in each call provides text for the legend, whichplt.legend()then displays. - Finally,
plt.grid(True)adds a background grid, improving the chart's readability.
Comparing model performance metrics with multiple lines
Multi-line plots are also essential in machine learning for tracking metrics like training and validation loss, which helps you diagnose how well a model is learning.
import matplotlib.pyplot as plt
epochs = range(1, 11)
train_loss = [0.8, 0.6, 0.5, 0.4, 0.3, 0.25, 0.2, 0.18, 0.15, 0.12]
val_loss = [0.85, 0.7, 0.65, 0.6, 0.55, 0.5, 0.45, 0.43, 0.42, 0.41]
plt.plot(epochs, train_loss, 'bo-', label='Training Loss')
plt.plot(epochs, val_loss, 'ro-', label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()
This code visualizes a model's learning progress across ten epochs. It plots two key metrics on the same chart to help you assess performance.
- The
train_lossline shows how well the model is learning from the data it's seen. - The
val_lossline tracks its performance on new, unseen data.
By comparing them, you can spot when the model stops generalizing well. Here, the validation loss flattens while training loss keeps dropping—a classic sign that the model might be starting to overfit.
Get started with Replit
Turn these plotting concepts into a real tool. Describe your idea to Replit Agent, like "build a stock comparison dashboard" or "visualize server performance metrics from a CSV file."
The agent writes the code, tests for errors, and deploys your application. Start building with Replit.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.


.png)
.png)