PHPで平均余命の伸び率をグラフ表示

(1/1)
厚生労働省は毎年、簡易生命表を発表している。男女とも、平均寿命はどんどん伸びている。
一方、身の回りで振り返ると他界した同期も少なくなく、年齢階層別の平均余命の伸びはどうなっているのだろうか、と疑問を感じた。
そこで、厚労省のデータを使って、「PHP で NHK 政治意識月例調査をグラフ表示」で作った PHP プログラムをベースに、平均余命の伸び率を暗く表示させてみることにする。

(2020 年 2 月 22 日)平成 30 年度簡易生命表に対応。
(2019 年 7 月 14 日)平成 29 年度簡易生命表に対応。

サンプル・プログラムの実行例

PHPで平均余命の伸び率をグラフ表示
男性の、年齢階層別の伸び率をグラフにしてみると、20 歳、40 歳の伸び率は、平均寿命の伸び率を下回っている。65 歳以上の高齢者の伸び率が平均寿命を押し上げているのだ。
女性で見ると、さらに顕著だ。年齢が高くなるに伴って、ますます長生きすることが見て取れる。
20~30 代の死因の上位は、自殺、事故であるから、これらを減らせば、平均寿命は更に伸びるのではないだろうか。

サンプル・プログラム

圧縮ファイルの内容
viewLifeExpectancy.phpサンプル・プログラム本体
LifeExpectancy.csv簡易生命表データファイル

解説:準備

0028: //グラフの表示幅・高さ(単位:ピクセル)
0029: define('WIDTH',  600);
0030: define('HEIGHT', 600);
0031: 
0032: //jqPlotのあるフォルダ
0033: define('JQPLOT', '../../../../common/jqplot/');
0034: 
0035: //データファイル名
0036: define('DATA_FILE', './LifeExpectancy.csv');

折れ線グラフを描くのに、jQuery プラグイン「jqPlot」を利用する。
公式サイト「jqPlot Charts and Graphs for jQuery」から圧縮ファイルをダウンロードし、適当な場所に解凍しておく。その場所を定数 JQPLOT に定義する。

また、厚生労働省「平成 30 年簡易生命表」に掲載されている図表データから、1947 年(昭和 22 年)以降の毎年の平均余命の推移を元に、データファイル "LifeExpectancy.csv" を用意した。カラム区切りはタブである。
これを読み込んで、プログラム内で伸び率を計算、グラフ表示させる。
データファイルの構造
西暦年 平均余命
男性 女性
0歳 20歳 40歳 65歳 75歳 90歳 0歳 20歳 40歳 65歳 75歳 90歳

解説:jqPlotスクリプト

