Skip to content

Commit bda9a20

Browse files
committed
Added PDF fileoutput for fitting results
1 parent ddb6db4 commit bda9a20

File tree

3 files changed

+281
-58
lines changed

3 files changed

+281
-58
lines changed

FittingResultsViewer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
f = open("pickledEquationFile", "rb")
1010
unPickledEquation = pickle.load(f)
1111
f.close()
12-
os.remove("pickledEquationFile")
1312
resultsFrame = CustomDialogs.ResultsFrame(None, '', "Fitting Results (resizable dialog)", equation=unPickledEquation)
1413
resultsFrame.Show()
1514
app.MainLoop()

guifiles/CustomDialogs.py

Lines changed: 135 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -498,94 +498,141 @@ def __init__(self, parent, inText):
498498

499499
# see the included wxNestedTabsExample.py file
500500
class TopLevelResultsNotebook(wx.Notebook):
501-
def __init__(self, parent, equation):
501+
def __init__(self, parent, inEquation):
502502
wx.Notebook.__init__(self, parent, id=wx.ID_ANY, style=wx.BK_DEFAULT)
503+
self.equation = inEquation
503504

505+
self.graphReportsListForPDF = []
506+
self.textReportsListForPDF = []
507+
self.sourceCodeReportsListForPDF = []
508+
504509
# graphs
505510
graphReportsTab = wx.Notebook(self)
506511
self.AddPage(graphReportsTab, "Graph Reports")
507512

508-
if equation.GetDimensionality() == 2:
509-
modelConfidenceScatter = Report_ModelScatterConfidenceGraph(graphReportsTab)
510-
modelConfidenceScatter.draw(equation)
511-
graphReportsTab.AddPage(modelConfidenceScatter, "Model With 95%Confidence")
513+
if self.equation.GetDimensionality() == 2:
514+
report = Report_ModelScatterConfidenceGraph(graphReportsTab)
515+
report.draw(self.equation)
516+
reportName = "Model With 95%Confidence"
517+
graphReportsTab.AddPage(report, reportName)
518+
self.graphReportsListForPDF.append([report.figure, reportName])
512519
else:
513-
surfacePlot = Report_SurfacePlot(graphReportsTab)
514-
surfacePlot.draw(equation)
515-
graphReportsTab.AddPage(surfacePlot, "Surface Plot")
520+
report = Report_SurfacePlot(graphReportsTab)
521+
report.draw(self.equation)
522+
reportName = "Surface Plot"
523+
graphReportsTab.AddPage(report, reportName)
524+
self.graphReportsListForPDF.append([report.figure, reportName])
516525

517-
contourPlot = Report_ContourPlot(graphReportsTab)
518-
contourPlot.draw(equation)
519-
graphReportsTab.AddPage(contourPlot, "Contour Plot")
520-
521-
absoluteErrorGraph = Report_AbsoluteErrorGraph(graphReportsTab)
522-
absoluteErrorGraph.draw(equation)
523-
graphReportsTab.AddPage(absoluteErrorGraph, "Absolute Error")
524-
525-
absoluteErrorHistogram = Report_AbsoluteErrorHistogram(graphReportsTab)
526-
absoluteErrorHistogram.draw(equation)
527-
graphReportsTab.AddPage(absoluteErrorHistogram, "Absolute Error Histogram")
528-
529-
if equation.dataCache.DependentDataContainsZeroFlag != 1:
530-
percentErrorGraph = Report_PercentErrorGraph(graphReportsTab)
531-
percentErrorGraph.draw(equation)
532-
graphReportsTab.AddPage(percentErrorGraph, "Percent Error")
526+
report = Report_ContourPlot(graphReportsTab)
527+
report.draw(self.equation)
528+
reportName = "Contour Plot"
529+
graphReportsTab.AddPage(report, reportName)
530+
self.graphReportsListForPDF.append([report.figure, reportName])
531+
532+
report = Report_AbsoluteErrorGraph(graphReportsTab)
533+
report.draw(self.equation)
534+
reportName = "Absolute Error"
535+
graphReportsTab.AddPage(report, reportName)
536+
self.graphReportsListForPDF.append([report.figure, reportName])
537+
538+
report = Report_AbsoluteErrorHistogram(graphReportsTab)
539+
report.draw(self.equation)
540+
reportName = "Absolute Error Histogram"
541+
graphReportsTab.AddPage(report, reportName)
542+
self.graphReportsListForPDF.append([report.figure, reportName])
543+
544+
if self.equation.dataCache.DependentDataContainsZeroFlag != 1:
545+
report = Report_PercentErrorGraph(graphReportsTab)
546+
report.draw(self.equation)
547+
reportName = "Percent Error"
548+
graphReportsTab.AddPage(report, reportName)
549+
self.graphReportsListForPDF.append([report.figure, reportName])
533550

