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

vcx34178
  • 961
  • 1
  • 8
  • 15
  • 2
    There's a funky couple lines at the bottom; is an `if` missing? – andyg0808 Nov 25 '17 at 02: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 https://stackoverflow.com/questions/101268/hidden-features-of-python#114420 – vcx34178 Nov 25 '17 at 11:54

1 Answers1

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

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712