Excel to PDF export using python: Getting split graphs - python

While converting from EXCEL (which contains Text and graphs) to PDF, I am getting the following in PDF report(one graph broke in two different pages).
Actual:
Expected:
'''code'''
def make_plot(self,chart_data):
#see report function: add_chart(report,chart_data) that built chart_data
try:
subplot(111)
subplots_adjust(bottom=0.3)
file = tempfile.mktemp(suffix=".png")
clf() #clear plot data
title(chart_data[1][0])
xlabel(chart_data[1][1])
ylabel(chart_data[1][2])
x=chart_data[2]
xcount=len(chart_data[2])
ycount=xcount-3
y = list()
iter=0
for ydata in chart_data:
if iter>=3: #y data starts on 3 array
y=ydata[2]
plot(x,y,color=chart_data[iter][1], label=chart_data[iter][0])
## y[:] = []
iter=iter+1
legend(loc=(-0.15,-0.35))
savefig(file, bbox_inches="tight", facecolor='w', dpi=120)
self.insert_image(file) #insert image from file into Excel
except:
ErrStr = "Error: make_plot(self,chart_data), " + chart_data[1][0]
print ErrStr
self.insert_comment(["COMMENT",ErrStr])
print sys.exc_info()
self.pass_status = 0
finally:
if(os.path.exists(file)):
os.remove(file)
def add_chart(report,chart_data):
#report created by ReportSetupTest("name",list) dict [TestName][pf]
#add_chart(report,[["Title","X Axis","Y Axis"], [x1,x2,xn],["ledged 1","color 1",[y1,y2,yn]],#["ledged 2","color 2",[2y1,2y2,2yn]],["ledged n","color n",[ny1,ny2,nyn]]])
chartlist =list()
chartlist=["CHART"]
for dat in chart_data:
chartlist.append(dat)
report[len(report) - 1]['pf'].append(chartlist)
How to make actual like Expected? Is it because of code or pdf problem? The images're displayed properly in EXCEL but the problem only gets in PDF. Can someone suggest me what to do?

Related

Save files of a modeling program in different files .txt

hello I am New to Python, I have worked with a library design by a professor in my university
I need help to save the results in different files .txt and in different folders
The model consists of a mesh of 2500 cells with coordinates x, y, z. I want in every step of the iteration to get a file .txt that has cell index, the coordinates of each cell, and the different attributes of this cell, I wrote the code below but I obtained the last cell index and the position 0.0.0... in only one file txt, and I don't know how to save it in a folder...
if os.path.exists('Model'):
import shutil
shutil.rmtree('Model')
os.mkdir('Model')
def save_m1(path, fluid_index):
assert isinstance(path, str)
with open(path, 'w') as file:
for cell in model.cells:
x, y, z = cell.pos
file.write(f'{cell.pos} {model.cell_number} {cell.get_fluid(fluid_index).mass}\n')
if step % 100 == 0:
model.print_cells("Model" % step)
dt = 10.0
for step in range(10):
model.iterate(dt=dt)
thermal.iterate(dt=dt)
thermal.exchange_heat(model, dt=dt, fid=0, na_g = na_g, fa_T = ID_T, fa_c = ID_K)
thermal.exchange_heat(model, dt=dt, fid=1, na_g = na_g, fa_T = ID_T, fa_c = ID_K)
thermal.exchange_heat(model, dt=dt, fid=2, na_g = na_g, fa_T = ID_T, fa_c = ID_K)
print(f'step = {step}, m1_produced = {get_mass1_produced(1) - InitialMass1}') # kg
save_m1('xxx.txt', 1)

For-loop over multiple files in same directory in Python

So I already tried to check other questions here about (almost) the same topic, however I did not find something that solves my problem.
Basically, I have a piece of code in Python that tries to open the file as a data frame and execute some eye tracking functions (PyGaze). I have 1000 files that I need to analyse and wanted to create a for-loop to execute my code on all the files automatically.
The code is the following:
os.chdir("/Users/Documents//Analyse/Eye movements/Python - Eye Analyse")
directory = '/Users/Documents/Analyse/Eye movements/R - Filtering Data/Filtered_data/Filtered_data_test'
for files in glob.glob(os.path.join(directory,"*.csv")):
#Downloas csv, plot
df = pd.read_csv(files, parse_dates = True)
#Plot raw data
plt.plot(df['eye_x'],df['eye_y'], 'ro', c="red")
plt.ylim([0,1080])
plt.xlim([0,1920])
#Fixation analysis
from detectors import fixation_detection
fixations_data = fixation_detection(df['eye_x'],df['eye_y'], df['time'],maxdist=25, mindur=100)
Efix_data = fixations_data[1]
numb_fixations = len(Efix_data) #number of fixations
fixation_start = [i[0] for i in Efix_data]
fixation_stop = [i[1] for i in Efix_data]
fixation = {'start' : fixation_start, 'stop': fixation_stop}
fixation_frame = pd.DataFrame(data=fixation)
fixation_frame['difference'] = fixation_frame['stop'] - fixation_frame['start']
mean_fixation_time = fixation_frame['difference'].mean() #mean fixation time
final = {'number_fixations' : [numb_fixations], 'mean_fixation_time': [mean_fixation_time]}
final_frame = pd.DataFrame(data=final)
#write everything in one document
final_frame.to_csv("/Users/Documents/Analyse/Eye movements/final_data.csv")
The code is running (no errors), however : it only runs for the first file. The code is not ran for the other files present in the folder/directory.
I do not see where my mistake is?
Your output file name is constant, so it gets overwritten with each iteration of the for loop. Try the following instead of your final line, which opens the file in "append" mode instead:
#write everything in one document
with open("/Users/Documents/Analyse/Eye movements/final_data.csv", "a") as f:
final_frame.to_csv(f, header=False)