534-
percentErrorHistogram = Report_PercentErrorHistogram(graphReportsTab)
535-
percentErrorHistogram.draw(equation)
536-
graphReportsTab.AddPage(percentErrorHistogram, "Percent Error Histogram")
551+
report = Report_PercentErrorHistogram(graphReportsTab)
552+
report.draw(self.equation)
553+
reportName = "Percent Error Histogram"
554+
graphReportsTab.AddPage(report, reportName)
555+
self.graphReportsListForPDF.append([report.figure, reportName])
537556

538557
textReportsTab = wx.Notebook(self)
539558
self.AddPage(textReportsTab, "Text Reports")
540559

541-
textReport1 = CoefficientAndFitStatisticsReport(textReportsTab, equation)
542-
textReportsTab.AddPage(textReport1, "Coefficient And Fit Statistics")
560+
report = CoefficientAndFitStatisticsReport(textReportsTab, self.equation)
561+
reportName = "Coefficient And Fit Statistics"
562+
textReportsTab.AddPage(report, reportName)
563+
self.textReportsListForPDF.append([str(report.text.GetValue()), reportName])
543564

544-
textReport2 = CoefficientsReport(textReportsTab, equation)
545-
textReportsTab.AddPage(textReport2, "Coefficient Listing")
565+
report = CoefficientsReport(textReportsTab, self.equation)
566+
reportName = "Coefficient Listing"
567+
textReportsTab.AddPage(report, reportName)
568+
self.textReportsListForPDF.append([str(report.text.GetValue()), reportName])
546569

547-
textReport3 = DataArrayStatisticsReport(textReportsTab, 'Absolute Error Statistics', equation.modelAbsoluteError)
548-
textReportsTab.AddPage(textReport3, "Absolute Error Statistics")
570+
report = DataArrayStatisticsReport(textReportsTab, 'Absolute Error Statistics', self.equation.modelAbsoluteError)
571+
reportName = "Absolute Error Statistics"
572+
textReportsTab.AddPage(report, reportName)
573+
self.textReportsListForPDF.append([str(report.text.GetValue()), reportName])
549574

550-
if equation.dataCache.DependentDataContainsZeroFlag != 1:
551-
textReport4 = DataArrayStatisticsReport(textReportsTab, 'Percent Error Statistics', equation.modelPercentError)
552-
textReportsTab.AddPage(textReport4, "Percent Error Statistics")
575+
if self.equation.dataCache.DependentDataContainsZeroFlag != 1:
576+
report = DataArrayStatisticsReport(textReportsTab, 'Percent Error Statistics', self.equation.modelPercentError)
577+
reportName = "Percent Error Statistics"
578+
textReportsTab.AddPage(report, reportName)
579+
self.textReportsListForPDF.append([str(report.text.GetValue()), reportName])
553580

554581
sourceCodeTab = wx.Notebook(self)
555582
self.AddPage(sourceCodeTab, "Source Code")
556583

557-
sourcecode1 = SourceCodeReport(sourceCodeTab, equation, 'CPP')
558-
sourceCodeTab.AddPage(sourcecode1, "C++")
584+
report = SourceCodeReport(sourceCodeTab, self.equation, 'CPP')
585+
reportName = "C++"
586+
sourceCodeTab.AddPage(report, reportName)
587+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
559588

560-
sourcecode2 = SourceCodeReport(sourceCodeTab, equation, 'CSHARP')
561-
sourceCodeTab.AddPage(sourcecode2, "CSHARP")
589+
report = SourceCodeReport(sourceCodeTab, self.equation, 'CSHARP')
590+
reportName = "CSHARP"
591+
sourceCodeTab.AddPage(report, reportName)
592+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
562593

