Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python matplotlib, get position of xtick labels

How do I get the positions of the xtick major labels? The values that I am getting from label.get_position() do not make sense.

import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# fig, ax = plt.figure(1)
fig, ax = plt.subplots()
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

# plt.show()
print(fig)
print(ax.get_position())

# ------------------------------------------------
# positions of the tick labels, incorrect (0,0) returned
# ------------------------------------------------
print([text.get_position() for text in ax.get_xticklabels()])
# correct tick label values
print(ax.get_xticks())

Output from the above code is:

Figure(640x480)
Bbox('array([[ 0.125,  0.1  ],\n       [ 0.9  ,  0.9  ]])')
[(0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0)] <-- incorrect positions
[ 0.  1.  2.  3.  4.  5.]

How do I get the positions of the xtick major labels? The values that I am getting from label.get_position() do not make sense. Is there a transform that I don't know about? Ultimately I want the position of the text boxes in (x,y) image pixel units.

like image 270
spacether Avatar asked May 16 '17 22:05

spacether


2 Answers

If you need the pixel coordinates, you need the figure coordinates, and tranform them.

If you need more information on transformations, check this tutorial on matplotlib transformations: ref

EDIT: for completeness, I added the option to specify the dpi, which will influence your figure dimensions

import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# set the dpi you want in your final figure
dpi = 300
mpl.rcParams['figure.dpi'] = dpi

fig, ax = plt.subplots()
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

# saving the figure: don't forget the dpi option!
fig.savefig('./out.png', format='png', dpi=dpi)

xtickslocs = ax.get_xticks()
ymin, _ = ax.get_ylim()
print('xticks pixel coordinates')
print(ax.transData.transform([(xtick, ymin) for xtick in xtickslocs]))
print('label bounding boxes')
print([l.get_window_extent() for l in ax.get_xticklabels()])

Output:

xticks pixel coordinates
array([[  60. ,   40. ],
       [ 134.4,   40. ],
       [ 208.8,   40. ],
       [ 283.2,   40. ],
       [ 357.6,   40. ],
       [ 432. ,   40. ]])
label bounding boxes
[Bbox([[56.4375, 25.5555555556], [63.5625, 35.5555555556]]),
 Bbox([[130.8375, 25.5555555556], [137.9625, 35.5555555556]]),
 Bbox([[205.2375, 25.5555555556], [212.3625, 35.5555555556]]),
 Bbox([[279.6375, 25.5555555556], [286.7625, 35.5555555556]]),
 Bbox([[354.0375, 25.5555555556], [361.1625, 35.5555555556]]),
 Bbox([[428.4375, 25.5555555556], [435.5625, 35.5555555556]])]
like image 85
Daan Avatar answered Sep 18 '22 16:09

Daan


Since you need the "position of the text boxes in (x,y)", adapting this answer to your request in comments/code, we have:

import numpy as np
import matplotlib.pyplot as plt

def f(t):
    return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

# fig, ax = plt.figure(1)
fig, ax = plt.subplots()
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

print(fig)
print(ax.get_position())


plt.gcf().canvas.draw()
ticks = [tick for tick in plt.gca().get_xticklabels()]

for i, t in enumerate(ticks):
    print("Label ", i, ", data: ", t.get_text(), " ; ", t.get_window_extent())

print(ax.get_xticks())
plt.show()

Which prints:

>>> 
 RESTART: C:/Users/Vinicius/AppData/Local/Programs/Python/Python35-32/stack21.py 
Figure(640x480)
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88)
Label  0 , data:    ;  Bbox(x0=102.54545454545455, y0=43.077777777777776, x1=102.54545454545455, y1=43.077777777777776)
Label  1 , data:  0  ;  Bbox(x0=98.17045454545455, y0=29.077777777777776, x1=106.92045454545455, y1=43.077777777777776)
Label  2 , data:  1  ;  Bbox(x0=188.65194870390656, y0=29.077777777777776, x1=197.52694870390656, y1=43.077777777777776)
Label  3 , data:  2  ;  Bbox(x0=279.25844286235855, y0=29.077777777777776, x1=288.00844286235855, y1=43.077777777777776)
Label  4 , data:  3  ;  Bbox(x0=369.80243702081054, y0=29.077777777777776, x1=378.55243702081054, y1=43.077777777777776)
Label  5 , data:  4  ;  Bbox(x0=460.34643117926254, y0=29.077777777777776, x1=469.09643117926254, y1=43.077777777777776)
Label  6 , data:  5  ;  Bbox(x0=550.8904253377145, y0=29.077777777777776, x1=559.6404253377145, y1=43.077777777777776)
Label  7 , data:    ;  Bbox(x0=102.54545454545455, y0=43.077777777777776, x1=102.54545454545455, y1=43.077777777777776)
[-1.  0.  1.  2.  3.  4.  5.  6.]
like image 21
Vinícius Figueiredo Avatar answered Sep 18 '22 16:09

Vinícius Figueiredo