3

I'm trying to position some additional annotations to line up with the axis label text in a matplotlib figure. How is this position calculated, as a function of the font size of the tick and axes labels, and the font size of the annotation?

Specifically, given a figure with a single set of tick labels and a single axis label along the x-axis, with font sizes tick_font_size and label_font_size respectively, what is the vertical position y in figure points that would result in

ax.annotate('Some text', (x, y), va='top', ...)

placing 'Some text' with font size annotation_font_size, in vertical alignment with the axis label?


For various reasons, I must use annotate for this, and va='top' is a constraint; and I need to use the font size information above — that is, I'm looking for the function of the form

y = f(tick_font_size, label_font_size, annotation_font_size)

with all values in figure points (i.e., usable with textcoords='offset points' in annotate). Such an algorithm must exist, since it is clearly used by matplotlib to position the axis label in the first place.

orome
  • 45,163
  • 57
  • 202
  • 418

1 Answers1

2

Get the object returned when setting xlabel. Render the figure and use get_position to get the position of the label. From there do some transformations and add the annotation.

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = x**2

xlabel = plt.xlabel("test")
plt.plot(x, y)

ax = plt.gca()
fig = plt.gcf()
fig.draw(fig.canvas.get_renderer())

trans = xlabel.get_transform()
xpos, ypos = trans.transform(xlabel.get_position())  # convert to display coordinates
xpos, ypos = fig.transFigure.inverted().transform([xpos, ypos])  # convert to figure coordinates
ax.annotate('Some text', (xpos+0.05, ypos), xycoords='figure fraction', va="top")
plt.show()
M4rtini
  • 13,186
  • 4
  • 35
  • 42
  • Assume I've just got `ax`, with axes and labels already set up. How do I get `xlabel`? – orome Jan 09 '14 at 20:40
  • ax.get_xaxis().get_label() – M4rtini Jan 09 '14 at 20:50
  • This is helpful, but not quite what I'm looking for. What I need is the function that maps `ax`, `tick_font_size`, `label_font_size` and `annotation_font_size` to a value for `y` that aligns the annotation with the axis label. (That function exists, since its used by `matplotlib` to position the axis label.) – orome Jan 09 '14 at 22:06