6

Trying to use seaborn and matplotlib to plot some data, need to add some descriptive text to my plot, normally I'd just use the matplotlib command text, and place it where I wanted relative to the axes, but it doesn't appear to work at all, I get no text showing beyond the default stuff on the axes, ticks, etc. What I want is some custom text showing in the top left corner of the plot area.

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

df is my pandas dataframe, it just contains some columns of time and coordinate data with a tag "p" which is an identifier.

ax2 = sns.scatterplot("t","x", data = df, hue = "p")
ax2.text(0.1, 0.9, r"$s = {}, F = {}, N = {}$".format(value1, valu2, value3))

plt.show()

Anyone know how I can get some text to show, relatively positioned, the "value" items are just the variables with the data I want to print. Thanks.

2 Answers 2

8

You want to position a text "in the top left corner of the plot area". The "plot area" is called axes. Three solutions come to mind:

Text in axes coordinates

You could specify the text in axes coordinates. Those range from (0,0) in the lower left corner of the axes to (1,1) in the top right corner of the axes. The corresponding transformation is obtained via ax.transAxes.

import matplotlib.pyplot as plt
fig, ax = plt.subplots()

ax.text(0.02, 0.98, "Text", ha="left", va="top", transform=ax.transAxes)

plt.show()

Annotation with offset

In the above the distance between the text and the top left corner will be dependent on the size of the axes. It might hence be beneficial to position the text exactly at the top left corner (i.e. (0,1) in axes coordinates) and then offset it by some points, i.e in absolute units.

ax.annotate("Text", xy=(0,1), xycoords="axes fraction",
                    xytext=(5,-5), textcoords="offset points",
                    ha="left", va="top")

The result here looks similar to the above, but is independent of the axes or figure size; the text will always be 5 pts away from the top left corner.

Text at an anchored position

Finally, you may not actually want to specify any coordinates at all. After all "upper left" should be enough as positioning information. This would be achieved via an AnchoredText as follows.

import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredText

fig, ax = plt.subplots()

anc = AnchoredText("Text", loc="upper left", frameon=False)
ax.add_artist(anc)

plt.show()
Sign up to request clarification or add additional context in comments.

3 Comments

I feel like you didn't read what I posted as the first example you've given me is the example I've given taht doesn't work with seaborn. I haven't tried anchoring but will, and the annotation stuff was unclear but your example might work, I'll have to give it a shot.
You can safely assume that I did read and understand your question. All 3 examples shown here will work! Note the difference between the arguments in the first example. (And of course you will need to replace ax by ax2 or whatever name you give the axes produced by seaborn.)
I think I see what you mean, though I think for these plot methods that annotate may be the better/clearer option. Thank you.
2

In order to position the text in the upper left corner for a plot without knowing the limits beforehand you can query the x and y limits of the axis and use that to position the text relative to the bounds of the plot. Consider this example (where I have also included code to generate some random data for demonstration)

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

np.random.seed(1)
df = pd.DataFrame({'t':np.linspace(1,2,100),
                  'x':np.random.randn(100)})

value1 = 1
value2 = 2
value3 = 3
ax2 = sns.scatterplot("t","x", data = df)
tl = ((ax2.get_xlim()[1] - ax2.get_xlim()[0])*0.010 + ax2.get_xlim()[0],
      (ax2.get_ylim()[1] - ax2.get_ylim()[0])*0.95 + ax2.get_ylim()[0])
ax2.text(tl[0], tl[1], r"$s = {}, F = {}, N = {}$".format(value1, value2, value3))

plt.show()

This will output

Text positioned in upper left

and changing the bounds will not change the position of the text, i.e.

Text positioned in upper left (with larger bounds)

You may need to adjust the multipliers 0.01 and 0.95 as you want based on exactly how close to the corner you want the text.

1 Comment

"changing the bounds will not change the position of the text" is misleading. The axes limits may change at any time even after the plot is first drawn, e.g. by zooming or by adding further elements. In those cases one would rather not have the text position in data coordinates at all. For recommended alternatives see the other answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.