pythonmatplotlibboxplotx-axis

Continuous x-axis ticks with boxplots in Python


I am plotting some distributions using box plots. I then find the median of each distribution, fit them with a second order polynomial and make a prediction at a certain x-axis value. I plot both the fit and the prediction. I would like to have the x-axis to show the ticks equally spaced like it does automatically when plotting a simple line, but instead it's only showing the x-axis values corresponding to the box plots. How to reformat the x-axis to show continuous values?

I created a simplified version of my code with dummy data to reproduce the issue:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# Dummy x-axis values
variable = [1.6, 1.8, 2.0, 2.2, 2.5]
# Dummy data
dummy1 = np.random.rand(10, len(variable))
# Plot dummy data as box plots
ax.boxplot(dummy1, positions=variable, notch=True, patch_artist=True)
# Fit data with a quadratic polynomial
fit = np.polyfit(variable, np.nanmedian(dummy1, axis=0), 2)
# More dummy data
dummy2 = np.random.rand(10, 1)
# Make a prediction
prediction = fit[0] * dummy2 ** 2 + fit[1] * dummy2 + fit[2]
# Plot the prediction median as a star
ax.plot(np.nanmedian(dummy2), np.nanmedian(prediction), '*')
# Get the lowest x-axis value
minim_x = min(variable[0], np.nanmedian(dummy2))
# Fine-grain values for the fit plot
x = np.linspace(minim_x, variable[-1], 1000)
y = fit[0] * x ** 2 + fit[1] * x + fit[2]
# Plot the fit
ax.plot(x, y, '--')
ax.grid(True)
plt.show()


Solution

  • I added some tick formatting code that does the following: resets the ticks so they are located every 0.25 (box plot placed them irregularly), and then reset the tick formatter so that all tick labels show (box plot hides some ticks).

    enter image description here

    <your existing plotting code>
    .
    .
    .
    from matplotlib import ticker
    
    #Set x tick locations to span x axis, with step=0.25
    ax.xaxis.set_major_locator(ticker.MultipleLocator(0.25))
    
    #Apply default tick formatting so the tick labels all show
    ax.xaxis.set_major_formatter(ticker.ScalarFormatter())
    
    #Optionally rotate the ticks
    ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
    
    plt.show()