3

With matplotlib, I am trying to annotate vertical lines that I have drawn on a plot of sequential data. With the line

plt.annotate('%.2f' % 2.34, xy=(0,0), xytext=(0,-20), xycoords='axes fraction', textcoords='offset points',color='r')

I am able to get text to show up below my plot. However, I have vertical lines plotted -- say, at intervals of 240 -- and I would like to specifically annotate each of these lines below the x-axis.

I tried switching the xycoords format to 'data' and then using xy=(240,0), but when I switch the xycoords format to 'data' the annotation text ceases to appear on my plot.

I also tried calculating the fraction where I wanted to place my annotation (e.g. 240/length of plot), but this still did not place it correctly.

Why does the annotation command stop adding text to my plot when I change the coordinate system to 'data' instead of 'axis fraction'? Thanks!

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
C. Mahany
  • 31
  • 1
  • 2

1 Answers1

3

It's difficult to say what is the exact problem without a workable example. In any case as solution to your problem I would advise you to duplicate your axis (in the same figure) and just use the second one to control the accessory stuff.

Here is a working solution:

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

# Add some extra space for the second axis at the bottom
fig.subplots_adjust(bottom=0.2)
ax1.set_xticks(range(-100, 100, 10))
ax1.set_xlim(-100, 100)
ax1.set_xticklabels([str(i) for i in range(-100, 100, 10)], rotation=45)

ax2.spines["bottom"].set_position(("axes", -0.1))
ax2.xaxis.set_ticks_position("bottom")
ax2.spines["bottom"].set_visible(True)
ax2.set_xticks([-50,50])
ax2.set_xticklabels(['Line 1', 'Line 2'], rotation=45, color='blue')
ax2.set_xlim(-100, 100)

b1 = np.random.randint(0,100,6)
b2 = np.random.randint(0,100,6)
b3 = np.random.randint(0,100,6)
ax1.scatter(np.random.normal(0, 1, 100)*100, np.random.normal(0, 1, 100)*100, c='green', s=90)
ax1.axvline(-50)
ax1.axvline(50)

plt.show()

, which results in this:

Using a second axis in one figure to provide labels to vlines in matplotlib

armatita
  • 12,825
  • 8
  • 48
  • 49