0

I am trying to plot the lines that connect starting (x,y) and ending (x,y) That means a line will be connecting (x1start,y1start) to (x1end,y1end) I have multiple rows in data frame. The sample data frame that replicate the actual dataframe and shown below:

df = pd.DataFrame()
df ['Xstart'] = [1,2,3,4,5]
df ['Xend'] = [6,8,9,10,12]
df ['Ystart'] = [0,1,2,3,4]
df ['Yend'] = [6,8,9,10,12]

According to that, if we look at the first row of df, a line will be connecting (1,0) to (6,6) For that I am using for loop to draw a line for each row as follow:

  fig,ax = plt.subplots()
fig.set_size_inches(7,5)

for i in range (len(df)):
    ax.plot((df.iloc[i]['Xstart'],df.iloc[i]['Xend']),(df.iloc[i]['Ystart'],df.iloc[i]['Yend']))
    ax.annotate("",xy = (df.iloc[i]['Xstart'],df.iloc[i]['Xend']),
    xycoords = 'data',
    xytext = (df.iloc[i]['Ystart'],df.iloc[i]['Yend']),
    textcoords = 'data',
    arrowprops = dict(arrowstyle = "->", connectionstyle = 'arc3', color = 'blue'))

plt.show()

I have the following error message when I run this.

I got the figure as shown below:

enter image description here

The arrow and line are in as expected. the arrow should be on the end point of each line.

Can anyone advise what is going on here?

Thanks,

Zep

Zephyr
  • 1,332
  • 2
  • 13
  • 31

3 Answers3

1

You're mixing up the positions of the arrows. Each coordinate pair in xy and xytext consists of an x and y value.

Also in order to see the arrows in the plot you need to set the limits of the plot manually, because annotations are - for good reason - not taken into account when scaling the data limits.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame()
df ['Xstart'] = [1,2,3,4,5]
df ['Xend'] = [6,8,9,10,12]
df ['Ystart'] = [0,1,2,3,4]
df ['Yend'] = [6,8,9,10,12]


fig,ax = plt.subplots()
fig.set_size_inches(7,5)

for i in range (len(df)):
    ax.annotate("",xy = (df.iloc[i]['Xend'],df.iloc[i]['Yend']),
                xycoords = 'data',
                xytext = (df.iloc[i]['Xstart'],df.iloc[i]['Ystart']),
                textcoords = 'data',
                arrowprops = dict(arrowstyle = "->", 
                                  connectionstyle = 'arc3', color = 'blue'))

ax.set(xlim=(df[["Xstart","Xend"]].values.min(), df[["Xstart","Xend"]].values.max()),
       ylim=(df[["Ystart","Yend"]].values.min(), df[["Ystart","Yend"]].values.max()))
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
1

If you want to plot the line segments, the following code works. You may want arrows or some sort of annotate element (notice correct spelling), but your goal seems to be plotting the line segments, which this accomplishes:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame()
df ['Xstart'] = [1,2,3,4,5]
df ['Xend'] = [6,8,9,10,12]
df ['Ystart'] = [0,1,2,3,4]
df ['Yend'] = [6,8,9,10,12]

fig = plt.figure()
ax = fig.add_subplot(111)
for i in range (len(df)):
    ax.plot(
        (df.iloc[i]['Xstart'],df.iloc[i]['Xend']),
        (df.iloc[i]['Ystart'],df.iloc[i]['Yend'])
    )
plt.show()
pjw
  • 2,133
  • 3
  • 27
  • 44
0

Not 100% certain but I think in line two you need to make the part after xy= a tuple because otherwise it sets the part in front of the , as keyword parameter and tries passing the part after the , as normal arg

SV-97
  • 431
  • 3
  • 15
  • Thanks for the reply. I solved the turple, But when I plot it i just got blank figure. I have updated in the question. – Zephyr Nov 18 '18 at 15:19