563-
sourcecode3 = SourceCodeReport(sourceCodeTab, equation, 'VBA')
564-
sourceCodeTab.AddPage(sourcecode3, "VBA")
594+
report = SourceCodeReport(sourceCodeTab, self.equation, 'VBA')
595+
reportName = "VBA"
596+
sourceCodeTab.AddPage(report, reportName)
597+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
565598

566-
sourcecode4 = SourceCodeReport(sourceCodeTab, equation, 'PYTHON')
567-
sourceCodeTab.AddPage(sourcecode4, "PYTHON")
599+
report = SourceCodeReport(sourceCodeTab, self.equation, 'PYTHON')
600+
reportName = "PYTHON"
601+
sourceCodeTab.AddPage(report, reportName)
602+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
568603

569-
sourcecode5 = SourceCodeReport(sourceCodeTab, equation, 'JAVA')
570-
sourceCodeTab.AddPage(sourcecode5, "JAVA")
604+
report = SourceCodeReport(sourceCodeTab, self.equation, 'JAVA')
605+
reportName = "JAVA"
606+
sourceCodeTab.AddPage(report, reportName)
607+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
571608

572-
sourcecode6 = SourceCodeReport(sourceCodeTab, equation, 'JAVASCRIPT')
573-
sourceCodeTab.AddPage(sourcecode6, "JAVASCRIPT")
609+
report = SourceCodeReport(sourceCodeTab, self.equation, 'JAVASCRIPT')
610+
reportName = "JAVASCRIPT"
611+
sourceCodeTab.AddPage(report, reportName)
612+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
574613

575-
sourcecode7 = SourceCodeReport(sourceCodeTab, equation, 'JULIA')
576-
sourceCodeTab.AddPage(sourcecode7, "JULIA")
614+
report = SourceCodeReport(sourceCodeTab, self.equation, 'JULIA')
615+
reportName = "JULIA"
616+
sourceCodeTab.AddPage(report, reportName)
617+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
577618

578-
sourcecode8 = SourceCodeReport(sourceCodeTab, equation, 'SCILAB')
579-
sourceCodeTab.AddPage(sourcecode8, "SCILAB")
619+
report = SourceCodeReport(sourceCodeTab, self.equation, 'SCILAB')
620+
reportName = "SCILAB"
621+
sourceCodeTab.AddPage(report, reportName)
622+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
580623

581-
sourcecode9 = SourceCodeReport(sourceCodeTab, equation, 'MATLAB')
582-
sourceCodeTab.AddPage(sourcecode9, "MATLAB")
624+
report = SourceCodeReport(sourceCodeTab, self.equation, 'MATLAB')
625+
reportName = "MATLAB"
626+
sourceCodeTab.AddPage(report, reportName)
627+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
583628

584-
sourcecode10 = SourceCodeReport(sourceCodeTab, equation, 'FORTRAN90')
585-
sourceCodeTab.AddPage(sourcecode10, "FORTRAN90")
629+
report = SourceCodeReport(sourceCodeTab, self.equation, 'FORTRAN90')
630+
reportName = "FORTRAN90"
631+
sourceCodeTab.AddPage(report, reportName)
632+
self.sourceCodeReportsListForPDF.append([str(report.text.GetValue()), reportName])
586633

587634
# equation list
588-
dim = equation.GetDimensionality()
635+
dim = self.equation.GetDimensionality()
589636
equationList = EquationListReport(self, dim)
590637
self.AddPage(equationList, "List Of Standard " + str(dim) + "D Equations")
591638

@@ -602,6 +649,37 @@ def __init__(self, parent, equation):
602649
info = AdditionalInfoReport(additionalInfoTab, AdditionalInfo.links)
603650
additionalInfoTab.AddPage(info, "Web Links")
604651

