Pandas Line Charts: Plotting Trends, Multi-Series and Styling

Use DataFrame.plot.line() (or df.plot(kind='line')) to visualise continuous data, sequences, and trends over time or category indices. Learn how to map X and Y coordinates, plot multiple columns, customise line styles, manage secondary axes, format grids and legends, and export high-resolution chart images.

Create a simple single-series line chart 🔝

When you call df.plot.line() without specifying coordinates, Pandas plots every numeric column against the DataFrame's row index. Let us start by constructing a sample student table.

import pandas as pd
import matplotlib.pyplot as plt

my_dict = {
    "NAME": ["Ravi", "Raju", "Alex", "Ron", "Geek", "Kim"],
    "MARK": [20, 30, 40, 30, 40, 50]
}
df = pd.DataFrame(data=my_dict)
print(df)

# Plot default line chart
ax = df.plot.line(title="Student Mark")
plt.show()

Expected console output:

   NAME  MARK
0  Ravi    20
1  Raju    30
2  Alex    40
3   Ron    30
4  Geek    40
5   Kim    50
Basic Pandas DataFrame line chart
Basic line chart plotted against default numeric index

Plot multiple lines on shared axes 🔝

If your table contains multiple numeric measures (such as marks across different subjects or multi-channel sales), Pandas automatically draws a distinct line for each measure and generates a matching legend entry.

import pandas as pd
import matplotlib.pyplot as plt

my_dict = {
    "NAME": ["Ravi", "Raju", "Alex", "Ron", "Geek", "Kim"],
    "MATH": [20, 30, 40, 30, 40, 50],
    "ENGLISH": [80, 70, 60, 70, 90, 80]
}
df = pd.DataFrame(data=my_dict)

# Plot multiple subject columns
df.plot.line(x="NAME", y=["MATH", "ENGLISH"], title="Subject Comparison", figsize=(6, 3), grid=True)
plt.show()

Explicitly map X and Y columns 🔝

By default, the X-axis uses row numbers (0, 1, 2, ...). Pass the column name to x= to display names, dates, or timestamps along the horizontal axis, and choose target metrics with y=.

# Plot English marks explicitly against Student Names
df.plot.line(title="Student English Performance", x="NAME", y="ENGLISH", figsize=(6, 3), legend=True)
plt.show()

Control index vs column mapping with use_index 🔝

The parameter use_index=True (default) tells Pandas to use DataFrame index labels on the X-axis when no explicit x= is given. Setting use_index=False ignores custom index labels and falls back to a 0-based range.

Line chart with use_index=True
use_index=True (uses DataFrame index)
Line chart with use_index=False
use_index=False (numeric sequence)

Customise line styles, markers, and colours 🔝

You can specify line patterns using standard Matplotlib style strings (such as dashed '--', dotted ':', or dash-dot '-.'). Pass a list to assign separate styles per series.

# Apply custom line styles to lines
my_style = ["-.", ":"]
df.plot.line(x="NAME", y=["MATH", "ENGLISH"], style=my_style, figsize=(6, 3), title="Custom Line Styles")
plt.show()
Line style variation 1
Dash-dot line style (-.)
Line style variation 2
Dotted line style (:)

Configure gridlines and legend positioning 🔝

Toggle gridlines using grid=True or grid=False. Control legend visibility using legend=True or legend=False.

grid=True line chart
grid=True
grid=False line chart
grid=False
legend=True line chart
legend=True (shows series names)
legend=False line chart
legend=False (clean uncluttered canvas)

Dual-scale comparison with secondary_y and mark_right 🔝

When comparing two metrics measured in different units (for instance, unit volume in hundreds and revenue in tens of thousands), plotting them on the same axis flattens the smaller measure. Use secondary_y=True (or specify a column list like secondary_y=['Revenue']) to create a right-hand scale. The mark_right=True option appends (right) to the legend label.

sales_df = pd.DataFrame({
    "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "Units_Sold": [120, 150, 190, 240, 290, 340],
    "Revenue": [12000, 15500, 18200, 26000, 31000, 38500]
})

ax = sales_df.plot.line(
    x="Month",
    secondary_y=["Revenue"],
    mark_right=True,
    figsize=(7, 4),
    title="Units vs Revenue Trend",
    grid=True
)
ax.set_ylabel("Units Sold (Left Axis)")
plt.show()
secondary_y=True plot
secondary_y=True (dual scale axes)
secondary_y=False plot
secondary_y=False (single compressed scale)

Handle wide value ranges with logy and loglog 🔝

If data values grow exponentially or span multiple orders of magnitude, linear axes compress the smaller values to the baseline. Use logarithmic scaling: logy=True applies log scaling to the Y-axis, logx=True to the X-axis, and loglog=True applies log scaling to both axes.

loglog=True option on Pandas line chart
loglog=True logarithmic scaling across both axes

Rotate axis labels with rot 🔝

When dates or names on the horizontal axis overlap, use rot=45 or rot=90 to angle tick labels for readability.

rot=45 tick rotation
rot=45 (angled labels)
rot=180 tick rotation
rot=180 (inverted labels demonstration)

Save charts as image files using savefig() 🔝

In automated reporting, web dashboards, or Jupyter/Colab notebooks, you often need to save your line chart as an image. Call plt.savefig() before calling plt.show():

ax = df.plot.line(x="NAME", y="MARK", title="Student Marks")
plt.tight_layout()
plt.savefig("student_marks_trend.png", dpi=300)
print("Saved chart as student_marks_trend.png")
plt.close()

Practical workflow: monthly revenue and unit trend 🔝

Here is an end-to-end verifiable workflow: load a table, calculate growth rates, configure secondary axes, and validate results with Python assertions.

import pandas as pd
import matplotlib.pyplot as plt

sales_history = pd.DataFrame({
    "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
    "Units_Sold": [120, 150, 190, 240, 290, 340],
    "Revenue": [12000, 15500, 18200, 26000, 31000, 38500]
})

assert len(sales_history) == 6
assert sales_history["Revenue"].sum() == 141200

ax = sales_history.plot.line(
    x="Month",
    y=["Units_Sold", "Revenue"],
    secondary_y=["Revenue"],
    title="H1 Sales and Volume Growth",
    figsize=(7, 4),
    grid=True
)
print("Total H1 Revenue:", sales_history["Revenue"].sum())
plt.show()

Expected console output:

Total H1 Revenue: 141200

Exercise: track weekly website visitors 🔝

Create a DataFrame with 5 weekdays (Mon to Fri) and daily Visitors count: [100, 150, 130, 180, 220]. Plot a line chart with Day on the X-axis, enable gridlines, title the chart "Weekly Traffic", and calculate the total visitor count.

Exercise solution 🔝

import pandas as pd
import matplotlib.pyplot as plt

traffic = pd.DataFrame({
    "Day": ["Mon", "Tue", "Wed", "Thu", "Fri"],
    "Visitors": [100, 150, 130, 180, 220]
})

assert traffic["Visitors"].sum() == 780
print("Total Visitors:", traffic["Visitors"].sum())

traffic.plot.line(x="Day", y="Visitors", title="Weekly Traffic", grid=True, figsize=(6, 3))
plt.show()

Expected console output:

Total Visitors: 780

Practice in Google Colab 🔝

Open in Google Colab View on GitHub
Run the line plot examples interactively, experiment with custom line styles, test dual secondary axes, and verify your exercises in Google Colab. All sample datasets are embedded directly in the notebook.

Continue building your Pandas visualization and analysis skills with these related guides:

Reference: Pandas DataFrame.plot.line official documentation.




Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
✖
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
© 2000-2026 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer