Python – How to get the position/index of xtick in matplotlib using tags? (Python 3.6 | Matplotlib 2.0)

How to get the position/index of xtick in matplotlib using tags? (Python 3.6 | Matplotlib 2.0)… here is a solution to the problem.

How to get the position/index of xtick in matplotlib using tags? (Python 3.6 | Matplotlib 2.0)

I’m trying to get an area dedicated to a drawing for a specific xtick tag (excluding marker size). For example, label=‘b’ seems to have (0.5 - 1.5) b/c tick position is 1 while I believe the default tick width is 1.

My question is, if I have a query_label (e.g. query_label= "c"), how can I get the tick position query_label along the x-axis and tick width Don’t assume that each tick position is separated by a width of 1 (e.g. [-1, 0, 1, 2, ...])?

Basically, I want to end :

query_position = (1.5, 2.5) # for query_label = "c"

Simple sample code:

# Data
x = np.arange(5)
y = np.sqrt(x)
s = [1000]*5
c = ["aquamarine"]*5

# Plot
with plt.style.context("dark_background"):
    fig, ax = plt.subplots()
    ax.scatter(x, y, c=c, s=s, edgecolors="ivory", linewidth=2.5)
    ax.set_xticklabels(list("-abcde"), fontsize=20)
    ax.grid(False, which="major")

# Trying to get the xtick info
ax.get_xticks()
# array([-1.,  0.,  1.,  2.,  3.,  4.,  5.])

# How to get position and tick width? 
query_label= "c"
def get_position(query_label, ax):
    # stuff to get tick index
    # stuff to get tick width
    tick_padding = tick_width/2
    return (tick_index - tick_padding, tick_index + tick_padding)

# Results
query_position = get_position(query_label, ax)
query_position
# (1.5, 2.5)

Maybe there is something similar to pd in matplotlib. Index(list("-abcde")).get_loc("c")?

enter image description here

Solution

I’m not sure if there’s a way, but you can generate a dictionary using ax.get_xticklabels() and it will return a list of xticklabel objects.

x_labels = list(ax.get_xticklabels())

These objects contain labels and their locations, which you can extract into a dictionary using list understanding.

x_label_dict = dict([(x.get_text(), x.get_position()[0]) for x in x_labels])

If you want to exclude some tick labels, you can use the if condition:

x_label_dict = dict([(x.get_text(), x.get_position()[0]) for x in x_labels if x.get_text() not in ['', '-']])

The width of each tick label can now be determined as :, using adjacent query labels

tick_width = x_label_dict['b'] - x_label_dict['a'] 

So the query position of 'c' becomes

x_label_dict['c'] - tick_width/2, x_label_dict['c'] + tick_width/2

Once you’ve decided on tick_width, you can update the dictionary so you can use it directly without the need for a function definition

x_query_position = {key: (x_label_dict[key]- tick_width/2, x_label_dict[key] + tick_width/2) for key in x_label_dict.keys()}

I guess the query location for 'c‘ is x_query_position['c']

Related Problems and Solutions