Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib text: Use data coords for x, axis coords for y

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

like image 646
orestisf Avatar asked Jul 29 '20 12:07

orestisf


People also ask

How do I make X and Y-axis scales the same in MatPlotLib?

The pyplot. axes() function returns an instance of the Axes object, the object in charge of the axes. The Axes instance have a set_aspect method, which we set to 'equal' . Now, both axes use the same scale.

What is the use of Xticks () and Yticks () in plotting?

The xticks() and yticks() function takes a list object as argument. The elements in the list denote the positions on corresponding action where ticks will be displayed. This method will mark the data points at the given positions with ticks.

How do you change the x and y-axis range in MatPlotLib?

To change the range of X and Y axes, we can use xlim() and ylim() methods.


1 Answers

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()
like image 125
tmdavison Avatar answered Oct 19 '22 14:10

tmdavison