0241: /**
0242:  * jqPlot用のスクリプト:下請け
0243:  * @param array  $items データ配列
0244:  * @param string $category 種別
0245:  * @return string スクリプト
0246: */
0247: function plotSub($items$category) {
0248:     //プロットするデータ
0249:     switch ($category) {
0250:         case 'zero':
0251:             $table  = array('男性', '女性');
0252:             $colors = array('blue', 'red');       //グラフの色
0253:             break;
0254:         default:
0255:             $table  = array('0歳', '20歳', '40歳', '65歳', '75歳', '90歳');
0256:             $colors = array('cyan', 'green', 'blue', 'red', 'purple', 'orange');
0257:             break;                               //グラフの色
0258:     }
0259: 
0260:     //系列の生成
0261:     $str2 = '';
0262:     foreach ($table as $key=>$val) {
0263:         $str2 .= "\t\t\t{ label: '{$val}', color: '{$colors[$key]}' },\n";
0264:         $series[] = '';
0265:     }
0266: 
0267:     $year_min = 9999;
0268:     $year_max = 0;
0269:     foreach ($items as $year=>$val) {
0270:         if ($year < $year_min)      $year_min = $year;       //X軸の最小値
0271:         if ($year > $year_max)      $year_max = $year;       //X軸の最大値
0272:         if ($category == 'male') {
0273:             for ($key = 0; $key < 6; $key++) {
0274:                 $series[$key] .= sprintf("['%04d-01-01', %4.1f],", $year$val[$key]);
0275:             }
0276:         } else if ($category == 'female') {
0277:             for ($key = 6; $key < 12; $key++) {
0278:                 $series[$key - 6] .= sprintf("['%04d-01-01', %4.1f],", $year$val[$key]);
0279:             }
0280:         } else {
0281:             $series[0] .= sprintf("['%04d-01-01', %4.1f],", $year$val[0]);
0282:             $series[1] .= sprintf("['%04d-01-01', %4.1f],", $year$val[6]);
0283:         }
0284:     }
0285:     $year_min = floor($year_min / 5) * 5;
0286:     $year_max = ceil($year_max / 5) * 5;
0287: 
0288:     $str1 = '';
0289:     foreach ($series as $val) {
0290:         $str1 .= "\t\t[ " . $val . "],\n";
0291:     }
0292: 
0293: $js =<<< EOD
0294: jQuery(function() {
0295:     jQuery.jqplot('jqPlot_polls',
0296:     [
0297: {$str1}
0298:     ],
0299:     {
0300:         //系列
0301:         series: [
0302: {$str2}
0303:         ],
0304:         legend: {
0305:             show: true,
0306:             placement: 'inside',
0307:             location: 'nw',
0308:             renderer: $.jqplot.EnhancedLegendRenderer,
0309:             rendererOptions: { numberRows: 1 }
0310:         },
0311:         seriesDefaults: {
0312:             showLine: true,
0313:             rendererOptions: { smooth: false },
0314:             markerOptions: { size: 0 },
0315:         },
0316:         //軸
0317:         axes: {
0318:             xaxis: {
0319:                 renderer:$.jqplot.DateAxisRenderer,
0320:                 tickOptions: { formatString: '%Y' },
0321:                 label: '西暦年',
0322:                 min: '{$year_min}-01-01',
0323:                 max: '{$year_max}-12-31',
0324:             },
0325:             yaxis: {
0326:                 label: '伸び率'
0327:             }
0328:         },
0329:         //ハイライター
0330:         highlighter: {
0331:             show: true,
0332:             showMarker: true,
0333:             tooltipLocation: 'sw',
0334:             fadeTooltip: false,
0335:             bringSeriesToFront: true,
0336:             tooltipAxes: 'xy',
0337:             formatString: '%s年<br />伸び率%s'
0338:         }
0339:     }
0340:     );
0341: });
0342: 
0343: EOD;
0344: 
0345:     return $js;
0346: }

0348: /**
0349:  * jqPlot用のスクリプト:男性
0350:  * @param array $items データ配列
0351:  * @return string スクリプト
0352: */
0353: function plotMale($items) {
0354:     return plotSub($items, 'male');
0355: }

0357: /**
0358:  * jqPlot用のスクリプト:女性
0359:  * @param array $items データ配列
0360:  * @return string スクリプト
0361: */
0362: function plotFemale($items) {
0363:     return plotSub($items, 'female');
0364: }

0366: /**
0367:  * jqPlot用のスクリプト:0歳余命
0368:  * @param array $items データ配列
0369:  * @return string スクリプト
0370: */
0371: function plotZero($items) {
0372:     return plotSub($items, 'zero');
0373: }

ここでは、jqPlot プラグインの「jqplot.dateAxisRenderer.js」(時間軸を扱う)、「jqplot.highlighter.js」(ツールチップなどハイライト表示を行う)、「jqplot.pointLabels.js」(データポイントラベルを表示する)の 3 つを使っている。
jqPlot の使い方は、「jqPlot - jQuery プラグイン」(アルファシス)が詳しい。

男性、女性、0 歳余命は、伸び率を格納しているデータ配列 $items から表示させる要素が違うだけなので、下請け関数 plotSub 内で場合分けしてスクリプトを発生させるように下。

参考サイト

(この項おわり)
header