How to plot binary data in python?

First of all I know my question is frequently asked. But I have not found a solution in them.
I work with USBTMC to control oscilloscope. Here you can find more information about it. I am able to capture screen and write it into a file (see picture). But I want to plot screen every n secs in real time. I would like to use matplotlib.pyplot, for example.
Here is my code (with a desperate attempt to plot data with pyplot):
import usbtmc
from time import sleep
import matplotlib.pyplot as plot
import numpy as np
import subprocess
maxTries = 3
scope = usbtmc.Instrument(0x0699, 0x03a6)
print scope.ask("*IDN?")
scope.write("ACQ:STOPA SEQ")
scope.write("ACQ:STATE ON")
while ( True ):
#get trigger state
trigState = scope.ask("TRIG:STATE?")
#check if Acq complete
if ( trigState.endswith('SAVE') ):
print 'Acquisition complete. Writing into file ...'
#save screen
scope.write("SAVE:IMAG:FILEF PNG")
scope.write("HARDCOPY START")
#HERE I get binary data
screenData = scope.read_raw()
#HERE I try to convert it?
strData = np.fromstring( screenData, dtype=np.uint8 )
#HERE I try to plot previous
plot.plot( strData )
plot.show()
#rewrite in file (this works fine)
try:
outFile = open("screen.png", "wb")
outFile.write( screenData )
except IOError:
print 'Error: cannot write to file'
else:
print 'Data was written successfully in file: ', outFile.name
finally:
outFile.close()
#continue doing something
After run this code I get ... look at the picture.
Unfortunately I cannot test it, but you may try something like this
import io
screenData = scope.read_raw()
arrayData = plt.imread(io.BytesIO(screenData))
plt.imshow(arrayData)
plt.show()
I would like to note that for live plotting, it is probably better not to obtain the image from the scope's screen but the raw data. This should allow for much faster operation.

"if" statement Looping through twice when using data driven pages

I have a script which is designed to place inset maps onto specific pages while exporting Data Driven Pages, the script is amalgamation of a friend's work and some of my own code from other projects.
The issue is the code exports pages 15 and 16 twice one with my inset maps and the other without and I can't figure out why.
I think it is something to do with the indentation within the Loop but I cant get it so it behaves in any other way. Any help would be appreciated!
import arcpy, os, time, datetime
from datetime import datetime
start_time = datetime.now()
PageNumber = "Page "
# Create an output directory variable i.e the location of your maps folder
outDir = r"C:\Users\support\Desktop\Python\Book of Reference"
# Create a new, empty pdf document in the specified output directory
# This will be your final product
finalpdf_filename = outDir + r"\FinalMapBook.pdf"
if os.path.exists(finalpdf_filename): # Check to see if file already exists, delete if it does
os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)
# Create a Data Driven Pages object from the mxd you wish to export
mxdPath = r"C:\Users\support\Desktop\Python\Book Of Reference\Book_Of_Reference_20160526_Python_Test.mxd"
tempMap = arcpy.mapping.MapDocument(mxdPath)
tempDDP = tempMap.dataDrivenPages
# Create objects for the layout elements that will be moving, e.g., inset data frame, scale text
Page15 = arcpy.mapping.ListDataFrames(tempMap)[1]
Page16 = arcpy.mapping.ListDataFrames(tempMap)[2]
# Instead of exporting all pages at once, you will need to use a loop to export one at a time
# This allows you to check each index and execute code to add inset maps to the correct pages
for pgIndex in range(1, tempDDP.pageCount + 1, 1):
# Create a name for the pdf file you will create for each page
temp_filename = r"C:\Users\support\Desktop\Python\Book of Reference\Book of Reference" + \
str(pgIndex) + ".pdf"
if os.path.exists(temp_filename):
os.remove(temp_filename) #Removes pdf if it is already in the folder
# Code for setting up the inset map on the first page #
if (pgIndex == 15):
# Set position of inset map to place it on the page layout
Page15.elementPositionX = 20.1717
Page15.elementPositionY = 2.0382
# Set the desired size of the inset map for this page
Page15.elementHeight = 9.7337
Page15.elementWidth = 12.7115
# Set the desired extent for the inset map
Page15insetExtent = arcpy.Extent(518878,108329,519831,107599)
Page15insetExtent = Page15insetExtent
arcpy.RefreshActiveView()
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
Page15.elementPositionX = 50 #Move the Inset back off the page
arcpy.RefreshActiveView() #Refresh to ensure the Inset has been removed
print PageNumber + str(pgIndex)
if (pgIndex == 16):
# Set up inset map
Page16.elementPositionX = 2.1013
Page16.elementPositionY = 18.1914
Page16.elementHeight = 9.7337
Page16.elementWidth = 12.7115
Page16insetExtent = arcpy.Extent(520012, 107962, 521156,107086)
Page16insetExtent = Page16insetExtent
arcpy.RefreshActiveView()
print PageNumber + str(pgIndex)
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
print PageNumber + str(pgIndex)
Page16.elementPositionX = 50
arcpy.RefreshActiveView()
# Else Fuction takes care of the pages that dont have insets and just itterates through using the loop on line 28
else :
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
print PageNumber + str(pgIndex)
# Clean up
del tempMap
# Update the properties of the final pdf
finalPdf.updateDocProperties(pdf_open_view="USE_THUMBS",
pdf_layout="SINGLE_PAGE")
# Save your result
finalPdf.saveAndClose()
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))
I believe your problem is that when the pgIndex is 15 it performs the export as intended. Then it checks if the pgIndex is 16. The pgIndex is not 16 so it drops into the else and re-exports without the inset maps. I would recommend changing the second if to an elif

