Make matplotlib plots look more appealing with just a few extra commands

2 minute read comments

In this tutorial we will learn, how to make default matplotlib plots look more appealing with just a few extra commands.

Let’s start with some dummy data:

import numpy as np
import matplotlib.pyplot as plt

# Generate some random dummy data:
np.random.seed(1)
Group_A = np.random.randn(10)*10+15
Group_B = np.random.randn(10)*10+2

# bar-plot:
fig=plt.figure(1, figsize=(4,6))
fig.clf()

plt.bar([1, 2], [Group_A.mean(), Group_B.mean()], 
        color=["blue", "orange"])

plt.xticks([1,2], labels=["A", "B"])
plt.xlabel("Groups")
plt.ylabel("measurments")
plt.title("A bar-plot")

plt.xlim([0.5, 2.5])

plt.tight_layout
plt.show()


png

First, we switch from the bar- to a dot-plot, which provides a better visual impression of the data distributions. We will also adjust the font sizes (fontsize):

fig=plt.figure(1, figsize=(4,6))
fig.clf()

xVals = np.ones(Group_A.shape[0])

# Group A data:
plt.plot(xVals, Group_A, 'o', markeredgecolor="blue",
         markerfacecolor="blue", markersize=20, alpha=0.5)
plt.plot(1, Group_A.mean(), 'o', markeredgecolor="k",
         markerfacecolor="white", markersize=20)

# Group B data:
plt.plot(xVals+1, Group_B, 'o', markeredgecolor="orange",
         markerfacecolor="orange", markersize=20, alpha=0.5)
plt.plot(2, Group_B.mean(), 'o', markeredgecolor="k",
         markerfacecolor="white", markersize=20)

plt.xticks([1,2], labels=["A", "B"], fontsize=16)
plt.xlabel("Groups", fontsize=16)
plt.ylabel("measurements", fontsize=16)
plt.title("A dot-plot", fontsize=22, fontweight="normal")

plt.xlim([0.5, 2.5])

plt.tight_layout
plt.show()


png

We also increased the discernibility of the individual data points via the alpha value, which controls the transparency. The transparency also had an effect on the dot colors, which became a bit muted and look less like matplotlib’s default color definitions.

Next, let’s remove parts of the black bounding box,

ax.spines["top/right"].set_visible(False)

change the thickness of the remaining bounds,

ax.spines["bottom/left"].set_linewidth(2)

and increase the size of the ticks,

ax.tick_params(width=2, length=10)

fig=plt.figure(1, figsize=(4,6))
fig.clf()

# Group A data:
plt.plot(xVals, Group_A, 'o', markeredgecolor="blue",
         markerfacecolor="blue", markersize=20, alpha=0.5)
plt.plot(1, Group_A.mean(), 'o', markeredgecolor="k",
         markerfacecolor="white", markersize=20)

# Group B data:
plt.plot(xVals+1, Group_B, 'o', markeredgecolor="orange",
         markerfacecolor="orange", markersize=20, alpha=0.5)
plt.plot(2, Group_B.mean(), 'o', markeredgecolor="k",
         markerfacecolor="white", markersize=20)

plt.xticks([1,2], labels=["A", "B"], fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel("Groups", fontsize=16)
plt.ylabel("measurments", fontsize=16)
plt.title("A dot-plot", fontsize=22, fontweight="normal")

# control the black bound box and tick sizes:
ax = plt.gca() # get current axis
ax.spines["right"].set_visible(False)
ax.spines["top"].set_visible(False)
ax.spines["bottom"].set_linewidth(2)
ax.spines["left"].set_linewidth(2)
ax.tick_params(width=2, length=10)

plt.xlim([0.5, 2.5])

plt.tight_layout
plt.show()


png

That’s it! While changing the transparency works best when you want to visualize multiple datapoints (e.g., in dot- and scatter-plots, multiple line plots), removing parts of the black bounding box and increasing the fontsizes work well for almost any matplotlib plot.

Extra tip: In case you want to set the figure size in centimeters, you can’t do that directly. However, you can convert the desired size from cm to inches by dividing the size in cm by 2.54:

cm = 1/2.54  # define conversion factor centimeters to inches
fig=plt.figure(1, figsize=(15*cm, 5*cm))

You can find a bunch of other visualization hacks in the free online book Fundamentals of Data Visualization: A Primer on Making Informative and Compelling Figures by Calus O. Wilke (O’Reilly, 2019)


Comments

Commenting on this post is currently disabled.

Comments on this website are based on a Mastodon-powered comment system. Learn more about it here.