1

I am trying to plot inside a for loop. I have point data pts dictionary storing point id and coordinates of points. Dictionary rect stores id of rectangle and what point it connects. Then I am trying to plot the rectangle using patches.Rectangle and put id of the rectangle at its center using text command. At the end of the loop, I am plotting the figure. But nothing gets plotted. I don't understand what is going wrong here. Any suggestions?

Also, can we use plt.axis([xmin, xmax, ymin, ymax]) instead of fig.add_axes([0,0,30,30])?

import matplotlib.pyplot as plt
import matplotlib.patches as patches

plt.close('all')
pts={}
#defining points
pts.update({1:(0,0)})
pts.update({2:(10,0)})
pts.update({3:(10,20)})
pts.update({4:(0,20)})
pts.update({5:(30,0)})
pts.update({6:(30,20)})

#defining rectangle connecting to points
rect={}
rect.update({10:(1,2,3,4)})
rect.update({11:(2,5,6,3)})

#plotting
fig = plt.figure()
ax = fig.add_axes([0,0,30,30])
for i in rect:
    p2=rect[i]
    dx,dy = pts[p2[0]]
    wd = pts[p2[1]][0] - pts[p2[0]][0]
    ht = pts[p2[3]][1] - pts[p2[0]][1]
    midpt = [ (pts[p2[0]][0] + pts[p2[2]][0])/2, (pts[p2[0]][1] + pts[p2[2]][1])/2 ]
    #finding midpoint of points zeroth and second 
    #x_mid= (x_0+x_2)/2 and similar for y_mid
    p = patches.Rectangle((dx,dy), wd,ht,fill=False, clip_on=False)
    ax.add_patch(p)

    plt.text(midpt[0],midpt[1],i,color='k')
else:
    plt.show()  

Update:

I am using else clause with for loop, which is allowed. The purpose is to plot after for loop execution is finished. For more information, Hidden features of Python

2
  • 2
    There's a funky couple lines at the bottom; is an if missing? Commented Nov 25, 2017 at 2:19
  • @andyg0808 : If you are talking about if else, it is not the case. Many people don't know for loop has optional else clause. I chose this way because plt.show() will execute after loop finished. Please take a look at stackoverflow.com/questions/101268/… Commented Nov 25, 2017 at 11:54

1 Answer 1

1

The problem lies in the lines

fig = plt.figure()
ax = fig.add_axes([0,0,30,30])

This will create an axes which is 30 times larger than the figure in each dimension. Hence you only see 1./(30*30) = 1 per mille of the axes.

What you would probably like to do is add a normal subplot and set its data range to 0..30 in both directions.

fig, ax = plt.subplots()
ax.axis([0,30,0,30])

Complete example:

import matplotlib.pyplot as plt
import matplotlib.patches as patches

plt.close('all')
pts={}
#defining points
pts.update({1:(0,0)})
pts.update({2:(10,0)})
pts.update({3:(10,20)})
pts.update({4:(0,20)})
pts.update({5:(30,0)})
pts.update({6:(30,20)})

#defining rectangle connecting to points
rect={}
rect.update({10:(1,2,3,4)})
rect.update({11:(2,5,6,3)})

#plotting
fig, ax = plt.subplots()
ax.axis([0,30,0,30])
for i in rect:
    p2=rect[i]
    dx,dy = pts[p2[0]]
    wd = pts[p2[1]][0] - pts[p2[0]][0]
    ht = pts[p2[3]][1] - pts[p2[0]][1]
    midpt = [ (pts[p2[0]][0] + pts[p2[2]][0])/2, (pts[p2[0]][1] + pts[p2[2]][1])/2 ]
    #finding midpoint of points zeroth and second 
    #x_mid= (x_0+x_2)/2 and similar for y_mid
    p = patches.Rectangle((dx,dy), wd,ht,fill=False, clip_on=False)
    ax.add_patch(p)

    plt.text(midpt[0],midpt[1],i,color='k')
else:
    plt.show()

enter image description here

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.