Why doesn't this code save my figures with titles?

I'm producing some figures with the following code:
def boxplot_data(self,parameters_file,figure_title):
data = pandas.read_csv(parameters_file)
header = data.keys()
number_of_full_subplots = len(header)/16
remainder = len(header)-(16*number_of_full_subplots)
try:
for i in range(number_of_full_subplots+1):
fig =plt.figure(i)
txt = fig.suptitle(figure_title+' (n='+str(len(data[header[0]]))+') '+'Page '+str(i)+' of '+str(number_of_full_subplots),fontsize='20')
txt.set_text(figure_title+' (n='+str(len(data[header[0]]))+') '+'Page '+str(i)+' of '+str(number_of_full_subplots))
for j in range(16):
plt.ioff()
plt.subplot(4,4,j)
plt.boxplot(data[header[16*i+j]])
plt.xlabel('')
mng=plt.get_current_fig_manager()
mng.window.showMaximized()
plt.savefig(str(i)+'.png',bbox_inches='tight',orientation='landscape')
plt.close(fig)
plt.ion()
except IndexError:
txt = fig.suptitle(figure_title+' (n='+str(len(data[header[0]]))+') '+'Page '+str(i)+' of '+str(number_of_full_subplots),fontsize='20')
txt.set_text(figure_title+' (n='+str(len(data[header[0]]))+') '+'Page '+str(i)+' of '+str(number_of_full_subplots))
print '{} full figures were created and 1 partially filled \
figure containing {} subplots'.format(number_of_full_subplots,remainder)
This produces and saves the figures to file in the properly formatted manner however, no matter what I do the code seems to bypass the fig.suptitle line(s) and consequently I can't give my figure a title. Apologies if it seems there is a lot going on in this function that I haven't explained but does anybody have an explanation as to why this code refuses to give my figures titles?
Your problem is not that suptitle is bypassed, but that you are never saving the figure that you call suptitle on. All your calls to savefig are within the inner loop and as such are saving only the subplots. You can actually watch this happening if you open the png file while your code is running - you see each of the 16 sub axes being added one by one.
Your code looks unnecessarily complicated. For instance, I don't think you need to use ion and ioff. Here is a simple example of how to do what I think you want, followed by a translation of your code to fit that (Obviously i can't test, because I don't have your data)
import matplotlib.pyplot as plt
test_y=range(10)
test_x=[8,13,59,8,81,2,5,6,2,3]
def subplotsave_test():
for i in range(5):
fig = plt.figure(i)
txt = fig.suptitle('Page '+str(i)+' of '+str(5),fontsize='20')
for j in range(16):
plt.subplot(4,4,j+1)
plt.plot(test_y,test_x)
plt.savefig(str(i)+'.png',bbox_inches='tight',orientation='landscape')
if __name__ == '__main__':
subplotsave_test()
One tip I have found works for me - do a plt.show() wherever you intend to save the figure and ensure it looks like you want beforehanad and then replace that call with plt.savefig()
Possible translation of your function
def boxplot_data(self,parameters_file,figure_title):
data = pandas.read_csv(parameters_file)
header = data.keys()
number_of_full_subplots = len(header)/16
remainder = len(header)-(16*number_of_full_subplots)
for i in range(number_of_full_subplots+1)
fig =plt.figure(i)
fig.suptitle(figure_title+' (n='+str(len(data[header[0]]))+') '+'Page '+str(i)+' of '+str(number_of_full_subplots),fontsize='20')
for j in range(16):
plt.subplot(4,4,j+1)
if 16*i + j < len(header):
plt.boxplot(data[header[16*i+j]])
plt.xlabel('')
#You might want the showMaximized() call here - does nothing
#on my machine but YMMV
else:
print '{} full figures were created and 1 partially filled \
figure containing {} subplots'.format(number_of_full_subplots,remainder)
break
plt.savefig(str(i)+'.png',bbox_inches='tight',orientation='landscape')
plt.close(fig)

Categories