source: tags/release-0.9.2/Cubes/plots.hh @ 1327

Last change on this file since 1327 was 88, checked in by Matthew Whiting, 18 years ago

Some minor fixes to the spectral plots to aid readability and consistency
of presentation.
Some minor edits to the Guide.

File size: 10.8 KB
Line 
1#include <iostream>
2#include <sstream>
3#include <string>
4#include <stdlib.h>
5#include <math.h>
6#include <cpgplot.h>
7
8using std::string;
9using std::stringstream;
10
11namespace Plot
12{
13  const float inchToCm=2.54; // Conversion factor from inches to centimetres.
14  const float a4width=21.0;  // A4 width in cm
15  const float a4height=29.7; // A4 height in cm
16  const float psHoffset=0.35; // The default offset applied to ps files by pgplot
17  const float psVoffset=0.25; // The default offset applied to ps files by pgplot
18
19
20  //***************************************************************************
21
22  class SpectralPlot
23  {
24    /**
25     *  SpectralPlot class
26     *    A class to hold the dimensions and set up for the plotting of the spectra
27     *     (including the full spectra, the zoomed in part, and the moment map).
28     *    The physical dimensions (in inches) of the plot and the elements within
29     *     it are stored, based on the assumption that the plot will go on an A4 page.
30     *    Simple accessor functions are provided to enable access to quantities needed
31     *     for pgplot routines.
32     */
33  public:
34    SpectralPlot(){
35      paperWidth=a4width/inchToCm - 2*psHoffset; paperHeight = paperWidth*M_SQRT2;
36      if(paperHeight+2*psVoffset > a4height){
37        paperHeight = a4height - 2*psVoffset;
38        paperWidth = paperHeight / M_SQRT2;
39      }
40      spectraCount=0;
41      numOnPage = 5;
42      indexSize = 0.6;
43      labelSize = 0.7;};
44    ~SpectralPlot(){};
45
46    void setUpPlot(string pgDestination){
47      /** SpectralPlot::setUpPlot
48       *    Opens the designated pgplot device.
49       *    Scales the paper so that it fits on an A4 sheet (using known values of
50       *     the default pgplot offsets).
51       */
52      cpgopen(pgDestination.c_str());
53      cpgpap(paperWidth, M_SQRT2); // make paper size to fit on A4.
54    }
55
56    void calcCoords(){
57      /** SpectralPlot::calcCoords()
58       *    Calculates the boundaries for the various boxes, in inches measured
59       *     from the lower left corner.
60       *    Based on the fact that there are numOnPage spectra shown on each page,
61       *     going down the page in increasing number -- given by spectraCount.
62       */
63      int posOnPage = (numOnPage - (spectraCount%numOnPage))%numOnPage;
64      mainCoords[0] = 2.0/inchToCm;
65      mainCoords[1] = 13.7/inchToCm;
66      zoomCoords[0] = 15.0/inchToCm;
67      zoomCoords[1] = 16.8/inchToCm;
68      mainCoords[2] = zoomCoords[2] = mapCoords[2] =
69        posOnPage*paperHeight/float(numOnPage) + 1.8/inchToCm;
70      mainCoords[3] = zoomCoords[3] = mapCoords[3] =
71        posOnPage*paperHeight/float(numOnPage) + 3.8/inchToCm;
72      mapCoords[0]  = 17.0/inchToCm;
73      mapCoords[1]  = mapCoords[0] + (mapCoords[3]-mapCoords[2]);
74   }
75
76    void gotoHeader(string xlabel){
77      /** SpectralPlot::gotoHeader(string)
78       *   Calls calcCoords, to calculate correct coordinates for this spectrum.
79       *   Defines the region for the header information, making it centred
80       *    on the page.
81       *   Also writes the velocity (x axis) label, given by the string argument.
82       */
83      if(spectraCount%numOnPage==0) cpgpage();
84      spectraCount++;
85      calcCoords();
86      cpgvsiz(0., paperWidth, mainCoords[2], mainCoords[3]); 
87      cpgsch(labelSize);
88      cpgmtxt("b",3.,0.5,0.5,xlabel.c_str());
89    }
90
91    /**
92     * Header line functions
93     *  Functions to write the header information above the boxes.
94     *  One for each line (position/velocity, widths & fluxes, pixel coords).
95     */
96    void firstHeaderLine(string line){  cpgmtxt("t",3.8,0.5,0.5,line.c_str());};
97    void secondHeaderLine(string line){ cpgmtxt("t",2.3,0.5,0.5,line.c_str());};
98    void thirdHeaderLine(string line){  cpgmtxt("t",0.8,0.5,0.5,line.c_str());};
99
100    void gotoMainSpectrum(float x1, float x2, float y1, float y2, string ylabel){
101      /** SpectralPlot::gotoMainSpectrum()
102       *   Defines the region for the main spectrum.
103       *   Draws the box, with tick marks, and
104       *    writes the flux (y axis) label, given by the string argument.
105       */
106      cpgvsiz(mainCoords[0],mainCoords[1],mainCoords[2],mainCoords[3]);
107      cpgsch(indexSize);
108      cpgswin(x1,x2,y1,y2);
109      cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
110      cpgsch(labelSize);
111      cpgmtxt("l",4.,0.5,0.5,ylabel.c_str());
112    }
113
114    void gotoZoomSpectrum(float x1, float x2, float y1, float y2){
115      /** SpectralPlot::gotoZoomSpectrum()
116       *   Defines the region for the zoomed-in part of the spectrum.
117       *   Draws the box, with special tick marks on the bottom axis.
118       */
119      cpgvsiz(zoomCoords[0],zoomCoords[1],zoomCoords[2],zoomCoords[3]);
120      cpgsch(indexSize);
121      cpgswin(x1,x2,y1,y2);
122      cpgbox("bc",0.,0,"bcstn1v",0.,0);
123      float lengthL,lengthR,disp,tickpt;
124      stringstream label;
125      for(int i=1;i<10;i++){
126        tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
127        switch(i)
128          {
129          case 2:
130          case 8:
131            lengthL = lengthR = 0.5;
132            disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
133            label.str("");
134            label << tickpt;
135            // do a labelled tick mark
136            cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,disp,0.,label.str().c_str());
137            break;
138          default:
139            label.str("");
140            lengthL = 0.25;
141            lengthR = 0.;
142            disp = 0.;  // not used in this case, but set it anyway.
143            break;
144          }
145        // first the bottom axis, just the tick
146        cpgaxis("",
147                tickpt-0.001*(x2-x1), y1,
148                tickpt+0.001*(x2-x1), y1,
149                tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
150                tickpt, -1, lengthL,lengthR, 0.5, disp, 0.);
151        // and now the top -- no labels, just tick marks
152        cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
153      }
154   }
155   
156    void gotoMap(){
157      /** SpectralPlot::gotoMap()
158       *   Defines the region for the moment map.
159       */
160      cpgvsiz(mapCoords[0],mapCoords[1],mapCoords[2],mapCoords[3]);
161      cpgsch(indexSize);
162    }
163
164    void drawVelRange(float v1, float v2){
165      /** SpectralPlot::drawVelRange(float v1, float v2)
166       *   Draws two vertical lines at the limits of velocity given by the arguments.
167       */
168      int ci,ls;
169      float dud,min,max;
170      cpgqwin(&dud,&dud,&min,&max);
171      cpgqci(&ci);
172      cpgqls(&ls);
173      cpgsci(4);
174      cpgsls(2);
175      cpgmove(v1,min);  cpgdraw(v1,max);
176      cpgmove(v2,min);  cpgdraw(v2,max);
177      cpgsci(ci);
178      cpgsls(ls);
179    }
180   
181  private:
182    int numOnPage;              // Number of spectra to put on one page.
183    int spectraCount;           // Number of spectra done so far -- where on the page?
184    float mainCoords[4];        // Boundaries for the main spectrum [inches]
185    float zoomCoords[4];        // Boundaries for the zoomed-in spectrum [inches]
186    float mapCoords[4];         // Boundaries for the map box [inches]
187    float paperWidth;           // Width of the plottable region of the paper [inches]
188    float paperHeight;          // Height of the plottable region of the paper [inches]
189    float indexSize;            // PGPlot character height for tick mark labels
190    float labelSize;            // PGPlot character height for axis labels.
191   
192  };
193
194  //***************************************************************************
195
196  class ImagePlot
197  {
198    /**
199     *  ImagePlot class
200     *    A class to hold the dimensions and set up for the plots used by the two
201     *     functions below.
202     *    The physical dimensions (in inches) of the plot and the elements within
203     *     it are stored, including maximum widths and heights (so that the plot will
204     *     fit on an A4 page).
205     *    Simple accessor functions are provided to enable access to quantities needed
206     *     for pgplot routines.
207     */
208  public:
209    ImagePlot(){
210      paperWidth = 7.5; maxPaperHeight = 10.; marginWidth = 0.8; wedgeWidth = 0.7;
211      imageWidth = paperWidth - 2*marginWidth - wedgeWidth;
212    };
213    ~ImagePlot(){};
214 
215    void setUpPlot(string pgDestination, float x, float y){
216      /**
217       * setUpPlot(string pgDestination, float x, float y)
218       *  Opens a pgplot device and scales it to the correct shape.
219       *  In doing so, the dimensions for the image are set, and the required aspect ratios
220       *   of the image and of the plot are calculated.
221       *  If the resulting image is going to be tall enough to exceed the maximum height
222       *  (given the default width), then scale everything down by enough to make the
223       *  height equal to maxPaperHeight.
224       */
225      xdim = x;
226      ydim = y;
227      imageRatio= ydim / xdim;
228      aspectRatio =  (imageRatio*imageWidth + 2*marginWidth) / paperWidth;
229      if((imageRatio*imageWidth + 2*marginWidth) > maxPaperHeight){
230        float correction = maxPaperHeight / (imageRatio*imageWidth + 2*marginWidth);
231        paperWidth *= correction;
232        marginWidth *= correction;
233        wedgeWidth *= correction;
234        imageWidth = paperWidth - 2*marginWidth - wedgeWidth;
235      }
236      cpgopen(pgDestination.c_str());
237      cpgpap(paperWidth, aspectRatio);
238    }
239
240    void  drawMapBox(float x1, float x2, float y1, float y2, string xlabel, string ylabel){
241      /**
242       * drawMapBox()
243       *  Defines the region that the box containing the map is to go in,
244       *  and draws the box with limits given by the arguments.
245       *  The labels for the x and y axes are also given as arguments.
246       */
247      cpgvsiz(marginWidth, marginWidth + imageWidth,
248              marginWidth, marginWidth + (imageWidth*imageRatio));
249      cpgslw(2);
250      cpgswin(x1,x2,y1,y2);
251      cpgbox("bcst",0.,0,"bcst",0.,0);
252      cpgslw(1);
253      cpgbox("bcnst",0.,0,"bcnst",0.,0);
254      cpglab(xlabel.c_str(), ylabel.c_str(), "");
255    }
256    void  makeTitle(string title){
257      /**
258       *  makeTitle(string)
259       *    Writes the title for the plot, making it centred for the entire plot
260       *    and not just the map.
261       */
262      cpgvstd();
263      cpgmtxt("t", 2.7, 0.5, 0.5, title.c_str());
264    }
265    float cmToCoord(float cm){return (cm/inchToCm) * ydim / (imageWidth*imageRatio);};
266    float getMargin()     {return marginWidth;};
267    float getPaperWidth() {return paperWidth;};
268    float getImageWidth() {return imageWidth;};
269    float getImageHeight(){return imageWidth*imageRatio;};
270    float getAspectRatio(){return aspectRatio;};
271
272  private:
273    float paperWidth;       // Default (maximum) width of "paper" [inches]
274    float maxPaperHeight;   // Maximum allowed height of paper [inches]
275    float marginWidth;      // Width allowed for margins around main plot (ie. label & numbers) [inches]
276    float wedgeWidth;       // Width allowed for placement of wedge on right hand side of plot. [inches]
277    float imageWidth;       // Calculated total width of the image part of the plot [inches]
278    float imageRatio;       // Aspect ratio of the image only (ie. y-value range / x-value range).
279    float aspectRatio;      // Aspect ratio of whole plot.
280    float xdim;             // Width of main plot, in display units.
281    float ydim;             // Height of main plot, in display units.
282  };
283
284}
Note: See TracBrowser for help on using the repository browser.