5 Alternatives to Matplotlib That Make Data Visualization a Breeze
Categories
If you find Matplotlib leaving a lot to be desired, you’re not the only one. While it’s not a bad library, you might find these five alternatives better for specific uses.
Matplotlib is usually considered the main plotting library in Python. However, many feel that this “grandaddy of visualization” is holding them and their data hostage behind cryptic syntax and a stack of indecipherable documentation.
Python is a fantastic ecosystem that is considered a Swiss Army knife for developers. What does that make Matplotlib? A knife that’s always dull?
Anyway, if you want to create a basic chart, Matplotlib’s got your back. Want to do anything more complex? Buckle up because it’s gonna get wild.
Matplotlib’s still around, though. It's kind of like a relic of the past. Did you notice how un-Pythonic it feels? Well, surprise! It’s basically a copy of the Matlab library—because, you know, that was the hot thing 20 years ago. That makes Matplotlib all about minimizing transition costs, but it does not make sense for Python. So, if you’ve ever thought, "This feels weird," it’s because it is.
But, hey, it still has legacy users. Sure, you can make anything with Matplotlib if you're willing to wrestle with it. So, why stick with Matplotlib when there's no need to keep banging your head against the wall with these five libraries?
1. Plotly – Interactive and Web-Ready Visualization
Plotly is your go-to library for highly interactive plots with minimal configuration. Take, for example, this Real estate returns data visualization question.
Construct a bubble chart to evaluate the investment returns of different real estate markets, using 'skyblue' for residential, 'darkgreen' for commercial, and 'gray' for industrial properties.
Link to the question: https://platform.stratascratch.com/visualizations/10536-real-estate-returns
You’re asked to construct a bubble chart. This is the code you'll need to create that chart in Matplotlib.
import matplotlib.pyplot as plt
# Color mapping based on property type
color_map = {'Residential': 'skyblue', 'Commercial': 'darkgreen', 'Industrial': 'gray'}
colors = df['category'].map(color_map)
# Plotting
plt.figure(figsize=(12, 8))
scatter = plt.scatter(df['investment_return'], df['market'], s=df['market_size']*10, c=colors, alpha=0.6, edgecolors='w', linewidth=0.5)
plt.title('Investment Returns of Different Real Estate Markets')
plt.xlabel('Investment Return (%)')
plt.ylabel('Market')
plt.grid(True)
# Adding legend manually
plt.legend(handles=[
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='skyblue', markersize=10, label='Residential'),
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='darkgreen', markersize=10, label='Commercial'),
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='gray', markersize=10, label='Industrial')
], title='Property Type', loc='upper right')
plt.show()
Here’s the visualization you get in Matplotlib.
Expected Visual Output
Now, to get precisely the same chart (only looking nicer) in Plotly, look at how much less code it requires.
import plotly.express as px
# Using Plotly Express to create the bubble chart
fig = px.scatter(df,
x='investment_return',
y='market',
size='market_size',
color='category',
color_discrete_map={'Residential': 'skyblue', 'Commercial': 'darkgreen', 'Industrial': 'gray'},
labels={'investment_return': 'Investment Return (%)',
'market': 'Market',
'market_size': 'Market Size'},
title='Investment Returns of Different Real Estate Markets')
fig.show()
Here’s the Plotly visualization.
Expected Visual Output
Unlike Matplotlib, which primarily focuses on static plots, Plotly enables zooming, hovering, and dynamic data exploration out of the box. It supports over 40 chart types and is optimized for dashboards and web applications. You can embed your visualizations directly into your web app using frameworks like Dash while seamlessly handling large data sets with ease.
2. Seaborn – Matplotlib's Statistical Extension
If you're already familiar with Matplotlib but find its syntax cumbersome, seaborn might be a smoother alternative to Matplotlib. Built on top of Matplotlib, seaborn automates complex statistical plotting like regression lines, heat maps, and distribution plots. It simplifies Matplotlib’s clunky API, offering predefined styles that make data visualization aesthetically pleasing right out of the box without manually tweaking every parameter.
For example, compare the seaborn distribution plot…
…with the Matplotlib one.
In Matplotlib, you get a plot that is quite incomprehensible. Also, you can't do anything with it, while in the seaborn distplot, you can get information about every data point—all that with significantly less coding.
3. Vega-Altair – Declarative, Grammar-Based Visualization
Vega-Altair is a declarative visualization library for those who prioritize simplicity and scalability.
Unlike imperative approaches like Matplotlib, Vega-Altair uses a concise "grammar of graphics" model, allowing users to specify what to visualize and leaving the library to handle the underlying complexity. This makes Altair ideal for clean visualizations, especially in Jupyter Notebooks, where complex charts are created with just a few lines of code.
Compared with this Matplotlib scatter plot…
…the one in Vega-Altair does look much better. It’s also an exploratory visualization, where you can do stuff with it, unlike in Matplotlib.
4. Bokeh – Web-Optimized for Large Datasets
For web developers handling large data sets, Bokeh provides a powerful alternative to Matplotlib. It allows you to create fully interactive, web-ready visualizations directly in the browser.
Bokeh’s architecture is more suited for complex layouts and interactive elements than Matplotlib, making it a top choice for dashboards. Though it requires a bit more configuration, the flexibility and integration with web technologies are well worth the effort.
For example, I can write this code to create an interactive sine wave plot.
# Step 1: Import necessary libraries
from bokeh.layouts import column
from bokeh.plotting import figure, curdoc
from bokeh.models import Slider
import numpy as np
# Step 2: Create the figure (plot)
plot = figure(title="Interactive Sine Wave Plot", x_axis_label='X', y_axis_label='Y', width=800, height=400)
# Step 3: Generate initial data
x = np.linspace(0, 10, 500)
y = np.sin(x)
# Step 4: Create a line renderer
line = plot.line(x, y, line_width=2)
# Step 5: Define a callback function to update the plot based on the slider value
def update_plot(attr, old, new):
frequency = slider.value
new_y = np.sin(frequency * x)
line.data_source.data['y'] = new_y # Update the y-values in the plot
# Step 6: Create a slider widget to control the frequency of the sine wave
slider = Slider(start=1, end=10, value=1, step=0.1, title="Frequency")
slider.on_change('value', update_plot)
# Step 7: Arrange the plot and slider in a layout
layout = column(slider, plot)
# Step 8: Add the layout to the current document for display in the browser
curdoc().add_root(layout)
Now, I save the script and execute it from Command Prompt (or Mac Terminal, depending on what you use) by running the bokeh serve --show bokeh_dashboard.py command after navigating to the folder where the script is saved. This will open the dashboard in my web browser, where I interact with it using a slider.
With Matplotlib, I can run this code in Jupyter…
# Step 1: Import necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
# Step 2: Create the figure and axis
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.1, bottom=0.25) # Adjust the subplot to make space for the slider
# Step 3: Generate initial data
x = np.linspace(0, 10, 500)
y = np.sin(x)
# Step 4: Plot the sine wave
line, = ax.plot(x, y, lw=2)
ax.set_title("Interactive Sine Wave Plot")
ax.set_xlabel('X')
ax.set_ylabel('Y')
# Step 5: Create the slider axes and Slider widget
ax_slider = plt.axes([0.1, 0.1, 0.8, 0.05], facecolor='lightgoldenrodyellow')
slider = Slider(ax_slider, 'Frequency', 1, 10, valinit=1, valstep=0.1)
# Step 6: Define a callback function to update the plot based on the slider value
def update(val):
frequency = slider.val
line.set_ydata(np.sin(frequency * x)) # Update the y-data of the line
fig.canvas.draw_idle() # Redraw the plot with updated data
# Step 7: Connect the update function to the slider
slider.on_changed(update)
# Step 8: Display the plot
plt.show()
…which returns a sinewave plot with a slider that doesn't, ahem, slide. Wow, this is an interactive plot that’s not interactive!
If I try the reworked code that uses the %matplotlib widget magic command, which enables interactive widgets in Jupyter Notebooks, it still won’t work! So, I have to tweak the code, install the ipympl Matplolib package, and whatnot. I’m close to giving up, but okay. Here’s the reworked code.
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact
from IPython.display import display
# Enable the interactive Matplotlib backend
%matplotlib widget
# Create the plot
x = np.linspace(0, 10, 500)
y = np.sin(x)
fig, ax = plt.subplots()
line, = ax.plot(x, y)
# Update function for the slider
def update(frequency=1):
line.set_ydata(np.sin(frequency * x))
ax.relim() # Recalculate limits for updated data
ax.autoscale_view() # Autoscale for new data
fig.canvas.draw_idle() # Update the figure canvas
# Create the slider
_ = interact(update, frequency=(1, 10, 0.1)) # Suppress output
That finally returns an interactive plot.
Yeah, you can do it in Matplotlib, but it’s much more trouble and clunkier than in Bokeh.
5. Plotnine – Python’s Answer to ggplot2
If you come from the R world and miss ggplot2, you'll love plotnine. It brings the grammar of graphics into Python, making it easier for users to create complex statistical plots with simple, declarative syntax.
Unlike Matplotlib’s verbose commands, plotnine allows you to layer plots in a more intuitive, elegant way, ideal for users familiar with data science workflows in R.
Here’s the layered plot in plotnine.
The plot is a bit more elegant than the one in Matplotlib below.
However, to produce that plot in Plotnine, you need to write this code:
# Step 1: Import necessary libraries
import pandas as pd
import numpy as np
from plotnine import ggplot, aes, geom_point, geom_line
%matplotlib inline
# Step 2: Create a sample dataset
np.random.seed(42)
df = pd.DataFrame({
'x': np.linspace(0, 10, 100),
'y1': np.sin(np.linspace(0, 10, 100)),
'y2': np.cos(np.linspace(0, 10, 100))
})
# Step 3: Create the layered plot
plot = (
ggplot(df) +
aes(x='x') +
geom_line(aes(y='y1'), color='blue', size=1) + # Line plot (sin)
geom_point(aes(y='y1'), color='blue') + # Scatter plot (sin)
geom_line(aes(y='y2'), color='red', size=1) + # Line plot (cos)
geom_point(aes(y='y2'), color='red') + # Scatter plot (cos)
labs(
title="Sine and Cosine Waves", # Add a title
x="x-axis", # Label for x-axis
y="y-axis", # Label for y-axis
color="Legend" # Legend title
)
)
# Step 4: Show the plot
plot.show()
which is less verbose and complex than the one below written in Matplotlib.
# Step 1: Import necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Step 2: Create a sample dataset
np.random.seed(42)
df = pd.DataFrame({
'x': np.linspace(0, 10, 100),
'y1': np.sin(np.linspace(0, 10, 100)),
'y2': np.cos(np.linspace(0, 10, 100))
})
# Step 3: Create the layered plot using Matplotlib
plt.figure(figsize=(8, 6))
# Line plot for y1 (sin)
plt.plot(df['x'], df['y1'], color='blue', label='sin(x)', linewidth=1)
# Scatter plot for y1 (sin)
plt.scatter(df['x'], df['y1'], color='blue')
# Line plot for y2 (cos)
plt.plot(df['x'], df['y2'], color='red', label='cos(x)', linewidth=1)
# Scatter plot for y2 (cos)
plt.scatter(df['x'], df['y2'], color='red')
# Step 4: Add labels, title, and legend
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Layered Plot: sin(x) and cos(x)')
plt.legend()
# Step 5: Show the plot
plt.show()
Conclusion
Why struggle with Matplotlib’s outdated, verbose syntax when you can use Plotly for interactivity, Seaborn for beauty, Altair for simplicity, Bokeh for web-based data exploration, and Plotnine for an R-like experience in Python?
Whether you're building a dashboard or running data analysis, these tools can save you time and frustration. Of course, if you prefer spending hours tweaking your plots, feel free to stick with Matplotlib.