1 // Plot buffer test program.  Adapted from example x01
2 //
3 // Copyright (C) 2004  Rafael Laboissiere
4 // Copyright (C) 2015  Jim Dishaw
5 //
6 // This file is part of PLplot.
7 //
8 // PLplot is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU Library General Public License as published
10 // by the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // PLplot is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public License
19 // along with PLplot; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 //
23 
24 #include "plplotP.h"
25 #include "plcdemos.h"
26 #include "plevent.h"
27 #ifdef PL_HAVE_NANOSLEEP
28 #include <time.h>
29 #endif
30 #ifdef PL_HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #include "plstrm.h"
34 
35 // Which test device to use.  The svg device is the best choice, however,
36 // I (jrd) find it easier to debug with psc.  YMMV.
37 #define TEST_DEVICE    "psc"
38 
39 // Reach into the guts of PLPlot to get access to the current stream.
40 // Not recommended behavior for user program.  Only needed for testing.
41 extern PLDLLIMPEXP_DATA( PLStream * ) plsc;
42 
43 // Variables and data arrays used by plot generators
44 
45 static PLGraphicsIn gin;
46 
47 // Function prototypes
48 
49 void plot1( PLFLT xscale, PLFLT yscale, PLFLT xoff, PLFLT yoff );
50 void plot2( void );
51 void plot3( void );
52 
53 //--------------------------------------------------------------------------
54 // main
55 //
56 // Generates several simple line plots.  Demonstrates:
57 //   - subwindow capability
58 //   - setting up the window, drawing plot, and labelling
59 //   - changing the color
60 //   - automatic axis rescaling to exponential notation
61 //   - placing the axes in the middle of the box
62 //   - gridded coordinate axes
63 //--------------------------------------------------------------------------
64 
65 int
main(int argc,char * argv[])66 main( int argc, char *argv[] )
67 {
68     PLINT cur_strm, new_strm;
69     char  ver[80];
70 
71     // plplot initialization
72 
73     // Set the output filename
74     plsfnam( "test_plbuf_0.out" );
75 
76     // Parse and process command line arguments
77 
78     plparseopts( &argc, argv, PL_PARSE_FULL );
79 
80     // Force the plot buffer on.  Typically the plot buffer is only used
81     // by interactive drivers and the plmeta driver.  Must do this before
82     // plot initialization occurs otherwise commands will be missed
83     // by the interactive drivers and the plmeta driver
84     plsc->plbuf_write = 1;
85 
86     // Initialize plplot
87     // Divide page into 2x2 plots
88     // Note: calling plstart replaces separate calls to plssub and plinit
89     plstart( TEST_DEVICE, 2, 2 );
90 
91     // Generate the plot for the first subwindow
92     plot1( 6.0, 1.0, 0.0, 0.0 );
93 
94     // Set the y-axis to 5 digits maximum and generate the plot for
95     // the second subwindow
96     plsyax( 5, 0 );
97     plot1( 1.0, 0.0014, 0.0, 0.0185 );
98 
99     // Generate a plot for the third subwindow
100     plot2();
101 
102     // Generate a plot for the fourth subwindow
103     plot3();
104 
105     // Replay the plot buffer
106     plgstrm( &cur_strm );          // get current stream
107     plmkstrm( &new_strm );         // create a new one
108 
109     plsfnam( "test_plbuf_1.out" ); // file name
110     plsdev( TEST_DEVICE );         // device type
111 
112     plcpstrm( cur_strm, 0 );       // copy old stream parameters to new stream
113     plreplot();                    // do the save by replaying the plot buffer
114     plend1();                      // finish the device
115 
116     plsstrm( cur_strm );           // return to previous stream
117     plend1();                      // and end the first plot stream
118 
119     // Start fresh and use the plmeta driver
120     plsfnam( "test_plbuf_0.plm" );
121     plstart( "plmeta", 2, 2 );
122 
123     // Generate the same plots as before
124 
125     // Generate the plot for the first subwindow
126     plot1( 6.0, 1.0, 0.0, 0.0 );
127 
128     // Set the y-axis to 5 digits maximum and generate the plot for
129     // the second subwindow
130     plsyax( 5, 0 );
131     plot1( 1.0, 0.0014, 0.0, 0.0185 );
132 
133     // Generate the plot for the third subwindow
134     plot2();
135 
136     // Generate the plot for the fourth subwindow
137     plot3();
138 
139     // Finish this stream
140     plend1();
141 
142     // Test reading of PLplot metafiles
143     plsfnam( "test_plbuf_2.out" );
144     plsdev( TEST_DEVICE );
145     //plstart( TEST_DEVICE, 2, 2 );
146     plreadmetafile( "test_plbuf_0.plm" );
147 
148     // Don't forget to call plend() to finish off!
149     plend();
150     exit( 0 );
151 }
152 
153 //--------------------------------------------------------------------------
154 
155 void
plot1(PLFLT xscale,PLFLT yscale,PLFLT xoff,PLFLT yoff)156 plot1( PLFLT xscale, PLFLT yscale, PLFLT xoff, PLFLT yoff )
157 {
158     static PLFLT x[101], y[101];
159     static PLFLT xs[6], ys[6];
160     int          i;
161     PLFLT        xmin, xmax, ymin, ymax;
162 
163     for ( i = 0; i < 60; i++ )
164     {
165         x[i] = xoff + xscale * ( i + 1 ) / 60.0;
166         y[i] = yoff + yscale * pow( x[i], 2. );
167     }
168 
169     xmin = x[0];
170     xmax = x[59];
171     ymin = y[0];
172     ymax = y[59];
173 
174     for ( i = 0; i < 6; i++ )
175     {
176         xs[i] = x[i * 10 + 3];
177         ys[i] = y[i * 10 + 3];
178     }
179 
180 // Set up the viewport and window using PLENV. The range in X is
181 // 0.0 to 6.0, and the range in Y is 0.0 to 30.0. The axes are
182 // scaled separately (just = 0), and we just draw a labelled
183 // box (axis = 0).
184 //
185     plcol0( 1 );
186     plenv( xmin, xmax, ymin, ymax, 0, 0 );
187     plcol0( 2 );
188     pllab( "(x)", "(y)", "#frPLplot Example 1 - y=x#u2" );
189 
190 // Plot the data points
191 
192     plcol0( 4 );
193     plpoin( 6, xs, ys, 9 );
194 
195 // Draw the line through the data
196 
197     plcol0( 3 );
198     plline( 60, x, y );
199 }
200 
201 //--------------------------------------------------------------------------
202 
203 void
plot2(void)204 plot2( void )
205 {
206     static PLFLT x[101], y[101];
207     static PLFLT xs[6], ys[6];
208     int          i;
209 
210 // Set up the viewport and window using PLENV. The range in X is -2.0 to
211 // 10.0, and the range in Y is -0.4 to 2.0. The axes are scaled separately
212 // (just = 0), and we draw a box with axes (axis = 1).
213 //
214     plcol0( 1 );
215     plenv( -2.0, 10.0, -0.4, 1.2, 0, 1 );
216     plcol0( 2 );
217     pllab( "(x)", "sin(x)/x", "#frPLplot Example 1 - Sinc Function" );
218 
219 // Fill up the arrays
220 
221     for ( i = 0; i < 100; i++ )
222     {
223         x[i] = ( i - 19.0 ) / 6.0;
224         y[i] = 1.0;
225         if ( x[i] != 0.0 )
226             y[i] = sin( x[i] ) / x[i];
227     }
228 
229 // Draw the line
230 
231     plcol0( 3 );
232     plwidth( 2 );
233     plline( 100, x, y );
234     plwidth( 1 );
235 }
236 
237 //--------------------------------------------------------------------------
238 
239 void
plot3(void)240 plot3( void )
241 {
242     static PLFLT x[101], y[101];
243     static PLFLT xs[6], ys[6];
244     PLINT        space0 = 0, mark0 = 0, space1 = 1500, mark1 = 1500;
245     int          i;
246 
247 // For the final graph we wish to override the default tick intervals, and
248 // so do not use plenv().
249 //
250     pladv( 0 );
251 
252 // Use standard viewport, and define X range from 0 to 360 degrees, Y range
253 // from -1.2 to 1.2.
254 //
255     plvsta();
256     plwind( 0.0, 360.0, -1.2, 1.2 );
257 
258 // Draw a box with ticks spaced 60 degrees apart in X, and 0.2 in Y.
259 
260     plcol0( 1 );
261     plbox( "bcnst", 60.0, 2, "bcnstv", 0.2, 2 );
262 
263 // Superimpose a dashed line grid, with 1.5 mm marks and spaces.
264 // plstyl expects a pointer!
265 //
266     plstyl( 1, &mark1, &space1 );
267     plcol0( 2 );
268     plbox( "g", 30.0, 0, "g", 0.2, 0 );
269     plstyl( 0, &mark0, &space0 );
270 
271     plcol0( 3 );
272     pllab( "Angle (degrees)", "sine", "#frPLplot Example 1 - Sine function" );
273 
274     for ( i = 0; i < 101; i++ )
275     {
276         x[i] = 3.6 * i;
277         y[i] = sin( x[i] * M_PI / 180.0 );
278     }
279 
280     plcol0( 4 );
281     plline( 101, x, y );
282 }
283