16

From the documentation:

The default transform specifies that text is in data coords, alternatively, you can specify text in axis coords (0,0 is lower-left and 1,1 is upper-right). The example below places text in the center of the axes:

>>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center',
...      verticalalignment='center', transform=ax.transAxes)

Can I instead use both data and axis coords? For x and y respectively.

Example code:

import random
import matplotlib.pyplot as plt

values = [random.randint(2,30) for _ in range(15)]
plt.violinplot(values, positions=[1])

# This might place the text outside the figure
plt.gca().text(1, 30, "Text")
# I would like to use axis coords for y instead of data coords. Example call
# would be something like this:
# text_mixed_coords(xdata=1, yaxis=0.9, "Text")

plt.savefig("plot.png")

Potential results:
plot.png plot.png

See also: Putting text in top left corner of matplotlib plot

orestisf
  • 1,396
  • 1
  • 15
  • 30
  • 1
    https://matplotlib.org/3.1.1/tutorials/advanced/transforms_tutorial.html#blended-transformations – DavidG Jul 29 '20 at 12:34

1 Answers1

17

This is known as a "blended transformation"

you can create a blended transformation that uses the data coordinates for the x axis and axes coordinates for the y axis, like so:

import matplotlib.transforms as transforms
trans = transforms.blended_transform_factory(ax.transData, ax.transAxes)

In your minimal example:

import random
import matplotlib.pyplot as plt
import matplotlib.transforms as transforms

fig, ax = plt.subplots()

values = [random.randint(2,30) for _ in range(15)]
ax.violinplot(values, positions=[1])

# the x coords of this transformation are data, and the
# y coord are axes
trans = transforms.blended_transform_factory(
    ax.transData, ax.transAxes)

ax.text(1, 0.9, "Text", transform=trans)

plt.savefig("plot.png")

enter image description here

Also worth noting this from the matplotlib tutorial which makes it a little easier in this particular case:

Note:

The blended transformations where x is in data coords and y in axes coordinates is so useful that we have helper methods to return the versions mpl uses internally for drawing ticks, ticklabels, etc. The methods are matplotlib.axes.Axes.get_xaxis_transform() and matplotlib.axes.Axes.get_yaxis_transform(). So in the example above, the call to blended_transform_factory() can be replaced by get_xaxis_transform:

trans = ax.get_xaxis_transform()
tmdavison
  • 64,360
  • 12
  • 187
  • 165