574 lines
55 KiB
HTML
574 lines
55 KiB
HTML
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Graphing the number of sun spots during the 19th Century</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch04.html" title="Chapter 4. Your first graph script"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Graphing the number of sun spots during the 19th Century</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 4. Your first graph script</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="Graphing the number of sun spots during the 19th Century"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec1.graphing-sun-spots"></a>Graphing the number of sun spots during the 19th Century</h2></div></div></div>
|
||
|
||
<div class="sect2" title="The historic data"><div class="titlepage"><div><div><h3 class="title"><a name="id2492934"></a>The historic data</h3></div></div></div>
|
||
|
||
<p>It is a well known fact that sun spots have a certain pattern and regularity.
|
||
The cause of these regular patterns are not currently fully understood (even
|
||
though investigation into this phenomenon has been made since beginning of the
|
||
17:th century). The fact that solar storms affects the earth in terms of
|
||
interference with radio traffic and other sensitive electronic devices makes it
|
||
very interesting to keep careful records of the suns activities.</p>
|
||
<p>For this reason the data of solar storm is readily available and makes an
|
||
interesting first example. The data used here is taken from SIDC (The Solar
|
||
Influences Data Analysis Center) in Belgium (<code class="uri"><a class="uri" href="http://sidc.oma.be/sunspot-data/SIDCpub.php" target="_top">http://sidc.oma.be/sunspot-data/SIDCpub.php</a></code>).
|
||
In this example we will use the summary historical data that shows the total
|
||
number of sun spots per year since 1700.. </p>
|
||
</div>
|
||
<div class="sect2" title="Preparing the data"><div class="titlepage"><div><div><h3 class="title"><a name="sec.preparing-sunspots-data"></a>Preparing the data</h3></div></div></div>
|
||
|
||
<p>The first step is to get the data into our PHP script which makes for a first
|
||
good discussion since all graphs needs to get data from some source. The library
|
||
itself is agnostic in regards to from where the data is collected and only needs
|
||
(and requires) data stored in a PHP array of numbers (integers or floats). </p>
|
||
<p>In principle the data to be plotted in the graph can come from :</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>Hard-coded data in the script. This is the least flexible and can
|
||
only really be recommended for examples and really static
|
||
data.</p>
|
||
</li><li class="listitem">
|
||
<p>Data stored in plain text files. (This is what we will use in this
|
||
example.)</p>
|
||
</li><li class="listitem">
|
||
<p>Data stored in binary format in flat files. </p>
|
||
</li><li class="listitem">
|
||
<p>Data stored in a database</p>
|
||
</li><li class="listitem">
|
||
<p>Data sent to the script via URI parameter passing (either GET or
|
||
POST HTTP constructs can be used).</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
<p>What is common among all these methods is that the creator of the script has
|
||
to read the data into one (or several) data arrays that can be used by the
|
||
library. For our example the data of sunspots are stored in a plain text file in
|
||
two columns, one column for the year (with a ".5" added which indicates the
|
||
average of the year) and one column for the number of sunspots for the
|
||
corresponding year. As illustration the first 10 lines of data is shown in <a class="xref" href="ch04s02.html#fig.first-ten-sunspot" title="Figure 4.1. The first ten rows of data of sunspot activities from year 1700">Figure 4.1. The first ten rows of data of sunspot activities from year
|
||
1700</a>.</p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.first-ten-sunspot"></a><p class="title"><b>Figure 4.1. The first ten rows of data of sunspot activities from year
|
||
1700</b></p><div class="figure-contents">
|
||
|
||
<div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">1700.5 5.0
|
||
1701.5 11.0
|
||
1702.5 16.0
|
||
1703.5 23.0
|
||
1704.5 36.0
|
||
1705.5 58.0
|
||
1706.5 29.0
|
||
1707.5 20.0
|
||
1708.5 10.0
|
||
1709.5 8.0</span></pre></td></tr></table></div>
|
||
</div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>From this data we need to create two arrays, one with the number of sunspots
|
||
and one with the corresponding years. If we assume that the data is stored in a
|
||
text file named "<code class="filename">yearssn.txt</code>" in the same directory as the
|
||
script file the function in <a class="xref" href="ch04s02.html#fig.getsunspots" title="Figure 4.2. Reading numeric tabulated sunspot data from a file">Figure 4.2. Reading numeric tabulated sunspot data from a file</a>will read the data into two arrays</p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.getsunspots"></a><p class="title"><b>Figure 4.2. Reading numeric tabulated sunspot data from a file</b></p><div class="figure-contents">
|
||
|
||
<a name="pl.getsunspots"></a><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">readsunspotdata</span><span class="hl-brackets">(</span><span class="hl-var">$aFile</span><span class="hl-code">, &</span><span class="hl-var">$aYears</span><span class="hl-code">, &</span><span class="hl-var">$aSunspots</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
||
</span><span class="hl-var">$lines</span><span class="hl-code"> = @</span><span class="hl-identifier">file</span><span class="hl-brackets">(</span><span class="hl-var">$aFile</span><span class="hl-code">,</span><span class="hl-identifier">FILE_IGNORE_NEW_LINES</span><span class="hl-code">|</span><span class="hl-identifier">FILE_SKIP_EMPTY_LINES</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-var">$lines</span><span class="hl-code"> === </span><span class="hl-reserved">false</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
||
</span><span class="hl-reserved">throw</span><span class="hl-code"> </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">JpGraphException</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Can not read sunspot data file.</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-brackets">}</span><span class="hl-code">
|
||
</span><span class="hl-reserved">foreach</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-var">$lines</span><span class="hl-code"> </span><span class="hl-reserved">as</span><span class="hl-code"> </span><span class="hl-var">$line</span><span class="hl-code"> => </span><span class="hl-var">$datarow</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
||
</span><span class="hl-var">$split</span><span class="hl-code"> = </span><span class="hl-identifier">preg_split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">/[\s]+/</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-var">$datarow</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-var">$aYears</span><span class="hl-brackets">[</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-identifier">substr</span><span class="hl-brackets">(</span><span class="hl-identifier">trim</span><span class="hl-brackets">(</span><span class="hl-var">$split</span><span class="hl-brackets">[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-brackets">)</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-var">$aSunspots</span><span class="hl-brackets">[</span><span class="hl-brackets">]</span><span class="hl-code"> = </span><span class="hl-identifier">trim</span><span class="hl-brackets">(</span><span class="hl-var">$split</span><span class="hl-brackets">[</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-brackets">}</span><span class="hl-code">
|
||
</span><span class="hl-brackets">}</span><span class="hl-code">
|
||
|
||
</span><span class="hl-var">$year</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-var">$ydata</span><span class="hl-code"> = </span><span class="hl-reserved">array</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-identifier">readsunspotdata</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">yearssn.txt</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-var">$year</span><span class="hl-code">,</span><span class="hl-var">$ydata</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div>
|
||
</div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>In the function above we have deviated from the common practice of not
|
||
including even the most basic error handling in examples by adding an exception
|
||
in case the data file could not be read. This is to emphasize that graph scripts
|
||
which reads data from potentially disconnected sources must have real quality
|
||
error and exception handling. As this is the first example we will not discuss
|
||
the details of the error handling other than saying that the library provides
|
||
one exception class <code class="code">JpGraphException</code> that is meant to be used by
|
||
clients to signal unrecoverable errors in the code. The full details on error
|
||
handling in the library is discussed in <a class="xref" href="ch06.html" title="Chapter 6. Error handling">Chapter 6. <i>Error handling</i></a></p>
|
||
<p>
|
||
</p><div class="tip" title="Tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3>
|
||
<p>In the library there is an auxiliary utility class
|
||
<code class="code">ReadFileData</code> to help read data from text files. In this
|
||
class there are methods to read data from a file in either of the
|
||
following formats</p>
|
||
<p>
|
||
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
||
<p> CSV (Comma Separated Values) format.
|
||
<code class="code">ReadFileData::FromCSV()</code></p>
|
||
</li><li class="listitem">
|
||
<p>two column format (almost) as we did manually above with
|
||
<code class="code">ReadFileData::From2Col()</code></p>
|
||
</li><li class="listitem">
|
||
<p>one column format
|
||
<code class="code">ReadFileData::From1Col()</code></p>
|
||
</li></ul></div><p>
|
||
</p>
|
||
</div><p>
|
||
</p>
|
||
<p>Armed with the data in the two arrays <code class="code">$year</code> and
|
||
<code class="code">$ydata</code> we will now plot the data in a basic line graph with
|
||
some variations and then show the data in a bar graph.</p>
|
||
</div>
|
||
<div class="sect2" title="A basic line graph"><div class="titlepage"><div><div><h3 class="title"><a name="id2492973"></a>A basic line graph</h3></div></div></div>
|
||
|
||
<p>As the very first start we will create a line graph which shows sun spots as a
|
||
line graph. To keep the code focused on the graph we do not include the previous
|
||
function to read the data again in the code snippet shown below. Before we get
|
||
into the code we start by briefly discuss how your script can include the
|
||
necessary library files.</p>
|
||
<p>All graph scripts must include at least two files,
|
||
<code class="filename">jpgraph.php</code> and some plot module. If we want to create
|
||
a line plot we must include <code class="filename">jpgraph_line.php</code>. Slightly
|
||
depending on the server setup and what paths are defined for PHP include files
|
||
(as discussed in <a class="xref" href="ch03s03.html#sec2.adjusting-php-include-path" title="Adjusting PHP include path">Adjusting PHP include path</a>) the include paths for the
|
||
library might look a bit different. However, we recommend that you install the
|
||
library files so they can be accessed, for example using,
|
||
<code class="code">require_once('jpgraph/jpgraph.php')</code> (since this is what is
|
||
assumed by the library examples). Furthermore, we would recommend that the
|
||
<code class="code">require_once()</code> construct is used to avoid including the same
|
||
file multiple times.</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27
|
||
28
|
||
29
|
||
30
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Width and height of the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$width</span><span class="hl-code"> = </span><span class="hl-number">600</span><span class="hl-code">; </span><span class="hl-var">$height</span><span class="hl-code"> = </span><span class="hl-number">200</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a graph instance</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Graph</span><span class="hl-brackets">(</span><span class="hl-var">$width</span><span class="hl-code">,</span><span class="hl-var">$height</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Specify what scale we want to use,</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> int = integer scale for the X-axis</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> int = integer scale for the Y-axis</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">intint</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a title for the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Sunspot example</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup titles and X-axis labels</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">(year from 1701)</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup Y-axis title</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">yaxis</span><span class="hl-code">-></span><span class="hl-identifier">title</span><span class="hl-code">-></span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">(# sunspots)</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Create the linear plot</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$lineplot</span><span class="hl-code">=</span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">LinePlot</span><span class="hl-brackets">(</span><span class="hl-var">$ydata</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Add the plot to the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Add</span><span class="hl-brackets">(</span><span class="hl-var">$lineplot</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Display the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>Before we explain this code in some more detail it is a good idea to visualize
|
||
what we get when we execute this as script. The result of running this script is
|
||
shown in <a class="xref" href="ch04s02.html#fig.sunspotsex1" title="Figure 4.3. Line plot showing the number of sun spots since 1700 (sunspotsex1.php)">Figure 4.3. Line plot showing the number of sun spots since 1700 <code class="uri"><a class="uri" href="example_src/sunspotsex1.html" target="_top">(<code class="filename">sunspotsex1.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex1"></a><p class="title"><b>Figure 4.3. Line plot showing the number of sun spots since 1700 <code class="uri"><a class="uri" href="example_src/sunspotsex1.html" target="_top">(<code class="filename">sunspotsex1.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex1.png" alt="Line plot showing the number of sun spots since 1700 (sunspotsex1.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>
|
||
</p><div class="tip" title="Tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3>
|
||
<p>You can always click on the filename in the title of a figure to view
|
||
the complete source code.</p>
|
||
</div><p>
|
||
</p>
|
||
<p>Let us now walk through this code in some details.</p>
|
||
<p>
|
||
</p><div class="variablelist"><dl><dt><span class="term">Line 1-12</span></dt><dd>
|
||
<p>The size of the graph must always be specified so the first
|
||
thing to do is to create a new graph object and set the width
|
||
and height of the overall graph. All graph scripts will need to
|
||
create at least one instance of the <code class="code">Graph()</code> class.
|
||
By convention in all our scripts we will name the created
|
||
instance of the Graph class "<code class="code">$graph</code>"..</p>
|
||
<p>The second thing that all graph scripts must specify is what
|
||
kind of scales should be used. The library supports linear,
|
||
integer, logarithmic, text and date scales. Since we know that
|
||
our data consist of only integers we keep things simple and set
|
||
both the X and the Y axis scale to be integers. The scale is
|
||
specified as a string where the first half of the string
|
||
denominates the X-axis scale and the second half denominates the
|
||
Y-axis scale. So in our example we specify
|
||
'<code class="code">intint'</code>. With this explanation you can probably
|
||
guess what '<code class="code">intlog</code>' or '<code class="code">linlog</code>' would
|
||
do. Why not try it ?</p>
|
||
</dd><dt><span class="term">Line 13-21</span></dt><dd>
|
||
<p>These lines sets some different text labels. By the naming
|
||
convention used in the library you can probably guess what all
|
||
those lines are doing. They set the overall graph title as well
|
||
as the X- and Y-axis titles. To keep the example as lean as
|
||
possible we use the default font and default size and color of
|
||
the text strings.</p>
|
||
</dd><dt><span class="term">Line 22-27</span></dt><dd>
|
||
<p>Each graph must have at least one plot (data series) that is
|
||
added to the graph. In our case we wanted to create a line graph
|
||
so we must create an instance of the class
|
||
'<code class="code">LinePlot</code>'. We create a new instance of this
|
||
class and as a parameter use the data for the data series we
|
||
want to create the line plot from, in our case the data array
|
||
with the sun spot numbers.</p>
|
||
</dd><dt><span class="term">Line 29</span></dt><dd>
|
||
<p>Understanding this single line is key to understanding dynamic
|
||
graph generation with PHP. This line instructs the library to
|
||
actually create the graph as an image, encode it in the chosen
|
||
image format (e.g. png, jpg, gif, etc) and stream it back to the
|
||
browser with the correct header identifying the data stream that
|
||
the client receives as a valid image stream. When the client
|
||
(most often a browser) calls the PHP script it will return data
|
||
that will make the browser think it is receiving an image and
|
||
not, as you might have done up to now from PHP scripts, text. </p>
|
||
<p>This is something that can be conceptually difficult to fully
|
||
understand at first and that is why we are spending the entire
|
||
next chapter <a class="xref" href="ch05.html" title="Chapter 5. Fundamentals of dynamic graph generation">Chapter 5. <i>Fundamentals of dynamic graph generation</i></a> on further exploring
|
||
this. But for now please accept that this works and by calling
|
||
the script above in your browser (it is available in the
|
||
"<code class="filename">Examples/</code>" directory in the
|
||
distribution as '<code class="filename">sunspotsex1.php</code>') you
|
||
should get the exact same image as shown above in <a class="xref" href="ch04s02.html#fig.sunspotsex1" title="Figure 4.3. Line plot showing the number of sun spots since 1700 (sunspotsex1.php)">Figure 4.3. Line plot showing the number of sun spots since 1700 <code class="uri"><a class="uri" href="example_src/sunspotsex1.html" target="_top">(<code class="filename">sunspotsex1.php</code>)</a></code> </a></p>
|
||
</dd></dl></div><p>
|
||
</p>
|
||
<p>Let's now make a small variation of the above line graph. Let's make it a
|
||
filled line graph. instead. In order to do this we only have to add one single
|
||
line</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-var">$lineplot</span><span class="hl-code">-></span><span class="hl-identifier">SetFillColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">orange@0.5</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>The line above actually does two things. First it sets the basic color to
|
||
'orange' and then it modifies this color to be 50% opaque (0.5) which makes the
|
||
grid line shine through the fill color to some extent. The whole color handling
|
||
in the library is further describe both in <a class="xref" href="apd.html" title="Appendix D. Named color list">Appendix D. <i>Named color list</i></a> as well as in <a class="xref" href="ch07.html" title="Chapter 7. Color handling">Chapter 7. <i>Color handling</i></a>. The result of adding the line above is
|
||
shown in <a class="xref" href="ch04s02.html#fig.sunspotsex2" title="Figure 4.4. Displaying sun spots with a semi filled line graph (sunspotsex2.php)">Figure 4.4. Displaying sun spots with a semi filled line graph <code class="uri"><a class="uri" href="example_src/sunspotsex2.html" target="_top">(<code class="filename">sunspotsex2.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex2"></a><p class="title"><b>Figure 4.4. Displaying sun spots with a semi filled line graph <code class="uri"><a class="uri" href="example_src/sunspotsex2.html" target="_top">(<code class="filename">sunspotsex2.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex2.png" alt="Displaying sun spots with a semi filled line graph (sunspotsex2.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
<div class="sect3" title="Adding tick labels to the X-axis"><div class="titlepage"><div><div><h4 class="title"><a name="id2493501"></a>Adding tick labels to the X-axis</h4></div></div></div>
|
||
|
||
<p>
|
||
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3>
|
||
<p>This section can be skipped at first reading since it contains
|
||
some slightly more advanced material. The reason why we have
|
||
included this section already now is that some of the issues
|
||
discussed here is an often repeated question among newcomers to the
|
||
library.</p>
|
||
</div><p>
|
||
</p>
|
||
<p>There is one bit of the available data that we haven't used yet and that
|
||
is the actual years. In the example above we can only see the count from
|
||
1700. (If we just want to look at the cyclic behaviour of the number of
|
||
sunspots this is fine since what year a specific number of sunspots appeared
|
||
is not relevant.) To make it easier to see what year corresponds to the
|
||
different sunspot numbers we must change the label on the X-axis scale to
|
||
show the years instead.</p>
|
||
<p>There is actually a couple of ways to do this. The easiest way is to just
|
||
add the labels we have (<code class="code">$years</code>) on the X-axis and instruct the
|
||
library to use them instead. This is done with a call to the method
|
||
<code class="code">SetTickLabels()</code> on the X-axis. This method call takes an
|
||
array as argument and uses the values in that array to populate all labels
|
||
on major tick marks. In order to make adequate room for the scale the
|
||
library automatically selects a suitable distance between each major tick
|
||
mark.</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetTickLabels</span><span class="hl-brackets">(</span><span class="hl-var">$year</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>Adding this line to our previous graph will generate the graph shown in <a class="xref" href="ch04s02.html#fig.sunspotsex3" title="Figure 4.5. Adding tick labels to the graph (sunspotsex3.php)">Figure 4.5. Adding tick labels to the graph <code class="uri"><a class="uri" href="example_src/sunspotsex3.html" target="_top">(<code class="filename">sunspotsex3.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex3"></a><p class="title"><b>Figure 4.5. Adding tick labels to the graph <code class="uri"><a class="uri" href="example_src/sunspotsex3.html" target="_top">(<code class="filename">sunspotsex3.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex3.png" alt="Adding tick labels to the graph (sunspotsex3.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>However, there is a problem in the graph above. There are valid years on
|
||
the X-axis up to "2000" but then there is a single label "320". </p>
|
||
<p><span class="bold"><strong>What is going on here?</strong></span> Have we already discovered
|
||
a bug in the library? </p>
|
||
<p>No, not really. In the way we have setup the graph we have not provided
|
||
the library with enough labels. What has happened is that the integer scale
|
||
has chosen a suitable interval between each tick label to have enough space
|
||
to be able to show the labels. As can be seen from the figure the distance
|
||
chosen with this particular graph seems to be 20 years between each tick.
|
||
The way the default labeling works is that the end tick should be labelled
|
||
and hence be an even multiple of 20 years (in this case).</p>
|
||
<p>Since the library needs to have tick labels for all ticks it uses the
|
||
labels we supplied as far as they go (up to 2008) but since we didn't supply
|
||
data more than up to "2008" (in the <code class="code">$year</code> array) the library
|
||
does what it can do and continues with the ordinal numbers where we failed
|
||
to provide enough labels.</p>
|
||
<p>Now, there are a some standard ways of correcting this abomination.</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>We can set a manual scale to make sure the scale ends exactly
|
||
at 2008, i.e. the scale is exactly as long as our data. This is
|
||
done by submitting the wanted scale min/max as additional
|
||
argument in the <code class="code">SetScale()</code> method. First the
|
||
min/max for the Y-axis and then the min/max for the X-scale.
|
||
Since we still want the Y-scale to be fully automatically
|
||
determined we just put a "0" for both min and max on the Y-scale
|
||
and specify 0 for the min x-value and then the exact number of
|
||
sunspots we have measured as the maximum x-value.</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">intint</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-identifier">max</span><span class="hl-brackets">(</span><span class="hl-var">$year</span><span class="hl-brackets">)</span><span class="hl-code">-</span><span class="hl-identifier">min</span><span class="hl-brackets">(</span><span class="hl-var">$year</span><span class="hl-brackets">)</span><span class="hl-code">+</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>The result of this is shown in <a class="xref" href="ch04s02.html#fig.sunspotsex4" title="Figure 4.6. Manually specifying the X scale to use just the supplied X values (sunspotsex4.php)">Figure 4.6. Manually specifying the X scale to use just the supplied X values <code class="uri"><a class="uri" href="example_src/sunspotsex4.html" target="_top">(<code class="filename">sunspotsex4.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex4"></a><p class="title"><b>Figure 4.6. Manually specifying the X scale to use just the supplied X values <code class="uri"><a class="uri" href="example_src/sunspotsex4.html" target="_top">(<code class="filename">sunspotsex4.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex4.png" alt="Manually specifying the X scale to use just the supplied X values (sunspotsex4.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
</li><li class="listitem">
|
||
<p>An alternative way to get labels is to use a callback function
|
||
to specify the labels. This works so that the library calls the
|
||
user specified function and as argument passes the label (or the
|
||
value of the label) that the library intends to put on a tick.
|
||
The library will then use as the actual label whatever string
|
||
value we return from our function. Since we know that the
|
||
integer label 0 (the first tick) corresponds to the first value,
|
||
i.e. "1700" we can simply take whatever label we get as
|
||
argument, add "1700" and return that value. This way all labels
|
||
will be properly named and even if the scale extends far beyond
|
||
where we have data a sensible tick label will be shown.</p>
|
||
<p>A suitable callback function together with the method to
|
||
instruct the library to use this callback would be</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Label callback</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">year_callback</span><span class="hl-brackets">(</span><span class="hl-var">$aLabel</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code">
|
||
</span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">1700</span><span class="hl-code">+</span><span class="hl-brackets">(</span><span class="hl-identifier">int</span><span class="hl-brackets">)</span><span class="hl-var">$aLabel</span><span class="hl-code">;
|
||
</span><span class="hl-brackets">}</span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">xaxis</span><span class="hl-code">-></span><span class="hl-identifier">SetLabelFormatCallback</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">year_callback</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>and the result can be seen in <a class="xref" href="ch04s02.html#fig.sunspotsex5" title="Figure 4.7. Using a callback to get correct values on the x axis (sunspotsex5.php)">Figure 4.7. Using a callback to get correct values on the x axis <code class="uri"><a class="uri" href="example_src/sunspotsex5.html" target="_top">(<code class="filename">sunspotsex5.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex5"></a><p class="title"><b>Figure 4.7. Using a callback to get correct values on the x axis <code class="uri"><a class="uri" href="example_src/sunspotsex5.html" target="_top">(<code class="filename">sunspotsex5.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex5.png" alt="Using a callback to get correct values on the x axis (sunspotsex5.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
</li><li class="listitem">
|
||
<p>There is one more way to handle this issue which we will not
|
||
cover in detail yet. This is to use a "text" scale. The
|
||
"text"scale can be used when there is no need to show numeric
|
||
values on the axis. A typical use for text scale would be to add
|
||
labels to mark bar graphs. Of course a text can contain numeric
|
||
strings that would make it visually indistinguishable from a
|
||
"real" numeric value.</p>
|
||
<p>For text scales every label counts. So by default the library
|
||
will assign a tick mark for each ordinal so that every label is
|
||
used. In some cases this will just be two dense and then the
|
||
tick and the labelling can be adjusted by calling the two
|
||
methods <code class="code">Axis::SetTextTickInterval()</code> and
|
||
<code class="code">Axis::SetTextLabelInterval()</code> to get to a wanted
|
||
result. But for now we do not discuss this technique further
|
||
here since it would bring too far.</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="sect2" title="A basic bar graph"><div class="titlepage"><div><div><h3 class="title"><a name="id2493198"></a>A basic bar graph</h3></div></div></div>
|
||
|
||
<p>As a final illustration we will show how easy it is to change the plot type.
|
||
We will make a small modification of the previous script and display the sun
|
||
spots as a bar graph instead. In order to do this we take the code from <a class="xref" href="ch04s02.html#fig.sunspotsex2" title="Figure 4.4. Displaying sun spots with a semi filled line graph (sunspotsex2.php)">Figure 4.4. Displaying sun spots with a semi filled line graph <code class="uri"><a class="uri" href="example_src/sunspotsex2.html" target="_top">(<code class="filename">sunspotsex2.php</code>)</a></code> </a> and just change the creation of an instance
|
||
of the <code class="code">LinePlot()</code> class to instead be an instance of the
|
||
<code class="code">BarPlot()</code> class (to make the code more readable we also change
|
||
the name of the variable where we store the instance so it makes more sense). In
|
||
order to use this class we must also change the include statement so that the
|
||
bar module is included by adding the statement
|
||
<code class="code">require_once('jpgraph/jpgraph_barplot.php')</code>. The changed code
|
||
would now look like this</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Create the bar plot</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$barplot</span><span class="hl-code">=</span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">BarPlot</span><span class="hl-brackets">(</span><span class="hl-var">$ydata</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Add the plot to the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Add</span><span class="hl-brackets">(</span><span class="hl-var">$barplot</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Display the graph</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>and would result in the graph displayed in <a class="xref" href="ch04s02.html#fig.sunspotsex6" title="Figure 4.8. Changing the plot type to a bar plot instead (sunspotsex6.php)">Figure 4.8. Changing the plot type to a bar plot instead <code class="uri"><a class="uri" href="example_src/sunspotsex6.html" target="_top">(<code class="filename">sunspotsex6.php</code>)</a></code> </a></p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex6"></a><p class="title"><b>Figure 4.8. Changing the plot type to a bar plot instead <code class="uri"><a class="uri" href="example_src/sunspotsex6.html" target="_top">(<code class="filename">sunspotsex6.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex6.png" alt="Changing the plot type to a bar plot instead (sunspotsex6.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>Since there are so many bars in small space we cannot see the individual bars
|
||
in the example in <a class="xref" href="ch04s02.html#fig.sunspotsex6" title="Figure 4.8. Changing the plot type to a bar plot instead (sunspotsex6.php)">Figure 4.8. Changing the plot type to a bar plot instead <code class="uri"><a class="uri" href="example_src/sunspotsex6.html" target="_top">(<code class="filename">sunspotsex6.php</code>)</a></code> </a>. So lets modify the script so that it only
|
||
shows the last 20 years of measurements so that we can see the individual bars.
|
||
To set this up there are two things we must do</p>
|
||
<p>
|
||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
|
||
<p>Change the scale ot a text scale since we want to make sure each
|
||
value is displayed. In addition the text scale actually changes one
|
||
more thing that we haven't mentioned. Using a text scale also
|
||
changes the alignment of the labels. For linear, integer,
|
||
logarithmic scales the labels are placed cantered below the tick
|
||
marks. For text labels they are instead place in between the tick
|
||
marks. This is the most common way of displaying bar graphs. This is
|
||
one more reason to think of text scales as a special scale mostly
|
||
suitable for bar graphs.</p>
|
||
</li><li class="listitem">
|
||
<p>Add two lines of code to "chop off" the extra not wanted data in
|
||
the input data arrays.</p>
|
||
</li></ol></div><p>
|
||
</p>
|
||
<p>The following code snippet shows the necessary modifications to the previous
|
||
script</p>
|
||
<p>
|
||
</p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags"><?php</span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Just keep the last 20 values in the arrays</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$year</span><span class="hl-code"> = </span><span class="hl-identifier">array_slice</span><span class="hl-brackets">(</span><span class="hl-var">$year</span><span class="hl-code">, -</span><span class="hl-number">20</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
</span><span class="hl-var">$ydata</span><span class="hl-code"> = </span><span class="hl-identifier">array_slice</span><span class="hl-brackets">(</span><span class="hl-var">$ydata</span><span class="hl-code">, -</span><span class="hl-number">20</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> Specify what scale we want to use,</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> text = txt scale for the X-axis</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> int = integer scale for the Y-axis</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-var">$graph</span><span class="hl-code">-></span><span class="hl-identifier">SetScale</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">textint</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
|
||
|
||
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
|
||
</span><span class="hl-inlinetags">?></span></pre></td></tr></table></div><p>
|
||
</p>
|
||
<p>The final graph with the "zoomed" last 20 years can now be seen in</p>
|
||
<p>
|
||
</p><div class="figure"><a name="fig.sunspotsex7"></a><p class="title"><b>Figure 4.9. Sunspots zoomed to only show the last 20 years <code class="uri"><a class="uri" href="example_src/sunspotsex7.html" target="_top">(<code class="filename">sunspotsex7.php</code>)</a></code> </b></p><div class="figure-contents"> <span class="inlinemediaobject"><img src="images/sunspotsex7.png" alt="Sunspots zoomed to only show the last 20 years (sunspotsex7.php)"></span> </div></div><p><br class="figure-break">
|
||
</p>
|
||
<p>Since the scale is larger we can now actually see the individual bars. By
|
||
default the library choses a light blue color to fill the interior. (Try to see
|
||
what happens if you add the method call
|
||
"<code class="code">$barplot->SetFillColor('orange@0.5');</code>" just after the
|
||
"<code class="code">$barplot</code>" variable has been assigned the new BarPlot
|
||
object.)</p>
|
||
</div>
|
||
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch04.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|