
最近かなり暑いね。熱中症も心配だ。
ある日、上司からそんな話とともに依頼が飛んできました。

今度の月次職場安全衛生委員会で使う資料、気温と湿度からどのくらい不快かが一目で分かるヒートマップにできない?

あとで1℃刻みじゃなくて0.1℃刻みにしたいとか、表示範囲を変えたいとか要望があるかもしれない。ExcelよりPower BIで作ってみてくれる?
本来、熱中症リスクを測るならWBGT(暑さ指数)を使うのが正攻法です。ただしWBGTは気温・湿度だけでなく日射や風、放射熱まで考慮する必要があります。そこで、今回は気温と湿度だけで計算できる「不快指数」を使用しました
完成イメージはこちらです。

以下、作り方を手順ごとにみていきます。
気温・湿度のマスターデータを作る
Power Queryで気温と湿度の一覧を用意します。
使ったのはList.Numbersだけです。
let
開始値 = 0,
終了値 = 45,
刻み幅 = 1,
個数 = Number.RoundUp((終了値 - 開始値) / 刻み幅) + 1,
Source = List.Numbers(開始値, 個数, 刻み幅),
Table=Table.FromList(Source, Splitter.SplitByNothing(), {"気温"})
in
Table
気温は0〜45℃を1℃刻みで作成しています。
湿度も同じ要領で作成します。
List.Numbersにしておくと、あとで「0.5℃刻みにしたい」「湿度は20〜100%だけでいい」と言われても、数値を書き換えるだけで済みます。上司の「あとで刻み幅や範囲を変えるかも」という要望に簡単に対応できます。
気温と湿度をクロス結合する
気温クエリに湿度クエリを列として追加し、展開します。
これを展開すると、以下のような表ができます。
| 気温 | 湿度 |
|---|---|
| 20 | 0 |
| 20 | 2 |
| 20 | 4 |
| … | … |
| 45 | 100 |
こうして全組み合わせのテーブルができます。Power Queryでいうクロス結合です。
気温クエリの名前を
気温×湿度
へ変更しておきます。
不快指数を計算する
計算式はこちらを使いました。
不快指数 = 0.81×気温 + 0.01×湿度×(0.99×気温−14.3) + 46.3
Power Queryのカスタム列として追加すれば、気温・湿度の全組み合わせに対して不快指数が一括で計算されます。
今回は、簡単のため不快指数を整数値として設定するよう、Number.Round関数を用いて小数点以下を四捨五入しています。

マトリックスでヒートマップにする
Power BIの視覚化、「マトリックス」ビジュアルを使い、
- 行:湿度
- 列:気温
- 値:不快指数
として表を作成します。
また、範囲指定するために、気温と湿度は「スライサー」に設定します。

数字だけの羅列では傾向が直感的に見えないため、ここに条件付き書式で色をつけていきます。
色はDAXテーブルで一元管理する
条件付き書式の「ルール」を都度設定してもいいのですが、それだと
- 色を変えたい
- しきい値を変えたい
- 凡例も同じ色にしたい
となるたびに、複数個所を修正する必要があります。修正漏れも起きやすくエラーの原因となります。
そこで、色のルールをDAXの1テーブルとしてまとめました。
色しきい値 =
DATATABLE(
"順序", INTEGER,
"下限", DOUBLE,
"上限", DOUBLE,
"色", STRING,
"ラベル", STRING,
"範囲", STRING,
{
{1, -999, 70, "#6BAED6", "快適", "70未満"},
{2, 70, 75, "#8FBC8F", "やや不快", "70-74"},
{3, 75, 80, "#E8B84B", "半数不快", "75-79"},
{4, 80, 85, "#E0793C", "大多数不快", "80-84"},
{5, 85, 999, "#C0504D", "全員不快", "85以上"}
}
)

下限・上限・色(HEX)・ラベル・表示用の範囲文字列を1行にまとめて持たせています。
この表から、現在の不快指数に対応する色を返すMeasureを作ります。
色_マトリクス =
VAR v = ROUND(AVERAGE('気温×湿度'[不快指数]), 0)
RETURN
CALCULATE(
SELECTEDVALUE('色しきい値'[色]),
FILTER('色しきい値', v >= '色しきい値'[下限] && v < '色しきい値'[上限])
)

ポイントは変数 v を ROUND で丸めていることです。表示されている数値(四捨五入後)と、色判定に使う数値がズレていると、「見た目は “70” なのに色は ”快適” のまま」というずれた結果になります。表示用と判定用の丸めは必ず揃えておく必要があります。
条件付き書式を設定するため、
セル要素→背景色→fx と選択し、
「スタイルの書式設定」を”フィールド値“、
「基準にする値」を先程作成したMeasure “色_マトリクス“とします。


これで色のルールが作成されました。

凡例は作成したDAXテーブルから作る
Power BIでヒートマップを作成しても、凡例は自動で作成されません。
そのため、色しきい値テーブルを用いて凡例を作成します。ラベルと範囲の列を「テーブル」ビジュアルで並べ、背景色の条件付き書式で色しきい値[色]列を直接参照させます。



ここで一つ注意点があります。
マトリクス側は色_マトリクスというMeasureを参照していますが、
凡例側でこのMeasureをそのまま使うとうまくいきません。
凡例テーブルには気温・湿度という行コンテキストが存在しないため、Measure内の[不快指数]が計算できず、意図しない挙動になります。凡例側はMeasureではなく色しきい値[色]列そのものを基準にするとうまく色が表示されます。
マトリックスと凡例が同じテーブルの色(’色しきい値’[色])を見にいく形にしておけば、’色しきい値’テーブルの ”しきい値” や ”色” を変えても両者が自動で追従します。片方だけ直し忘れる、というミスがなくなります。

この作り方は他のデータにも使える
今回は気温×湿度でしたが、構造としては「独立した2つの数値を掛け合わせて、第三の指標を導く」というものです。この形に当てはまるデータであれば、同じ手法がそのまま使えます。
- 単価×販売数量 → 売上高(価格改定や販促のシミュレーション表に)
- 利益率×売上高 → 利益額(事業計画のシナリオ比較に)
- 借入金利×返済期間 → 総返済額(ローンの試算表に)
- 残業時間×人数 → 想定人件費(人員計画の試算に)
逆に、片方の数値がもう片方から一意に決まってしまう組み合わせ(例:年収と手取り額)は、2軸のマトリクスにする意味がないので向きません。「2つの独立変数を、式で掛け合わせて第三の値を出す」という条件に当てはまるかどうかが、この手法を使えるかの判断基準になります。
まとめ
Power BIで気温×湿度の不快指数ヒートマップを作った手順を紹介しました。ポイントは3つです。
List.Numbersで、後から刻み幅や範囲を変えやすいマスターデータを作ること- Power Queryのクロス結合で全組み合わせのテーブルを作ること
- 条件付き書式の色をDAXの1テーブルに集約し、マトリクスと凡例で色を共有すること
数字の羅列では気づきにくい傾向も、ヒートマップにすると一目で伝わります。委員会資料のような「パッと見て分かってほしい」場面では特に効果を発揮します。今回のような環境データに限らず、売上や人件費の試算表にも応用できるので、手元のデータで一度試してみてください。






コメント