Is there a way to add a new tick to the y axis in pyplot while using a log scale?

Viewed 69

I have a heatmap and I wanted to had a tick, for a value above the maximum tick represented.
Something like this:

this.

I tried to add the tick and the tick label:

yticks_i_want = np.append(ax.get_yticks(), 2600)
ax.set_yticks(yticks_i_want)

However, this happens:

this

The best solution I found so far was to use ax.text(), like so:

ax.text(-0.059, 2600, '2600 -', transform=ax.get_yaxis_transform(),
            ha='center', va='top')

Am I missing something?
Is there another way to add the tick or must I "cut" plot 2 to show only the values I want?

1 Answers

The problem is that ax.get_yticks() returns ticks that are outside the limits of the axis, in this case:

In [6]: ax.get_yticks()
Out[6]: array([1.e-01, 1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05])

which is why when you then set the new ticks after appending your custom value, the y axis limits change.

Option 1: exclude the ticks outside the current axis limits

We can get around this with a simple list comprehension to exclude ticks outside of the current ylim. For example:

yticks_i_want = [y for y in ax.get_yticks() if (y >= ax.get_ylim()[0] and y <= ax.get_ylim()[1])]
yticks_i_want.append(2600.)

Putting it in a minimal example:

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig, ax = plt.subplots()
ax.set_yscale('log')
ax.set_ylim(1, 3000)

yticks_i_want = [y for y in ax.get_yticks() if (y >= ax.get_ylim()[0] and y <= ax.get_ylim()[1])]
yticks_i_want.append(2600.)

ax.set_yticks(yticks_i_want)

ax.yaxis.set_major_formatter(ticker.ScalarFormatter())

plt.show()

(note the ScalarFormatter()) is just there to get the tick label format to match the ones in the question rather than using scientific style).

enter image description here

Option 2: reset the axis limits after adding the tick

Of course, a simple alternative would be to just set the axis limits again after adding the custom tick location:

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np

fig, ax = plt.subplots()
ax.set_yscale('log')
ax.set_ylim(1, 3000)

ylim = ax.get_ylim()
yticks_i_want = np.append(ax.get_yticks(), 2600)
ax.set_yticks(yticks_i_want)

ax.set_ylim(*ylim)

ax.yaxis.set_major_formatter(ticker.ScalarFormatter())

plt.show()
Related