0

I would like to label data points in pandas with x axis value. And I am trying to apply this solution into my code: Annotate data points while plotting from Pandas DataFrame

I'm getting an error saying:

AttributeError: 'PathCollection' object has no attribute 'text'

Here's my code:

def draw_scatter_plot(xaxis, yaxis, title, xaxis_label, yaxis_label, save_filename, color, figsize=(9, 7), dpi=100):
    fig = plt.figure(figsize=figsize, dpi=dpi)

    ax = plt.scatter(xaxis, yaxis, c=color)

    plt.xlabel(xaxis_label)
    plt.ylabel(yaxis_label)

    label_point(xaxis, yaxis, xaxis, ax)

    plt.title(title)

    fig.savefig(save_filename, dpi=100)

# label code from https://stackoverflow.com/questions/15910019/annotate-data-points-while-plotting-from-pandas-dataframe/15911372#15911372

def label_point(x, y, val, ax):
    a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1)
    for i, point in a.iterrows():
        ax.text(point['x'], point['y'], str(point['x']))

Any advice on this problem?

5
  • 1
    Pandas' plot returns an axes-object docs. You use plt.scatter, which returns a paths-object docs. Commented Aug 14, 2017 at 18:20
  • @sascha oh got ya. How to apply annotate function here? Commented Aug 14, 2017 at 18:20
  • 2
    Create an axes-object manually, use it to call scatter, then pass it to your label-func. I'm not sure what's best practice, but f, ax = plt.subplots(1) followed by ax.scatter() (maybe ax[0])) might work. (although it looks silly because of subplots) Commented Aug 14, 2017 at 18:25
  • @sascha I've fixed code as guided. But it shows nothing. Commented Aug 14, 2017 at 18:31
  • Then you should probably show your modified code. Edit: or use MaxU's more clever approach! Commented Aug 14, 2017 at 18:31

2 Answers 2

3

Consider the following demo:

In [6]: df = pd.DataFrame(np.random.randint(100, size=(10, 2)), columns=list('xy'))

In [7]: df
Out[7]:
    x   y
0  44  13
1  69  53
2  52  80
3  72  64
4  66  42
5  96  33
6  31  13
7  61  81
8  98  63
9  21  95

In [8]: ax = df.plot.scatter(x='x', y='y')

In [9]: df.apply(lambda r: ax.annotate(r['x'].astype(str)+'|'+r['y'].astype(str), 
                                       (r.x*1.02, r.y*1.02)), axis=1)
Out[9]:
0    Annotation(44,13,'44|13')
1    Annotation(69,53,'69|53')
2    Annotation(52,80,'52|80')
3    Annotation(72,64,'72|64')
4    Annotation(66,42,'66|42')
5    Annotation(96,33,'96|33')
6    Annotation(31,13,'31|13')
7    Annotation(61,81,'61|81')
8    Annotation(98,63,'98|63')
9    Annotation(21,95,'21|95')
dtype: object

Result:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Very nice combination of matplotlib and pandas!
0

The problem appears because you give the return of plt.scatter the name ax. This is confusing, because it is not an axes, but a 'PathCollection' (as the error tells you).

Replace the first two lines

fig = plt.figure(figsize=figsize, dpi=dpi)
ax = plt.scatter(xaxis, yaxis, c=color)

by

fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
ax.scatter(xaxis, yaxis, c=color)

and keep the rest of the code the same.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.