PSPlot
MPD78
07-24-2009, 09:58 AM
Hello all,
The PSPlot routine in NR3 uses the PSPlot freely available software from SourceForge.net. Does this version of PSPlot work well on a Windows XP platform? If not is there one that does work on a Windows XP platform?
Thanks
Matt
davekw7x
07-24-2009, 10:22 AM
...Does this version of PSPlot work well on a Windows XP platform?...
What compiler are you using? Do you have gsview32.exe installed at "C:\Program Files\Ghostgum\gsview"?
With recent compilers from Borland and Microsoft, psplot.h in NR3 works just fine on my Windows XP workstation.
With Visual C++ version 6, a workaround for a compiler bug can be effected by applying some "minor" changes to nr3.h
With GNU/cygwin on Windows XP, there are a few other issues, but it can be made to work.
Bottom line: IWFMYMMV (It Works For Me; Your Mileage May Vary).
Regards,
Dave
MPD78
07-24-2009, 10:23 AM
Dave,
I am using the Visual Studio 2008 Express compilier. I do not have ghostview. I will check into ghostview.
Thanks
Matt.
MPD78
07-28-2009, 09:29 AM
I have ghostview installed and working properly but I keep getting the error "failure opening output file for plot" from the PSplot routine.
Here is my simple main() function
#include "psplot.h"
#include "psplotexample.h"
int main()
{
psplot_example();
return 0;
}
Any help would be greatly appreciated.
Thanks
Matt
davekw7x
07-28-2009, 10:37 AM
...error "failure opening output file for plot" from the PSplot routine...
Well, did you look in psplotexample.h to see what it is trying to open as an output file?
In line 12 I see the following:
PSpage pg("d:\\nr3\\newchap20\\myplot.ps");
So, unless you have a directory d:\nr3\newchap20 it will fail.
Try the following:
Make a copy of the distribution psplotexample.h file (just in case...). Give the copy a name something like psplotexample_distribution.h
Change the PSpage pg declaration in the psplotexample.h file that you will be using to something like:
PSpage pg("myplot.ps");
Now recompile the program. When you run it, it will open a file named myplot.psin the current directory and call gnuplot to display it.
Well, at least that's how it worked for me (Windows XP, Microsoft Visual C++ 2008 Express Edition). As always, I close with my universal disclaimer that YMMV (Your Mileage May Vary).
Regards,
Dave
MPD78
07-28-2009, 10:43 AM
Yes, I changed the directory to one that actually exists on my computer and I still have the same error message.
davekw7x
07-28-2009, 10:45 AM
Yes, I changed the directory to one that actually exists on my computer and I still have the same error message.
How about trying the change exactly as I showed?
Regards,
Dave
MPD78
07-28-2009, 10:54 AM
Yes, I followed the instructions. Now I get a new error from the compilier. "Windows has triggered a break point" Then I am sent over to the nr3.h file line 219.
davekw7x
07-28-2009, 11:20 AM
Yes, I followed the instructions. Now I get a new error from the compilier. "Windows has triggered a break point" Then I am sent over to the nr3.h file line 219.
Is this a compile-time error? Reboot your machine and try again.
If this doesn't change things, then???
Well...
Line 219 in my nr3.h is the destructor for an NRvector object.
Nothing in your main program or psplot.h or psplotexample.h will cause a call to the NRvector destructor, so I can't help you with anything specific .
Here's a suggestion: Go back to the original distribution files nr3.h, psplot.h, and psplotexample.h. (That's why I always recommend making backup copies of any NR files that you are going to edit.)
Compile your main program again. You apparently didn't get any errors from your original attempt. (Right?) How about now?
Ok, now make backup copies of psplot.h and psplotexample.h so that you can make changes to them for your tests:
If lines 9-10 of psplotexample.h look like this:
PSpage pg("d:\\nr3\\newchap20\\myplot.ps");
PSplot plot1(pg,100.,500.,100.,500.);
Make changes like this. (Don't retype my additions, just paste them into your text editor window.)
// PSpage pg("d:\\nr3\\newchap20\\myplot.ps");// commented out
char *outname = "myplot.ps";
printf("In psplot_example(): Calling PSpage(%s)\n", outname);
PSpage pg(outname);
PSplot plot1(pg,100.,500.,100.,500.);
Now, in psplot.h the PSpage constructor starts like this:
PSpage(char *filnam) {
file = new char[128];
strcpy(file,filnam);
PLT = fopen(file,"wb");
if (!PLT) throw("failure opening output file for plot");
fprintf(PLT,"%%!\n/mt{moveto}def /lt{lineto}def /np{newpath}def\n");
Make changes like this:
PSpage(char *filnam) {
printf("In PSpage(): filnam = <%s>\n", filnam);
file = new char[128];
strcpy(file,filnam);
printf("In PSpage(): Calling fopen(%s,\"wb\")\n", file);
PLT = fopen(file,"wb");
//if (!PLT) throw("failure opening output file for plot");
if (!PLT) {
printf("fopen failed\n");
exit(1);
}
else {
printf("Opened %s for writing\n", file);
}
fprintf(PLT,"%%!\n/mt{moveto}def /lt{lineto}def /np{newpath}def\n");
Here's what I see when I run your main program:
In psplot_example(): Calling PSpage(myplot.ps)
In PSpage(): filnam = <myplot.ps>
In PSpage(): Calling fopen(myplot.ps,"wb")
In PSpage(): Opened myplot.ps for writing
Regards,
Dave
Footnote: Are you compiling from a command line or from within the Integrated Development Environment? For getting help "by remote control" I recommend compiling from a command line so that we aren't confused by IDE project settings that may be different in our two systems in a way that makes it hard to reproduce problems.
MPD78
07-28-2009, 02:01 PM
Dave,
I made the changes and I obtain the same results that you display however, the program still blows up with this message right after the output created by the changes.
The message is
'C:Program' is not a recognized as an internal or external command, operable program, or batch file.
davekw7x
07-28-2009, 02:36 PM
....
'C:Program' is not a recognized as an internal or external command, operable program, or batch file.
I guess that comes from the system() call in the display() function. It seems that the path is not properly formed.
Let's go back to the original psplot.h file:
In psplot.h there are the following lines in the display() member function of the PSpage struct. In my copy of the distribution psplot.h file they are lines 68-70:
strcpy(cmd,"\"C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe\" ");
strcat(cmd,file);
system(cmd);
Add a line before the system(cmd) function call to see exactly what is being attempted:
strcpy(cmd,"\"C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe\" ");
strcat(cmd,file);
printf("In PSpage::display(): Calling system(%s)\n", cmd); // Add this line
system(cmd);
ON my system I see:
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.exe" myplot.ps)
And it plots the file.
If you have installed gsview32.exe at C:\Program Files\Ghostgum\gsview, as I mentioned in my first post, it should work for you.
If you have changed the strcpy() function call to accommodate some other path, how about showing us exactly what that line is?
Regards,
Dave
MPD78
07-28-2009, 03:18 PM
I have the program running corretly now. Gsview is launched correctly but I still don't see the graph in Gsview. Is there something else that has to be done in Gsview to view the graph?
davekw7x
07-28-2009, 03:36 PM
I have the program running corretly now. Gsview is launched correctly but I still don't see the graph in Gsview. Is there something else that has to be done in Gsview to view the graph?
If you do it right, it gsview will plot the file whose name you feed it in the system(cmd) function call.
OK! You printed out the system(cmd) line as I suggested, right? Did it give the correct file name?
I hate to repeat myself, but with the changes that I made in psplotexample.h, my program showed
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.exe" myplot.ps)
If yours is different, then how about posting exactly what yours showed?
Do you have a file named "myplot.ps" anywhere? Look around. Is it in the same directory as your test program? Or what? Or where?
Anyhow, before changing anything:
In gsview, click on the File menu item and click "Open..." You should see an "Open" dialog box. It will show names of all "*.ps" and "*.pdf" files in the directory from which you are executing. If myplot.ps is not in the correct directory, then you can navigate to the correct directory and display "myplot.ps"
Then figure out the difference(s) between what I suggested and what you did. The idea is to get the program to create the file and write to it and feed that file's name to gsview32. If you just give the file name (not any path), it will be in the directory from which you launched the program.
Regards,
Dave
MPD78
07-28-2009, 05:39 PM
Dave,
Here is what I see
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.exe")
The difference between yours and mine is; mine is missing the myplot.ps after the end quote. I am not sure why.
Yes, I do have a file named myplot. It is located in my project folder. When I browse from Gsview to open it, all I get is the ghostscript message box that appears to contain the code to create the chart but no chart is created when I click okay on the ghostscript message box.
davekw7x
07-28-2009, 05:52 PM
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.exe")
The difference between yours and mine is; mine is missing the myplot.ps after the end quote. I am not sure why.
Because you have lost something when you edited the file. Try the following.
void display() {
char cmd[128];
if (PLT) close();
printf("In PSpage::display: file = <%s>\n", file);
strcpy(cmd,"\"C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe\" ");
strcat(cmd,file);
printf("In PSpage::display(): Calling system(%s)\n", cmd);
system(cmd);
}
Output is
In PSpage::display: file = <myplot.ps>
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.exe" myplot.ps)
Now, I have shown you mine, how about you showing me yours?
Paste the exact code of the PSpage::display() function that you are using into your post.
Regards,
Dave
MPD78
07-28-2009, 06:16 PM
Here is my exact code for the PSpage::display() function.
void display() {
char cmd[128];
if (PLT) close();
printf("In PSpage::display: file = <%s>\n", file);
strcpy(cmd,"\"C:\\Program Files\\Ghostgum\\gsview\\gsview32.exe\" ");
strcat(cmd,file);
printf("In PSpage::display(): Calling system(%s)\n", cmd);
system(cmd);
}
And here is the exact output.
In psplot_example(): Calling PSpage(myplot.ps)
In PSpage(): filnam = <myplot.ps>
In PSpage(): Calling fopen(myplot.ps,"wb")
Opened myplot.ps for writing
In PSpage::display: file = <myplot.ps>
In PSpage::display(): Calling system("C:\Program Files\Ghostgum\gsview\gsview32.
exe" myplot.ps)
Now I have the myplot.ps but I still don't have a graph in Gsview. Again, I only have the ghostscript message window.
davekw7x
07-28-2009, 06:58 PM
...
Now I have the myplot.ps but I still don't have a graph in Gsview. Again, I only have the ghostscript message window.
Have you ever displayed any .ps file with gsview?
That is, have you configured it to use whatever gs you have? Use the help menu from gsview (or read some documentation) to learn how to do it. In the gs\examples directory there are some goodies like tiger.ps and escher.ps and some others.
I have attached a zipped file from myplot.ps. Unzip it and compare with your ps file. Try to display it with gsview.
I also attached a pdf file to show what it should look like. (You can view the pdf file with gsview or with Adobe acrobat reader.)
Regards,
Dave
MPD78
07-29-2009, 05:47 AM
Yes, I have viewed .ps files before. The attachment that contains your .ps file opens correctly. When I open my myplot.ps file the ghostscript window displays an error that I didn't see last night. The error is;
Error: /stackunderflow in --moveto--
Could that be what is causing my myplot.ps to not display? If so what is causing that error?
Thanks for all your help on this so far.
Matt
davekw7x
07-29-2009, 09:20 AM
...
Error: /stackunderflow in --moveto--
Could that be what is causing my myplot.ps to not display?
Of course.
Let me get this straight: The file that my program created works OK with your gsview32.exe but yours doesn't. Is that right?
How about posting your myplot.ps file? Just zip it and attach to your post.
what is causing that error?Since you said that you are using Visual Studio 2008 Express and I am testing with that compiler with your main() source file, I would guess that something is different in your psplot.h or psplotexample.h. (See Footnote.)
I mean, if the compiler were not installed correctly I think you would have problems compiling and/or executing. I can't see where it would simply give a different output file.
Now, the changes that I suggested for psplot.h were for debug purposes and aren't necessary to make it run (assuming that you have installed gsview32.exe at C:\Program Files\Ghostgum\gsview, as you seem to have indicated).
So: go back to your original psplot.h
Here's a program that just uses psplot.h, not psplotexample.h. Try it:
#include "nr3.h"
#include "psplot.h"
#ifndef M_PI
const Doub M_PI = 3.14159265358979323846;
#endif
Doub f(Doub x)
{
if (x == 0) {
return 1;
}
Doub mpx = M_PI*x;
return sin(mpx)/(mpx);
}
int main(void)
{
Int n = 300; // This many points
VecDoub x(n), y(n);
Doub xmin = 0;
Doub xmax = 4.0;
Doub deltax = (xmax - xmin) / (n - 1.0);
Doub xx = xmin;
Int i;
for (i = 0, xx=0; i < n; i++, xx+=deltax) {
x[i] = xx;
y[i] = f(xx);
}
const char *outname = "myplot.ps";
PSpage pg(outname);
PSplot plot1(pg, 100.0, 500.0, 100.0, 500.0); //
plot1.setlimits(xmin, xmax, -1.0, 1.0);
plot1.frame();
plot1.autoscales();
plot1.lineplot(x, y);
pg.close();
printf("Calling display()\n");
pg.display();
return 0;
}
I have attached output files as before. Compile and run the program.
Compare the myplot.ps from the attachment with the one generated by running the program on your system. Are the myplot.ps files identical? Does either one work with your gsview32?
Regards,
Dave
Footnote: Where did you get nr3.h and psplot.h? CD from NR? Download from nr.com? Where?
MPD78
07-29-2009, 10:11 AM
First, I purchased an online subscription to the book in late 2008. The code I am using for PSpage and PSplot comes from Webnote No. 26, Rev. 1. I typed in all of the code by hand. Now, I know your thinking typo but I checked every line for typos and I didn't have any. Second, my nr3.h file is from the nr.com website.
I compilied your program but my compilier didn't like this line.
const char *outname = "myplot.ps";
I commented out that line and changed the line below to
PSpage pg("myplot.ps");
The programmed compilied correctly and ran, but once again I don't have a graph, I just have the ghostscript message window. It is the same error message as before;
Error: /stackunderflow in --moveto--
Again, your files open correctly in Gsview.
See attachment for my myplot.ps file.
Yes, I have the Gsview32.exe located in C:\Program Files\Ghostgum\gsview
davekw7x
07-29-2009, 10:53 AM
...I typed in all of the code by hand.
Aha, and double Aha! See Footnote.
...I checked every line for typos and I didn't have any
Wanna bet?
Let's investigate the differences between the output file that works (mine) and the one that doesn't work (yours).
Look at line number two of the output. This is created by line number 14 of psplot.h
In my psplot.h, line 14 is this:
fprintf(PLT,"/st{stroke}def /cp{closepath}def /fi{fill}def\n");
I'm guessing that yours looks more like this:
fprintf(PLT,"/st{stroke}def /cp{closepath}def /fil{fill}def\n");
Of course your line numbers may be a little different, depending on whether you put in blank lines here and there, but you should be able to locate the place in psplot.h that creates particular output lines. Just compare your output file with mine.
See the difference? Look again at your output line number two:
/st{stroke}def /cp{closepath}def /fil{fill}def
Now, look at the next output line. Line number three of the output comes from line number 15 of psplot.h. Here's mine in psplot.h:
fprintf(PLT,"/zp {gsave /ZapfDingbats findfont exch ");
I'm thinking that yours looks more like
fprintf(PLT,"/zp {gsave /ZapDingbats findfont exch ");
(No 'f' in ZapfDingbats, right?)
Etc.
my compilier didn't like this line.
const char *outname = "myplot.ps";
Oops! I had been experimenting with making psplot.h "const safe," and had inadvertently left that line in there. Sorry. Your fix is correct.
Regards,
Dave
Footnote from the text:
...experience has shown that virtually all reported bugs in such cases are typing errors!
MPD78
07-29-2009, 11:04 AM
Dave,
Yes, I did have an L (lower case) in fil and yes there is an f in the other line.
I changed my lines to be exactly the same as yours and still no graph.
Is the webnote incorrect then in having the L (lower case) and the f in the other line?
davekw7x
07-29-2009, 11:31 AM
Dave,
Yes, I did have an L (lower case) in fil and yes there is an f in the other line.
I changed my lines to be exactly the same as yours and still no graph.
What I meant by Let's investigate
.
. A couple of steps of investigation by davekw7x
.
Etc.
was to suggest that you proceed as follows:
Compare each and every line in the output file that works (mine) with the corresponding line in the output file that doesn't work (yours).
Find the line in your psplot.h that creates a line in which there is a discrepancy.
Fix it.
Compile and execute. If it doesn't work, then look at the output files again.
Repeat the previous steps until the output files are exactly the same. (Exactly!)
Is the webnote incorrect then in having the L (lower case) and the f in the other line?
The lines in nr3web26.pdf are like the ones I showed in my version of psplot.h, not like the ones that I'm guessing about in yours.
Here are the correct lines in nr3web26.pdf and in my psplot.h
fprintf(PLT,"/st{stroke}def /cp{closepath}def /fi{fill}def\n");
fprintf(PLT,"/zp {gsave /ZapfDingbats findfont exch ");
Note that the correct line has "fi{fill}", not "fil{fill}"
Note that the correct line has "ZapfDingbats", not "ZapDingbats"
I'm done for this thread.
Regards,
Dave
"Over and out."
MPD78
07-30-2009, 09:54 AM
Dave,
Thanks so much for your help.
I have it running now.
Hope I get a lot of mileage.
Matt