Python plotting for data science almost always starts with matplotlib’s pyplot module and pandas’ built-in .plot() method, which wraps matplotlib under the hood. Together they cover the vast majority of exploratory charts a data scientist needs: line plots for trends, bar plots for comparisons, and scatter plots for relationships — before you ever reach for a heavier library like Plotly.
I still open a fresh notebook with the same three lines I’ve used for years. Old habits, but they work:
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
Below is the workflow I actually use when a client hands me a raw CSV and asks “what does this data look like,” from first plot to publication-ready figure.
Step 1: Get the Data Into a Plottable Shape
Real-world data is rarely plot-ready on arrival. A recent project had GDP-per-capita columns named like gdpPercap_1952, gdpPercap_1957 — useless as an x-axis until cleaned:
years = data.columns.str.strip('gdpPercap_')
data.columns = years.astype(int)
This one-line habit — stripping prefixes and casting to the right dtype before plotting anything — has saved me more debugging time than any charting trick. A mislabeled or string-typed axis is the single most common reason a plot silently looks wrong.
Step 2: Line Plots for Trends
For a single country’s trend over time, pandas’ DataFrame plotting is the fastest path:
data.loc['Australia'].plot()
For more control — multiple series, custom colors, explicit labels — I drop down to plt.plot() directly:
plt.plot(years, gdp_australia, 'b-', label='Australia')
plt.plot(years, gdp_nz, 'g--', label='New Zealand')
plt.xlabel('Year')
plt.ylabel('GDP per capita ($)')
plt.legend(loc='upper left')
plt.show()
The style string ('b-', 'g--') sets color and line style in one shorthand: letter for color, symbol for line type. I lean on dashed and dotted styles — not just color — whenever a chart might get printed in black and white or viewed by a colorblind reader; it’s a small change that has saved more than one report from being unreadable in a printed board packet.
Step 3: Plotting Multiple Series at Once
When comparing many countries or categories, transpose the DataFrame so each column becomes its own line:
data.T.plot()
plt.ylabel('GDP per capita ($)')
This is a small transformation, but it’s the difference between writing a loop with a dozen plt.plot() calls and a single readable line. I check the shape of my DataFrame with .T mentally before every multi-series plot now — it’s become reflexive.
Step 4: Bar and Scatter Plots
Bar plots suit categorical comparisons; scatter plots suit relationships between two continuous variables:
data.plot(kind='bar')
plt.scatter(data['gdpPercap_2007'], data['lifeExp_2007'])
plt.xlabel('GDP per capita')
plt.ylabel('Life expectancy')
I use scatter plots constantly during exploratory analysis specifically to eyeball whether a relationship looks linear before I commit to a linear regression — it’s a five-second sanity check that has stopped me from fitting the wrong model more than once.
Step 5: Saving Figures for Reports
Two approaches, depending on whether pandas or matplotlib created the figure:
plt.savefig('my_figure.png', dpi=300, bbox_inches='tight')
fig = plt.gcf()
data.plot(kind='bar')
fig.savefig('my_figure.png', dpi=300)
I always set dpi=300 for anything going into a PDF report and bbox_inches='tight' to stop matplotlib from clipping axis labels — a default-settings figure looks noticeably worse in a client deck than one with these two arguments added.
Common Mistakes I See in Early-Career Portfolios
- Forgetting axis labels and units. A chart of “value” over “time” with no units is unreviewable.
- Relying on color alone to distinguish series. Add line style or markers as a backup encoding.
- Not checking dtypes before plotting. A column read in as a string will silently produce a nonsensical x-axis order.
- Skipping
plt.show()or figure cleanup in scripts, which causes matplotlib to bleed formatting from one plot into the next in a loop.
Frequently Asked Questions
What is the difference between matplotlib and pandas plotting?
Pandas’ .plot() method is a convenience wrapper around matplotlib — it infers sensible defaults from your DataFrame’s structure. Matplotlib’s pyplot gives you full manual control. I use pandas plotting for quick exploration and drop to raw matplotlib when a chart needs to be presentation-ready.
Why isn’t my matplotlib plot showing in Jupyter?
Make sure %matplotlib inline is run in its own cell before any plotting commands. Without it, figures may render blank or not at all in classic Jupyter notebooks.
What’s the best Python library for data visualization?
For static, publication-quality charts, matplotlib and Seaborn (built on top of it) cover most needs. For interactive dashboards, Plotly or Bokeh are better suited. Most of my exploratory work still starts in matplotlib because of its speed and ubiquity.
Related Reading
Once your plots are working, choosing the right colors matters just as much as the chart type — see our practical guide to Seaborn color palettes. For mapping geographic data specifically, check our choropleth mapping guide.
Elizabeth Sramek is a data scientist at Automatic Statistician, where she works on automated statistical modeling, data visualization, and applied machine learning workflows.
