Home > Software engineering >  three/multiple subplots per page in loop using python
three/multiple subplots per page in loop using python

Time:01-22

I want to keep three plots(1 col, 3rows) in each page of the pdf. This code is generating 12 plots in 12 pages, it's also creating 12 pngs. I don't know how to use the subplots in loop so that per page contains 3 plots and there will be a total 4 pages. Combinig three consecutive pngs into one png will also work. Thanks.

"""
import re
import os
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

#plt.style.use('ggplot')
plt.style.use('default')



obs = pd.read_excel(r'T:/Active Projects/US Army Corps of Engineers/St Louis District/LD25/Model/Model_Testing/Excel/LD25 Model testing Velocity_210119.xlsm','base')

sim1=pd.read_excel(r'T:/Active Projects/US Army Corps of Engineers/St Louis District/LD25/Model/Model_Testing/Excel/LD25 Model testing Velocity_210119.xlsm', 'itl')

p='T:/Active Projects/US Army Corps of Engineers/St Louis District/LD25/Model/Model_Testing/plot/raw data/' #p=path loc
pdf = PdfPages(p 'LDbase_211229_LDitl_211229_vel1.pdf')  # set pdf name
folder='LDbase_211229_LDitl_211229_vel1/' # set folder name for png files,pdf and folder name are same 


path=p folder
isExist = os.path.exists(path)
if not isExist:
    os.makedirs(path, exist_ok=False)
    
x=[0,1,2,3,4,5,6,7,8,9,10,11]
y=[0,1,2,0,1,2,0,1,2,0,1,2]


for i,j in zip(x,y): # no of rows of obs is 24 or obs.shape[1]=24, so range(0,obs.shape[1]-1)
     title=[' Existing Pool Lock Approach: 2265 cms', ' Existing Pool Lock Approach: 3511 cms',' Existing Pool Lock Approach: 8920 cms',
            ' Existing TW Lock Approach: 2265 cms',' Existing TW Lock Approach: 3511 cms',' Existing TW Lock Approach 8920: cms',
            ' Proposed Pool Lock Approach: 2265 cms', ' Proposed Pool Lock Approach: 3511 cms',' Proposed Pool Lock Approach: 8920 cms',
            ' Proposed TW Lock Approach: 2265 cms', ' Proposed TW Lock Approach: 3511 cms',' Proposed TW Lock Approach: 8920 cms']
     b=[re.sub(r':', '', i) for i in title] # replace colon coz filename can't be saved with :
     #plt.rcParams.update({'font.size': 10})  
     fig, ax = plt.subplots(3,figsize=(7,3))
    
     a= 3.28084 # m to ft converter
    
     
     ax[j].plot(obs.iloc[:,2*i]*a,obs.iloc[:,2*i 1]*a,linestyle='-',ms='6',mfc='none') # base model
     ax[j].plot(sim1.iloc[:,2*i]*a,sim1.iloc[:,2*i 1]*a,linestyle='--',ms='6',mfc='none') # sim1 
     
     plt.grid(which='major',  linestyle='-',linewidth=0.3)
     plt.grid(which='minor',  linestyle='--',linewidth=0.2)
     #plt.minorticks_on()
     
     plt.xlabel("Distance (ft)")
     plt.ylabel(" Velocity (ft/s)")
     ax[j].legend(['Base','ITL'],prop={"size":10})
     ax[j].set_title(title[i])
   

   
     plt.savefig(path '\{}.png'.format(str(b[i])),bbox_inches='tight',dpi=300)
     pdf.savefig(fig)     

       
pdf.close() 

but it give the attached plot: https://drive.google.com/file/d/19uBwC2b9CfiC68zQnhSoOebFrta68iln/view?usp=sharing

here is the excel file used as input: https://docs.google.com/spreadsheets/d/18wIyrnW0M4CfjyyZIUmnkT2OQ-hOsR0R/edit?usp=sharing&ouid=102781316443126205856&rtpof=true&sd=true

CodePudding user response:

You are looping through x, that has 12 items, and creating a new figure each time, so you get 12 of everything. A possible solution is:

# --- snipped first part: it's the same as OP's ---

# these constructs are unnecessary
# x=[0,1,2,3,4,5,6,7,8,9,10,11]
# y=[0,1,2,0,1,2,0,1,2,0,1,2]

title=[' Existing Pool Lock Approach: 2265 cms', ' Existing Pool Lock Approach: 3511 cms',' Existing Pool Lock Approach: 8920 cms',
       ' Existing TW Lock Approach: 2265 cms',' Existing TW Lock Approach: 3511 cms',' Existing TW Lock Approach 8920: cms',
       ' Proposed Pool Lock Approach: 2265 cms', ' Proposed Pool Lock Approach: 3511 cms',' Proposed Pool Lock Approach: 8920 cms',
       ' Proposed TW Lock Approach: 2265 cms', ' Proposed TW Lock Approach: 3511 cms',' Proposed TW Lock Approach: 8920 cms']
b = [re.sub(r':', '', i) for i in title]
a = 3.28084 # m to ft converter
# for i,j in zip(x,y):  # BAD
for page in range(4):
    fig, ax = plt.subplots(3, figsize=(7,3)) # One figure per page
    for j in range(3):
         i = page * 3   j 
         ax[j].plot(obs.iloc[:,2*i]*a,obs.iloc[:,2*i 1]*a,linestyle='-',ms='6',mfc='none') # base model
         ax[j].plot(sim1.iloc[:,2*i]*a,sim1.iloc[:,2*i 1]*a,linestyle='--',ms='6',mfc='none') # sim1 
         plt.grid(which='major',  linestyle='-',linewidth=0.3)
         plt.grid(which='minor',  linestyle='--',linewidth=0.2)
         plt.xlabel("Distance (ft)")
         plt.ylabel(" Velocity (ft/s)")
         ax[j].legend(['Base','ITL'],prop={"size":10})
         ax[j].set_title(title[i])
    plt.savefig(path '\{}.png'.format(str(b[i])),bbox_inches='tight',dpi=300)
    pdf.savefig(fig)
       
pdf.close() 

It can be done more general, but it's not the point of the question.

  •  Tags:  
  • Related