652+
# additional information
653+
pdfPanel = wx.Panel(self, id=wx.ID_ANY)
654+
self.AddPage(pdfPanel, "Save To PDF File")
655+
656+
btnCreatePDF = wx.Button(pdfPanel, -1, "Save To PDF")
657+
self.Bind(wx.EVT_BUTTON, self.createPDF, btnCreatePDF)
658+
659+
660+
def createPDF(self, evt):
661+
try:
662+
import reportlab
663+
except:
664+
wx.MessageBox("\nCould not import reportlab.\n\nPlease install using the command\n\n'pip3 install reportlab'", "Error")
665+
return
666+
667+
fd =wx.FileDialog(self, "PDF file name", "", "",
668+
"PDF files (*.pdf)|*.pdf", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
669+
670+
fName = ''
671+
if fd.ShowModal() != wx.CANCEL:
672+
fName = fd.GetPath()
673+
if fName:
674+
from . import pdfCode
675+
pdfCode.CreatePDF(fName,
676+
self.equation,
677+
self.graphReportsListForPDF,
678+
self.textReportsListForPDF,
679+
self.sourceCodeReportsListForPDF
680+
)
681+
wx.MessageBox("\nSuccessfully created PDF file.", "Success")
682+
605683

606684

607685
# see the included wxNestedTabsExample.py file

guifiles/pdfCode.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import time, os, glob
2+
import reportlab
3+
import reportlab.platypus
4+
from reportlab.pdfgen import canvas
5+
from reportlab.lib.units import mm
6+
import reportlab.lib.pagesizes
7+
8+
9+
# from http://code.activestate.com/recipes/576832-improved-reportlab-recipe-for-page-x-of-y/
10+
class NumberedCanvas(canvas.Canvas):
11+
def __init__(self, *args, **kwargs):
12+
canvas.Canvas.__init__(self, *args, **kwargs)
13+
self._saved_page_states = []
14+
15+
def showPage(self):
16+
self._saved_page_states.append(dict(self.__dict__))
17+
self._startPage()
18+
19+
def save(self):
20+
"""add page info to each page (page x of y)"""
21+
num_pages = len(self._saved_page_states)
22+
for state in self._saved_page_states:
23+
self.__dict__.update(state)
24+
self.draw_page_number(num_pages)
25+
canvas.Canvas.showPage(self)
26+
canvas.Canvas.save(self)
27+
28+
def draw_page_number(self, page_count):
29+
self.setFont("Helvetica", 7)
30+
self.drawRightString(200*mm, 20*mm, "Page %d of %d" % (self._pageNumber, page_count))
31+
self.drawCentredString(25*mm, 20*mm, 'https://github.com/zunzun/wxPythonFit')
32+
33+
34+
35+
def CreatePDF(inFileAndPathName, inEquation, inGraphList, inTextList, inSourceCodeList):
36+
pageElements = []
37+
38+
styles = reportlab.lib.styles.getSampleStyleSheet()
39+
40+
styles.add(reportlab.lib.styles.ParagraphStyle(name='CenteredBodyText', parent=styles['BodyText'], alignment=reportlab.lib.enums.TA_CENTER))
41+
styles.add(reportlab.lib.styles.ParagraphStyle(name='SmallCode', parent=styles['Code'], fontSize=6, alignment=reportlab.lib.enums.TA_LEFT)) # 'Code' and wordwrap=CJK causes problems
42+
43+
myTableStyle = [('ALIGN', (1,1), (-1,-1), 'CENTER'),
44+
('VALIGN', (1,1), (-1,-1), 'MIDDLE')]
45+
46+
tableRow = ['wxPythonFit'] # originally included images that are now unused
47+
48+
table = reportlab.platypus.Table([tableRow], style=myTableStyle)
49+
50+
pageElements.append(table)
51+
52+
pageElements.append(reportlab.platypus.XPreformatted('<br/><br/><br/><br/>', styles['CenteredBodyText']))
53+
54+
pageElements.append(reportlab.platypus.Paragraph(inEquation.GetDisplayName(), styles['CenteredBodyText']))
55+
pageElements.append(reportlab.platypus.XPreformatted('<br/><br/>', styles['CenteredBodyText']))
56+
57+
pageElements.append(reportlab.platypus.XPreformatted('<br/><br/>', styles['CenteredBodyText']))
58+
pageElements.append(reportlab.platypus.Paragraph("Created " + time.asctime(time.localtime()), styles['CenteredBodyText']))
59+
60+
pageElements.append(reportlab.platypus.PageBreak())
61+
62+
# make a page for each report output, with report name as page header
63+
filenamePrefix = 'temp_'
64+
index = 1
65+
for report in inGraphList:
66+
pageElements.append(reportlab.platypus.XPreformatted('<br/><br/>', styles['CenteredBodyText']))
67+
68+
# I could not get io.BytesIO and ImageReader to work, using files instead
69+
# each image file name must be unique for reportlab's use - delete when done
70+
fname = filenamePrefix + str(index) + '.png'
71+
report[0].savefig(fname, format='png')
72+
im = reportlab.platypus.Image(fname)
73+
im._restrictSize(600, 600) # if image is too large for one page
74+
im.hAlign = 'CENTER'
75+
pageElements.append(im)
76+
77+
index += 1
78+
79+
pageElements.append(reportlab.platypus.PageBreak())
80+
81+
for report in inTextList + inSourceCodeList:
82+
pageElements.append(reportlab.platypus.Preformatted(report[1], styles['SmallCode']))
83+
pageElements.append(reportlab.platypus.XPreformatted('<br/><br/><br/>', styles['CenteredBodyText']))
84+
85+
replacedText = report[0]
86+
87+
if -1 != report[1].find('Coefficients'):
88+
reportText = reportText.replace('<sup>', '^')
89+
reportText = reportText.replace('<SUP>', '^')
90+
91+
replacedText = replacedText.replace('\t', ' ') # convert tabs to four spaces
92+
replacedText = replacedText.replace('\r\n', '\n')
93+
94+
rebuiltText = ''
95+
for line in replacedText.split('\n'):
96+
if line == '':
97+
rebuiltText += '\n'
98+
else:
99+
if line[0] == '<':
100+
splitLine = line.split('>')
101+
if len(splitLine) > 1:
102+
newLine = splitLine[len(splitLine)-1]
103+
else:
104+
newLine = ''
105+
else:
106+
newLine = line
107+
108+
# crude line wrapping
109+
if len(newLine) > 500:
110+
rebuiltText += newLine[:100] + '\n'
111+
rebuiltText += newLine[100:200] + '\n'
112+
rebuiltText += newLine[200:300] + '\n'
113+
rebuiltText += newLine[300:400] + '\n'
114+
rebuiltText += newLine[400:500] + '\n'
115+
rebuiltText += newLine[500:] + '\n'
116+
elif len(newLine) > 400:
117+
rebuiltText += newLine[:100] + '\n'
118+
rebuiltText += newLine[100:200] + '\n'
119+
rebuiltText += newLine[200:300] + '\n'
120+
rebuiltText += newLine[300:400] + '\n'
121+
rebuiltText += newLine[400:] + '\n'
122+
elif len(newLine) > 300:
123+
rebuiltText += newLine[:100] + '\n'
124+
rebuiltText += newLine[100:200] + '\n'
125+
rebuiltText += newLine[200:300] + '\n'
126+
rebuiltText += newLine[300:] + '\n'
127+
elif len(newLine) > 200:
128+
rebuiltText += newLine[:100] + '\n'
129+
rebuiltText += newLine[100:200] + '\n'
130+
rebuiltText += newLine[200:] + '\n'
131+
elif len(newLine) > 100:
132+
rebuiltText += newLine[:100] + '\n'
133+
rebuiltText += newLine[100:] + '\n'
134+
else:
135+
rebuiltText += newLine + '\n'
136+
137+
pageElements.append(reportlab.platypus.Preformatted(rebuiltText, styles['SmallCode']))
138+
139+
pageElements.append(reportlab.platypus.PageBreak())
140+
141+
doc = reportlab.platypus.SimpleDocTemplate(inFileAndPathName, pagesize=reportlab.lib.pagesizes.letter)
142+
doc.build(pageElements, canvasmaker=NumberedCanvas)
143+
144+
# Done, now delete the temporary image files
145+
for fname in glob.glob(filenamePrefix + "*.png"):
146+
os.remove(fname)

0 commit comments

Comments
 (0)