source: tags/release-0.9/Cubes/plots.hh @ 813

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

*Changed colour of velocity range lines in spectral plots.
*Fixed typo in definition of Image class.

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