Set a Logarithmic Scale on the Y-Axis in Matplotlib

Visualizing data with massive variations can be quite a headache. I often find that a standard linear scale makes small values disappear while large values hog the entire chart.

In my experience, switching to a logarithmic scale is the best way to solve this. It allows you to see the percentage change and growth patterns much more clearly.

In this tutorial, I will show you exactly how to set the y-axis to a log scale in Matplotlib using several different methods.

Use a Log Scale

Before we dive into the code, let’s talk about why you would even want to do this.

If you are plotting the population of US cities, New York City will dwarf a small town in Wyoming. On a normal scale, the Wyoming data looks like a flat line at zero.

By using a log scale, we can see the relative differences between these data points regardless of their magnitude. It is an essential tool for any data scientist.

Method 1: Use the plt.yscale() Function

The easy way I have found to change the scale is by using the plt.yscale() function. It is a quick, one-line fix that works perfectly for simple scripts.

In this example, let’s look at the growth of a hypothetical US tech investment over several decades.

import matplotlib.pyplot as plt

# Years and corresponding investment value in USD
years = [1980, 1990, 2000, 2010, 2020]
investment_value = [1000, 15000, 200000, 5000000, 80000000]

plt.figure(figsize=(10, 6))
plt.plot(years, investment_value, marker='o', linestyle='-', color='b')

# Setting the y-axis to log scale
plt.yscale('log')

plt.title('Growth of US Tech Venture Capital (Log Scale)')
plt.xlabel('Year')
plt.ylabel('Value in USD (Logarithmic)')
plt.grid(True, which="both", ls="-", alpha=0.5)

plt.show()

You can see the output in the screenshot below.

Set Logarithmic Scale on the Y-Axis in Matplotlib

When I use plt.yscale(‘log’), Matplotlib automatically calculates the powers of 10 for the axis. It makes the exponential growth look like a steady upward trend.

Method 2: Use the set_yscale() Method on Axes Objects

If you prefer using the object-oriented approach (which I highly recommend for complex layouts), you should use set_yscale().

I find this method much more robust when I am working with subplots or multiple figures in a single script.

Let’s use US National Debt data (simplified) to demonstrate this.

import matplotlib.pyplot as plt

# Decades and approximate US National Debt in Billions
decades = [1950, 1970, 1990, 2010, 2023]
debt_billions = [257, 370, 3233, 13561, 33000]

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(decades, debt_billions, marker='s', color='red', label='Total Debt')

# Applying log scale to the axes object
ax.set_yscale('log')

ax.set_title('US National Debt Over Time')
ax.set_xlabel('Year')
ax.set_ylabel('Debt in Billions (Log Scale)')
ax.legend()
ax.grid(True, which="both")

plt.show()

You can see the output in the screenshot below.

Set a Logarithmic Scale on the Y-Axis in Matplotlib

By calling ax.set_yscale(‘log’), you are explicitly telling that specific subplot to transform its vertical axis. It’s clean and avoids confusion in larger projects.

Method 3: Handle Log Scales in Bar Charts

Sometimes people think log scales are only for line graphs. However, I often use them for bar charts, especially when comparing US State populations or GDPs.

Without a log scale, California and Texas would make smaller states like Vermont look non-existent on the chart.

import matplotlib.pyplot as plt

# US States and their approximate populations
states = ['California', 'Texas', 'Florida', 'South Dakota', 'Vermont', 'Wyoming']
populations = [39000000, 30000000, 22000000, 900000, 647000, 581000]

plt.figure(figsize=(10, 6))
plt.bar(states, populations, color='teal')

# Set y-axis to log scale
plt.yscale('log')

plt.title('Comparison of US State Populations')
plt.ylabel('Population (Log Scale)')
plt.xlabel('State')

plt.show()

You can see the output in the screenshot below.

Logarithmic Scale on the Y-Axis in Matplotlib

Using a log scale here allows the viewer to actually see the bars for Wyoming and Vermont. In a linear scale, those bars would be just a few pixels high.

Method 4: Customize Log Base (e.g., Base 2)

While base 10 is the default, there are times I need to use a different base. For example, in computing or certain biological studies, base 2 is much more relevant.

You can easily pass the base parameter into the scale function.

import matplotlib.pyplot as plt
import numpy as np

# Example: Computing power growth in a US Data Center
nodes = np.array([1, 2, 4, 8, 16, 32, 64])
processing_time = 1000 / nodes # Artificial data

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(nodes, processing_time, 'go--')

# Setting log scale with base 2
ax.set_yscale('log', base=2)

ax.set_title('Processing Time vs Nodes (Base 2 Log)')
ax.set_xlabel('Number of Nodes')
ax.set_ylabel('Time (ms)')
ax.grid(True)

plt.show()

You can see the output in the screenshot below.

Set Logarithmic Scale on the Y-Axis in Python Matplotlib

I find this particularly useful when dealing with binary systems or any data that doubles or halves at regular intervals.

Method 5: Use Symlog for Negative Values

One common issue I encounter is trying to use a log scale on data that contains zeros or negative numbers. A standard log scale will break because the log of zero is undefined.

To fix this, I use symlog (Symmetrical Log). This allows for a linear range around zero and a log range for everything else.

import matplotlib.pyplot as plt
import numpy as np

# Sample US Economic Growth rates (including negatives for recessions)
quarters = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6']
growth_values = [100, 1000, -50, 5000, -1000, 10000]

plt.figure(figsize=(10, 6))
plt.plot(quarters, growth_values, marker='d', color='purple')

# Using symlog to handle negative values
plt.yscale('symlog')

plt.title('US Sector Growth with Negative Values')
plt.ylabel('Growth Index (Symlog)')
plt.grid(True)

plt.show()

symlog is a lifesaver when you have volatile data that occasionally dips below the axis but still spans several orders of magnitude.

Adjust Ticks and Labels

When you switch to a log scale, Matplotlib might not always place the ticks exactly where you want them.

I usually use the LogLocator and LogFormatter from matplotlib.ticker to gain full control over how the axis looks.

import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, ScalarFormatter

# US Median Home Prices (Approximate)
years = [1940, 1970, 2000, 2023]
prices = [2900, 17000, 119000, 430000]

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(years, prices, marker='o', linewidth=2, color='darkgreen')

ax.set_yscale('log')

# Customizing ticks
ax.yaxis.set_major_locator(LogLocator(base=10, numticks=10))
ax.yaxis.set_major_formatter(ScalarFormatter()) # Keeps labels as numbers

ax.set_title('US Median Home Price Growth')
ax.set_ylabel('Price in USD')
ax.grid(True, which="both")

plt.show()

I like using ScalarFormatter because it changes labels from scientific notation (like $10^5$) back to standard numbers (like 100,000), which is often easier for clients to read.

Common Issues to Avoid

When working with log scales, I have run into a few recurring problems. Here is how to avoid them:

  1. Zero Values: As mentioned, plt.yscale(‘log’) will fail or ignore data points that are zero. Use symlog or add a very small constant to your data.
  2. Grid Lines: Always use plt.grid(True, which=’both’). If you only show major grid lines, the log scale can be very hard for the reader to interpret.
  3. Labeling: Be very clear in your axis titles that the scale is logarithmic. Otherwise, people might misinterpret the rate of change.

In this tutorial, I have covered various ways to set and customize the y-axis log scale in Matplotlib.

Whether you are using the simple plt.yscale() or the more robust ax.set_yscale(), these techniques are vital for handling large-scale US data sets effectively.

You may also like to read other matplotlib tutorials:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.