How can you change the y-axis in matplotlib such that you have specified ticks ([0, -1, -8, -44, -244]) but they are evenly spread over the y-axis (the gap between 0 and -1 is just as big as the gap between -44 and -244 if you visualise the figure). So you do not have an linear distribution on the y-axis but it makes you plot look better. The distance between the ticks should be equal and this makes your graph look better.
I tried to use the normal yticks first. I also tried the method where you use ax.set_yticks and ax.set_ytickslabels. However, it did not give me the wanted result.
It would be great to have a minimally working example to see what kind of data/plot are you working with. But generally speaking, it sounds like you need to transform your data/axis, rather than just selecting custom ticks.
You could do this with a custom scale in matplotlib. Below, I have used interpolation to force the [-244, -44, -8, -1, 0]
to have equally spaced values (in this case [0..4]
). The advantage of using a scaling function rather than scaling your input data is that the yticks, etc. can be specified in the original scale.
I've assumed that you really need a particular set of values to be equally spaced but you should also checkout other (simpler) scaling methods like set_yscale('log')
if they make your plots look better.
import matplotlib.pyplot as plt
import numpy as np
# Sample data
x = np.linspace(0, 10, 100)
y = 255*(np.sin(x)/2 - 0.5)
# Define the values that need to be equally spaced
y_scale = [-244, -44, -8, -1, 0]
y_scale_vals = np.arange(len(y_scale))
# Interpolate such that -244 -> 0, -44 -> 1, -8 -> 2, -1 -> 3, 0 -> 4
def forward(y):
return np.interp(y, y_scale, y_scale_vals)
def inverse(y):
return np.interp(y, y_scale_vals, y_scale)
fig, ax = plt.subplots(1,2, layout='constrained')
ax[0].plot(x, y)
ax[0].set_title('Linear scale')
ax[1].plot(x, y)
ax[1].set_yscale('function', functions=(forward, inverse))
ax[1].yaxis.set_ticks(y_scale)
ax[1].set_title('Custom scale')