acdr
acdr

Reputation: 4706

Matplotlib: automatically modify axis labels

I'm aware that it's possible to change axis labels by setting them manually. (E.g.: Modify tick label text)

However, this obviously only works if you know what labels you want, which is not the case for me.

Here's an example of what I'd like to accomplish: I have two numpy arrays: x contains numbers between 1 and 366 (but not necessarily all of them), representing days of the year 2016. 'y' contains some other number. I'd like to make a scatter plot of 'y' versus 'x':

import numpy as np
import matplotlib.pyplot as plt
x = np.array([27, 38, 100, 300])
y = np.array([0.5, 2.5, 1.0, 0.8])
plt.scatter(x, y)

Unsurprisingly, this generates a graph with ticks at 0, 50, 100, ..., 350. I'd like to change these tick labels to individual dates. (E.g. the tick at 50 would be labeled something like 'February 19'.) Suppose I have a function tick_to_date which can transform the number 0 into a date string, so it'd be easy for me to manually change all the ticks in my graph. (If you need a placeholder function: tick_to_date = lambda x: ("day " + str(x)))

ax = plt.gca()
ax.set_xticklabels([tick_to_date(tick.get_text()) for tick in ax.get_xticklabels()])

However, this only does it once. If I now zoom in, or undertake any action that changes the ticks, the new tick labels aren't going to be what I want them to be.

Ideally, instead of setting the labels manually, I'd tell the axis to always transform the tick labels with my own tick_to_date function. Alternatively, call the above line of code every time the ticks are changed, but I'm not sure that would work so well. Is either of these possible/feasible/pleasantly available?

Upvotes: 4

Views: 2648

Answers (1)

Serenity
Serenity

Reputation: 36635

If I truly understand your question you are looking for function formatter from matplotlib.ticker:

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

# I added 'y' to fit second argument (position) of FuncFormatter
tick_to_date = lambda x,y: ("day " + str(x))

x = np.array([27, 38, 100, 300])
y = np.array([0.5, 2.5, 1.0, 0.8])
plt.scatter(x, y)

ax = plt.gca()
# tick_to_date will affect all tick labels through MyFormatter
myFormatter = ticker.FuncFormatter(tick_to_date)
# apply formatter for selected axis
ax.xaxis.set_major_formatter(myFormatter)
plt.show()

Upvotes: 5

Related Questions