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