简体   繁体   中英

how to annotate (label) on the overlay scatterplot?

Here is my code. I got an error on the 2nd plot label. How to include the labels for both scatterplots which overlay each other. Also how to add a legend to specify the green is "leaf" and red is "fruit". Thanks in advance.

import pandas as pd
import matplotlib.pyplot as plt

df = {'id': ['a','b', 'c', 'd'],
    'x1': [2,3,4,5],
    'y1': [2,6,7,2],
        'x2': [4, 5, 6, 7],
      'y2':[4,6,7,9]}
df = pd.DataFrame(df)

ax =df.plot.scatter('x1', 'y1', c='green')
for i, txt in enumerate(df.id):
    ax.annotate(txt, (df.x1.iat[i],df.y1.iat[i]))
ax =plt.scatter(df['x2'],df['y2'],c='red')
for i, txt in enumerate(df.id):
    ax.annotate(txt, (df.x2.iat[i],df.y2.iat[i]))
plt.show()

The issue is when you call plt.scatter you have renamed the ax variable. While the pandas df.plot.scatter does return the matplotlib Axes instance the plot was created on, the native matplotlib plt.scatter instead returns a PathCollection instance. You then try calling ax.annotate , but annotate is not a valid method for a path collection.

It is safer to create the axes from matplotlib, and then you can control where each plot should be created.

Here, I will assume that you intended to use the two different scatter methods for a reason, and show how you can control which Axes they will appear on.

You don't state exactly where you want each of the scatter plots to appear, so here's a couple of options:

2 seperate figures

Assuming you want the two scatter plots in separate Figure instances, you could do the following:

import pandas as pd
import matplotlib.pyplot as plt

df = {'id': ['a', 'b', 'c', 'd'],
      'x1': [2, 3, 4, 5],
      'y1': [2, 6, 7, 2],
      'x2': [4, 5, 6, 7],
      'y2': [4, 6, 7, 9]}
df = pd.DataFrame(df)

fig1, ax1 = plt.subplots()
df.plot.scatter('x1', 'y1', c='green', ax=ax1)
for i, txt in enumerate(df.id):
    ax1.annotate(txt, (df.x1.iat[i], df.y1.iat[i]))

fig2, ax2 = plt.subplots()
ax2.scatter(df['x2'], df['y2'], c='red')
for i, txt in enumerate(df.id):
    ax2.annotate(txt, (df.x2.iat[i], df.y2.iat[i]))

plt.show()

2 subplots on the same figure

Assuming you want 2 subplots on the same figure:

import pandas as pd
import matplotlib.pyplot as plt

df = {'id': ['a', 'b', 'c', 'd'],
      'x1': [2, 3, 4, 5],
      'y1': [2, 6, 7, 2],
      'x2': [4, 5, 6, 7],
      'y2': [4, 6, 7, 9]}
df = pd.DataFrame(df)

fig, (ax1, ax2) = plt.subplots(ncols=2)

df.plot.scatter('x1', 'y1', c='green', ax=ax1)
for i, txt in enumerate(df.id):
    ax1.annotate(txt, (df.x1.iat[i], df.y1.iat[i]))

ax2.scatter(df['x2'], df['y2'], c='red')
for i, txt in enumerate(df.id):
    ax2.annotate(txt, (df.x2.iat[i], df.y2.iat[i]))

plt.show()

Both scatter plots in the same Axes

Assuming you want both scatter plots to appear on the same subplot you could:

import pandas as pd
import matplotlib.pyplot as plt

df = {'id': ['a', 'b', 'c', 'd'],
      'x1': [2, 3, 4, 5],
      'y1': [2, 6, 7, 2],
      'x2': [4, 5, 6, 7],
      'y2': [4, 6, 7, 9]}
df = pd.DataFrame(df)

fig, ax = plt.subplots()

df.plot.scatter('x1', 'y1', c='green', ax=ax)
for i, txt in enumerate(df.id):
    ax.annotate(txt, (df.x1.iat[i], df.y1.iat[i]))

ax.scatter(df['x2'], df['y2'], c='red')
for i, txt in enumerate(df.id):
    ax.annotate(txt, (df.x2.iat[i], df.y2.iat[i]))

plt.show()

Legend

And finally, to answer your question about labelling the colours. You can assign a label to each scatterplot instance, eg:

df.plot.scatter('x1', 'y1', c='green', ax=ax, label='leaf')
ax.scatter(df['x2'], df['y2'], c='red', label='fruit')

and the produce a legend on the given Axes with:

ax.legend()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM