<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Pottal-Portal 3.0</title>
<link>https://pottal-portal.com/PtPr3/</link>
<atom:link href="https://pottal-portal.com/PtPr3/index.xml" rel="self" type="application/rss+xml"/>
<description>新しい世界へ誘うPortalになりたい</description>
<image>
<url>https://pottal-portal.com/cover_Lite.png</url>
<title>Pottal-Portal 3.0</title>
<link>https://pottal-portal.com/PtPr3/</link>
<height>144</height>
<width>144</width>
</image>
<generator>quarto-1.7.20</generator>
<lastBuildDate>Sun, 07 Jul 2024 15:00:00 GMT</lastBuildDate>
<item>
  <title>【改訂版】EXP21レンタルレビュー</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Refresh/exp21.html</link>
  <description><![CDATA[ 




<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<div class="callout callout-style-default callout-important callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
この記事は、ASUS JAPAN様から製品のお貸出しを受けて書かれたものです。
</div>
</div>
<div class="callout-body-container callout-body">
<p>私Pottal及び弊ブログPottal-PortalはASUS信者でありASUS製品に関しては愛ゆえに厳しく評価いたします。たとえPR記事であっても提灯記事は書きません。<br> また、ASUS JAPAN様から内容に当たっては特に指定を受けていないため、タイトルに「PR」の文字は入れていません。<br> なお、この記事の執筆にあたって、ASUS様との間に一切の金銭関係は発生しておりません。(私の方から企画を提案したものであり、報酬金などは頂いておりません。愛です。)</p>
</div>
</div>
<p>以下、文体が変わります。</p>
<hr>
<section id="改訂にあたって" class="level2">
<h2 class="anchored" data-anchor-id="改訂にあたって">改訂にあたって:</h2>
<p>本記事は、はてなブログにて運営していたPottal-Portalにて掲載していたEXP21のレビューを(Pottal-Portal 3.0 へのリニューアルにあたって)改訂したものである。当初の記事は5万字を超えた長々としたレビューであり読み難いものであったが、Pottal-Portal 3.0 の採用するQuarto1.4の機能を用いることで、読み難さを多少なりとも改善できると考えたため、改訂を行った。なお、改訂後の文字数はソースコード含めて10万字となった。</p>
<p><a href="../../post_images/EXP21サムネ用.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/EXP21サムネ用.png" class="img-fluid"></a></p>
<hr>
<p>長々と前説をしてしまったので、ここからは端的にレビューをしていく。</p>
<p>まず、今回レビューするEXP21だが、正式名称は「Smartphone for Snapdragon Insiders (ZS675KW-BL512R16)」となる。（長いので今後はEXP21と呼ぶ。）</p>
<div id="fig-EXP21_Smartphone_info" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Smartphone_info-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116080542.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="図&nbsp;1: 端末名はEXP21 Smartphoneとなっている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116080542.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Smartphone_info-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: 端末名はEXP21 Smartphoneとなっている
</figcaption>
</figure>
</div>
<p>Smartphone for Snapdragon Insidersシリーズ（？）の中のEXP21ということなのだろう。</p>
<p>また、製品版と異なり提供用のモデルとなるため、製品版とは異なる仕様がある恐れがある。実際、VoLTEが使えず音声通話の発着信が行えないという不具合がみられた。ASUS JAPANに確認したところ、この症状は試供用モデルの日本向けOS書き換え不良によるものとのことで、後日、正常な日本版OSのものをレンタルさせていただくこととなった。</p>
<p>さて、気を取り直してレビューを始めていこう。なお、このレビュー記事は愛ゆえに長い。まずは目次で全体の内容を確認し概要を把握した上で、気になる項目を読むという形を推奨する。</p>
<p>(記事を項目ごとに分割しアクセス数を稼ぐということはしたくなかったため、あくまで1つの記事にまとめている。広告収入等を考えるとスマートではないが、筆者のように通読したいという人の気持ちを尊重した。)</p>
<p>なお、この記事で公開している作例や多くの検証結果は<a href="https://drive.google.com/drive/folders/1MAgb__o8NL7pX-L42Zp_PWyBx46Ncy-R?usp=sharing">Google Driveにて完全版を公開している。</a>詳細が気になる方はそちらをご覧頂ければ幸いだ。</p>
<section id="目次" class="level3">
<h3 class="anchored" data-anchor-id="目次">目次</h3>
<ul>
<li>改訂にあたって:
<ul>
<li>目次</li>
<li>これは何？</li>
<li>EXP21の開封の儀: 付属品の確認とフォトレビューで外観をチェック
<ul>
<li>EXP21の付属品について
<ul>
<li>バンパーケースについて</li>
<li>65W HyperCharge対応急速充電器及びTypeC to C ケーブルについて</li>
<li>ワイヤレスイヤフォンについて</li>
<li>その他の付属品に関して</li>
</ul></li>
<li>EXP21フォトレビュー:存在感を放つSnapdragonロゴ
<ul>
<li>EXP21の背面について:Snapdragonここに在り</li>
<li>側面について:おそらくプラスチック製だが、安っぽさはない。</li>
<li>前面について:ノッチやパンチホールはなし。</li>
<li>プリインストールアプリ等の確認</li>
</ul></li>
</ul></li>
<li>最強なスペックを確認:Qualcommの全てを詰め込んでみせたASUSの信頼性と技術力の高さ
<ul>
<li>EXP21のスペック</li>
</ul></li>
<li>EXP21の良いところ
<ul>
<li>◎綺麗/便利なカメラ</li>
<li>◎最新のゲーミングスマホに引けを取らないマシンスペック</li>
<li>◎512GBと大容量かつ高速な内蔵ストレージ</li>
<li>◎万が一の時も安心なQualcomm QuickCharge5.0急速充電</li>
<li>◎普段は充電速度や電池持ち残量を制御し「長く使う」選択肢も選べるASUSらしさ</li>
<li>◎音質良し接続性良しの完全ワイヤレスイヤフォン付属</li>
<li>◎抜群なアンテナ感度と通信速度</li>
<li>◎綺麗かつヌルヌル動く動くディスプレイ</li>
<li>○AOSP（ピュアAndroid）っぽいUI</li>
<li>○指紋や顔認証の「速度」や「精度」は良い</li>
<li>○デュアルフロントではないものの本体スピーカーの質も良い</li>
</ul></li>
<li>EXP21のイマイチなところ
<ul>
<li>△防水非対応</li>
<li>△指紋センサーが「指紋認証」にしか使えない</li>
<li>△有線接続でのファイル転送が遅い</li>
<li>△3.5mmオーディオジャック非搭載</li>
<li>△microSDカードスロット非搭載</li>
<li>△「片手モード」が使いにくい</li>
<li>△デカくて重い</li>
<li>△ワイヤレス充電非対応</li>
<li>✕マニュアル撮影出来ないカメラ</li>
<li>✕指紋センサーの見つけにくさ</li>
<li>✕ゲームに便利なASUS独自機能「Game Genie」非対応</li>
<li>✕rootを取らなきゃ電測には向かない</li>
<li>✕無意味に光るだけのSnapdragonロゴ</li>
</ul></li>
<li>処理性能について:これだけ詰め込んで熱暴走せず、性能も大きく損なわないのは流石
<ul>
<li>10連続AnTuTuベンチマーク結果
<ul>
<li>ベンチマークスコアの解釈</li>
<li>バッテリー温度≒内部温度について</li>
<li>背面及びディスプレイの温度について:放熱システムを探る</li>
</ul></li>
</ul></li>
<li>カメラについて:とても綺麗に撮れるが「撮影は楽しめない」
<ul>
<li>EXP21メインカメラ</li>
<li>EXP21 超広角カメラ</li>
<li>EXP21 望遠カメラ</li>
<li>EXP21のカメラは「マニュアル撮影」が出来ない。</li>
<li>余談:AIシーン認識による補正差について</li>
</ul></li>
<li>カメラについて その2:ASUSスマホを用いた「ハード」と「ソフト」の比較
<ul>
<li>「飯テロ」性能</li>
<li>風景(メイン、超広角、3倍望遠or電子ズーム)
<ul>
<li>メインカメラの風景写真比較</li>
<li>超広角カメラの風景写真比較</li>
<li>3倍望遠もしくは電子ズームでの風景写真比較</li>
</ul></li>
<li>薄暗い場所での癖を確認</li>
<li>夜景その1(メイン、超広角)</li>
<li>夜景その2(メイン、超広角、6倍ズーム)
<ul>
<li>メインカメラでの新宿西口の夜景写真比較</li>
<li>超広角カメラでの新宿西口夜景写真比較</li>
<li>6倍ズームで新宿西口夜景写真比較</li>
</ul></li>
<li>接写(マクロ)性能比較</li>
<li>EXP21のカメラ性能比較を総評</li>
</ul></li>
<li>カメラについて その3:動画性能について
<ul>
<li>光学式手ブレ補正の実力を確認</li>
<li>8K動画は室温(20℃)で30分以上撮影可能</li>
</ul></li>
<li>ディスプレイについて:美麗かつ144Hzでヌルヌル動く
<ul>
<li>144Hz表示について</li>
<li>明るさについて</li>
</ul></li>
<li>オーディオについて：付属イヤフォンが最高
<ul>
<li>付属の完全ワイヤレスイヤフォン「MW08S」について
<ul>
<li>Snapdragon Sound Optimizationは切った方が良い。</li>
<li>付属品であるMW08Sの音質について</li>
<li>ノイズキャンセリング機能について</li>
<li>接続性について</li>
<li>音ゲーもできる遅延のなさについて</li>
</ul></li>
<li>EXP21の本体スピーカーについて:音量も音質も十分</li>
<li>EXP21そのもののBluetooth性能について</li>
</ul></li>
<li>EXP21のセルラー通信について
<ul>
<li>EXP21の5G安定性について:</li>
<li>EXP21の5G速度について</li>
</ul></li>
<li>EXP21のWi-Fi速度やアンテナ感度について:速い！そしてROG Phone5を超える感度の良さ
<ul>
<li>EXP21のWi-Fi性能について
<ul>
<li>EXP21のWi-Fi転送速度について実測:予想を超える160MHz×2ストリーム</li>
<li>EXP21のWi-Fi感度について:ゲーミングスマホより優秀！</li>
</ul></li>
</ul></li>
<li>バッテリー持ちと充電速度について:充電速度が速いので、4000mAhであることに不満なし
<ul>
<li>充電速度について: 付属品での場合（HyperCharge 65）</li>
<li>サードパーティ製の充電器・モバイルバッテリーを使った場合（USB PD PPS）</li>
<li>サードパーティ製の充電器・モバイルバッテリーを使った場合(Quick Charge5.0)</li>
<li>サードパーティ製の充電器・モバイルバッテリーを使った場合(普通のUSB PD)</li>
<li>サードパーティ製の充電器・モバイルバッテリーを使った場合(Quick Charge3.0)</li>
<li>充電まとめ: EXP21の充電速度は20％→100％の範囲なら、どの充電規格でも大差ない</li>
</ul></li>
<li>EXP21の生体認証について:指紋認証の精度は良いが設計がダメ。顔認証はマスクでも可能。
<ul>
<li>指紋認証について</li>
<li>顔認証について</li>
</ul></li>
<li>使い勝手について:EXP21は確かにASUSスマホだが、ASUSスマホの良さが消されている
<ul>
<li>ASUSスマホにはあってEXP21にはない機能</li>
<li>EXP21の独自機能について
<ul>
<li>「アドバンスドモード」での詳細設定</li>
<li>「Elite Gamingオプション」</li>
<li>背面ロゴの「照明エフェクト」</li>
</ul></li>
</ul></li>
<li>蛇足その1:USB性能の検証
<ul>
<li>EXP21の映像出力について</li>
<li>EXP21のファイル転送速度について</li>
<li>EXP21のUSB規格は分からなかった。</li>
</ul></li>
<li>蛇足その2:EXP21の充電規格詳細</li>
<li>総評:Qualcommの全てを詰め込んだ「キワモノ」スマホ。ゲーム性能ならROG Phone5シリーズを、使い勝手ならZenfone8を買え。「わかってる」人だけが買うべき。</li>
</ul></li>
</ul>
</section>
<section id="これは何" class="level3">
<h3 class="anchored" data-anchor-id="これは何">これは何？</h3>
<p>Qualcommの全てが詰まったASUS製スマホ。Smartphone for Snapdragon Insidersという名の通り。</p>
<div id="fig-EXP21_Smartphone" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Smartphone-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116195406.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-3" title="図&nbsp;2: EXP21と外装"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116195406.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Smartphone-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;2: EXP21と外装
</figcaption>
</figure>
</div>
</section>
<section id="exp21の開封の儀-付属品の確認とフォトレビューで外観をチェック" class="level3">
<h3 class="anchored" data-anchor-id="exp21の開封の儀-付属品の確認とフォトレビューで外観をチェック">EXP21の開封の儀: 付属品の確認とフォトレビューで外観をチェック</h3>
<div id="fig-EXP21_Smartphone_open" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Smartphone_open-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125840.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-4" title="図&nbsp;3: 開封の儀"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125840.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125842.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-5" title="箱を左右に開くと、まず目にするのがメッセージカードだ。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125842.jpg" class="img-fluid figure-img"></a></p>
<figcaption>箱を左右に開くと、まず目にするのがメッセージカードだ。</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125845.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-6" title="その下にはEXP21本体と付属イヤフォンが鎮座する。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125845.jpg" class="img-fluid figure-img"></a></p>
<figcaption>その下にはEXP21本体と付属イヤフォンが鎮座する。</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125848.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-7" title="付属品の箱達"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125848.jpg" class="img-fluid figure-img"></a></p>
<figcaption>付属品の箱達</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125850.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-8" title="一番下にはユーザーマニュアル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125850.jpg" class="img-fluid figure-img"></a></p>
<figcaption>一番下にはユーザーマニュアル</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Smartphone_open-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;3: 開封の儀
</figcaption>
</figure>
</div>
<div id="fig-EXP21_Smartphone_open2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Smartphone_open2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125853.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-9" title="図&nbsp;4: EXP21の付属品一覧"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125853.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Smartphone_open2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;4: EXP21の付属品一覧
</figcaption>
</figure>
</div>
<section id="exp21の付属品について" class="level4">
<h4 class="anchored" data-anchor-id="exp21の付属品について">EXP21の付属品について</h4>
<p>付属品は写真の通りである。順に挙げていくと、</p>
<ul>
<li>バンパーケース</li>
<li>65W HyperCharge対応急速充電器及びTypeC to C ケーブル、USB Standard-A to TypeCケーブル</li>
<li>ワイヤレスイヤフォン”Premium Earbuds” 及び充電ケース</li>
<li>SIMピン</li>
<li>説明書等の書類</li>
</ul>
<p>の上記5種類である。</p>
<section id="バンパーケースについて" class="level5">
<h5 class="anchored" data-anchor-id="バンパーケースについて">バンパーケースについて</h5>
<div id="fig-PhoneCase" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-PhoneCase-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125855.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-10" title="PHONE CASEの外装"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125855.jpg" class="img-fluid figure-img"></a></p>
<figcaption>PHONE CASEの外装</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125858.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-11" title="いつものASUS SIMピンも付属"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125858.jpg" class="img-fluid figure-img"></a></p>
<figcaption>いつものASUS SIMピンも付属</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125900.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-12" title="バンパーケース"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125900.jpg" class="img-fluid figure-img"></a></p>
<figcaption>バンパーケース</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-PhoneCase-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;5: Phone Caseと書かれた箱にはSIMピンとバンパーケースが入っている
</figcaption>
</figure>
</div>
<div id="fig-PhoneCaseDetails" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-PhoneCaseDetails-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125902.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-13" title="図&nbsp;6: バンパーケースの詳細"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125902.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125905.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-14" title="バンパーケースの内側は六角形があしらわれている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125905.jpg" class="img-fluid figure-img"></a></p>
<figcaption>バンパーケースの内側は六角形があしらわれている</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125907.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-15" title="Snapdragonの文字も刻まれている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125907.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Snapdragonの文字も刻まれている</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-PhoneCaseDetails-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;6: バンパーケースの詳細
</figcaption>
</figure>
</div>
<div id="fig-PhoneCaseDetails2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-PhoneCaseDetails2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130001.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-16" title="図&nbsp;7: バンパーケースを装着した様子"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130001.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130003.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-17" title="図&nbsp;7: バンパーケースを装着した様子"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130003.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130032.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-18" title="カメラよりバンパーケースの方が厚みがあり、カメラをしっかり保護できている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130032.jpg" class="img-fluid figure-img"></a></p>
<figcaption>カメラよりバンパーケースの方が厚みがあり、カメラをしっかり保護できている</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-PhoneCaseDetails2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;7: バンパーケースを装着した様子
</figcaption>
</figure>
</div>
<p>純正品だけあって本体カメラ部分の突起が机等に触れないように上部が厚くなっている点は高く評価したい。</p>
<p>ただ、寸法がタイトで取り外しがしにくいのが難点である。このスマホは普通のスマホと違い、SIMを入れ替えるシーンも多々あるだろうから、そのたびにケースと格闘することを思うといっそケースを付けずに運用したくなるが、本体の価格を考えると使わざるを得ない。</p>
<p>また、筆者は(ベンチマークテストやスピードテスト時を除き)常にこのケースを取り付けた状態でEXP21を使っていたが、回線速度やアンテナ感度等が落ちたとは感じなかった。</p>
<p>(とは言え、スピードテスト等を行う際には念の為外している。また、5Gミリ波に関しては確認が取れなかったため、ミリ波に対する性能低下があるかは未確認である。)</p>
<p>余談だが、ROG Phone5 Ultimateにもこのケースを取り付けることが出来た(図&nbsp;8)。</p>
<div id="fig-PhoneCase_ROG5" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-PhoneCase_ROG5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125955.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-19" title="図&nbsp;8: ROG Phone5と寸法が同じためバンパーケースを共用できたが、ボタンの位置は異なる"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125955.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130030.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-20" title="図&nbsp;8: ROG Phone5と寸法が同じためバンパーケースを共用できたが、ボタンの位置は異なる"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130030.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-PhoneCase_ROG5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;8: ROG Phone5と寸法が同じためバンパーケースを共用できたが、ボタンの位置は異なる
</figcaption>
</figure>
</div>
<p>流石にボタン位置が異なるため常用は出来ないが、寸法的には全く同じであることが確認出来た。</p>
</section>
<section id="w-hypercharge対応急速充電器及びtypec-to-c-ケーブルについて" class="level5">
<h5 class="anchored" data-anchor-id="w-hypercharge対応急速充電器及びtypec-to-c-ケーブルについて">65W HyperCharge対応急速充電器及びTypeC to C ケーブルについて</h5>
<div id="fig-Charger" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Charger-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125910.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-21" title="図&nbsp;9: 付属の充電セットについて"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125910.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125912.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-22" title="図&nbsp;9: 付属の充電セットについて"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125912.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125915.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-23" title="図&nbsp;9: 付属の充電セットについて"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125915.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125923.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-24" title="Qualcomm Quick Charge5.0対応アピール"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125923.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Qualcomm Quick Charge5.0対応アピール</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125925.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-25" title="ケーブルにもQuick Charge5.0ロゴ"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125925.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ケーブルにもQuick Charge5.0ロゴ</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Charger-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;9: 付属の充電セットについて
</figcaption>
</figure>
</div>
<p>なお、付属のケーブルはeMarkerが検出できなかったため、5Aには非対応と思われる。</p>
<p>中身としては、ROG Phone5 Ultimateの付属品と全く同じであり(詳細はバッテリー持ちと充電速度についてにて解説)、ただ型番が1文字違うのとロゴがROGではなく「Qualcomm quick charge5」となっているに過ぎない(図&nbsp;10)。</p>
<div id="fig-Charger_ROG5" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Charger_ROG5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130034.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-26" title="図&nbsp;10: 左がROG Phone5 Ultimateの付属品、右がEXP21の付属品"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130034.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130037.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-27" title="図&nbsp;10: 左がROG Phone5 Ultimateの付属品、右がEXP21の付属品"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130037.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130039.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-28" title="型番はRかQかの違いしかない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130039.jpg" class="img-fluid figure-img"></a></p>
<figcaption>型番はRかQかの違いしかない</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Charger_ROG5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;10: 左がROG Phone5 Ultimateの付属品、右がEXP21の付属品
</figcaption>
</figure>
</div>
<p>EXP21の充電性能のところで詳しく触れるが、スペックは下記の通りである。</p>
<ul>
<li>Model:A320Q-200325C-US</li>
<li>Input:100-240V~50/60Hz,1.5A</li>
<li>Output:5V⎓3A/9V⎓3A/12V⎓3A/15V⎓3A/20V⎓3.25A</li>
<li>PPS:3.3-11V⎓5A/3.3-21V⎓3.25A 65W MAX</li>
<li>その他:ひし形PSEマーク ASUS JAPAN株式会社</li>
</ul>
<p>USB TypeC to CケーブルにはQuick Charge5.0のマークが片側にだけ刻印されている。また、AVHzY CT-3を用いてeMarkerの有無を確認したところ、少なくともCT-3では確認出来なかったため、付属のケーブルは5Aの充電に対応しないものと見られる。</p>
<p>また、付属のケーブルが5Aに対応しないことは同じく付属の充電器のPDOを調べることでも確認でき、5A対応ケーブルを挿した際には3.3-11V⎓5Aを提示したのに対し付属のケーブルを挿した際には3.3-11V⎓3Aとなった。</p>
</section>
<section id="ワイヤレスイヤフォンについて" class="level5">
<h5 class="anchored" data-anchor-id="ワイヤレスイヤフォンについて">ワイヤレスイヤフォンについて</h5>
<div id="fig-EarBudCaseBox" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EarBudCaseBox-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125928.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-29" title="図&nbsp;11: 「EARBUD CASE」の箱には充電ケースとイヤーピースが入っていた"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125928.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125930.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-30" title="図&nbsp;11: 「EARBUD CASE」の箱には充電ケースとイヤーピースが入っていた"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125930.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125933.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-31" title="図&nbsp;11: 「EARBUD CASE」の箱には充電ケースとイヤーピースが入っていた"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125933.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EarBudCaseBox-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;11: 「EARBUD CASE」の箱には充電ケースとイヤーピースが入っていた
</figcaption>
</figure>
</div>
<p>イヤーピースは予め取り付けられているものの他に4セット付属していた。サイズについては確認していない。</p>
<div id="fig-EarBud" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EarBud-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EarBud" style="flex-basis: 100.0%;justify-content: flex-start;">
<div id="fig-EarBads_1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-EarBads_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125943.jpg" class="lightbox" data-gallery="fig-EarBud" title="図&nbsp;12&nbsp;(a): イヤフォンケース(充電器)に本体が収められていないというちょっと面白い仕様"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125943.jpg" class="img-fluid figure-img" data-ref-parent="fig-EarBud"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-EarBads_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) イヤフォンケース(充電器)に本体が収められていないというちょっと面白い仕様
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EarBud" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-EarBads_2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-EarBads_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125945.jpg" class="lightbox" data-gallery="fig-EarBud" title="図&nbsp;12&nbsp;(b): 充電器に入ってないのだから絶縁は必要ないのでは"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125945.jpg" class="img-fluid figure-img" data-ref-parent="fig-EarBud"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-EarBads_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 充電器に入ってないのだから絶縁は必要ないのでは
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EarBud" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-EarBads_3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-EarBads_3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130211.jpg" class="lightbox" data-gallery="fig-EarBud" title="図&nbsp;12&nbsp;(c): アンテナラインがしっかり通っているのが印象的"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130211.jpg" class="img-fluid figure-img" data-ref-parent="fig-EarBud"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-EarBads_3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) アンテナラインがしっかり通っているのが印象的
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EarBud" style="flex-basis: 100.0%;justify-content: flex-start;">
<div id="fig-EarBads_img" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-EarBads_img-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125948.jpg" class="lightbox" data-gallery="fig-EarBud" title="図&nbsp;12&nbsp;(d): ケースに収めた様子"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125948.jpg" class="img-fluid figure-img" data-ref-parent="fig-EarBud"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-EarBads_img-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(d) ケースに収めた様子
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EarBud-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;12: 付属のイヤフォンについて
</figcaption>
</figure>
</div>
<p>中身はMaster &amp; Dynamic社の完全ワイヤレスイヤフォンMW08Sとなる。</p>
<div id="fig-EarBud_app" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EarBud_app-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116081156.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-36" title="MW08S"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116081156.jpg" class="img-fluid figure-img"></a></p>
<figcaption>MW08S</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EarBud_app-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;13: プリインストールされている「M&amp;D Connect」アプリを開いた様子
</figcaption>
</figure>
</div>
<p>型番的にMW08をベースモデルとしているようだが、ベースモデルの方はSnapdragon Sound対応を謳っていないのに対し、こちらはもちろんSnapdragon Soundに対応していることと、アプリ側で「MW08S」と識別されているので、全く同じというわけではないのだろう。イヤフォンのレビューはこちらで行っている。</p>
<p>イヤフォンのケースは、充電用のUSB Type-Cポートを備えている。 ワイヤレス充電には非対応である。 充電は約5V⎓1Aの5Wで行われ、赤いインジケータが表示された状態(29％以下)から充電し100％になるまで1時間程かかった。</p>
<div id="fig-EarBudCase" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EarBudCase-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125938.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-37" title="イヤフォンのケースはUSB Type-Cを搭載している"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125938.jpg" class="img-fluid figure-img"></a></p>
<figcaption>イヤフォンのケースはUSB Type-Cを搭載している</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125936.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-38" title="寸法目安"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125936.jpg" class="img-fluid figure-img"></a></p>
<figcaption>寸法目安</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125940.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-39" title="Snapdragon Soundのキャッチフレーズ"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125940.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Snapdragon Soundのキャッチフレーズ</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EarBudCase-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;14: イヤフォンケースについて
</figcaption>
</figure>
</div>
</section>
<section id="その他の付属品に関して" class="level5">
<h5 class="anchored" data-anchor-id="その他の付属品に関して">その他の付属品に関して</h5>
<p>SIMピンはいつものASUS SIMピンである。マニュアルに関しては興味がないので特筆することがない。</p>
</section>
</section>
<section id="exp21フォトレビュー存在感を放つsnapdragonロゴ" class="level4">
<h4 class="anchored" data-anchor-id="exp21フォトレビュー存在感を放つsnapdragonロゴ">EXP21フォトレビュー:存在感を放つSnapdragonロゴ</h4>
<p>開封の儀セッションの最後は写真と共にEXP21の外観をチェックしていく。</p>
<section id="exp21の背面についてsnapdragonここに在り" class="level5">
<h5 class="anchored" data-anchor-id="exp21の背面についてsnapdragonここに在り">EXP21の背面について:Snapdragonここに在り</h5>
<div id="fig-EXP21_Snapdragon-logo" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Snapdragon-logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130148.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-40" title="図&nbsp;15: EXP21の背面"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130148.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Snapdragon-logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;15: EXP21の背面
</figcaption>
</figure>
</div>
<p>一際目を惹くのはやはり、Snapdragonの代紋だろう。白く光るが、天下のSnapdragonがここにあるということを主張する以上の意味は持たない。Snapdragonであるという価値を示すためのものだ。</p>
<p>今となっては珍しいことに、背面に指紋センサを搭載する。指紋センサに関しては別項でレビューするが、これがまた使いにくい。質感の違いから、自分が指紋センサを触っているのか背面を撫でているのかはわかるものの、見ての通りシームレスに取り付けられているため位置が分かりにくく慣れが必要だ。精度や速度に申し分ないだけに、かなり惜しいと感じる。</p>
<p>カメラ部分は分厚く出っ張っている。厚さはSIMカード3枚分といったところか(図&nbsp;16 (a))。 参考までにROG Phone5 UltimateはSIMカード1.5枚ほどの厚さだ(図&nbsp;16 (b))。 両者の厚さの違いは光学式手ぶれ補正(OIS)の違いに起因すると考えられる。</p>
<div id="fig-EXP21_Camera_bmp" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Camera_bmp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EXP21_Camera_bmp" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-EXP21-CamSIM" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-EXP21-CamSIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130022.jpg" class="lightbox" data-gallery="fig-EXP21_Camera_bmp" title="図&nbsp;16&nbsp;(a): EXP21のカメラバンプはSIMカード3枚分"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130022.jpg" class="img-fluid figure-img" data-ref-parent="fig-EXP21_Camera_bmp"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-EXP21-CamSIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) EXP21のカメラバンプはSIMカード3枚分
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-EXP21_Camera_bmp" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-ROG5-CamSIM" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-ROG5-CamSIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130027.jpg" class="lightbox" data-gallery="fig-EXP21_Camera_bmp" title="図&nbsp;16&nbsp;(b): ROG Phone5 UltimateはSIMカード1.5枚分"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130027.jpg" class="img-fluid figure-img" data-ref-parent="fig-EXP21_Camera_bmp"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-ROG5-CamSIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) ROG Phone5 UltimateはSIMカード1.5枚分
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Camera_bmp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;16: カメラの厚みについて
</figcaption>
</figure>
</div>
</section>
<section id="側面についておそらくプラスチック製だが安っぽさはない" class="level5">
<h5 class="anchored" data-anchor-id="側面についておそらくプラスチック製だが安っぽさはない">側面について:おそらくプラスチック製だが、安っぽさはない。</h5>
<p>側面にアンテナラインを持たないことから、金属製ではないことが伺える。</p>
<div id="fig-EXP21_Side_1" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Side_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130151.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-43" title="アンテナラインがない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130151.jpg" class="img-fluid figure-img"></a></p>
<figcaption>アンテナラインがない</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Side_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;17: EXP21のフレームはおそらくプラスチック製である
</figcaption>
</figure>
</div>
<p>金属製なのにアンテナラインを持たないという例は4Gスマホでも類がなく、ましてやミリ波に対応するスマートフォンで金属製のフレームなのにアンテナラインを持たないなど考えられない。</p>
<p>（余談だが、金属製のフレームでアンテナラインを限りなく目立たなくした例として同じくASUSのZenFone3Deluxeが挙げられる。なお、実用には問題ないもののアンテナ感度は弱かったことを記憶している。）</p>
<p>また、爪で叩いたときの様子からおそらくプラスチック製だと推測できる。しかし、価格が価格だけにプラスチックの安っぽさは感じなかった。</p>
<div id="fig-EXP21_Side_2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Side_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<p>&nbsp; <a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130018.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-44" title="図&nbsp;18: EXP21の側面について"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130018.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130015.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-45" title="左側面には何も無い"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130015.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左側面には何も無い</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130025.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-46" title="上部はマイクがあるだけで、3.5mmのオーディオジャックは存在しない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130025.jpg" class="img-fluid figure-img"></a></p>
<figcaption>上部はマイクがあるだけで、3.5mmのオーディオジャックは存在しない</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130020.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-47" title="底部にはスピーカー、TypeC端子、マイク、SIMトレーを備える"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130020.jpg" class="img-fluid figure-img"></a></p>
<figcaption>底部にはスピーカー、TypeC端子、マイク、SIMトレーを備える</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Side_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;18: EXP21の側面について
</figcaption>
</figure>
</div>
<p>なお、SIMトレーは表裏にSIMをはめ込むコンパクトタイプとなっており、microSDカードには非対応。</p>
<div id="fig-EXP21_SIM" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_SIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130208.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-48" title="表と裏にSIMを載せられる物理デュアルSIMスロット"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130208.jpg" class="img-fluid figure-img"></a></p>
<figcaption>表と裏にSIMを載せられる物理デュアルSIMスロット</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_SIM-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;19: EXP21のSIMトレー
</figcaption>
</figure>
</div>
</section>
<section id="前面についてノッチやパンチホールはなし" class="level5">
<h5 class="anchored" data-anchor-id="前面についてノッチやパンチホールはなし">前面について:ノッチやパンチホールはなし。</h5>
<p>ディスプレイは今どき珍しいノッチ・パンチホールレスな仕様。 ディスプレイ上部にはスピーカーを備えるものの、下部にスピーカーはなく、そのスペースだけが残されている。 これは、ROG Phone5と同じディスプレイを使っているからだろう。</p>
<div id="fig-EXP21_Front" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130206.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-49" title="前面にノッチやパンチホールといった邪魔なものはない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130206.jpg" class="img-fluid figure-img"></a></p>
<figcaption>前面にノッチやパンチホールといった邪魔なものはない</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113141936.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-50" title="EXP21のディスプレイ下部には切り抜きがあるもののスピーカーは非搭載"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113141936.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21のディスプレイ下部には切り抜きがあるもののスピーカーは非搭載</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113142041.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-51" title="参考:ROG Phone5(右)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113142041.jpg" class="img-fluid figure-img"></a></p>
<figcaption>参考:ROG Phone5(右)</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;20: EXP21の前面について
</figcaption>
</figure>
</div>
</section>
<section id="プリインストールアプリ等の確認" class="level5">
<h5 class="anchored" data-anchor-id="プリインストールアプリ等の確認">プリインストールアプリ等の確認</h5>
<p>フォトレビューではないが、話の流れ的にここでプリインストールアプリや設定画面の確認も行いたい。</p>
<div id="fig-EXP21_app" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_app-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130314.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-52" title="EXP21のプリインストールアプリ一覧"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130314.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21のプリインストールアプリ一覧</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130327.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-53" title="EXP21の設定画面"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130327.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21の設定画面</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig quarto-uncaptioned" id="fig-EXP21_app-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;21
</figcaption>
</figure>
</div>
<div id="fig-EXP21_Q-settings" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Q-settings-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130330.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-54" title="図&nbsp;22: EXP21のクイック設定パネル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130330.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130332.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-55" title="図&nbsp;22: EXP21のクイック設定パネル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130332.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130334.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-56" title="図&nbsp;22: EXP21のクイック設定パネル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130334.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Q-settings-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;22: EXP21のクイック設定パネル
</figcaption>
</figure>
</div>
<div id="fig-EXP21_wp" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_wp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130316.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-57" title="図&nbsp;23: EXP21の壁紙"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130316.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130319.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-58" title="図&nbsp;23: EXP21の壁紙"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130319.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130322.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-59" title="図&nbsp;23: EXP21の壁紙"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130322.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130324.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-60" title="図&nbsp;23: EXP21の壁紙"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130324.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_wp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;23: EXP21の壁紙
</figcaption>
</figure>
</div>
</section>
</section>
</section>
<section id="最強なスペックを確認qualcommの全てを詰め込んでみせたasusの信頼性と技術力の高さ" class="level3">
<h3 class="anchored" data-anchor-id="最強なスペックを確認qualcommの全てを詰め込んでみせたasusの信頼性と技術力の高さ">最強なスペックを確認:Qualcommの全てを詰め込んでみせたASUSの信頼性と技術力の高さ</h3>
<p>EXP21のスペックについて確認したい。と言っても基本的にはスペックシートとベンチマークテストの結果を実感込めてなぞっていくだけになる。長くなりそうなものはそれぞれ詳しく語った別項へのリンクが貼ってあるので、詳細が知りたい方はそちらをご覧いただきたい。</p>
<p>また、一部仕様に関しては公表されていなかったため、独自に検証を行った。</p>
<p>筆者の勉強不足により、検証方法あるいは検証結果が間違っていることも考えられるので、あくまで参考程度に留めてほしい。また、そのようなミスを発見した場合には<a href="https://twitter.com/Pottal_MDS">Twitter</a>または<a href="https://docs.google.com/forms/d/e/1FAIpQLSeBGdRTISv2ywxM-w22xTgtF4uZFaqN1K3wU_PnSRICaJcGYQ/viewform">こちらのフォーム</a>でご指導いただければ幸いだ。</p>
<section id="exp21のスペック" class="level4">
<h4 class="anchored" data-anchor-id="exp21のスペック">EXP21のスペック</h4>
<div id="tbl-spec" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;1: EXP21のスペックシート（筆者作成）
</figcaption>
<div aria-describedby="tbl-spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116160057.png" class="lightbox" data-gallery="quarto-lightbox-gallery-61" title="フォーマットがASUSっぽいのは信仰心によるもの"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116160057.png" class="img-fluid figure-img"></a></p>
<figcaption>フォーマットがASUSっぽいのは信仰心によるもの</figcaption>
</figure>
</div>
</div>
</figure>
</div>
<div id="lst-spec" class="listing quarto-float quarto-figure quarto-figure-left anchored">
<figure class="quarto-float quarto-float-lst figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-lst" id="lst-spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
リスト&nbsp;1: スペックリスト
</figcaption>
<div aria-describedby="lst-spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<ul>
<li><ul>
<li>OS:Android11(2021年10月現在）
<ul>
<li>SoC:Snapdragon888 CPU最大2.84GHz駆動(≒独自のオーバークロックなし)※SoCのベンチマークテスト結果については後述する</li>
<li>RAM:16GB</li>
<li>内蔵ストレージ:512GB (UFS3.1) Reed1985MB/s Write 785MB/s</li>
<li>ディスプレイ:6.78インチAMOLEDディスプレイ</li>
<li>解像度:2,448×1,080ドット 144Hz</li>
<li>カメラ:詳細は図の通り。また、作例については『カメラについて』をご覧いただきたい。</li>
<li>メインカメラ64MP（OIS),ウルトラワイドカメラ12MP，望遠カメラ8MP（OIS）</li>
<li>インカメラ:24MP</li>
<li>センサ:画像の通り 特筆事項として「みちびき(QZSS)」対応</li>
<li>Wi-Fi機能:Wi-Fi6対応 802.11a/b/g/n/ac/ax, 2x2 MIMO 理論値160MHz×2ストリーム2401Mbps 実測値1500Mbps ※Wi-Fi性能の詳細はこちら</li>
<li>(Wi-Fi6Eにも対応しているものの、2021年10月現在、日本ではWi-Fi6Eの根幹となる6GHz帯の利用が出来ない)</li>
<li>Bluetooth:Bluetooth5.2,Qualcomm aptX Adaptive及びSnapdragon Sound technologyに対応。LDACへの対応も確認している。 ※Snapdragon Soundを含めたBluetooth性能の詳細はこちら</li>
</ul></li>
</ul></li>
<li><p>通信方式:詳細は画像の通りだが、5G sub6(n77, n78, n79)及びミリ波(n257)に対応している。</p>
<ul>
<li>余談となるが、東京都立大学南大沢キャンパスにてn79を用いたローカル5Gを利用することができた。詳細はこちらの記事を参照していただければ幸いである。 <a href="https://www.pottal-portal.com/entry/tmu_local5g_exp21">www.pottal-portal.com</a></li>
</ul></li>
<li><p>テザリング機能: セルラー通信及びWi-Fiのテザリングは可能。セルラー通信のテザリングを行う際は、Wi-Fi6もしくはWi-Fi5として振る舞う他、2.4GHz、5GHz、あるいはその両方を選ぶことができる。また、正常に日本版OSが焼かれたモデルではWi-FiをWi-Fiテザリングすることも可能であった。ただし、Wi-Fiをテザリングする際には2.4GHz帯と5GHzの排他利用となる仕様であった。つまり、2.4GHz帯か5GHzのどちらかでしかAPとして機能させられない</p></li>
<li><p>USBポート: USB TypeCポートを採用したUSB 3.1(?)、映像出力可能。</p>
<ul>
<li>DisplayPort Alt Modeを用いてTypeCケーブル1本で映像出力が可能であったため、USB 3.1に対応していることがわかるが、USB3.1 Gen1(5Gbps)なのかUSB3.1 Gen2(10Gbps)なのかまでは不明である。このレビューでは、映像出力の観点とファイルの転送速度の観点からEXP21のUSB規格について推測を試みたものの、結論が出なかった。ちなみに、転送速度の観点から言えばUSB2.0レベルであった。詳細については『蛇足1:USB規格の検証』をご覧いただきたい。</li>
</ul></li>
<li><p>バッテリー容量:4000mAh（未評価）</p>
<ul>
<li>バッテリー持ちの検証は実用に根付き、なおかつ再現性のある測定方法が思いつかなかったために行えていない。「まあ、普通に持つ」「特に電池持ちの悪さは感じなかった」などとお茶を濁しても問題ないバッテリー持ちだったと体感しているが、数字として示せない以上何とでも言えよう。</li>
<li>※ベンチマークテストでの「非実用的な」バッテリーテストの詳細はこちら</li>
</ul></li>
<li><p>充電速度:最大65Wの急速充電に対応するものの、実測45Wが限界か</p>
<ul>
<li>※充電速度の詳細はこちら</li>
<li>充電速度の検証に当たっては、測定器としてAVHzY CT-3を用いた。</li>
</ul></li>
</ul>
</div>
</figure>
</div>
<p>一通りスペックをなぞってみたがスペックシート上は何一つ不満がなく、特に対応bandなど圧巻と言ってもいいだろう。筆者は別にアンテナ設計に詳しいわけではないが、一般的に数多くのband(周波数)に対応させるには技術がいると聞く。</p>
<p>特に周波数帯の高いミリ波などは扱いが難しいとされている中、周波数帯を決め打ちするならまだしもn257, n258, n260, n261に対応(つまり、26GHz、28GHz、跳んで39GHz)とASUSはよくもまあこんなに詰め込んでみせたものだと感心した。</p>
<p>これはASUS信者の目線だが、Qualcommが初めて一般発売するリファレンススマホを手掛ける会社としてASUSを選んだのも、ASUSがマザーボードのトップを走りそして長年スマートフォンを手掛けてきた信頼と実績があるからだろう。</p>
<p>さて、詰め込んだと聞いて、不安になるのが発熱やそれに伴う熱暴走だろう。「処理性能について」ではそんな懸念を検証しているため、気になる方はそちらをご覧いただきたい。</p>
</section>
</section>
<section id="exp21の良いところ" class="level3">
<h3 class="anchored" data-anchor-id="exp21の良いところ">EXP21の良いところ</h3>
<p>本レビューは長いため、気になる項目だけ読むスタイルを推奨している。列挙した「良かった点」についての詳細は対応する項を読んでいただければ幸いだ。</p>
<p>あえて良かった点をまとめるなら、EXP21はQualcomの目指すスマートフォンのあり方を体現出来ており素晴らしいと言ったところだろうか。Qualcomというスマートフォンの主要なチップを作る会社が、マザーボードという基板を作っているASUSと組んだのだ。しかもどちらもトップメーカーであり実力は折り紙付きだ。盤石な基盤で作られているという強さが、各メリットに表れている。</p>
<section id="綺麗便利なカメラ" class="level5">
<h5 class="anchored" data-anchor-id="綺麗便利なカメラ">◎綺麗/便利なカメラ</h5>
<p>筆者の使う範囲では文句なしに綺麗な写真が撮れるメインカメラを搭載しており、なおかつGoogleレンズにワンタッチで接続出来るUIも良い。</p>
<p>超広角カメラもメインカメラと間違える程綺麗に撮れる。</p>
<p>望遠カメラは、光学式手ブレ補正の存在が地味に助かるシーンが多かった。</p>
</section>
<section id="最新のゲーミングスマホに引けを取らないマシンスペック" class="level5">
<h5 class="anchored" data-anchor-id="最新のゲーミングスマホに引けを取らないマシンスペック">◎最新のゲーミングスマホに引けを取らないマシンスペック</h5>
<p>AnTuTuベンチマークテストでは最上位のゲーミングスマートフォンであるROG Phone5 Ultimateをも上回るスコアを叩き出した。</p>
<div id="fig-AnTuTu_EXP21" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-AnTuTu_EXP21-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116172030.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-62" title="AnTuTuのデータベース上「ZenFone8Pro」となっているが、これはEXP21のAnTuTu Ver.9.1.7結果である"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116172030.jpg" class="img-fluid figure-img"></a></p>
<figcaption>AnTuTuのデータベース上「ZenFone8Pro」となっているが、これはEXP21のAnTuTu Ver.9.1.7結果である</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-AnTuTu_EXP21-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;24: AnTuTu Ver.9.1.7で83万点
</figcaption>
</figure>
</div>
<p>連続してベンチマークテストをするとスコアはROG Phone5を下回っていったが、それでもなお1年前のハイエンドゲーミングスマホ(空冷クーラー付き)には勝るスコアであった。※AnTuTuベンチマークテストの結果はこちら</p>
<p>CPUやGPUだけでなく144Hzのリフレッシュレートを備えたディスプレイや高速かつ大容量のストレージを備えるなど、スペックだけみればゲーミングスマホそのものだ。EXP21でゲームをして負けることがあっても、それはスマホのせいではないだろう。</p>
<p>とはいえ、ゲーミングスマホでは必須となったショルダーボタン（L1/R1ボタン）や純正冷却ファンが存在しないといった点や、そもそもゲームをアシストするソフトウェアを備えない点から、いくら性能が高くともEXP21をゲーム用のスマホとして購入することはおすすめ出来ない。EXP21の文句なしのマシンパワーはゲームをするために高められているのではないのだ。</p>
</section>
<section id="gbと大容量かつ高速な内蔵ストレージ" class="level5">
<h5 class="anchored" data-anchor-id="gbと大容量かつ高速な内蔵ストレージ">◎512GBと大容量かつ高速な内蔵ストレージ</h5>
<p>マシンスペックを語る際にも触れたが、EXP21は読み書き共に高速な512GBストレージを搭載している。 規格はUFS3.1というものが使われており、その速度を測ったところ、Read（Input）が1985MB/s, Write（Output）が785MB/sのため、スマートフォンとして使う上で不満になることがまずない。超高速かつ大容量なストレージを備えるため、これならmicroSDカードスロット非搭載な点も納得は出来る。</p>
<div id="fig-AnTuTu_Storage" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-AnTuTu_Storage-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116172900.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-63" title="EXP21の内蔵ストレージは高速かつ大容量"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116172900.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21の内蔵ストレージは高速かつ大容量</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-AnTuTu_Storage-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;25: AnTuTu Storage Testの結果
</figcaption>
</figure>
</div>
</section>
<section id="万が一の時も安心なqualcomm-quickcharge5.0急速充電" class="level5">
<h5 class="anchored" data-anchor-id="万が一の時も安心なqualcomm-quickcharge5.0急速充電">◎万が一の時も安心なQualcomm QuickCharge5.0急速充電</h5>
<p>独自の急速充電規格では速くても、一般的な急速充電規格に対応していなければ、良さは半減してしまう。</p>
<p>しかし、EXP21は違う。一般的なUSB PD PPSや急速充電規格の最大手であるQualcomm QuickChargeに対応している。そのため、「普通の」モバイルバッテリーやACアダプターでも急速充電が可能だ。</p>
<p>実際、Qualcommの規格ではなくUSBとしての規格であるUSB PD PPSに対応したモバイルバッテリーを使っても約30Wで充電され、20%から100%になるまで、僅か59分しかかからなかった。</p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
<p>ちなみに付属品である純正ACアダプターで充電した際にも同様に30W程で充電され52分（20%→100%）だったので、わざわざデカくてプラグの折り畳めない付属のACアダプターを持ち歩く必要はない点が素晴らしい。※急速充電の検証はこちら</p>
</section>
<section id="普段は充電速度や電池持ち残量を制御し長く使う選択肢も選べるasusらしさ" class="level5">
<h5 class="anchored" data-anchor-id="普段は充電速度や電池持ち残量を制御し長く使う選択肢も選べるasusらしさ">◎普段は充電速度や電池持ち残量を制御し「長く使う」選択肢も選べるASUSらしさ</h5>
<p>急速充電は確かに便利だ。万が一充電を忘れてもさっと充電出来るし、外出先でも困らない。 とはいえ、例えば寝る時にまで急速充電をする必要はない。いくら対策は練られているとは言え、発熱やバッテリー劣化が気になって寝られないなんて人もいるかもしれない。</p>
<p>ASUSスマートフォンはそういった声にも応え、「スケジュール充電」や「低速充電モード」さらには「80%（90%）充電制限」といったバッテリー劣化を抑える（バッテリーケア）機能も用意している。</p>
<div id="fig-Battery_Care" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Battery_Care-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130350.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-64" title="図&nbsp;26: 「バッテリーケア」機能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130350.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Battery_Care-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;26: 「バッテリーケア」機能
</figcaption>
</figure>
</div>
<p>数々のASUSらしい嬉しい機能が取り除かれ、ピュアなAndroidに近くなっているEXP21だが、バッテリーケア機能が残されたのは嬉しい。</p>
</section>
<section id="音質良し接続性良しの完全ワイヤレスイヤフォン付属" class="level5">
<h5 class="anchored" data-anchor-id="音質良し接続性良しの完全ワイヤレスイヤフォン付属">◎音質良し接続性良しの完全ワイヤレスイヤフォン付属</h5>
<p>付属品の完全ワイヤレスイヤフォンの外観はフォトセクションで示した通り(図&nbsp;12 (d))だが、高音質かつ低遅延を両立していて最高である。雑踏でも音が途切れないのも素晴らしい。 この付属品は非売品であるものの、姉妹モデル(これと違いSnapdragon Soundには非対応)のMW08が3万7千円を下回ることがないので、より上位モデルとなるこの「MW08S」は4万円くらいの代物だろう。そう考えるとEXP21は実質12万円程度とお安くなってしまう。※付属する完全ワイヤレスイヤフォンの詳細はこちら</p>
</section>
<section id="抜群なアンテナ感度と通信速度" class="level5">
<h5 class="anchored" data-anchor-id="抜群なアンテナ感度と通信速度">◎抜群なアンテナ感度と通信速度</h5>
<p>詳細はこちらの通りであるが、最強のゲーミングスマホROG Phone5 Ultimateと比較してWi-Fiの受信信号強度が高く、アンテナ性能が良いことが分かった。Wi-Fiの通信速度はなんと2401Mbpsのリンク速度を表示するため、最新のパソコン並のWi-Fi性能(Wi-Fi6 160MHz×2ストリーム)である。※Wi-Fi速度の詳細はこちら</p>
</section>
<section id="綺麗かつヌルヌル動く動くディスプレイ" class="level5">
<h5 class="anchored" data-anchor-id="綺麗かつヌルヌル動く動くディスプレイ">◎綺麗かつヌルヌル動く動くディスプレイ</h5>
<p>こちらで検証した通り、綺麗な発色と144Hzの高リフレッシュレートを両立している。カタログスペックによれば111.23% DCI-P3の色域でかつ色精度がDelta-E &lt;1なのだから、鮮やかかつ正確な発色だ。筆者としては今の解像度に全く不満はないが、2448 x 1080ドットなので、4Kディスプレイにはならないところがカタログスペック上唯一の弱点だろうか。実際にはスマホのディスプレイサイズで4Kにしたところで…と言ったところなのでスマホとして使う分には問題ないだろう。</p>
<p>明るさは800nitが保証されており(おそらくこれがディスプレイ全体の最大輝度)、最大1200nitのピーク輝度(画面の一部を点灯させた際の最大輝度)になっている。ピーク輝度の方はHDRコンテンツの視聴等で役立つだろう。なお、筆者が秋空の下で試したところ800nitでも問題なかった。※ディスプレイ性能についてはこちら</p>
</section>
<section id="aospピュアandroidっぽいui" class="level5">
<h5 class="anchored" data-anchor-id="aospピュアandroidっぽいui">○AOSP（ピュアAndroid）っぽいUI</h5>
<p>筆者は生粋のASUS信者のため、無個性なAOSPライクなUIよりも使い慣れておりかつ便利なZenUI、つまりASUSのカスタマイズが施されたスマホの方が嬉しい。</p>
<p>とは言え一般的にはAOSP、つまりピュアなAndroidの方がスマホを買い替えたり(あるいは複数台使うときに)戸惑わないし、何より余計なカスタマイズがない分OSアップデートが早い(だろう)から喜ばれるのだろう。</p>
<p>EXP21が特殊なスマートフォンなので、2台目のスマホとして非ASUSユーザーから選ばれることも十分想定される。もともと最近のASUSスマホがAOSPライクになってきた中、さらに純度を高めたEXP21はそういった面では好ましい。</p>
</section>
<section id="指紋や顔認証の速度や精度は良い" class="level5">
<h5 class="anchored" data-anchor-id="指紋や顔認証の速度や精度は良い">○指紋や顔認証の「速度」や「精度」は良い</h5>
<p>少なくとも顔認証は何1つ不満がない。マスクをしたままでも行える点も良いし速度もワンテンポだけ遅く、カメラを見つめる間があるが、ストレスになる程ではない。</p>
<p>指紋認証も、速度は爆速だ。0.1秒、指で指紋センサを弾くように叩くだけで認証される。精度も問題なく、同じ指であれば先端でもサイドでも（しっかり指紋登録をしていれば）問題なく認証されるし、逆に他の指ではもちろん弾かれる。※顔認証や指紋認証の詳細はこちら</p>
<p>速度や精度は問題ないのだ。含みを持たせた言い方だが、くどくなるのでその詳細は指紋センサーについてや、 「×指紋センサーの見つけにくさ」をご覧いただきたい。</p>
</section>
<section id="デュアルフロントではないものの本体スピーカーの質も良い" class="level5">
<h5 class="anchored" data-anchor-id="デュアルフロントではないものの本体スピーカーの質も良い">○デュアルフロントではないものの本体スピーカーの質も良い</h5>
<p>ROG Phoneシリーズとは違い、デュアルフロントスピーカーではないものの、本体の画面上部と、側面(底部)にスピーカーを備えるため、大きな違和感(左右差をおぼえること)なくステレオを楽しむ事ができる。</p>
<p>最大音量がけっこう大きくなおかつ目立った音割れはしなかったため、スマートフォンのスピーカーとしてはかなり上位のものとなるのではないだろうか。</p>
</section>
</section>
<section id="exp21のイマイチなところ" class="level3">
<h3 class="anchored" data-anchor-id="exp21のイマイチなところ">EXP21のイマイチなところ</h3>
<p>本レビューは長いため、気になる項目だけ読むスタイルを推奨している。列挙した「イマイチな点」についての詳細は対応する項を読んでいただければ幸いだ。</p>
<p>あえてイマイチな点をまとめるなら、防水やおサイフケータイ、3.5mmイヤフォンジャックなど日本市場で求められるニーズに応えてないというのが1つと、「ASUS」らしさが無くなってしまっているというところだろうか。特に後者については 「使い勝手について」 で更に詳しく掘り下げられているので、そちらをご覧いただきたい。</p>
<section id="防水非対応" class="level5">
<h5 class="anchored" data-anchor-id="防水非対応">△防水非対応</h5>
<p>まあ、ASUSスマートフォンで防水に対応しているのは初代ROG Phone（IPX4のお守り程度の生活防水）とZenfone8(IP68防水防塵)くらいで、ASUS自体あまり防水スマートフォンに力を入れていなかったので、まあ仕方ないと諦めるしかない。 （EXP21も端子やスピーカー周りに浸水防止のキャップを付けるくらいのことはやってそうだが、水没させたら完全にアウトだろう）</p>
</section>
<section id="指紋センサーが指紋認証にしか使えない" class="level5">
<h5 class="anchored" data-anchor-id="指紋センサーが指紋認証にしか使えない">△指紋センサーが「指紋認証」にしか使えない</h5>
<p>画面が大きいので、通知バーをスワイプさせる時に背面の指紋センサーで代用できれば便利なのだが、ZenFone6で出来たことがEXP21では出来ない。</p>
<div id="fig-mottainai_fps" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-mottainai_fps-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082229.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-65" title="図&nbsp;27: ZenFone6では背面の指紋センサーを活用できる"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082229.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082227.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-66" title="図&nbsp;27: ZenFone6では背面の指紋センサーを活用できる"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082227.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-mottainai_fps-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;27: ZenFone6では背面の指紋センサーを活用できる
</figcaption>
</figure>
</div>
<p>そのため片手で通知バーを下ろすには、不便になったASUSの改悪版「片手モード」で画面全体を下に下げてスワイプするしかない。片手モードの改悪については、EXP21と直接関係ない(EXP21は改悪版片手モードがデフォルト搭載だった)ため、ここではこれ以上深堀りしないことにする。</p>
<p>とにかく、指紋センサーが指紋センサーとしてしか使えないので、背面に置かれている意味が半減してしまっている。</p>
</section>
<section id="有線接続でのファイル転送が遅い" class="level5">
<h5 class="anchored" data-anchor-id="有線接続でのファイル転送が遅い">△有線接続でのファイル転送が遅い</h5>
<p>USB 2.0と紛う程遅い。ファイルサイズに関わらず300Mbps程度しか出せずWi-Fiで転送した方が速いというのはいかがなものか。せっかくの高速内蔵ストレージなのだから、USB 3.1 Gen2（10Gbps）の転送速度を出してくれても良さそうなのだが…※USBでの転送速度についてはこちら</p>
</section>
<section id="mmオーディオジャック非搭載" class="level5">
<h5 class="anchored" data-anchor-id="mmオーディオジャック非搭載">△3.5mmオーディオジャック非搭載</h5>
<p>これはまあ、付属品の完全ワイヤレスイヤフォンMW08SとSnapdragon Sound technologyが素晴らしいので許せる。許せるが、別に3.5mmオーディオジャックがあって困ることはないので、非搭載なことを△とした。EXP21とMW08Sの組み合わせで使う分にはなくても困らない。</p>
</section>
<section id="microsdカードスロット非搭載" class="level5">
<h5 class="anchored" data-anchor-id="microsdカードスロット非搭載">△microSDカードスロット非搭載</h5>
<p>まあ、これも内蔵ストレージが512GBもあってなおかつUFS3.1と高速なので許せる範囲だ。</p>
</section>
<section id="片手モードが使いにくい" class="level5">
<h5 class="anchored" data-anchor-id="片手モードが使いにくい">△「片手モード」が使いにくい</h5>
<p>EXP21の片手モードは、iOSの「簡易アクセス」やAndroid12標準機能？の片手モードと同じ、画面が下半分にスライドする(筆者にとって)不便な片手モードだ(図&nbsp;28 (a))。画面を縮小するタイプの片手モード(図&nbsp;28 (b))の方が使いやすいと考えているため、これは受け入れがたい。</p>
<div id="fig-one_hand_mode" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-one_hand_mode-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-one_hand_mode" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-one_hand_mode_old" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-one_hand_mode_old-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116161620.jpg" class="lightbox" data-gallery="fig-one_hand_mode" title="図&nbsp;28&nbsp;(a): 画面を縮小するタイプの旧「片手モード」"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116161620.jpg" class="img-fluid figure-img" data-ref-parent="fig-one_hand_mode"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-one_hand_mode_old-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 画面を縮小するタイプの旧「片手モード」
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-one_hand_mode" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-one_hand_mode_new" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-one_hand_mode_new-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116161623.jpg" class="lightbox" data-gallery="fig-one_hand_mode" title="図&nbsp;28&nbsp;(b): 画面を下に下ろすタイプの新「片手モード」"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116161623.jpg" class="img-fluid figure-img" data-ref-parent="fig-one_hand_mode"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-one_hand_mode_new-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 画面を下に下ろすタイプの新「片手モード」
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-one_hand_mode-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;28: 片手モード比較 左が初代ROG Phone, 右がROG Phone5
</figcaption>
</figure>
</div>
<p>写真は都合上ROG Phone5のものを使用しているが、EXP21でも同様である。</p>
</section>
<section id="デカくて重い" class="level5">
<h5 class="anchored" data-anchor-id="デカくて重い">△デカくて重い</h5>
<p>仕方のないことだが、デカくて重い。デカいのは、建前としては「5Gで提供されるリッチなコンテンツを大画面で楽しむため」とかそういったところだろう。実際は、内部設計的にコンパクトサイズに収めるのは無理があったからに違いない。その証左に、同じサイズでROG Phone5は6000mAhのバッテリーを搭載しているところ、EXP21は4000mAhだ。内部設計の余裕がないことが容易に想像出来る。</p>
<p>重さは210gだ。まあ、最近のスマートフォンは200gも超えることも珍しくない。ROG Phone5なぞ(6000mAhの大容量バッテリーを搭載していることもあり)239gだ。ちなみに、iPhone 13Pro Maxも同じような画面サイズ(6.7インチ)で238gだ。もう、このサイズのスマートフォンになると重いのは仕方のないことなのだろう。</p>
</section>
<section id="ワイヤレス充電非対応" class="level5">
<h5 class="anchored" data-anchor-id="ワイヤレス充電非対応">△ワイヤレス充電非対応</h5>
<p>Qualcomはワイヤレス充電にも関わっており、最近ではQuick Charge3を用いた30Wのワイヤレス充電器を<a href="https://www.qualcomm.com/news/onq/2020/08/05/deep-dive-quick-charge-5-and-other-cool-quick-charge-news">(さらっと)発表している</a>。また、ワイヤレス充電の国際標準規格Qiとも相互運用性を確保しているため、てっきりQiに対応させてくるものだと思っていたのだが…</p>
<p>EXP21は非金属ボディのため、材質的にはワイヤレス充電が可能なはずだが、ワイヤレス充電に対応するコイルやチップ、内部ケーブルを置く余裕がなかったのかもしれない。</p>
<p>まあ、ワイヤレス充電は発熱や遅さもあり、かつ位置合わせもけっこう面倒という問題もある。そして当たり前だが、ワイヤレス充電器そのものはワイヤレスではない。結局のところ充電器とスマホの間がワイヤレスかどうかという話なので、筆者としては魅力を感じていないし、搭載されいなくても問題はないと考えている。ただ、Qualcommの描くワイヤレス充電の世界を見たかったという気持ちはあるため△とした。</p>
</section>
<section id="マニュアル撮影出来ないカメラ" class="level5">
<h5 class="anchored" data-anchor-id="マニュアル撮影出来ないカメラ">✕マニュアル撮影出来ないカメラ</h5>
<p>「カメラについて1」のマニュアルカメラの項目で触れている通り、これは許しがたい。なまじ性能が良いだけに、自分の思う設定で撮れないのが歯痒く感じる。とても綺麗な絵が撮れるが、これでは筆者がシャッターを切っただけで、Snapdragonの作品となってしまう。もちろん、Snapdragonのサポートがあって始めてEXP21で写真が撮れるのだが、マニュアル撮影が出来ないとなると、筆者が介入する余地がないのだ。これでは写真は楽しめても撮影が楽しめない。</p>
<p>また、EXP21の癖として青白い色味になる点やISO感度を上げて明るく撮りたがる点、彩度やコントラストが強い写真になるという点がある。マニュアル撮影が出来れば、少なくとも色味やISO感度はこちらで抑えられるのだ。筆者の腕前がない分、普段はもちろんSnapdragonのサポートには頼りたいが、たまにはマニュアル撮影がしたい。</p>
<p>ASUSスマートフォンは古くからマニュアル撮影(Proモード)をサポートしてきた。そのため、技術的には今すぐにでも対応出来るはずだ。Qualcommの意向であれば仕方のないことだが、なんとしてもマニュアル撮影に対応して欲しいものだ。</p>
</section>
<section id="指紋センサーの見つけにくさ" class="level5">
<h5 class="anchored" data-anchor-id="指紋センサーの見つけにくさ">✕指紋センサーの見つけにくさ</h5>
<p>「指紋センサーについて」で触れている通り、指紋センサーが見つけにくい。背面にあるため手探りで指紋センサーを見つけることになるのだが、指紋センサーの周りは凹凸がなく、すぐにはそれと分からない。使い勝手に直結する問題なので、この点はなんとかして欲しかった。</p>
<p>まあ、指紋センサーは動いたりしないので、最終的には慣れの問題だとは思うが、指紋認証そのものは速く高精度なため惜しく感じる。</p>
</section>
<section id="ゲームに便利なasus独自機能game-genie非対応" class="level5">
<h5 class="anchored" data-anchor-id="ゲームに便利なasus独自機能game-genie非対応">✕ゲームに便利なASUS独自機能「Game Genie」非対応</h5>
<p>筆者は生粋のROG Phoneユーザーであり、ゲームをする上で「Game Genie」は必須と感じている。</p>
<p>「Game Genie」はROG Phone・Zenfoneシリーズに搭載されているゲームをサポートする機能(図&nbsp;42)で、例えばゲーム中の着信・通知の拒否や、スクリーンレコーダー、バックグラウンドアプリ等をKILLする「最適化」、オート周回時に誤作動やスリープモードにならない「ロックタッチ」などが、スワイプ1つで呼び出せる便利さがある。</p>
<div id="fig-GAME_GENIE" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-GAME_GENIE-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162716.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-69" title="一般的なASUSスマホ ZenFone6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162716.jpg" class="img-fluid figure-img"></a></p>
<figcaption>一般的なASUSスマホ ZenFone6</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162711.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-70" title="ゲーミングスマホROG Phone5 ゲーミングスマホのため機能も多い"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162711.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ゲーミングスマホROG Phone5<br>ゲーミングスマホのため機能も多い</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-GAME_GENIE-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;29: Game Genieの例
</figcaption>
</figure>
</div>
<p>また、大っぴらには言えないが、マクロ機能(予め指定した通りに画面を自動でポチポチとタップしてくれる機能)もあるのだが(図&nbsp;30)、EXP21にはそれらの機能を備えたGame Genieがない。</p>
<div id="fig-macro" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-macro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162713.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-71" title="ゲーミングスマホではないZenFone6にすら「マクロ機能」がある"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162713.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ゲーミングスマホではないZenFone6にすら「マクロ機能」がある</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-macro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;30: ASUSスマホ標準搭載のはずのマクロ機能
</figcaption>
</figure>
</div>
<p>これではいくら性能が高くても…と言ったところだ。まあ、ゲームをしたいならROG Phoneシリーズを買うべきだろう。EXP21のマシンスペックはゲームに特化したものではないのだ。</p>
</section>
<section id="rootを取らなきゃ電測には向かない" class="level5">
<h5 class="anchored" data-anchor-id="rootを取らなきゃ電測には向かない">✕rootを取らなきゃ電測には向かない</h5>
<p>一般的なスマートフォンの使い方ではないが、EXP21の使い方としては一般的と言える電測だが、EXP21はrootを取らないとNRバンドやCAの組み合わせが分からない。</p>
<p>※何を言っているか分からないという方には不要の機能なので気にする必要はない。</p>
<p>せっかく対応bandが(ありえない程に)豊富なのに、これはあまりにも痛すぎる。Android12でNRやCAの組み合わせが見れるようになることを切に願う。</p>
</section>
<section id="無意味に光るだけのsnapdragonロゴ" class="level5">
<h5 class="anchored" data-anchor-id="無意味に光るだけのsnapdragonロゴ">✕無意味に光るだけのSnapdragonロゴ</h5>
<p>せめて通知があった時だけ光るとか、そういう利便性を付けてほしいものだ。色も白一色と味気ない。ROG Phoneシリーズは通知に合わせて、例えばTwitterからの通知なら水色に、Instagramからの通知なら紫色に、といった感じで通知+カラーで光らせ方を変えることが可能だ(図&nbsp;31)。</p>
<div id="fig-GamingLight" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-GamingLight-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082628.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-72" title="図&nbsp;31: ROG Phoneシリーズでは、背面のロゴマークを通知に合わせて光らせることが可能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082628.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082631.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-73" title="図&nbsp;31: ROG Phoneシリーズでは、背面のロゴマークを通知に合わせて光らせることが可能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082631.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-GamingLight-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;31: ROG Phoneシリーズでは、背面のロゴマークを通知に合わせて光らせることが可能
</figcaption>
</figure>
</div>
<p>EXP21の場合、白色LEDしか搭載していない(と思われる)ため、カラーの方は諦めるしかないが、せめて光らせ方をもっと増やして欲しいものだ。光らせ方のカスタマイズは、ROGの十八番だ。技術的には問題ないはずなので、これはQualcommの意向なのかもしれない。</p>
<p>「このQualcomm様のSnapdragonロゴを通知に合わせて光らせるなど許せん、Snapdragonはただ輝いていれば良い。そこにそれ以外の意味などない。」なんてことを考えるのは流石にQualcommに対する偏見が過ぎるだろうか。冗談はさておき、今の仕様だと本体にバッテリーの無駄遣いである。それでSnapdragon Insiders達が喜ぶなら、まあ良いが。</p>
<hr>
<p>なお、ここからは各項目について詳細をチェックしていく。膨大な量となっているので、気になる項目だけを読んでいくことを推奨する。</p>
</section>
</section>
<section id="処理性能についてこれだけ詰め込んで熱暴走せず性能も大きく損なわないのは流石" class="level3">
<h3 class="anchored" data-anchor-id="処理性能についてこれだけ詰め込んで熱暴走せず性能も大きく損なわないのは流石">処理性能について:これだけ詰め込んで熱暴走せず、性能も大きく損なわないのは流石</h3>
<p>皆さんお待ちかねであろう、AnTuTu10連ベンチマークテストの結果を、サーマルカメラ(サーモグラフィー)の結果と合わせてお伝えしたい。</p>
<p>当計測は、Pottal-Portalベンチマークレギュレーションver1.1に基づき行った。レギュレーション内容は以下の通りである。</p>
<blockquote class="blockquote">
<p>室温は22.5±1℃、熱気がこもらないように10cm程の高さを確保した網の上に載せて行う。スマートフォンは満充電後、1時間半以上放置。室温と同程度まで放熱されたことを確認後スタート。</p>
<p>AnTuTuBenchmarkのバージョンは9.1.7とする。（バージョンそのものに意味はないため、同一性が確認出来たらアップデートも検討する）</p>
</blockquote>
<p>使用したサーマルカメラはFLIR ONE Gen3(メーカー品番：435-0005-03)である。</p>
<p>測定内容は、</p>
<ul>
<li>AnTuTuスコア(SoCの性能)</li>
<li>バッテリー温度(スマートフォン内部の温度)</li>
<li>スマートフォン背面の最高温度及び熱分布(冷却性能)</li>
<li>スマートフォン前面の最高温度及び熱分布(冷却性能)</li>
<li>バッテリー残量(電池持ちの目安)</li>
</ul>
<p>上記の5項目である。できることならCPU温度も加えたかったのだが、CPU温度を「表示」ではなく長時間「記録」してくれるアプリが見つからなかったので断念した。</p>
<p>バッテリー温度や残量を記録するアプリとしてはBattery Mixを使用した。</p>
<p>バッテリー温度や残量の詳細は、本記事には載せきれないので<a href="https://docs.google.com/spreadsheets/d/1d8nkxalAGj4aPZy7UfpglWCTKLRJkUb_L0bdxtYdKe4/edit?usp=sharing">スプレッドシート</a>をご覧いただければ幸いだ。</p>
<p>また、比較対象はEXP21と同じSoC(Snapdragon888)を採用する同社のゲーミングスマートフォン、ROG Phone5 Ultimate(表記の都合上、以下ROG Phone5もしくはROG5)である。</p>
<section id="連続antutuベンチマーク結果" class="level4">
<h4 class="anchored" data-anchor-id="連続antutuベンチマーク結果">10連続AnTuTuベンチマーク結果</h4>
<div class="cell">
<div class="cell-output-display">
<div id="fig-AnTuTuLine" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-AnTuTuLine-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-AnTuTuLine-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-74" title="図&nbsp;32: AnTuTu Benchmark(ver9.1.7)スコアの推移"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-AnTuTuLine-1.png" class="img-fluid figure-img" width="1152"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-AnTuTuLine-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;32: AnTuTu Benchmark(ver9.1.7)スコアの推移
</figcaption>
</figure>
</div>
</div>
</div>
<div class="cell">
<div id="fig-violin" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-violin-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<div id="fig-violin" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-violin-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-violin-3.png" class="lightbox" data-gallery="fig-violin" title="図&nbsp;33&nbsp;(a): シャピロ・ウィルク検定の結果, p < 0.05であったため、マン・ホイットニーU検定を行ったところ  p=0.002であったため、両者のスコアは統計学的に有意に差があるといえる"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-violin-3.png" class="img-fluid figure-img" data-ref-parent="fig-violin" width="672"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-violin-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) シャピロ・ウィルク検定の結果, <img src="https://latex.codecogs.com/png.latex?p%20%3C%200.05">であったため、マン・ホイットニーU検定を行ったところ<br> <img src="https://latex.codecogs.com/png.latex?p=0.002">であったため、両者のスコアは統計学的に有意に差があるといえる
</figcaption>
</figure>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-violin-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;33: AnTuTuスコアのばらつき
</figcaption>
</figure>
</div>
</div>
<div class="cell">
<div class="cell-output-display">
<div id="fig-AnTuTuTemp" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-AnTuTuTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-AnTuTuTemp-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-76" title="図&nbsp;34: AnTuTuスコアと温度変化の推移"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-AnTuTuTemp-1.png" class="img-fluid figure-img" width="1152"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-AnTuTuTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;34: AnTuTuスコアと温度変化の推移
</figcaption>
</figure>
</div>
</div>
</div>
<section id="ベンチマークスコアの解釈" class="level5">
<h5 class="anchored" data-anchor-id="ベンチマークスコアの解釈">ベンチマークスコアの解釈</h5>
<p>図&nbsp;32, 図&nbsp;33から、ROG Phone5(図中赤色)が、安定した性能を発揮しているのに対し、EXP21(図中青色)は初回こそROG Phone5を超えるスコアを出したものの、それ以降は明らかにサーマルスロットリング<sup>1</sup>(一定以上の温度を超えた際、CPUやGPUの性能を制限してこれ以上温度が上昇しないようにする機能制限)を起こしていることが読み取れる。これは両者の戦略の差によるものだろう。</p>
<p>ROG Phone5はゲーマーのためのスマートフォン、ゲーミングスマホであるため、SoCの発熱によって性能を制限することは極力避けたい。そのため、サーマルスロットリングの閾値を緩くし、かなりの高温にならないと性能制限を行わないようにしていると見える。逆に言えば、それだけ発熱をさせても熱暴走を起こさない放熱性能を備えているからこそ、サーマルスロットリングを緩くしていると考えられる。</p>
<p>また、サーマルスロットリングを緩くしているからといえ、バッテリー温度は45℃を下回っており、表面(背面及びディスプレイ)の温度も43℃を超えることはないこと(図&nbsp;34)から、極めて適切な熱設計をしていることが伺える。</p>
<p>一方のEXP21は、リファレンスモデルとは言え普段使いのスマートフォンである。発熱は熱暴走やスマートフォンの寿命を縮めることにも繋がるため、サーマルスロットリングを厳しくし、「発熱を防ぐために」<strong>わずかに</strong>性能を抑えているのだろう。また、発熱による効率の低下はバッテリー持ちにも悪影響を与える。</p>
<p>サーマルスロットリング──つまり性能を制限してしまうというと聞こえが悪いが、サーマルスロットリングしたAnTuTuスコア(ver9.1.7)であっても74万点というのは、1つ前の世代であるROG Phone3<sup>2</sup>の全力よりもはるかに高い。(空冷ファンを取り付けたROG Phone3で同じAnTuTuベンチマーク ver9.1.7を試したところ、最高値で71万点であった)</p>
<aside id="footnotes" class="footnotes footnotes-end-of-section">
<hr>
<ol>
<li id="fn1"><p>CPUやGPU(を統合したSoC)は、どうしても熱を発してしまう。特にクロック周波数を上げ性能を上げると、その傾向は顕著なものになる。<br> 熱による故障を防ぐために、SoCは一定の温度を超えると、クロックを下げるなどし、性能を制限することでそれ以上の発熱を防ぐ。<br> スマートフォンの場合は、SoCの温度が上昇することで、その周囲にあるバッテリー温度が上昇してしまうことを避けたり、やけどを防いだりという目的があるため、PCに比べて遥かに厳しい温度設定になっている。↩︎</p></li>
<li id="fn2"><p>ROG Phone5の1つ前の世代はROG Phone3である(縁起の悪い4を避けるために、スキップされた)。<br> EXP21やROG Phone5のSoCはSnapdragon 888, ROG Phone3のSoCはSnapdragon 865で、こちらもやはり縁起の問題で末広がりである888という名称になった<span class="citation" data-cites="SDM888">(Frumusanu 2020)</span>。<br> ちなみに、Snapdragonシリーズはこの888を最後に命名規則を変えている。↩︎</p></li>
</ol>
</aside>
</section>
<section id="バッテリー温度内部温度について" class="level5">
<h5 class="anchored" data-anchor-id="バッテリー温度内部温度について">バッテリー温度≒内部温度について</h5>
<p>続いて筆者が着目したのはバッテリーの温度だ。バッテリー(スマートフォンに搭載されているリチウムイオン電池のことを指す)というのは熱に弱く、45℃以上になると劣化が始まると言われている<span class="citation" data-cites="Anker FUJITSU">(Anker 2022, FUJITSU 2014)</span>。</p>
<p>両者ともに45℃のラインは下回っている(図&nbsp;32, 図&nbsp;35)。これは、放熱性能やサーマルスロットリングなどの結果、スマホ内部の温度を適切に保てていると言えよう。当然とは言え、サーマルスロットリングを行っているEXP21の方が統計学的に有意に温度が低い。</p>
<div class="cell">
<div id="fig-BatteryTemp" class="cell quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-BatteryTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell-output-display">
<div id="fig-BatteryTemp" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-BatteryTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-BatteryTemp-3.png" class="lightbox" data-gallery="fig-BatteryTemp" title="図&nbsp;35&nbsp;(a): シャピロ・ウィルク検定の結果, p < 0.05であったため、マン・ホイットニーU検定を行ったところ  p=1.81 × 10^{-6}であったため、両者のスコアは統計学的に有意に差があるといえる。 ボックスプロットは四分位点に基づいて描かれ、ボックスプロットの箱の下辺と上辺は それぞれ第1四分位点と第3四分位点を示し、 箱の内部に描かれる線は第2四分位点(中央値)を示す"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-BatteryTemp-3.png" class="img-fluid figure-img" data-ref-parent="fig-BatteryTemp" width="672"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-BatteryTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) シャピロ・ウィルク検定の結果, <img src="https://latex.codecogs.com/png.latex?p%20%3C%200.05">であったため、マン・ホイットニーU検定を行ったところ<br> <img src="https://latex.codecogs.com/png.latex?p=1.81%20%C3%97%2010%5E%7B-6%7D">であったため、両者のスコアは統計学的に有意に差があるといえる。<br>ボックスプロットは四分位点に基づいて描かれ、ボックスプロットの箱の下辺と上辺は<br>それぞれ第1四分位点と第3四分位点を示し、<br>箱の内部に描かれる線は第2四分位点(中央値)を示す
</figcaption>
</figure>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-BatteryTemp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;35: バッテリースコアのばらつき
</figcaption>
</figure>
</div>
</div>
</section>
<section id="背面及びディスプレイの温度について放熱システムを探る" class="level5">
<h5 class="anchored" data-anchor-id="背面及びディスプレイの温度について放熱システムを探る">背面及びディスプレイの温度について:放熱システムを探る</h5>
<p>高性能なスマートフォンにおいて、SoCの発熱は避けて通れない。そして安全のため、一定の温度を超えたら性能を制限する(サーマルスロットリングを行う)というのは先述の通りである。</p>
<p>もちろん、発熱を抑えるのも大事だが、その熱を冷ましてやるというのも大事なことである。ただ、熱を冷ますと言っても熱が勝手に消えてくれるわけではない。熱というのはどこかに移動させて外部に逃がしてやるものだ。そしてその外部と接触する場所というのが、スマートフォンの表面、つまりディスプレイや背面、フレームにあたる。</p>
<p>放熱をする上で表面が火傷をする程熱くなってしまう、言わば「ホッカイロ」では問題だが、全体がじんわり温かいというのは適切に熱を内部から逃せている証拠であり喜ぶべきことなのだ。(正確には、ディスプレイの場合はディスプレイ自体の発熱もあるため、ディスプレイが温かい=SoCの熱を逃がせているというわけではないが、ディスプレイもまた放熱面であることは事実である)</p>
<div>

</div>
<div class="cell quarto-layout-panel" data-layout-ncol="2">
<div class="quarto-layout-row">
<div class="cell-output-display quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Back_and_DisplayTemp-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Back_and_DisplayTemp-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-Back_and_DisplayTemp-1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-78" title="図&nbsp;36: 背面温度のばらつき"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-Back_and_DisplayTemp-1.png" class="img-fluid figure-img" width="672"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Back_and_DisplayTemp-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;36: 背面温度のばらつき
</figcaption>
</figure>
</div>
</div>
<div class="cell-output-display quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Back_and_DisplayTemp-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Back_and_DisplayTemp-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="exp21_files/figure-html/fig-Back_and_DisplayTemp-2.png" class="lightbox" data-gallery="quarto-lightbox-gallery-79" title="図&nbsp;37: ディスプレイ温度のばらつき"><img src="https://pottal-portal.com/PtPr3/posts/Refresh/exp21_files/figure-html/fig-Back_and_DisplayTemp-2.png" class="img-fluid figure-img" width="672"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Back_and_DisplayTemp-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;37: ディスプレイ温度のばらつき
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<p>図&nbsp;36, 図&nbsp;37の通り、背面及びディスプレイの温度はEXP21とROG Phone5の間に有意な差があるとはいえない結果になった。</p>
<p>それよりも、注目したいのは熱の分布だ。</p>
<div id="fig-heat" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-heat-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-heat" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-heat_back" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-heat_back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140050.gif" class="lightbox" data-gallery="fig-heat" title="図&nbsp;38&nbsp;(a): 【GIF】AnTuTuベンチマークテスト中の温度変化（背面）"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140050.gif" class="img-fluid figure-img" data-ref-parent="fig-heat"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-heat_back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 【GIF】AnTuTuベンチマークテスト中の温度変化（背面）
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-heat" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-heat_display" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-heat_display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140244.gif" class="lightbox" data-gallery="fig-heat" title="図&nbsp;38&nbsp;(b): 【GIF】AnTuTuベンチマークテスト中の温度変化（ディスプレイ側）"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140244.gif" class="img-fluid figure-img" data-ref-parent="fig-heat"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-heat_display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 【GIF】AnTuTuベンチマークテスト中の温度変化（ディスプレイ側）
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-heat-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;38: サーマルカメラで撮影したベンチマーク中の熱分布 上がROG Phone5, 下がEXP21
</figcaption>
</figure>
</div>
<p>サーモグラフィー(図&nbsp;38)を見ていただければわかるが、ROG Phone5もEXP21も中央部はまんべんなく熱くなっており、高負荷なゲーム等で横持ちした際に手に触れる部分は最大でも35.7℃と人肌以下に抑えられている。これはユーザーに不快感を与えず効率的に熱を逃がしているので100点満点だ。</p>
<p>というわけで前置きが長くなってしまったが、この項では、冷却(放熱)性能・冷却システムに焦点を当ててEXP21をレビューしたい。</p>
<p>とは言っても、貸出機であるしそもそも筆者にそんな技術はないので、分解して内部構造を探ることは出来ない。あくまでサーモグラフィーの結果と、明らかにされているROG Phone5の冷却システムをもとに推測をしていくこととなる。</p>
<p>まず、熱源となるSoCだが、これはROG Phone5もEXP21も同じものになる。注目したいのはその配置だ。ROG Phone5では、スマートフォンの中央にSoCを置くことで、均等に熱を分散すると共に、横持ちした際、手に熱を感じさせないような工夫をしていた図&nbsp;39。</p>
<div id="fig-ROG5_YT" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ROG5_YT-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140355.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-82" title="[@YouTube_ROG5]より筆者引用"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140355.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="YouTube_ROG5">(ROG 2021)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ROG5_YT-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;39: ROG Phone5の内部構造
</figcaption>
</figure>
</div>
<p>EXP21のSoCがどこに配置されているか言及された公式資料はなかったが、サーモグラフィーの結果図&nbsp;38を見るに、ROG Phone5と同じく中央に配置されていると思われる。</p>
<p>EXP21の設計はASUSが行っていためROG Phone5と同じような設計であることになんらおかしさはない。0から新しく設計するよりか、同じ筐体サイズであるROG Phone5の設計を下地にしたと考える方が自然だ。(ちなみに、図&nbsp;20で示した通り、ディスプレイパネルは完全にROG Phone5のパーツを流用しており、ディスプレイ下部には、EXP21には不要なスピーカーノッチが存在している)</p>
<p>余談となるが、本体中央にSoCを置くということは、マザーボードの配置もROG Phone5と同じような形となるはずだ。そうなると、4000mAhのバッテリーを単体で下部に配置することはスペースの制約上おそらく出来ない。ということは、EXP21はROG Phone5同様に2つのバッテリーの間にマザーボードが挟まている形となるのだろう。</p>
<p>EXP21の内部構造は不明ながら、製品紹介ビデオでは図&nbsp;40のようななイメージになっている</p>
<div id="fig-EXP21_YT" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_YT-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140659.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-83" title="[@YouTube_EXP21]より筆者引用"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140659.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="YouTube_EXP21">(Snapdragon 2021)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_YT-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;40: EXP21の構造についてのイメージ
</figcaption>
</figure>
</div>
<p>最近はバッテリーを2つに分割し直列接続する(2Sバッテリーにする)ことで、高電圧での急速充電を行うのが流行りだ。</p>
<div id="fig-EXP21_QC5" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_QC5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140805.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-84" title="[@YouTube_QC5]より筆者引用"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114140805.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="YouTube_QC5">(Qualcomm 2020)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_QC5-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;41: Quick Charge 5.0では2Sバッテリーをサポートしているのがアピールポイントの1つだ
</figcaption>
</figure>
</div>
<p>EXP21はSnapdragon Insidersなスマートフォンであり、Qualcommの技術を体現するスマートフォンだ。そんなQualcommのQuick Charge 5.0ではこの2Sバッテリーへの対応が売りの1つになっていること図&nbsp;41や、逆にシングルバッテリーのZenfoneシリーズが65Wの急速充電に対応していないことから、この65W急速充電では2Sバッテリーの証左であり、ひいてはROG Phone5と同じように中央にSoCやマザーボードを、そしてその左右にバッテリーを備えるという形であると考えられよう。</p>
<p>話を戻そう。中央に熱源を持ってくることで、熱は均等に伝えられそうだ。</p>
<p>では、どうやって熱を伝えているのか。これもROG Phone5と同じであれば、3Dベイパーチャンバーとグラファイトシートだろう。</p>
<p>（これも余談だが、ROG Phoneシリーズでは従来これに加えてヒートシンクを採用していることを大々的に喧伝していたが、ROG Phone5ではそのような宣伝はなかった。）</p>
<div id="fig-GAME_GENIE" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-GAME_GENIE-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../../post_images/ROGPhone3_heatsink.png" class="lightbox" data-gallery="quarto-lightbox-gallery-85" title="[@ROG3_Heatsink]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/ROGPhone3_heatsink.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="ROG3_Heatsink">(ASUS)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig quarto-uncaptioned" id="fig-GAME_GENIE-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;42
</figcaption>
</figure>
</div>
<p>おそらくベイパーチャンバーやグラファイトシートで運ばれた熱はディスプレイと背面、そしてサイドのメタルフレームを用いてスマートフォンの表面全体で放熱されるのだろう。内部に余裕がなくヒートシンクを置くスペースがなさそうなEXP21もこれと同様と思われる。</p>
<p>ということで、EXP21の冷却システムはベイパーチャンバーとグラファイトシートによる熱移動と本体表面での放熱(自然冷却)に支えられてそうだ。</p>
<p>スペースの都合上、ROG Phone5とベイパーチャンバーやグラファイトシートが同等のサイズであるとは限らない。むしろ小さくなっている可能性の方が高いだろう。また、放熱箇所の1つであるサイドフレームもROG Phoneと違って金属製ではない。熱伝導率は劣るだろう。まあ、おかげでフレーム部分を持ってもあまり熱くないというメリットもあったのだが。</p>
<p>さて、これで冷却システムの話は一通り出来たと思う。御託はいいから放熱性能はどうなんだよという話だが、実際、ROG Phone5に比べるとEXP21の放熱性能はやや弱いように思える。 実際、サーマルカメラで見た熱の分布(図&nbsp;38)もROG Phone5に比べ高温（図中白色）の分布が少なく、かつ最高温度も高い。</p>
<p>たとえば、背面のサーモグラフィー(図&nbsp;38 (a))を見ると、ROG Phone5に比べて高温部(白く塗られた箇所)が集中しており、最大温度はEXP21の方が高いか同等という結果だ。これはつまり、熱を上手く拡散出来ていないということだ。 背面側にあるのはROG Phone5と同じであればグラファイトシートである(図&nbsp;39)。グラファイトシートの面積が足りてないのか、あるいは単純に背面ガラスパネルの中央にあるSnapdragonのロゴが熱伝導率の差を引き起こし足を引っ張っているのかもしれない。繰り返しになるが、筆者は熱力学や熱設計に詳しくない。この考察が誤りである可能性もある。ただ、まあ熱の分散がROG Phone5に比べて劣っているのと、そもそもサーマルスロットリングを行っているのでSoCの発熱自体は抑えられているはずなのに、ROG Phone5と同じかわずかに高い温度を出しているため放熱能力がやや劣るというのは言えそうだ。</p>
<p>一方のディスプレイサイド(図&nbsp;38 (b))はROG Phone5の設計で同じであれば主力であるベイパーチャンバーがある方になる(図&nbsp;39)。サーマルスロットリングを行っている関係上EXP21の方が温度が低いのは当然だ。そのため色の塗り分けで熱分散を見るのが難しいが、どちらもしっかりベイパーチャンバーが仕事をしているように思える。強いて言えば、ROG Phone5のほうが仕事をしてそうだ。</p>
<p>長くなってきたので、話をまとめよう。まあ、素人目線で見る限りはどちらもしっかりSoCの熱を外に逃せているように見える。しかも、手に触れる部分はきっちり避けているのが見事だ。</p>
<p>EXP21がサーマルスロットリングを行った背景、つまり、なぜサーマルスロットリングの閾値が厳しいのかその理由は定かではないが、筆者はこれこそゲーミングスマートフォンと一般的なスマートフォンの違いであると考える。</p>
<p>ASUSのゲーミングブランド、ROGから出ているROG Phone5は、まさしくゲーマーのためのゲーミングスマートフォンであるため、たとえその影響が僅かであってもサーマルスロットリングによる性能の制限はしたくないと考えるのに対し、一般向けの(EXP21が一般的かはさておき)スマートフォンであれば、最高性能に張り付く意味は薄く、むしろ、発熱というエネルギーロス・能率の低下はバッテリーの浪費に繋がるため避けたいと考えるはずだ。また、バッテリー容量もROG Phone5が6000mAhなのに対し、EXP21は4000mAhだ。なおさら、バッテリーの浪費は避けたいところだろう。サーマルカメラを通じた分析でもEXP21の放熱設計は(ROG Phone5に比べて僅かに劣るとはいえ)優秀のため、熱を扱いきれないからサーマルスロットリングをしているのではなく、バッテリーの節約のために行っていると考えるのが自然だ。</p>
<p>サーマルスロットリングを行っていながら、大幅な性能低下は見られず、昨年のフラグシップモデル以上のパフォーマンスは出せているので、結論としては両者とも優れた放熱性能を持っていると言えよう。ROG Phone5以上に色々と詰め込んでいて余裕がないはずなのに、発熱で大きく性能を落とすことがないのは流石だ。</p>
<p>目次に戻る</p>
</section>
</section>
</section>
<section id="カメラについてとても綺麗に撮れるが撮影は楽しめない" class="level3">
<h3 class="anchored" data-anchor-id="カメラについてとても綺麗に撮れるが撮影は楽しめない">カメラについて:とても綺麗に撮れるが「撮影は楽しめない」</h3>
<p>EXP21は64万画素(Quad Bayer配列のため普段は12万画素)のメインカメラの他に超広角カメラと光学3倍望遠カメラを備えたトリプルカメラ構成となっている。</p>
<p>カメラの設定画面は写真の通りだ。</p>
<div id="fig-EXP21_Cam_Config" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Cam_Config-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130413.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-86" title="図&nbsp;43: EXP21のカメラ設定画面"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130413.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130415.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-87" title="図&nbsp;43: EXP21のカメラ設定画面"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130415.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130418.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-88" title="図&nbsp;43: EXP21のカメラ設定画面"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130418.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Cam_Config-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;43: EXP21のカメラ設定画面
</figcaption>
</figure>
</div>
<p>なお、ウォーターマークも挿入出来るが、後から消すことは出来ない。</p>
<p>「あるもの」がないことを除けば、ASUSスマホのカメラと同じUIだ。Googleレンズにワンタッチで切り替えられるので、地味にすごく便利である。水準器もありがたい。</p>
<div id="fig-EXP21_Cam_G-lens" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Cam_G-lens-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116163958.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-89" title="図&nbsp;44: EXP21のカメラ画面にはGoogleレンズもついているし水準器もある"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116163958.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Cam_G-lens-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;44: EXP21のカメラ画面にはGoogleレンズもついているし水準器もある
</figcaption>
</figure>
</div>
<p>まあ、御託はいいので、作例を見ていただきたい。ちなみに、「カメラについて その2」では他機種と比較しながらの作例を載せているため、そちらも合わせてご覧いただければ幸いだ。(一部写真は被っている)</p>
<p>撮影はHDR補正を含め「オート」かつAIシーン検出をオンにして行い、掲載している写真は縮小(それに伴うEXIF情報の削除)以外編集をしていない。</p>
<p>(EXIFを含めたオリジナルサイズの写真は<a href="https://drive.google.com/drive/folders/1MkDTMCPDWABPoIrPCgyNCO52-K39jwbc?usp=sharing">GoogleDriveにアップ</a>しているのでそちらをご覧いただきたい。なお、ウォーターマークである「Pottal」の文字は撮影前の設定で行っているので、後から消すことは出来ない。)</p>
<section id="exp21メインカメラ" class="level5">
<h5 class="anchored" data-anchor-id="exp21メインカメラ">EXP21メインカメラ</h5>
<div id="fig-EXP21_Cam_Main" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Cam_Main-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194053.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-90" title="ダイナミックレンジも十分に広い"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194053.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ダイナミックレンジも十分に広い</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194051.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-91" title="白飛びもしているが、むしろ味がある気がする"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194051.jpg" class="img-fluid figure-img"></a></p>
<figcaption>白飛びもしているが、むしろ味がある気がする</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194059.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-92" title="図&nbsp;45: EXP21のメインカメラ作例"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194059.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194056.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-93" title="図&nbsp;45: EXP21のメインカメラ作例"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194056.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194040.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-94" title="図&nbsp;45: EXP21のメインカメラ作例"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194040.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194048.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-95" title="質感も良好に捉えている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194048.jpg" class="img-fluid figure-img"></a></p>
<figcaption>質感も良好に捉えている</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194045.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-96" title="前ボケもする"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194045.jpg" class="img-fluid figure-img"></a></p>
<figcaption>前ボケもする</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194043.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-97" title="流石にフレアやゴーストもゼロではないが、表現としては好きだ"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194043.jpg" class="img-fluid figure-img"></a></p>
<figcaption>流石にフレアやゴーストもゼロではないが、表現としては好きだ</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Cam_Main-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;45: EXP21のメインカメラ作例
</figcaption>
</figure>
</div>
<p>筆者としてはとても綺麗に撮れているという印象だ。筆者のセンスがあればもっと素敵な写真が撮れていたことだろう。オートモードのため何も設定はしていないが、全体的に「バエる」仕上がりになっている点は好みが分かれるかもしれない。</p>
</section>
<section id="exp21-超広角カメラ" class="level5">
<h5 class="anchored" data-anchor-id="exp21-超広角カメラ">EXP21 超広角カメラ</h5>
<div id="fig-EXP21_Cam_Wide" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Cam_Wide-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194416.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-98" title="HDRが強すぎるかもしれないが、筆者は好きだ。四隅の甘さもこの写真では良い表現になっている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194416.jpg" class="img-fluid figure-img"></a></p>
<figcaption>HDRが強すぎるかもしれないが、筆者は好きだ。四隅の甘さもこの写真では良い表現になっている</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194411.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-99" title="ディテールがいまいち"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194411.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ディテールがいまいち</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194414.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-100" title="WBは好みが分かれるかもしれない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194414.jpg" class="img-fluid figure-img"></a></p>
<figcaption>WBは好みが分かれるかもしれない</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194407.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-101" title="空のHDR感と右上の松の質感はイマイチかもしれない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194407.jpg" class="img-fluid figure-img"></a></p>
<figcaption>空のHDR感と右上の松の質感はイマイチかもしれない</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194419.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-102" title="端がノイジーなのは否めない"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194419.jpg" class="img-fluid figure-img"></a></p>
<figcaption>端がノイジーなのは否めない</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194421.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-103" title="レンズ性能はそこまで高くなさそうな他、のっぺりしている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194421.jpg" class="img-fluid figure-img"></a></p>
<figcaption>レンズ性能はそこまで高くなさそうな他、のっぺりしている</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Cam_Wide-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;46: EXP21の超広角カメラ作例
</figcaption>
</figure>
</div>
<p>メインカメラももちろん美しく撮れるが、印象的だったのが超広角カメラの写りだ。具体的な比較は後に行うが、ROG Phoneシリーズでは積極的に使おうと思わなかった超広角カメラの写りが(キャプションではちょっと厳し目に評しているが)劇的に良い。超広角で撮ったと言われなければ気付けない程だ。</p>
</section>
<section id="exp21-望遠カメラ" class="level5">
<h5 class="anchored" data-anchor-id="exp21-望遠カメラ">EXP21 望遠カメラ</h5>
<p>望遠も必要十分といった写りだ。光学式なので電子ズームより画質は良いし、何より嬉しいのが光学式手ブレ補正である。望遠はブレやすいので光学式手ブレ補正はありがたい。</p>
<div id="fig-EXP21_Cam_zoom" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Cam_zoom-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194645.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-104" title="図&nbsp;47: EXP21の望遠カメラ作例"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194645.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Cam_zoom-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;47: EXP21の望遠カメラ作例
</figcaption>
</figure>
</div>
<p>作例としてはまったくバエないが、基地局のシールを撮影するときなどは、光学式ズームと光学式手ブレ補正のWパンチが大いに役立った。</p>
<p>さて、ということで文句なしに綺麗な写真が撮れるメインカメラ、そのメインカメラと遜色ない質でワイドな写真が撮れる超広角カメラ、光学式手ブレ補正もついた便利な光学式3倍望遠カメラと文句なしなカメラ構成なEXP21だが、本当に文句はないのだろうか。実はある。</p>
</section>
<section id="exp21のカメラはマニュアル撮影が出来ない" class="level4">
<h4 class="anchored" data-anchor-id="exp21のカメラはマニュアル撮影が出来ない">EXP21のカメラは「マニュアル撮影」が出来ない。</h4>
<p>マニュアル撮影ができない、つまり自分でシャッタースピードやISO、フォーカスを調節出来ないというのは、人によっては「はい、解散。」となる致命的な欠点だ。というか筆者がそのたちである。</p>
<p>スマートフォンのカメラは、ソフトウェアの調整が強く、さらにはコンピュテーショナルフォトグラフィー（Computational photography）、つまりAIを用いてボケ感を強めたり画像合成を行うという要素が強い。レンズやセンサーはスマートフォン向けの小型サイズであり、得られる光学情報は限られているので、デジタル補正でバエる写真にしようという訳だ。</p>
<p>その流れはもちろん分かる。手軽にバエる写真が撮れるのは良いことだ。だが、EXP21は光学的にも優れている。だから、<strong>だからこそその強さを活かした「こだわった」写真が撮りたい</strong>。綺麗な写真が撮れれば撮れる程、筆者の歯がゆさは増していった。</p>
<p>特に流し撮りや光跡といった躍動感のある写真を撮るためには(Pixel6などを除き)マニュアル撮影が必要になる。また、写真好きにとってはスマホで手軽に撮れる良さを享受しつつも自分でも撮ってみたいという気持ちが湧くシーンもあることだろう。やっぱり撮ってて楽しいのはマニュアル撮影なのだ。</p>
<p>ということで、「綺麗な写真」は撮れるが「撮影体験は楽しめない」というのが、EXP21に抱いた感想である。マニュアル撮影など、ZenFoneは古くからサポートしてきたのに、EXP21ではそれが出来ないというのは不思議でならない。Qualcommの意向だとすれば、今後のアップデートで追加される望みも薄いだろう。「綺麗に撮れる」からこそ、筆者にはそれが残念でならない。</p>
<div id="fig-Cam_Compare_Auto" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Auto-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194918.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-105" title="EXP21オート"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194918.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21オート</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194924.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-106" title="ROG Phone5オート"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194924.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG Phone5オート</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194921.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-107" title="ZenFone6オート"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113194921.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ZenFone6オート</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Auto-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;48: オート撮影
</figcaption>
</figure>
</div>
<div id="fig-Cam_Compare_Manual" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Manual-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195351.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-108" title="ROG Phone5マニュアル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195351.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG Phone5マニュアル</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195348.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-109" title="ZenFone6マニュアル"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195348.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ZenFone6マニュアル</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Manual-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;49: マニュアル撮影（ISO25 SS<img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7B120%7D">秒）
</figcaption>
</figure>
</div>
<p>&nbsp;</p>
<p>上手い作例が用意出来なかったが、これが一応その例だ。オートだとどれも明るい写りとなってしまい、静謐な兼六園の雰囲気とは合わない(図&nbsp;48)。</p>
<p>しかし、マニュアル撮影であればこのように落ち着いた雰囲気を捉えることが出来る(図&nbsp;49)。</p>
<p>どちらがよりSNS映えするかは分からないが、筆者が撮りたかったのは後者である。</p>
</section>
<section id="余談aiシーン認識による補正差について" class="level4">
<h4 class="anchored" data-anchor-id="余談aiシーン認識による補正差について">余談:AIシーン認識による補正差について</h4>
<p>2018年以降のASUSスマートフォンのカメラには「AIシーン認識」という機能がある。</p>
<p>これは、認識されたシーンに合わせて自動で写真の写り(おそらく色味など)を調節をしてくれる機能であり、EXP21もその例に漏れずAIシーン認識機能が搭載されている。</p>
<p>EXP21の写真が比較的「バエ」より、つまり彩度やコントラストが高めな仕上がりになるのは、もしかしたらこのAIシーン認識による補正によるものなのではという疑問が生じたため、軽くだが検証してみた。</p>
<p>結論から先に言えば、その差は僅かであり比較してみないと気づかない程自然な仕上がりだった。</p>
<div id="fig-Cam_Compare_AI" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_AI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195555.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-110" title="EXP21 AIシーン認識あり"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195555.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識あり</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195639.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-111" title="EXP21 AIシーン認識なし"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195639.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識なし</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195558.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-112" title="EXP21 AIシーン認識あり"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195558.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識あり</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195641.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-113" title="EXP21 AIシーン認識なし"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195641.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識なし</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195550.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-114" title="EXP21 AIシーン認識あり"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195550.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識あり</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195633.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-115" title="EXP21 AIシーン認識なし"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195633.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識なし</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113200026.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-116" title="EXP21 AIシーン認識あり"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113200026.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識あり</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195636.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-117" title="EXP21 AIシーン認識なし"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113195636.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21 AIシーン認識なし</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_AI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;50: AIシーン認識の比較
</figcaption>
</figure>
</div>
<p>「引き」で見たときに若干緑の彩度が高いと感じる程度なので、AIシーン認識による調節は誤差の範囲と言ってよく、「バエ」な写真に仕上げるのはEXP21のチューニングによるものだと言えそうだ。</p>
<p>目次に戻る</p>
</section>
</section>
<section id="カメラについて-その2asusスマホを用いたハードとソフトの比較" class="level3">
<h3 class="anchored" data-anchor-id="カメラについて-その2asusスマホを用いたハードとソフトの比較">カメラについて その2:ASUSスマホを用いた「ハード」と「ソフト」の比較</h3>
<p>正直に告白しよう。筆者の財力がないせいで、他の名だたるカメラスマホとEXP21の比較が出来なかったのである。そのため、他のASUSスマホと比較して、カメラ性能の違いを見てみようという話になっている。</p>
<p>カメラスペックの詳細は表の通りだ。</p>
<div id="tbl-Cam_spec" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-Cam_spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;2: カメラのスペック比較表（筆者作成）
</figcaption>
<div aria-describedby="tbl-Cam_spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116165254.png" class="lightbox" data-gallery="quarto-lightbox-gallery-118" title="表&nbsp;2: カメラのスペック比較表（筆者作成）"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116165254.png" class="img-fluid figure-img"></a>
</div>
</figure>
</div>
<p>メインカメラの構成は光学式手ブレ補正の有無を除いて、ROG Phone5と同じはずである。つまり、メインカメラにおいては両者の違いを分けるのは「ソフトウェア処理」だけである。(公式サイトのスペックシートでも紹介されていないがEXP21はレーザーAFも備えているため、厳密にはその点もROG Phone5と異なるが、AF性能は今回検証していない)</p>
<p>また、ROG Phone3もメインカメラに限って言えばレンズのF値及びイメージセンサは同じものとなるが、それを処理するSoC(のISP)が異なる。ISPの進化という観点でROG Phone3と比較することができるのだ。</p>
<p>ZenFone6はハードウェアもソフトウェアも1世代以上古い。言ってしまえば噛ませ犬のようなものだが、比較しなければ十分に綺麗な写真が撮れることは証明済みだ。</p>
<p>ちなみに、おまけとしてiPad Pro 12.9インチ(M1)も載せてある。一応最新のiPad ProなのでISPは強いと思われる。iPhone程カメラに力を入れていないはずのiPadでも参考になるだろう。</p>
<p>はてなブログがHEICに対応していなかったため、iPad Pro12.9インチで撮った写真はブログ上では公開しないことにした。(変換しても良かったのだが、iPad Proでの写真を除けば、ちょうど4枚に収まり見栄えも良いためやめた。なお、Google Drive上ではiPad Proで撮った写真も公開しているので、気になる方はそちらをご覧いただきたい。)</p>
<p>繰り返しになるが、撮影はHDR補正を含め「オート」かつAIシーン検出をオンにして行い、掲載している写真は縮小(とそれに伴うEXIF情報の削除)以外編集をしていない。<a href="https://drive.google.com/drive/folders/1MkDTMCPDWABPoIrPCgyNCO52-K39jwbc?usp=sharing">オリジナルサイズの写真はGoogleDriveにアップしている</a>のでそちらをご覧いただきたい。(Google Drive版はEXIF情報も残してあるが、一部写真は位置情報を削除している。)</p>
<section id="飯テロ性能" class="level4">
<h4 class="anchored" data-anchor-id="飯テロ性能">「飯テロ」性能</h4>
<p>まずは、食事の比較だ。いずれも撮影はオートモードで行った。</p>
<div id="fig-Cam_Compare_SeaFood" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_SeaFood-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185236.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-119" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185236.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185233.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-120" title="ROG Phone5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185233.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG Phone5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185238.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-121" title="ROG Phone3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185238.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG Phone3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185241.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-122" title="ZenFone6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113185241.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ZenFone6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_SeaFood-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;51: 海鮮丼の比較
</figcaption>
</figure>
</div>
<p>&nbsp;</p>
<p>海鮮丼で比較をしてみたところ、近距離だったこともありピントの合う範囲がシビアな印象で、iPadを除きどれもエビの頭や足などはボケている。（iPad Proに使われるイメージセンサの詳細は分からないものの、他機種と比べセンサーサイズが小さくボケにくい可能性がある）</p>
<p>EXP21は他の機種と違い、青白い写りとなっている。いわゆる飯テロ画像においては、暖色系が好まれる印象だが、これはこれで悪くない気がする。ホワイトバランス以外で言うと、特に青じその葉脈がはっきり見えるのは、何かシャープに見える補正をかけているからだろうか。</p>
<p>ROG Phone5とは手ブレ補正を除きハードウェアスペックは全く同じだが、ホワイトバランスという点で顕著な差が出た。また、ASUSスマートフォンはEXP21を含めすべて「食事モード」でAI認識されているのにも関わらず、ここまで差が出るとは思ってもいなかった。これがQualcommのチューニングなのだろう。</p>
<p>別日に自宅でも比較をしてみた。</p>
<p>被写体はそれぞれ寿司、野菜、デザートだ。特に設定していないがいずれも「食事モード」となった。</p>
<div id="fig-Cam_Compare_Food" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Food-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191317.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-123" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191317.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191319.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-124" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191319.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191343.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-125" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191343.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191352.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-126" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191352.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191536.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-127" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191536.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191539.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-128" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191539.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191608.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-129" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191608.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191553.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-130" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191553.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191716.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-131" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191716.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191713.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-132" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191713.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191724.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-133" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191724.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191711.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-134" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191711.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Food-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;52: 飯テロ性能の比較
</figcaption>
</figure>
</div>
<p>傾向として、EXP21はとにかく明るく撮りたがるようでISO感度が他機種よりも高めになっている。光学式手ブレ補正を搭載しているのだから、筆者ならISOを下げシャッタースピードを遅くするアプローチで明るくするのだが…。</p>
<p>また、寿司においてはEXP21の明るくコントラストの高い写真に仕上げるという癖が裏目に出ており、玉子ずしが完全に白飛びしてしまっている。</p>
</section>
<section id="風景メイン超広角3倍望遠or電子ズーム" class="level4">
<h4 class="anchored" data-anchor-id="風景メイン超広角3倍望遠or電子ズーム">風景(メイン、超広角、3倍望遠or電子ズーム)</h4>
<p>続いては青空と緑を含む風景画だ。これは橋の上から広角、超広角、3倍望遠でそれぞれ比較した。</p>
<section id="メインカメラの風景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="メインカメラの風景写真比較">メインカメラの風景写真比較</h5>
<div id="fig-Cam_Compare_MainCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_MainCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191931.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-135" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191931.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191933.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-136" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191933.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191938.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-137" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191938.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191936.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-138" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113191936.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_MainCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;53: メインカメラの比較
</figcaption>
</figure>
</div>
<p>まずは、メインである広角カメラでの写りだが、EXP21は青の彩度が高めな印象だ。他のASUSスマホも世代を追うごとに青の彩度が高まっていることから、そういう写りが流行っておりEXP21は最もトレンドをゆくということなのかもしれない。</p>
</section>
<section id="超広角カメラの風景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="超広角カメラの風景写真比較">超広角カメラの風景写真比較</h5>
<div id="fig-Cam_Compare_WideCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_WideCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192051.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-139" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192051.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192054.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-140" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192054.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192102.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-141" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192102.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192048.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-142" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192048.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_WideCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;54: 超広角カメラの比較
</figcaption>
</figure>
</div>
<p>続いて超広角だが、古い機種ではフレアが見られる。出来る限り同じ場所同じ角度で撮ったので、フレアの有無はレンズの質の差だと思われる。(余談だが、この比較をして初めてROG Phone5とROG Phone3で超広角レンズが異なることに気づいた。)</p>
<p>その他はっきり言えるのは色収差だろうか。電柱を拡大してみると、EXP21とそれ以外のASUSスマホで顕著な差がある。ROG Phone5とは同じF値だが、レンズの質が異なるのかEXP21がレンズ補正をしっかりかけているのかは分からない。上記のフレアの有無を考えると、レンズの質は同じで補正をしっかりやっている可能性の方が高そうだ。ASUSとしても同じ部品を大量調達してスケールメリットを得ることでコストを下げたいだろうから、同じF値の異なるレンズを採用するとは考えにくい。</p>
<p>ソフトウェアに関して言えば、ISOやシャッタースピードの選択からチューニングの差を読み取るのが面白いかもしれない。EXP21はISOをけっこう上げシャッタースピードを速くしている一方、他はISOを下げシャッタースピードを遅くしている。</p>
</section>
<section id="倍望遠もしくは電子ズームでの風景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="倍望遠もしくは電子ズームでの風景写真比較">3倍望遠もしくは電子ズームでの風景写真比較</h5>
<div id="fig-Cam_Compare_ZoomCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_ZoomCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192238.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-143" title="EXP21(3倍光学望遠)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192238.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21(3倍光学望遠)</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192241.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-144" title="ROG 5(3倍電子ズーム)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192241.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5(3倍電子ズーム)</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192259.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-145" title="ROG 3(3倍電子ズーム)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192259.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3(3倍電子ズーム)</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192243.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-146" title="Zen 6(3倍電子ズーム)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192243.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6(3倍電子ズーム)</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_ZoomCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;55: 3倍望遠比較
</figcaption>
</figure>
</div>
<p>最後に望遠だが、EXP21のみ光学3倍レンズであとはすべて3倍電子ズームである。</p>
<p>EXP21は光学3倍レンズだけあって他と比べると、かなり草木のディテールがはっきりしている。とは言え、作品として引き伸ばしで見るのは難しく、あくまで「スマホで見る分には」実用的という評価になる。</p>
</section>
</section>
<section id="薄暗い場所での癖を確認" class="level4">
<h4 class="anchored" data-anchor-id="薄暗い場所での癖を確認">薄暗い場所での癖を確認</h4>
<p>次に薄暗い(雰囲気のある)喫茶店での比較だ。</p>
<p>筆者としては薄暗くコントラストに乏しい場所が一番スマホにとって難しく、そしてチューニング(戦略)の差が出るところだと思っている。というのも夜景となればコントラストがはっきりしているし、最近は「夜景モード」なんてものもあるくらい各社が力を入れているが、曖昧な薄暗い場所はそうではない。ワキの甘さが出かねず、気を抜くとノイジーな写りになり、ノイズを避けようとするならソフトウェア補正で潰すか、ISO感度を下げる代わりに(手ブレのリスクを負いながら)シャッタースピードを遅くするしかないからだ。</p>
<p>前置きが長くなった割にバエない写真で恐縮だが、これがその比較である。</p>
<div id="fig-Cam_Compare_Dark" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Dark-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192423.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-147" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192423.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192421.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-148" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192421.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192448.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-149" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192448.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192451.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-150" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192451.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Dark-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;56: 暗所性能の比較
</figcaption>
</figure>
</div>
<p>EXP21は寒色寄りに写す癖があるというのが一番目立つが、面白いのがシャッタースピードだ。EXP21はメインカメラに光学式手ブレ補正を搭載しているので、シャッタースピードを遅くしてもブレには強いはずであり、そのメリットを活かしISOを下げてノイズを潰すものだと思っていたのだが、予想に反しシャッタースピードがROG Phone5と同じだっただけでなく、ISOを上げて、より明るい写りを求めていた。繰り返しになるが、手ブレ補正に強いのだから、シャッタースピードを遅くして明るくするのが筋であるのにも関わらず、だ。</p>
<p>穿った見方かもしれないが、光学的優位よりも、自身のISPとそのチューニングにQualcommは自信を持っているのかもしれない。光学式手ブレ補正を除けばROG Phone5と同じレンズとイメージセンサ、そしてISPを持っていながら、まさかこのような差が生じるとは思わなかった。</p>
<p>食事の写真を比較した際にも感じたことだが、EXP21は明るく撮りたがる傾向がありそうだ。</p>
</section>
<section id="夜景その1メイン超広角" class="level4">
<h4 class="anchored" data-anchor-id="夜景その1メイン超広角">夜景その1(メイン、超広角)</h4>
<p>続いて夜景の比較だ。iPad Proを交えた計5機種での比較はこれが最後となる(iPad ProはGoogleDriveでのみ公開)。</p>
<p>人目もあり、やや画角が異なるが概ね同じ場所から金沢駅を撮った。</p>
<div id="fig-Cam_Compare_Night_MainCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Night_MainCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192820.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-151" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192820.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192817.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-152" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192817.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192831.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-153" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192831.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192822.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-154" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113192822.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Night_MainCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;57: 夜景比較(メインカメラ)
</figcaption>
</figure>
</div>
<p>&nbsp;</p>
<p>流石のQualcommも夜景レベルまで暗くなると光学式手ブレ補正を活かしてくるようで、EXP21のシャッタースピードが1/15秒と一番遅かったが、貪欲なことにISOも最も高く明るさを求めてきた。ISOを高めてもノイズはしっかり処理出来ており、結果として最も綺麗な仕上がりになっている。</p>
<div id="fig-Cam_Compare_Night_WideCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Night_WideCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193056.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-155" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193056.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193054.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-156" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193054.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193104.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-157" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193104.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193051.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-158" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193051.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Night_WideCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;58: 夜景比較(超広角カメラ)
</figcaption>
</figure>
</div>
<p>超広角も広角と同じ画角で撮ってみた。</p>
<p>不思議なことにEXP21はシャッタースピードを広角から変えることなくISOを下げた。スペック表にある通り、超広角には光学式手ブレ補正ではなく電子式手ブレ補正しかないのにも関わらずシャッタースピードを変えることがないのも、そのくせISOを上げるのではなくむしろ下げてきたことも意外だ。ただ、超広角側でISOを下げるという選択は他の機種でも同様だったため、画素ピッチなどを鑑みて、ノイズを避けるための挙動なのかもしれない。</p>
<p>なお、レンズのF値はEXP21とROG Phone5がF2.2と光学的に明るい作りとなっている。光学的優位と優秀なソフトウェア調整もあって、やはりEXP21が一番綺麗な写りになっている。</p>
</section>
<section id="夜景その2メイン超広角6倍ズーム" class="level4">
<h4 class="anchored" data-anchor-id="夜景その2メイン超広角6倍ズーム">夜景その2(メイン、超広角、6倍ズーム)</h4>
<p>夜景としては上記の作例はやや光源に欠けていたので、新宿でも夜景の比較を行った。</p>
<p>なお、この場所は筆者がいつも夜景比較を行っている場所であるため日付を跨いでの比較も可能ではあるものの、今回はそれを行わず、出来うる限り同じ条件で比較を行う。要するにiPad Proを使って撮り忘れたので、iPadとの比較は行わないということである。</p>
<p>新宿での夜景撮影は、広角、超広角、望遠6倍で行った。</p>
<section id="メインカメラでの新宿西口の夜景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="メインカメラでの新宿西口の夜景写真比較">メインカメラでの新宿西口の夜景写真比較</h5>
<div id="fig-Cam_Compare_Night_MainCam_2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Night_MainCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193230.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-159" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193230.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193228.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-160" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193228.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193250.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-161" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193250.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193253.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-162" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193253.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Night_MainCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;59: 夜景比較(メインカメラ)
</figcaption>
</figure>
</div>
<p>まずは、広角の比較だ。明るさが十分であったたためどの機種も夜景モードにはならなかった。</p>
<p>十分な明るさがあったからか、EXP21は大胆にも(他機種と比べ)シャッタースピードを速めISOも下げた。やはり光学式手ブレ補正よりもソフトウェア補正で上手く処理出来るのか、光学的には暗いはずの設定にも関わらず、ROG Phone5と同じかやや明るそうな写真に仕上がった。</p>
<p>夜空に浮かぶ雲は描かれていないが、夜景において中途半端に空が明るいと夜景の明るさが目立たなくなってしまうので、あえてEXP21はコントラストを高めているのかもしれない。</p>
</section>
<section id="超広角カメラでの新宿西口夜景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="超広角カメラでの新宿西口夜景写真比較">超広角カメラでの新宿西口夜景写真比較</h5>
<div id="fig-Cam_Compare_Night_WideCam_2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Night_WideCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193345.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-163" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193345.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193348.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-164" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193348.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193357.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-165" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193357.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193400.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-166" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193400.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Night_WideCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;60: 夜景比較(超広角カメラ)
</figcaption>
</figure>
</div>
<p>同じ場所からの超広角である。目立つのはホワイトバランスの差だろうか。これまでの傾向と同様EXP21はやや青っぽい仕上がりだ。</p>
<p>なお、これまでの傾向などと知った顔で語っているが、ISOやシャッタースピードはこれまでの傾向とはことなり広角に比べISOを上げてきた。その割にシャッタースピードは(光学式手ブレ補正がないのにも関わらず)遅くなっている。ちょっとこれまでの傾向にないことなので、この分析めいた行為への自信がなくなってきた。</p>
<p>とりあえず、処理の傾向としては広角と変わらず夜空を黒く塗るようだ。なんなら、ROG Phone5よりも明るい設定にも関わらず、夜空が暗いのでコントラストをはっきりさせたいというチューニングなのだろう。</p>
</section>
<section id="倍ズームで新宿西口夜景写真比較" class="level5">
<h5 class="anchored" data-anchor-id="倍ズームで新宿西口夜景写真比較">6倍ズームで新宿西口夜景写真比較</h5>
<p>望遠6倍は流石に絵として厳しいものがあるが、それでも光学3倍レンズを使っての6倍ズームというだけあって、他のデジタルズームよりもディテールが明らかにしっかりしている。</p>
<div id="fig-Cam_Compare_Night_ZoomCam_2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_Night_ZoomCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193555.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-167" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193555.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193552.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-168" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193552.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193605.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-169" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193605.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193607.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-170" title="Zen 6"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193607.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Zen 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_Night_ZoomCam_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;61: 夜景比較(6倍ズーム)
</figcaption>
</figure>
</div>
</section>
</section>
<section id="接写マクロ性能比較" class="level4">
<h4 class="anchored" data-anchor-id="接写マクロ性能比較">接写(マクロ)性能比較</h4>
<p>最後に接写の比較を行う。</p>
<p>EXP21はマクロレンズを持たないものの、超広角レンズを用いての接写が可能である。ROG Phone5及びROG Phone3は専用のマクロレンズを持っているので、そちらで撮影した。ZenFone6はそもそもマクロ撮影に対応していないため、今回の比較からは外した。</p>
<div id="fig-Cam_Compare_MacroCam" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Compare_MacroCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193829.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-171" title="EXP21"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193829.jpg" class="img-fluid figure-img"></a></p>
<figcaption>EXP21</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193826.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-172" title="ROG 5"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193826.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 5</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193840.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-173" title="ROG 3"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211113/20211113193840.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ROG 3</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Compare_MacroCam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;62: マクロカメラ比較
</figcaption>
</figure>
</div>
<p>結論から言えば、専用のマクロレンズよりもEXP21の超広角レンズでマクロ撮影を行った方がはるかに綺麗な写真となった。比較にもならない。</p>
<p>「トリプルカメラ搭載」を謳いたいがために数合わせで用意したマクロカメラより、IMX363というちゃんとしたイメージセンサとレンズで撮った方がはるかに綺麗なのだ。ゲーミングスマホにマクロ撮影など求めてない。ROG Phone6(仮)では、いい加減マクロカメラなどやめて少しでも価格を下げて欲しいものだ。</p>
<p>&nbsp;</p>
</section>
<section id="exp21のカメラ性能比較を総評" class="level4">
<h4 class="anchored" data-anchor-id="exp21のカメラ性能比較を総評">EXP21のカメラ性能比較を総評</h4>
<p>EXP21のカメラは全体的に「バエる」写りを意識しており、明るめかつ彩度とコントラストが高い写真に仕上げる。また、寒色寄りの青白い写真になる傾向がある。</p>
<p>メインカメラにおいて、ISOを上げて明るく撮りたがる傾向がある。光学式手ブレ補正を備えているのにも関わらず、シャッタースピードを遅くするよりISOで明るくするきらいがあるのは、とりあえず明るい写真にしノイズはソフトウェア補正で消せるという自信だろうか。</p>
<p>超広角に関しては他機種と比較した際に気になる癖は(ホワイトバランス以外)見られない。写りとしては前述の通りバエを意識した仕上がりになる。</p>
<p>望遠における癖は、そもそも比較に用いた機種に望遠レンズを搭載しているものがなかったため何とも言えない。他機種と違い電子ズームではなく光学3倍という優位と光学式手ブレ補正という強みから、他機種と比較し綺麗に写るがこれはある意味当たり前だろう。</p>
<p>最後になるが、ここで掲載した写真はすべてGoogle Driveにオリジナル(ものによっては位置情報のみ削除している）をアップロードしてある。また、ブログには掲載しきれなかった写真もあるので、興味があればそちらをご覧いただきたい。</p>
<p>目次に戻る</p>
</section>
</section>
<section id="カメラについて-その3動画性能について" class="level3">
<h3 class="anchored" data-anchor-id="カメラについて-その3動画性能について">カメラについて その3:動画性能について</h3>
<p>と言っても書くことは少ない。なぜなら筆者があまり動画をとらないからだ。</p>
<section id="光学式手ブレ補正の実力を確認" class="level5">
<h5 class="anchored" data-anchor-id="光学式手ブレ補正の実力を確認">光学式手ブレ補正の実力を確認</h5>
<p>とりあえず、EXP21の光学式手ブレ補正が動画撮影時にどう頑張っているのかをROG Phone5と比較してみた。すでに何度も触れている通り、メインカメラのハードウェア的には光学式手ブレ補正を除きEXP21とROG Phone5で共通である。そのため、この動画は純粋に「光学式手ブレ補正＆電子手ブレ補正」vs「電子手ブレ補正のみ」 という比較になるはずだ。</p>
<blockquote class="twitter-tweet blockquote" data-media-max-width="560">
<p lang="ja" dir="ltr">
ROG Phone5 UltimateとEXP21の4K60fps動画撮影比較です。<br>EXP21は光学式手ぶれ補正機構を搭載しています。<br>トリミングして比較しやすくしたのが後半にあります。 <a href="https://t.co/5wSuheQNHu">pic.twitter.com/5wSuheQNHu</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1455827876352118791?ref_src=twsrc%5Etfw">November 3, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
ROG Phone5 UltimateとEXP21の4K60fps動画撮影比較です。<br>EXP21は光学式手ぶれ補正機構を搭載しています。<br>トリミングして比較しやすくしたのが後半にあります。 <a href="https://t.co/5wSuheQNHu">pic.twitter.com/5wSuheQNHu</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1455827876352118791?ref_src=twsrc%5Etfw">November 3, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>Twitterでの動画再生がうまくいかない場合や画質が悪い場合は、例のごとくGoogle Driveにあるデータを参照してもらえれば幸いだ。なお今回は容量の都合上生データではなく「比較動画」のみのアップロードとなる。</p>
<p>動画の通り、確かに光学式手ブレ補正は仕事をしており、電子手ブレ補正のみのROG Phone5よりもブレのない映像がとれている。</p>
</section>
<section id="k動画は室温20で30分以上撮影可能" class="level5">
<h5 class="anchored" data-anchor-id="k動画は室温20で30分以上撮影可能">8K動画は室温(20℃)で30分以上撮影可能</h5>
<p>EXP21は8K@30FPS動画も撮影可能なため、どの程度の時間撮影出来るのか≒どの程度発熱に耐えられるのかを検証してみた。</p>
<p>検証は室温（20℃）環境下にて、スマホホルダーを使って三脚に取り付けた状態で行った。</p>
<p>結論から言うと30分を過ぎたあたりで、発熱警告が出たものの撮影そのものは続行可能で、50分ほどで強制停止された。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
8Kチャレンジ、室温20℃で50分間撮影可能だった。本体（バッテリー）温度50℃で制限かけてるのかな。 <a href="https://t.co/nU05W7n11c">pic.twitter.com/nU05W7n11c</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1473554988400246786?ref_src=twsrc%5Etfw">December 22, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>具体的にどこの温度を参照しカメラを矯正停止したのかは分からないものの、強制停止された時のバッテリー温度は48.1℃と記録されており、これが最大値である。</p>
<p>とりあえず、8K@30FPSで50分間撮影した結果、動画のファイルサイズは49.8GBであった。また、バッテリーは80％から25％まで減った。</p>
<p>また、サーマルカメラで本体の温度を測定したところ、このような結果となった。</p>
<p>熱くて持てないということはなさそうだが、低温火傷の可能性や本体の放熱を考えるとスマホホルダーを使って挟みこみミニ一脚や三脚を使うのが良さそうである。</p>
<div id="fig-Cam_Heat" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Cam_Heat-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144148.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-174" title="図&nbsp;63: 長尺動画撮影中の温度"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144148.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144150.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-175" title="図&nbsp;63: 長尺動画撮影中の温度"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144150.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144206.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-176" title="図&nbsp;63: 長尺動画撮影中の温度"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114144206.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Cam_Heat-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;63: 長尺動画撮影中の温度
</figcaption>
</figure>
</div>
<p>本体温度は手に触れないであろうディスプレイ部分で42℃、手に触れるであろうフレーム部分で38℃ほどであった。</p>
<p>1時間を超える撮影となると、おそらく熱云々よりバッテリーが尽きるため、充電しながら撮影することになるが、充電の際に発熱するため今度はバッテリーは問題なくとも熱で長時間の撮影が行えないことになる。</p>
<p>ちなみに、発熱対策としてペルチェ素子クーラーで冷却をしながら撮影したところ1時間を超えて撮影出来たが、バッテリーが先に尽きてしまった。</p>
<p>つまり、長時間撮影するためには、ペルチェ素子クーラーの電源とEXP21本体の充電と2つ給電ポートを用意する必要があるが、そもそもペルチェ素子クーラーの音がノイズとなるので実用的ではない…</p>
<p>実用の範囲内で撮影するとなると8K@30FPSの場合は30分程度と考えておくべきだろう。</p>
<p>&nbsp;</p>
</section>
</section>
<section id="ディスプレイについて美麗かつ144hzでヌルヌル動く" class="level3">
<h3 class="anchored" data-anchor-id="ディスプレイについて美麗かつ144hzでヌルヌル動く">ディスプレイについて:美麗かつ144Hzでヌルヌル動く</h3>
<p>EXP21のディスプレイはゲーミングスマホと同等の…というよりROG Phone5に搭載されたものをそのまま流用したように思える。少なくともカタログスペックを並べる限りハードウェア的には全く同じもののようだ。</p>
<div id="tbl-spec_display" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl quarto-uncaptioned" id="tbl-spec_display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;3
</figcaption>
<div aria-describedby="tbl-spec_display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142006.png" class="lightbox" data-gallery="quarto-lightbox-gallery-177" title="EXP21のディスプレイ周りのスペックシート（筆者作成）"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142006.png" class="img-fluid figure-img"></a></p>
<figcaption>EXP21のディスプレイ周りのスペックシート（筆者作成）</figcaption>
</figure>
</div>
</div>
</figure>
</div>
<p>ROG Phone5と同様、2448 x 1080ドットで20.4:9のアスペクト比を持つ6.78インチSamsung AMOLEDディスプレイで、144Hz 1msの表示機能を持つ。HDR10+に対応し色の表示もDelta-E &lt;1の精度で行える。</p>
<p>ちなみに、Snapdragonの製品ページには111.23％DCI-P3、106.87％NTSC、150.89％sRGB色域カバレッジを備えると書かれているが、ROG Phone5では非公開である。ハードウェア的には同じものを使っているため、(EXP21が特別な補正を行っていない限り)ROG Phone5も同等の色再現が行えると考えられる。</p>
<p>また、ディスプレイの配列はこのようになっている</p>
<div id="fig-Display_Macro" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_Macro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113143229.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-178" title="図&nbsp;64: ディスプレイ配列"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113143229.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_Macro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;64: ディスプレイ配列
</figcaption>
</figure>
</div>
<p>そんなディスプレイはCorning社のGorilla GlassVictusで覆われており高い落下耐性と耐擦傷性を備える。</p>
<p>本当にハードウェア的にはまるっきりROG Phone5と同じもので、EXP21には存在しないはずのデュアルフロントスピーカー(下部)用のスペースまでそのまま残されているくらいだ。</p>
<p>論より証拠、ということでEXP21のディスプレイをROG Phone5 Ultimate及びROG Phone3と比較してみた。</p>
<p>（ROG Phone3に搭載されている有機ELディスプレイは少なくともSamsung製ではないものの、同じく144Hz 1msの表示応答性を持ちHDR10+に対応しておりDelta-E &lt;1の精度もある。大きく異なるのはサイズで、こちらは6.59インチ 2340x1080ドットのAMOLEDディスプレイだ。）</p>
<p>写真はすべて左から順にEXP21、ROG Phone5(Ultimate)、ROG Phone3となる。</p>
<div id="fig-Display_HK" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_HK-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142209.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-179" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 筆者が数年前にZenFone3Deluxe（ZS570KL）を使って撮影した香港の写真"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142209.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>筆者が数年前にZenFone3Deluxe（ZS570KL）を使って撮影した香港の写真</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_HK-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;65: ディスプレイ性能(発色等)比較
</figcaption>
</figure>
</div>
<div id="fig-Display_ASUS-WP" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_ASUS-WP-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142207.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-180" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 かつてのZenFoneにプリインされていた壁紙"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142207.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>かつてのZenFoneにプリインされていた壁紙</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142211.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-181" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 かつてのZenFoneにプリインされていた壁紙2"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142211.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>かつてのZenFoneにプリインされていた壁紙2</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_ASUS-WP-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;66: ディスプレイ性能比較2
</figcaption>
</figure>
</div>
<div id="fig-Display_MyPic" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_MyPic-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142235.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-182" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 筆者撮影の写真"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142235.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>筆者撮影の写真</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142240.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-183" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 筆者撮影の写真2"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142240.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>筆者撮影の写真2</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_MyPic-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;67: ディスプレイ性能比較3
</figcaption>
</figure>
</div>
<div id="fig-Display_AnTuTu" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_AnTuTu-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142232.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-184" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 AnTuTuベンチマークのカラーバー"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142232.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>AnTuTuベンチマークのカラーバー</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142242.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-185" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 AnTuTuベンチマークのカラーバー2"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142242.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>AnTuTuベンチマークのカラーバー2</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_AnTuTu-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;68: ディスプレイ性能比較4
</figcaption>
</figure>
</div>
<div id="fig-Display_Dark" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_Dark-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142244.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-186" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示 有機ELなので、黒一色の場合発光しない（はず）"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142244.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示<br>有機ELなので、黒一色の場合発光しない（はず）</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_Dark-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;69: ディスプレイ性能比較5
</figcaption>
</figure>
</div>
<p>こうしてみて見ると、やはりEXP21とROG Phone5では同じディスプレイ品質と言えそうだ。厳密に言うと、ソフトウェア制御が異なる可能性もあるのだが、こうして見る限りでは違いが分からない。両者ともに綺麗に表示出来ている。</p>
<p>ROG Phone3と両者を比較すると、特に肌の表現や、緑(植物)の表現でやや違いが見受けられる。</p>
<p>なお、余談だが、ROG Phone3は144Hzで表示するとディスプレイの質が悪化し、黒つぶれが酷くなる。(そのため、キャプションにリフレッシュレートを表示していた)</p>
<div id="fig-Display_ROG3_problem" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_ROG3_problem-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142237.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-187" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114142237.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3<br>144Hz</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114143325.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-188" title="左から順にEXP21、ROG Phone5、ROG Phone3 60Hz"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114143325.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3<br>60Hz</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_ROG3_problem-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;70: リフレッシュレートの違いによるディスプレイ性能の変化（Lightroomを用いて露光量+4.35）
</figcaption>
</figure>
</div>
<div id="fig-Display_ROG3_problem2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Display_ROG3_problem2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114143949.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-189" title="左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114143949.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左から順にEXP21、ROG Phone5、ROG Phone3 144Hz表示</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Display_ROG3_problem2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;71: リフレッシュレートの違いによるディスプレイ性能の変化 Pixel3XLでも撮影
</figcaption>
</figure>
</div>
<p>写真がいい加減で申し分ないが、ROG Phone3では144Hz表示時に黒つぶれが見られたが、同様の現象はEXP21及びROG Phone5では確認されず、144Hzだろうと60Hzだろうと変わらぬ精度で表示された。筆者の知る限りしばらくSamsung製のディスプレイを採用しなかった(あるいは公表しなかった)ASUSスマートフォンだが、今年度（2021年度）のASUSスマートフォンでは一転してすべてのモデルでSamsung製AMOLEDディスプレイの採用を公表した。(Zenfone8シリーズは製品ページにその記載はないものの製品発表会でSamsung製ディスプレイの採用を公言している<span class="citation" data-cites="YouTube_Zen8">(ASUS 2021)</span>。</p>
<p>これが、Samsung製AMOLEDディスプレイかと感動した。数年前の筆者のメインスマホであるZenFone3Deluxe(ZS570KL)も確かSamsung製AMOLEDディスプレイだったと記憶しているし、それが筆者にとって初めての有機ELディスプレイスマホだったのだが、その時以上の感動を覚える。</p>
<p>余談ではあるが、Zenfone8 FlipとZenFone7のディスプレイスペックは同じである。そのため、Zenfoneシリーズに限っていえば、ZenFone7の世代からSamsung製のAMOLEDディスプレイを採用していた可能性はあるが、筆者も発表会の詳細を逐一覚えているわけではないのでZenFone7の発表でSamsung製ディスプレイの搭載を公表していたかは不明である。少なくとも製品ページにその記載はない。</p>
<p>※紙幅の都合上、60Hz表示時のディスプレイ比較は掲載していないが<a href="https://drive.google.com/drive/folders/1ArM_zmTSlBUkY4-vklCpxnwUM4m8CLDZ?usp=sharing">GoogleDrive</a>には掲載している。興味があればそちらをご覧いただきたい。</p>
<section id="hz表示について" class="level4">
<h4 class="anchored" data-anchor-id="hz表示について">144Hz表示について</h4>
<p>EXP21のディスプレイは144Hz/120Hz/60Hz/そしてコンテンツに応じてリフレッシュレートを選択するAutoモードの計4種類の表示モードがある。</p>
<p>なお、Autoモードでのリフレッシュレートがどのように選択されるのか、正確に言えば「60Hz」「120Hz」「144Hz」という3つの選択肢から選んでいるのか、それとも可変リフレッシュレート(もっと柔軟にリフレッシュレートを選べるもの)なのかは検証はしていない。</p>
<p>筆者は144Hzしか使わないものの、人によっては「90Hzで十分！それよりバッテリー持ちを重視したい」ということもあるので90Hzという選択肢があれば、なお良かったと思う。</p>
<p>また、前述の通り144Hz表示をしてもROG Phone3のように画質が悪くなることもない。</p>
</section>
<section id="明るさについて" class="level4">
<h4 class="anchored" data-anchor-id="明るさについて">明るさについて</h4>
<p>季節がもう秋だったこともあり、少なくとも野外で問題なく使えるディスプレイ輝度であった。</p>
<p>カタログスペック上は800nit、ピーク輝度は1200nitとなっている。ピーク輝度はHDR表示などで使われるものなので、参考にすべきはこの800nitというところだろう。繰り返しになるが、秋空の下で使う分には問題ない明るさであった。</p>
<p>目次に戻る</p>
</section>
</section>
<section id="オーディオについて付属イヤフォンが最高" class="level3">
<h3 class="anchored" data-anchor-id="オーディオについて付属イヤフォンが最高">オーディオについて：付属イヤフォンが最高</h3>
<p>EXP21のオーディオに関して語るなら、外せないのが付属の完全ワイヤレスイヤフォン「MW08S」の存在だ。</p>
<p>音質及び接続性(途切れにくさ)、そして遅延のなさ、それを取っても素晴らしい。また、最低限のノイズキャンセル機能も備えている。これがあるから3.5mmオーディオジャックがないことは許せよう。付属品にUSB TypeCから3.5mmオーディオジャックに変換するアダプタがないことも許せる。QualcomはそれだけこのBluetooth技術、つまりQualcomm aptX Adaptiveを軸にしたSnapdragon Sound technologyに自信を持っているのだ。そして3.5mmオーディオジャックを「残しておいて欲しい派」の筆者もそれを認めざるを得ない。ああ、これならオーディオジャックなくてもいいや、と。</p>
<p>誤解を招かぬよう補足すると、筆者も普段はBluetoothヘッドフォンを使っている。しかし、遅延や人混みでの音切れもあり、やっぱり3.5mmオーディオジャックもあって欲しいなぁと思ってしまう、いわばどっち付かずな人間だ。強硬派は寝返る時は寝返るものだが、筆者のようなどっち付かずな人間というのは、両者のメリットデメリットが見えている分、なかなか踏み切れない。自分で言うのもアレだが、そんなどっち付かずな人間にここまで言わせる程、Snapdragon Sound technologyは素晴らしかった。</p>
<p>まあ、現状この技術はスマホもオーディオ機器も厳しい検査が必要で、aptX AdaptiveはまだしもSnapdragon Sound technologyは流行ると思えない(相当組合わせを選ぶと思う)ので、完全に寝返ったわけではないのだが。</p>
<p>前置きがまた長くなってしまったが、ここからEXP21とその付属イヤフォンの話をしていき、本体スピーカーの話はその後に行う。</p>
<section id="付属の完全ワイヤレスイヤフォンmw08sについて" class="level4">
<h4 class="anchored" data-anchor-id="付属の完全ワイヤレスイヤフォンmw08sについて">付属の完全ワイヤレスイヤフォン「MW08S」について</h4>
<p>EXP21にはSnapdragon Sound technologyだけでなく、Snapdragon Sound Optimizationと呼ばれるオーディオイコライザーのような機能も備えている。</p>
<div id="fig-SnapdragonSound" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-SnapdragonSound-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130337.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-190" title="図&nbsp;72: Snapdragon Sound Optimization プリセットは、オートモードの他、「Music」「Video」「Game」「Voice」の4種類が選べ、オートモード以外は手動でプロファイルを調節することができる。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130337.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130339.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-191" title="図&nbsp;72: Snapdragon Sound Optimization プリセットは、オートモードの他、「Music」「Video」「Game」「Voice」の4種類が選べ、オートモード以外は手動でプロファイルを調節することができる。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130339.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130341.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-192" title="図&nbsp;72: Snapdragon Sound Optimization プリセットは、オートモードの他、「Music」「Video」「Game」「Voice」の4種類が選べ、オートモード以外は手動でプロファイルを調節することができる。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130341.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-SnapdragonSound-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;72: Snapdragon Sound Optimization<br>プリセットは、オートモードの他、「Music」「Video」「Game」「Voice」の4種類が選べ、オートモード以外は手動でプロファイルを調節することができる。
</figcaption>
</figure>
</div>
<p>デフォルト（Snapdragon Sound Optimizationオンかつのオート状態）ではベースがやけにくっきり聴こえる。無理して1音1音をはっきり聴かせようとしてるからか、聴き疲れする。</p>
<section id="snapdragon-sound-optimizationは切った方が良い" class="level5">
<h5 class="anchored" data-anchor-id="snapdragon-sound-optimizationは切った方が良い">Snapdragon Sound Optimizationは切った方が良い。</h5>
<p>オフにした状態でも、ちゃんと1音1音が聴こえるため基本的にはオフにした方が良い…と言いたいのだが、人間とは本当に勝手なもので、オフにしたらしたで、段々と濃い味付けが恋しくなるものだ。先程は香水を過剰に振りまいた時のように感じたチューニングが、打って変わって、香りが花開いたと感じるのだから、我ながら呆れてしまう。ただ、香りと違って嗅覚疲労（段々と強い匂いに慣れてしまう）ならぬ「聴覚疲労」は起こらず、文字通り聴いていて「疲れて」しまうので、長時間聴く場合はオフにしたい。ノイズキャンセリングと併せて、通勤電車や人混みなどノイジーなところで濃いめに味付けたいときに使うのが良いだろう。</p>
<p>ちなみに、このSnapdragon Sound Optimizationは他のBluetoothオーディオでも使用が可能だ。傾向は概ね同じで、オンにすると音圧強めで聴き疲れする。</p>
<div id="fig-Sound_opt" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Sound_opt-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150515.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-193" title="図&nbsp;73: WH-1000XM3に接続したときの通知"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150515.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Sound_opt-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;73: WH-1000XM3に接続したときの通知
</figcaption>
</figure>
</div>
</section>
<section id="付属品であるmw08sの音質について" class="level5">
<h5 class="anchored" data-anchor-id="付属品であるmw08sの音質について">付属品であるMW08Sの音質について</h5>
<p>前述の通り、普段はEXP21のSnapdragon Sound Optimizationをオフにしている。つまり、ピュアな状態でのレビューとなる。</p>
<p>と、言っても筆者はオーディオオタクではないので多くのオーディオ機器を聴き比べた経験はなく、また筆者の耳は音を聴き分けるためではなく眼鏡をかけるためにあるとすら思っている。</p>
<p>そんな筆者のレビューなど、なんの参考にならない気がするが一応レビューしておく。</p>
<p>まず、全体的な印象として、解像度が高いのに嫌味のない透き通った音だと感じた。1音1音がはっきり聴こえるのに聴き疲れしないのでいつまでも聴き続けられる。</p>
<p>繰り返しになるが、筆者の耳は飾りでありなおかつオーディオオタクではない。そのため、Hi-Res音源は、アニメ版「ゆるキャン△」のエンディングテーマである「ふゆびより」(24bit/96kHz)と「きのこ帝国」の「金木犀の夜」(24bit/48kHz)の2つしか持っていない。この2曲がオーディオ評価に適切かは分からないものの、「ふゆびより」では冬の空気感が伝わってくるような澄んだ歌声と繊細な口笛が楽しめ、「金木犀の夜」は今まであまり意識して来なかったベースの音をはっきり意識するようになった。また、両者ともHi-Res音源対応のアプリNePLAYER Liteの24bit/192kHz再生可能な買い切りオプションを使った上で再生した。</p>
<p>高音域の評価はCD音源となってしまうが、吉田有里さんが「三峰真白」役を務める「未確認で進行形」のキャラソンや、彼女を含む5人のメンバーで構成された「FIVE STARS」のアルバム「A&amp;G NEXT BREAKS FIVE STARS BEST」を用いた。</p>
<p>吉田有里さんの声は非常に高く、高音域の評価には丁度いいからというのが建前で、本音は推しの声をいい音で聴きたいからなのだが、それはさて置き、キャラソンや「ラブラブのテーマ(ソロ)」では彼女の特徴的な声が如何なく発揮され、グループ曲では「FIVE STARS」5人の声がはっきりと聴き分けられた。</p>
</section>
<section id="ノイズキャンセリング機能について" class="level5">
<h5 class="anchored" data-anchor-id="ノイズキャンセリング機能について">ノイズキャンセリング機能について</h5>
<p>ノイズキャンセル機能の設定は、プリインストールされているMaster &amp; Dynamic社のアプリを通じて行う。</p>
<p>ノイズキャンセルモードは「強い方(MAX ANC)」と「弱い方(ALL DAY)」の二種類。PCファンや扇風機の音が響く室内で試したところ、強い方はむしろホワイトノイズ製造機という感じで弱い方は普通にファンの音が聴こえるため、ないよりマシ程度であった。</p>
<p>外でも試したが、どちらもホワイトノイズは気にならなかった。</p>
<p>筆者はBluetoothイヤフォンを持っておらず、比較対象がトップクラスのノイズキャンセル機能を持つヘッドフォンWH-1000XM3となっているため、正しくノイズキャンセル機能を評価出来ているとは思えないが、総じて「ないよりマシ」のノイズキャンセル性能だったという印象だ。</p>
<p>音楽を流せばそれなりに周囲の音は消えるものの、無音のままだと耳栓よりちょっとマシ程度なので、ノイズキャンセル機能を目当てにするものではない。尤も、これは付属品であり非売品だ。流石にこれを目当てにEXP21を買うような猛者はいないだろう。</p>
<p>&nbsp;</p>
</section>
<section id="接続性について" class="level5">
<h5 class="anchored" data-anchor-id="接続性について">接続性について</h5>
<p>外でBluetoothオーディオ機器を使っていると悩ませられるのが音飛びだ。人混みはもともと電波にとって鬼門だったところに、完全ワイヤレスイヤフォンの普及によって、人混み=音飛びというのが当たり前になってしまった。</p>
<p>筆者はEXP21とMW08Sの組み合わせについてベタ褒めしているが、果たして「音飛び」は問題ないのだろうか。</p>
<p>結論から言えば、Snapdragon Sound technologyを使っている限り音「飛び」はない。途切れることなく聴こえる。聴こえるのだが、人混みで問題がないわけではない。混雑すると、音質が目に見えてガタっと切り替わるのですぐに分かってしまうのだ。</p>
<p>これは、Qualcomm aptX Adaptiveないしそれに支えられているSnapdragon Sound technologyが、Bluetoothの転送データレートを状況によって切り替えているからだと思われる。通信が安定しているところでは、高いデータレートに、通信が不安定な人混みでは低いデータレートにすることで音質と接続安定性のバランスを取っているのだ。</p>
<p>が、しかし、このデータレートの選択による音質の変化が極端なため、「音飛び」はしないものの一貫したリスニング体験は出来ない。</p>
<p>具体的には、「耳に水が詰まった/抜けた」時の感覚で音質が切り替わる。音の鳴っている場所も違って聴こえ、混雑している所では音がこもる。そしてもちろん音の解像度も落ちる。本当に笑ってしまうくらい耳に水が入った時の感覚なのだ。</p>
<p>途切れるよりは音が聞こえた方がまだマシなのだが、ここまで極端な音質変化はもうちょいどうにかシームレスに出来なかったのかという気になる。（なお、この極端な音質変化はSnapdragon Sound technologyに対応していないROG Phone5との組み合わせでは発生しなかったため、aptX Adaptiveの挙動ではなくSnapdragon Sound technologyによる可能性がある。尤も単にROG Phone5でテストした時にこの音質変化が発生しなかっただけということも考えられるので、何が原因でこうなるのか明言することは出来ない。）</p>
<p>繰り返しになるが、従来のワイヤレスイヤフォンで悩まされる音飛びよりははるかにマシであり、さらに言えば外で有線イヤフォンを使った際のあの絡まりやタッチノイズ（ケーブルが擦れた時のノイズ）など耐えられる気がしないので、筆者の中では現状これが一番である。</p>
</section>
<section id="音ゲーもできる遅延のなさについて" class="level5">
<h5 class="anchored" data-anchor-id="音ゲーもできる遅延のなさについて">音ゲーもできる遅延のなさについて</h5>
<p>イヤフォンの評価なのか本体の評価なのか堺が怪しいが、EXP21と付属のイヤフォンの組み合わせで実現されたSnapdragon Sound technologyは、遅延にシビアなリズムゲーム(音ゲー)を難なくこなせる程に低遅延だった。</p>
<p>これは、高音質なモードと低遅延なモードを上手く切り替えられているからである。</p>
<p>具体的には音ゲーをプレイするときはQualcomm aptX Adaptiveのプロファイルが自動的(というか強制的に)Low Latencyモードに切り替わる。</p>
<div id="fig-Qualcomm_aptX_Adaptive" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Qualcomm_aptX_Adaptive-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150701.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-194" title="図&nbsp;74: デレステを起動したところ、強制的にLow Latencyモードに切り替わった"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150701.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Qualcomm_aptX_Adaptive-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;74: デレステを起動したところ、強制的にLow Latencyモードに切り替わった
</figcaption>
</figure>
</div>
<p>なお、この挙動はMW08SとEXP21の組み合わせでのみ見られ、ROG Phone5やROG Phone3とMW08Sを接続した際は、aptX Adaptiveこそ有効になるものの、aptX Adaptiveの設定画面を呼び出すことは出来なかった。</p>
<div id="fig-Qualcomm_aptX_Adaptive_Setting" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Qualcomm_aptX_Adaptive_Setting-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150816.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-195" title="Low Latency"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150816.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Low Latency</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150803.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-196" title="High Quality"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114150803.jpg" class="img-fluid figure-img"></a></p>
<figcaption>High Quality</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Qualcomm_aptX_Adaptive_Setting-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;75: aptX Adaptiveの設定画面
</figcaption>
</figure>
</div>
<p>ちなみに、プロファイルの切替えは手動で行えない。 そのため、aptX Adaptiveの挙動なのかSnapdragon Sound technology対応機であるEXP21だからなせる技なのかは分からなかった。特にROG Phone5では相性が悪く高音質モードのまま切り替わらないような挙動で遅延が酷かった（実際にはプロファイルが見れないため不明)。</p>
<p>今回の遅延評価に用いたのは「アイドルマスター シンデレラガールズ スターライトステージ（デレステ）」である。なお、筆者の腕前のせいで難易度「MASTER」(大きく分けて5段階ある難易度のうち上から2番目)の「お願いシンデレラ」すらフルコンボ(ミスなしでクリア)出来ていないが、これは遅延のせいではなくあくまで筆者の腕前のせいだ。</p>
<div id="fig-EXP21_BT_Latency" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BT_Latency-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114151235.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-197" title="無調整でのタイミング表示は23"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114151235.jpg" class="img-fluid figure-img"></a></p>
<figcaption>無調整でのタイミング表示は23</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114151238.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-198" title="遅延は感じずプレイに支障はない(が、筆者が下手なので説得力に欠ける)"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114151238.jpg" class="img-fluid figure-img"></a></p>
<figcaption>遅延は感じずプレイに支障はない(が、筆者が下手なので説得力に欠ける)</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BT_Latency-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;76: EXP21とMW08Sの組み合わせ(Low Latencyモード)
</figcaption>
</figure>
</div>
<p>Qualcomm aptX AdaptiveのLow Latencyは本当に低遅延であり、デレステでのタイミング調整値の差(本体スピーカーの調整値と付属の完全ワイヤレスイヤフォンMW08SをQualcomm aptX Adaptive Low Latencyで接続した際の調整値)は僅か2.6であった。筆者の体感としては「±8」程度の差であれば問題なくプレイ出来るという認識であるから、これは恐るべき数値だ。</p>
<div id="fig-EXP21_BT_Latency_Test" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BT_Latency_Test-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../../post_images/EXP21_BT_Test.png" class="lightbox" data-gallery="quarto-lightbox-gallery-199" title="本体スピーカーのタイミング調整値を0とした際の遅延の比較 タイミング調整値そのものの絶対値は(おそらくSoCやDACの差などで)個体値があり、他機種と直接比較することはできない(意味がない) そのため、本体スピーカーで測定したタイミング調整値を0(基準値)とし、その差をみた"><img src="https://pottal-portal.com/PtPr3/post_images/EXP21_BT_Test.png" class="img-fluid figure-img"></a></p>
<figcaption>本体スピーカーのタイミング調整値を0とした際の遅延の比較<br>タイミング調整値そのものの絶対値は(おそらくSoCやDACの差などで)個体値があり、他機種と直接比較することはできない(意味がない)<br>そのため、本体スピーカーで測定したタイミング調整値を0(基準値)とし、その差をみた</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BT_Latency_Test-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;77: デレステのタイミング調整機能を用いた遅延の測定
</figcaption>
</figure>
</div>
<p>なお、結果は<a href="https://docs.google.com/spreadsheets/d/1KqIXyngaZ2IjiECjj8Il3hWpnsquT4uUXIuIkS7EEvc/edit?usp=sharing">Google Drive</a>でも公開している。</p>
<p>目次に戻る</p>
</section>
</section>
<section id="exp21の本体スピーカーについて音量も音質も十分" class="level4">
<h4 class="anchored" data-anchor-id="exp21の本体スピーカーについて音量も音質も十分">EXP21の本体スピーカーについて:音量も音質も十分</h4>
<p>EXP21は画面上部と本体側面(底部)にスピーカーを備える。ROG Phoneシリーズとは違い、デュアルフロントスピーカーではないものの、大きな違和感(左右差をおぼえること)なくステレオを楽しむ事ができる。</p>
<blockquote class="twitter-tweet blockquote" data-media-max-width="560">
<p lang="ja" dir="ltr">
EXP21 Smartphone vs ROG Phone5 Ultimate <br>スピーカー比較テスト <a href="https://t.co/9XdvIeIJR0">pic.twitter.com/9XdvIeIJR0</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1481832803436462082?ref_src=twsrc%5Etfw">January 14, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
EXP21 Smartphone vs ROG Phone5 Ultimate <br>スピーカー比較テスト <a href="https://t.co/9XdvIeIJR0">pic.twitter.com/9XdvIeIJR0</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1481832803436462082?ref_src=twsrc%5Etfw">January 14, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>（Twitterでの動画再生がうまくいかない場合や画質が悪い場合は、例のごとく<a href="https://drive.google.com/drive/folders/1w8wM4K6UvahdUoYcXNeBVbmy4JdH6DzP?usp=sharing">Google Drive</a>にあるデータを参照してもらえれば幸いだ。）</p>
<p>最大音量がけっこう大きくなおかつ目立った音割れはしなかったため、スマートフォンのスピーカーとしてはかなり上位のものとなるのではないだろうか。</p>
<p>ちなみに、ROG Phone5と比べるとやや見劣りする他、高音域の音質に顕著な差がある。とはいえ、最高峰のROG Phone5と比べてしまうのは酷であろう。</p>
<p>&nbsp;</p>
</section>
<section id="exp21そのもののbluetooth性能について" class="level4">
<h4 class="anchored" data-anchor-id="exp21そのもののbluetooth性能について">EXP21そのもののBluetooth性能について</h4>
<p>繰り返しになるが、EXP21はSnapdragon Sound technology（Qualcomm aptX Adaptive）に対応している他、LDAC、SBC、AACといったBluetoothオーディオコーデックに対応していることを確認した。BluetoothのバージョンはBluetooth5.2とある。</p>
<p>アンテナ感度は(定量的測定ではなく、あくまで主観によるものだが)これまでで抜群に良く、LDACでもほとんど音飛びしなかった。（Snapdragon Sound technologyとは違い全く音飛びしないというわけではない。）</p>
</section>
</section>
<section id="exp21のセルラー通信について" class="level3">
<h3 class="anchored" data-anchor-id="exp21のセルラー通信について">EXP21のセルラー通信について</h3>
<p>EXP21の対応bandは画像の通りである。</p>
<div id="fig-EXP21_Band" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Band-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152142.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-200" title="[@EXP21_Spec]より筆者引用"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152142.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="EXP21_Spec">(Qualcomm)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Band-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;78: EXP21の対応バンド
</figcaption>
</figure>
</div>
<p>他のSIMフリー端末ではiPhoneぐらいでしか類を見ないbandの充実ぶりである。(もちろん、キャリアモデルであれば自社のband以外には力をいれない)</p>
<p>一般的に、複数bandに対応するためにはコストと技術がいると聞くので、EXP21がいかに力を入れて作られているかがわかる。</p>
<p>5Gに関して言えば、EXP21は5G sub6(n77, n78, n79)及びミリ波(n257)に対応している。</p>
<p>（転用5Gを含む正確なbandは画像の通りである。）</p>
<p>特にSIMフリースマホでn79に対応しているのは珍しい。例えば同じASUS製5Gスマホでも、フラグシップであるZenfoneシリーズはn79に対応していない。</p>
<p>これは、n79が世界的には普及していないbandであり、なおかつSub6波の中でも他が3.7GHz帯な中n79は4.5GHzと離れておりかつ高い周波数だからだ。</p>
<p>ちなみに、EXP21では(もちろんローカル5GのSIMとそのAPN設定が必要なものの)ローカル5Gを利用することができた。今回試したのは都立大学南大沢キャンパスで用いられているもので、これはn79を使っている。</p>
<div id="fig-EXP21_BT_Local5G" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BT_Local5G-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211215/20211215191717.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-201" title="都立大にて運用されているローカル5G(n79)を受信している様子"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211215/20211215191717.jpg" class="img-fluid figure-img"></a></p>
<figcaption>都立大にて運用されているローカル5G(n79)を受信している様子</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BT_Local5G-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;79: 東京都立大学南大沢キャンパスで行われた「ローカル5Gを活用した実証実験の体験会」にて筆者撮影
</figcaption>
</figure>
</div>
<p>周波数は高ければ高いほど扱いが難しく、しかも離れた周波数を1つのアンテナで効率良く受信するのは更に難しいことだと聞く。そのため、docomo以外のスマートフォンでn79に対応する端末は珍しいのだ。</p>
<p>さらに言えば、ミリ波のbandもすごい。日本ではn257以外用いられていないがスペック上はn260にも対応している。ミリ波はおそらくミリ波用のアンテナを用いているものだと思われるが、これも26GHz、28GHz、跳んで39GHzと幅が広い。</p>
<p>ASUSがミリ波のスマートフォンを出すのはこれが初めてなのに、よくもまあこれだけ詰め込んだと感心してしまった。</p>
<p>話を戻そう。</p>
<p>今回はdocomoの5G及び、au(povo2.0)、楽天モバイルで検証を行っている。一方、今回検証が行えなかったSoftbank回線だが、公式により動作確認がなされている<span class="citation" data-cites="SoftBank">(SoftBank)</span>。</p>
<p>また、ローカル5GのSA運用がされている東京都立大学 南大沢キャンパスにて「999002」というIMSIを検知し、実際にローカル5GのSIMを指すことで通信が行えた。ちなみにこのIMSIはROG Phone5では確認出来ていない。</p>
<div id="fig-EXP21_Local_5G_IMSI" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Local_5G_IMSI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152313.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-202" title="2021年10月25日 東京都立大学南大沢キャンパスにて筆者撮影"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152313.jpg" class="img-fluid figure-img"></a></p>
<figcaption>2021年10月25日 東京都立大学南大沢キャンパスにて筆者撮影</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Local_5G_IMSI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;80: ローカル5GのIMSI
</figcaption>
</figure>
</div>
<blockquote class="blockquote">
<p>ローカル５Ｇの運用者が、自らコアネットワーク設備（ＨＬＲ/ＨＳＳ）を構築してローカル５Ｇを運用しようとする場合であって、当該ローカル５Ｇの設備を自らの通信の用にのみ供しようとする場合は、「999-002」から始まるＩＭＳＩを使用することとする。 <span class="citation" data-cites="Soumu">(総務省 2019)</span></p>
</blockquote>
<p>とあるため、これはSAで運用されているローカル5Gのものであり、付近でこれを行っているのは東京都立大学 南大沢キャンパスだけである。</p>
<p>なお、当レビューでは実際に掴むバンドやEN-DC,CAの組み合わせについて実測を行っていない。</p>
<p>これは</p>
<ol type="1">
<li>EXP21ではrootを外さない限りNRの詳細やCAの組み合わせを見ることが出来ないという点</li>
<li>筆者が基地局に疎く、これらの情報なしに吹いてるNRが分からないという点</li>
<li>貸出機では何故か5Gを安定して掴むことが出来なかったという点</li>
</ol>
<p>という上記3点が理由だ。</p>
<p>①に関しては、Android12で開放されるとの噂があるので期待したい。</p>
<p>③に関しては試供用モデルの日本向けOS書き換え不良によるものとのことで、後日再貸出されたモデルでは正常に通信が行えた</p>
<section id="exp21の5g安定性について" class="level4">
<h4 class="anchored" data-anchor-id="exp21の5g安定性について">EXP21の5G安定性について:</h4>
<p>この記事の冒頭で書いた通り、今回お貸りしたEXP21はVoLTEが有効にならないという挙動を見せたが、これは試供用モデルの日本向けOS書き換え不良によるものとのことで、正常な日本版OSのものをレンタルさせていただくこととなった。</p>
<p>その後の、貸出機では問題なく使用できたが、詳細な検証は時間の都合上行っていない。</p>
</section>
<section id="exp21の5g速度について" class="level4">
<h4 class="anchored" data-anchor-id="exp21の5g速度について">EXP21の5G速度について</h4>
<p>前述の通り、安定して5Gが受信出来ず、かつNRが見れないためSub6なのかミリ波なのか分からないが、ミリ波が吹いているであろうdocomoの基地局前で測定を行った。</p>
<p>その最高速度がこちらである。</p>
<div id="fig-EXP21_5G_SppedTest" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_5G_SppedTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152719.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-203" title="図&nbsp;81: EXP21の5G速度 新宿都庁付近にて筆者撮影"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152719.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152729.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-204" title="図&nbsp;81: EXP21の5G速度 新宿都庁付近にて筆者撮影"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114152729.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_5G_SppedTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;81: EXP21の5G速度 新宿都庁付近にて筆者撮影
</figcaption>
</figure>
</div>
<p>とりあえず、実測で最大1.5Gbpsのダウンロード速度が出ている。アップロード速度は最大30Mbps程である。</p>
<p>docomoだけでなく、KDDI、Rakuten、ローカル5Gを使った5G通信を確認している</p>
<div id="fig-EXP21_5G" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_5G-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153326.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-205" title="Rakuten"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153326.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Rakuten</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153329.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-206" title="KDDI"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153329.jpg" class="img-fluid figure-img"></a></p>
<figcaption>KDDI</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153332.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-207" title="Docomo"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153332.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Docomo</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153334.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-208" title="都立大ローカル5G"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113153334.jpg" class="img-fluid figure-img"></a></p>
<figcaption>都立大ローカル5G</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_5G-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;82: 左から順に、Rakuten、KDDI、Docomo、都立大ローカル5G
</figcaption>
</figure>
</div>
<p>目次に戻る</p>
</section>
</section>
<section id="exp21のwi-fi速度やアンテナ感度について速いそしてrog-phone5を超える感度の良さ" class="level3">
<h3 class="anchored" data-anchor-id="exp21のwi-fi速度やアンテナ感度について速いそしてrog-phone5を超える感度の良さ">EXP21のWi-Fi速度やアンテナ感度について:速い！そしてROG Phone5を超える感度の良さ</h3>
<section id="exp21のwi-fi性能について" class="level4">
<h4 class="anchored" data-anchor-id="exp21のwi-fi性能について">EXP21のWi-Fi性能について</h4>
<p>EXP21は6GHz帯を用いたWi-Fi 6Eに対応しているものの、日本ではまだWi-Fi6Eを使うことが出来ない。そのため、日本においてはWi-Fi6 (802.11a/b/g/n/ac/ax)まで利用可能だ。2x2 MIMOにも対応している。</p>
<p>5GHz帯において、80MHzまでのサポートか160MHzの帯域幅をサポートしているのか明らかにされていないが、<strong>実測の結果160MHzに対応している可能性が高い</strong>と言えた。</p>
<section id="exp21のwi-fi転送速度について実測予想を超える160mhz2ストリーム" class="level5">
<h5 class="anchored" data-anchor-id="exp21のwi-fi転送速度について実測予想を超える160mhz2ストリーム">EXP21のWi-Fi転送速度について実測:予想を超える160MHz×2ストリーム</h5>
<p>スペックシートには書かれていないが、<strong>Wi-Fi6利用時に5GHz帯で160MHzの帯域幅を利用し、160MHz×2ストリームで通信が可能と思われる。</strong></p>
<p>表示された最大転送速度は2401Mbps,</p>
<p>実測では1.5Gbits/sec(≒1500Mbps、少なくとも1200Mbps以上の転送速度)を確認した。</p>
<div id="fig-EXP21_WiFi_SppedTest" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_WiFi_SppedTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173605.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-209" title="リンク速度2401Mbps"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173605.jpg" class="img-fluid figure-img"></a></p>
<figcaption>リンク速度2401Mbps</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173353.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-210" title="実測1.5Gbps"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173353.jpg" class="img-fluid figure-img"></a></p>
<figcaption>実測1.5Gbps</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_WiFi_SppedTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;83: EXP21のWi-Fi速度
</figcaption>
</figure>
</div>
<p>スペックシートから5GHzを用いたWi-Fi6での通信時に1200Mbps(80MHz×2ストリーム)に対応することは予想通りであり、他のWi-Fi6対応スマートフォンやタブレットも最大転送速度は1200Mbps(80MHz×2ストリーム)なため本機種も同様と考えていたが、EXP21及びROG Phone5は実測値において1500Mbps,Wi-Fi設定で表示されるリンク速度には2401Mbpsとあったため、160MHz×2ストリームで通信が可能と思われる。</p>
<p>(一応可能性としては、80MHz×4ストリームで2400Mbpsを実現することも考えられるが、スペックシートには2×2 MIMOとあり、4ストリームで通信を行うとは考えにくい。)</p>
<p>なお、今回の実測は、5GHz帯において160MHzの帯域幅で4ストリーム通信が可能なROG(ASUS)製のWi-Fi6ルーター、「GT-AX11000」を利用した。(GT-AX11000についてはいつかレビューを掲載する予定である)</p>
<p>測定に使ったアプリはiPerf3を通じてサーバーにもクライアントにもなれる「Magic iPerf」である。これを使ってGT-AX11000を媒介としEXP21とROG Phone5で相互に通信しその速度を測定した。</p>
<p>同様の手法で、「RT-AX89X」を使った場合はリンク速度1200Mbps、実測700Mbps程であった。</p>
<p>これは、RT-AX89Xが帯域幅80MHzの5GHz帯までしかサポートしていないためである(2021年当時)。</p>
<p>このことからも、EXP21及びROG Phone5は160MHz×2ストリームで通信を行うことが伺える。</p>
<p>(RT-AX89Xについてもいつかレビューを掲載する予定である)</p>
<p>※今回の測定においてiPerf3のコマンドについて<a href="https://twitter.com/isam3349800">イサム</a>さんよりアドバイスをいただいた。この場を用いて改めてお礼申し上げたい。</p>
<p>目次に戻る</p>
</section>
<section id="exp21のwi-fi感度についてゲーミングスマホより優秀" class="level5">
<h5 class="anchored" data-anchor-id="exp21のwi-fi感度についてゲーミングスマホより優秀">EXP21のWi-Fi感度について:ゲーミングスマホより優秀！</h5>
<p>EXP21のWi-Fi感度を測定した。</p>
<p>筆者は普段、ASUSルーターを4台使ってメッシュWi-Fiにして家全体を1つのWi-Fi APでカバーしているが、それでは測定にならないため今回は親機である「RT-AX89X」のみを用いて測定を行った。</p>
<p>なお、5GHz帯を用いたWi-Fi6しか取り扱っていない。2.4GHz帯であればもっと感度は良いはずである。</p>
<p>測定エリアはそれぞれ、基準となる</p>
<ol type="1">
<li>リビング(Wi-Fiのすぐ近く)、</li>
<li>階段踊り場</li>
<li>1階「客間」</li>
<li>1階「風呂」（脱衣場）</li>
<li>1階「部屋」</li>
</ol>
<p>である。</p>
<div id="fig-MyHouse" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-MyHouse-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171443.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-211" title="図&nbsp;84: Wi-Fiテスト環境"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171443.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-MyHouse-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;84: Wi-Fiテスト環境
</figcaption>
</figure>
</div>
<p>測定はAndroid11の開発者オプションで「Wi-Fi詳細ログの有効化」をし、RSSI、Scoreを取得した。また、Wi-Fiの設定画面から送信リンク速度と受信リンク速度を取得した。</p>
<p>テストの様子は以下のTweetの他、<a href="https://docs.google.com/spreadsheets/d/1Bqiy_PilOMbjBUTJ-gVHa86vHr5RJVIdrFmOAKm-Vsw/edit?usp=sharing">Google Drive</a>でも公開している</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
EXP21とROG Phone5で同時に測定。
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1459778128100823040?ref_src=twsrc%5Etfw">November 14, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<div id="fig-EXP21_Wi-Fi_Antena_Test" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Wi-Fi_Antena_Test-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171758.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-212" title="アンテナ性能詳細"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171758.jpg" class="img-fluid figure-img"></a></p>
<figcaption>アンテナ性能詳細</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171724.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-213" title="Wi-Fiのリンク速度によるアンテナ性能の比較"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114171724.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Wi-Fiのリンク速度によるアンテナ性能の比較</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Wi-Fi_Antena_Test-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;85: Wi-Fiアンテナ性能
</figcaption>
</figure>
</div>
<p>RSSIやリンク速度などの結果(図&nbsp;85)を総合して見るに、EXP21の方がWi-Fiの感度が良かったと言えそうだ。</p>
<p>今回は都合上ROG Phone5としか比較していないが、ROG Phone5はゲーミングスマホのため、Wi-Fi性能に力を入れている。それに勝るのだから、EXP21のWi-Fi性能(感度)はピカイチと言っていいだろう。</p>
<p>ちなみに(公開はしていないものの)測定地点は写真でも控えている。そのためいつでも同所での測定可能なので、今後はこの地点をWi-Fi測定の基準にするつもりだ。</p>
<p>目次に戻る</p>
</section>
</section>
</section>
<section id="バッテリー持ちと充電速度について充電速度が速いので4000mahであることに不満なし" class="level3">
<h3 class="anchored" data-anchor-id="バッテリー持ちと充電速度について充電速度が速いので4000mahであることに不満なし">バッテリー持ちと充電速度について:充電速度が速いので、4000mAhであることに不満なし</h3>
<p>よくあるYouTube連続再生時間テストなどは、そもそもYouTubeの公式アプリを使った再生が60FPSに制限されている以上、60Hzを超えるリフレッシュレートに対応したスマートフォンの検証にはならないというのが筆者の持論だ。また、「普通に使ってn時間持つ」というのは、普通に使ってというのが曖昧で再現性がない</p>
<p>とはいえ、何も判断材料がないのも問題なので参考までにAnTuTuストレステストを行ったときの結果を貼っておく。</p>
<div id="fig-EXP21_BatteryTest" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BatteryTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173832.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-214" title="AnTuTu Ver.9.1.7"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114173832.jpg" class="img-fluid figure-img"></a></p>
<figcaption>AnTuTu Ver.9.1.7</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BatteryTest-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;86: AnTuTuベンチマークのバッテリーテスト
</figcaption>
</figure>
</div>
<p>また、同様に実用性の観点からは全く参考にならないが、AnTuTuベンチマークテストを10回連続で回した際には、約110分かかり100％から25％となった。(ROG Phone5 Ultimateは47％である)</p>
<p>どうして、こう「普通に」使った結果がないのかと思われるかもしれないが、同じように筆者も首を傾げている。試用端末を限られた期間でメイン端末と同じように使うのは難しいからだろう。加えて、今回使用したEXP21には音声通話の発着信が出来ないという問題があり、メインのSIMをなかなか挿せなかったという事情もある</p>
<p>スマートフォンのレビューをしていく上でバッテリー持ちの検証は避けて通れない問題なので、今後もレビューをしていくのであれば、上手いこと「実用に根付きなおかつ再現性のある」検証方法を編み出したい。</p>
<p>ちなみに、ただのスタンバイ状態だとこのくらいはもつ。</p>
<div id="fig-EXP21_BatteryMix" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BatteryMix-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114112755.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-215" title="BatteryMixによるバッテリー残量のログ"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114112755.jpg" class="img-fluid figure-img"></a></p>
<figcaption>BatteryMixによるバッテリー残量のログ</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BatteryMix-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;87: EXP21 待機性能
</figcaption>
</figure>
</div>
<p>目次に戻る</p>
<section id="充電速度について-付属品での場合hypercharge-65" class="level5">
<h5 class="anchored" data-anchor-id="充電速度について-付属品での場合hypercharge-65">充電速度について: 付属品での場合（HyperCharge 65）</h5>
<p>まず、付属品である65Wの充電器及び3Aケーブルを使用したところ、EXP21に「Hyper Charge65」という表示と「⚡⚡」という充電アイコンが表示された。（ちなみに後述するが、HyperCharge 65はASUSの独自充電規格でありQualcommのQuick Charge5.0とは異なる）</p>
<div id="fig-EXP21_Charge_HyperCharge65" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Charge_HyperCharge65-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113155226.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-216" title="付属品で充電したところASUSの独自規格「HyperCharge65」と表示された"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113155226.jpg" class="img-fluid figure-img"></a></p>
<figcaption>付属品で充電したところASUSの独自規格「HyperCharge65」と表示された</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Charge_HyperCharge65-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;88: 付属品で充電したときの様子
</figcaption>
</figure>
</div>
<p>なお、付属品である65W充電器の詳細は下記の通りである。</p>
<ul>
<li>Model:A320Q-200325C-US</li>
<li>Input:100-240V~50/60Hz,1.5A</li>
<li>Output:5V⎓3A/9V⎓3A/12V⎓3A/15V⎓3A/20V⎓3.25A</li>
<li>PPS:3.3-11V⎓5A/3.3-21V⎓3.25A 65W MAX</li>
<li>その他:ひし形PSEマーク ASUS JAPAN株式会社</li>
</ul>
<div id="fig-EXP21_A320Q-200325C-US" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_A320Q-200325C-US-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125918.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-217" title="図&nbsp;89: 付属充電器 A320Q-200325C-US"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114125918.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_A320Q-200325C-US-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;89: 付属充電器 A320Q-200325C-US
</figcaption>
</figure>
</div>
<p>余談であるが、付属充電器A320Q-200325C-USの性能はROG Phone5の付属品と全く同じである(図&nbsp;10)</p>
<p>AVHzY CT-3を用いてPDOをキャプチャしたところ、充電器が通知した7つのPDOのうち、7つ目のPDOである3.3-21V⎓3Aを選択し最大2.35A⎓19.22Vのリクエストが行われた。</p>
<div id="fig-EXP21_A320Q-200325C-US_PDO" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_A320Q-200325C-US_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175120.png" class="lightbox" data-gallery="quarto-lightbox-gallery-218" title="付属65W充電器及び付属ケーブルを使用時のPDO通知"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175120.png" class="img-fluid figure-img"></a></p>
<figcaption>付属65W充電器及び付属ケーブルを使用時のPDO通知</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114174641.png" class="lightbox" data-gallery="quarto-lightbox-gallery-219" title="付属品である3Aのケーブルを使用したため、PDOもきちんと3A"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114174641.png" class="img-fluid figure-img"></a></p>
<figcaption>付属品である3Aのケーブルを使用したため、PDOもきちんと3A</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114174803.png" class="lightbox" data-gallery="quarto-lightbox-gallery-220" title="付属品の組み合わせでは最大2.35A⎓19.22Vのリクエストが行われた。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114174803.png" class="img-fluid figure-img"></a></p>
<figcaption>付属品の組み合わせでは最大2.35A⎓19.22Vのリクエストが行われた。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_A320Q-200325C-US_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;90: 付属品を用いたPDO検証
</figcaption>
</figure>
</div>
<p>実際の電流及び電圧の変動はグラフの通りである。</p>
<div id="fig-EXP21_A320Q-200325C-US_Charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_A320Q-200325C-US_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175238.png" class="lightbox" data-gallery="quarto-lightbox-gallery-221" title="EXP21の付属品65W充電器と付属3Aケーブルの組み合わせで充電 EXP21は約50分で20％→100％まで充電された。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175238.png" class="img-fluid figure-img"></a></p>
<figcaption>EXP21の付属品65W充電器と付属3Aケーブルの組み合わせで充電<br>EXP21は約50分で20％→100％まで充電された。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_A320Q-200325C-US_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;91: 付属品を用いてEXP21を20%→100%まで充電した際の電圧及び電流
</figcaption>
</figure>
</div>
<p>図&nbsp;91を見ても、やはり45Wが最大である。なお、上記の結果は20％から100％充電するまでのものであるため、0％→20％の充電速度に関しては分からない。この区間で65Wの充電が行われている可能性は十分にある。とりあえず、20％から100％まで充電するのに50分ほどかかることがわかった。</p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
</section>
<section id="サードパーティ製の充電器モバイルバッテリーを使った場合usb-pd-pps" class="level5">
<h5 class="anchored" data-anchor-id="サードパーティ製の充電器モバイルバッテリーを使った場合usb-pd-pps">サードパーティ製の充電器・モバイルバッテリーを使った場合（USB PD PPS）</h5>
<p>次にPPS対応のモバイルバッテリーを用いた際の結果を示す。</p>
<p>使用したモバイルバッテリーは良くも悪くも話題のCIO製のSMARTCOBY 20000mAh 60Wである。</p>
<div id="fig-CIO" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-CIO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113859.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-222" title="図&nbsp;92: CIO SMARTCOBY 20000mAh 60W"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113859.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113909.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-223" title="図&nbsp;92: CIO SMARTCOBY 20000mAh 60W"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113909.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-CIO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;92: CIO SMARTCOBY 20000mAh 60W
</figcaption>
</figure>
</div>
<p>PDOをキャプチャしたところ、3Aまでのケーブルに対してモバイルバッテリーが3.3-11V⎓5AのPDOを通知し、最大9.08V⎓2.5AをEXP21がリクエストしたのだが、モバイルバッテリー側は8.74V⎓3.8Aで出力した(図&nbsp;93)。</p>
<div id="fig-EXP21_CIO" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_CIO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175553.png" class="lightbox" data-gallery="quarto-lightbox-gallery-224" title="3Aのケーブルで5Aを通知するPDO通知"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175553.png" class="img-fluid figure-img"></a></p>
<figcaption>3Aのケーブルで5Aを通知するPDO通知</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175618.png" class="lightbox" data-gallery="quarto-lightbox-gallery-225" title="図&nbsp;93: "><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175618.png" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_CIO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;93: <a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175721.png" class="lightbox" data-gallery="quarto-lightbox-gallery-226" title="図&nbsp;93: "><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175721.png" class="img-fluid figure-img"></a>
</figcaption>
</figure>
</div>
<div id="fig-EXP21_CIO_Charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_CIO_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175735.png" class="lightbox" data-gallery="quarto-lightbox-gallery-227" title="EXP21は約60分で20％→100％まで充電された。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114175735.png" class="img-fluid figure-img"></a></p>
<figcaption>EXP21は約60分で20％→100％まで充電された。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_CIO_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;94: CIOのPPS対応モバイルバッテリーとEXP21の付属3Aケーブルの組み合わせで充電
</figcaption>
</figure>
</div>
<p>電流及び電圧変動のグラフ(図&nbsp;94)を見ると最大35W、電流は最大3.9Aで充電されていることがわかった。また、上記の結果は同様に20％から100％充電するまでのものであるため、0％→20％の充電速度に関しては分からない。純正のACアダプタを使って充電するのに約50分かかったのに対しモバイルバッテリーでも約60分と大差なく、<strong>モバイルバッテリーを使っても十分な速度で充電できるのは嬉しい。</strong></p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
<p>モバイルバッテリーが3Aのケーブルに対して5Aの出力を通知し実際3.9A流すのは正直いい気持ちがしないが、これはCIOが悪いのでここでは追求しない。</p>
<p>ちなみに、「急速充電」という表示と⚡の充電アイコンが表示された。</p>
<div id="fig-EXP21_CIO_icon" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_CIO_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../../post_images/EXP21_CIO.png" class="lightbox" data-gallery="quarto-lightbox-gallery-228" title="USB PD PPSの場合、「急速充電」表示でアイコンは⚡"><img src="https://pottal-portal.com/PtPr3/post_images/EXP21_CIO.png" class="img-fluid figure-img"></a></p>
<figcaption>USB PD PPSの場合、「急速充電」表示でアイコンは⚡</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_CIO_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;95: USB PD PPS充電時の認識
</figcaption>
</figure>
</div>
<p>HyperCharge65の場合は「HyperCharge65」「⚡⚡」という表示であった(図&nbsp;88)ため区別されていることがわかる。</p>
</section>
<section id="サードパーティ製の充電器モバイルバッテリーを使った場合quick-charge5.0" class="level5">
<h5 class="anchored" data-anchor-id="サードパーティ製の充電器モバイルバッテリーを使った場合quick-charge5.0">サードパーティ製の充電器・モバイルバッテリーを使った場合(Quick Charge5.0)</h5>
<p>筆者がずっと気になっていたのが、HyperCharge65という表示だ。これは果たして何なのか。QualcommのQuick Charge5.0とは異なるのか。異なるのであれば、なぜ付属品にはデカデカとQuick Charge5.0とあるのか。</p>
<p>結論から言うと、<strong>Quick Change5.0とHyperCharge65は別物であった</strong>。</p>
<p>その証左に、Quick Charge5.0対応の充電器を使って充電しても「HyperCharge65」とは表示されず、「急速充電中」「⚡⚡」という表示であった。</p>
<div id="fig-EXP21_QC5_icon" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_QC5_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../../post_images/EXP21_QC5.png" class="lightbox" data-gallery="quarto-lightbox-gallery-229" title="Quick Charge5.0の場合、「急速充電」表示でアイコンは⚡⚡"><img src="https://pottal-portal.com/PtPr3/post_images/EXP21_QC5.png" class="img-fluid figure-img"></a></p>
<figcaption>Quick Charge5.0の場合、「急速充電」表示でアイコンは⚡⚡</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig quarto-uncaptioned" id="fig-EXP21_QC5_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;96
</figcaption>
</figure>
</div>
<p>ということで、Quick Charge5.0で充電した際の結果を記す。</p>
<p>今回の検証に使用したのは、<a href="https://www.amazon.co.jp/dp/B093PWJDJQ/ref=cm_sw_r_tw_dp_13WHQC8V5GB5940AR6GS?_encoding=UTF8&amp;psc=1">Baseus 100W PD 充電器 CCGAN100CS</a>だ。</p>
<div id="fig-CCGAN100CS" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-CCGAN100CS-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113907.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-230" title="図&nbsp;97: Baseus 100W PD 充電器 CCGAN100CS"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113907.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113904.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-231" title="図&nbsp;97: Baseus 100W PD 充電器 CCGAN100CS"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113904.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113902.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-232" title="図&nbsp;97: Baseus 100W PD 充電器 CCGAN100CS"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114113902.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-CCGAN100CS-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;97: Baseus 100W PD 充電器 CCGAN100CS
</figcaption>
</figure>
</div>
<p>使用したケーブルはEXP21の付属品（3A）のものだ。</p>
<p>3Aまでのケーブルに対してQC5.0の充電器側が3.33-20.00V⎓3AのPDOを通知し、最大9V⎓2.5AをEXP21がリクエストし、充電器側は9V⎓2.7A程で出力した。</p>
<div id="fig-EXP21_QC5_PDO" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_QC5_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113162816.png" class="lightbox" data-gallery="quarto-lightbox-gallery-233" title="Baseus100WPD充電器CCGAN100CSのPDO通知 3Aまでのケーブルにきちんと3Aまでで応えている"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113162816.png" class="img-fluid figure-img"></a></p>
<figcaption>Baseus100WPD充電器CCGAN100CSのPDO通知<br>3Aまでのケーブルにきちんと3Aまでで応えている</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113163601.png" class="lightbox" data-gallery="quarto-lightbox-gallery-234" title="図&nbsp;98: "><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113163601.png" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_QC5_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;98: <a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113163631.png" class="lightbox" data-gallery="quarto-lightbox-gallery-235" title="図&nbsp;98: "><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113163631.png" class="img-fluid figure-img"></a>
</figcaption>
</figure>
</div>
<div id="fig-EXP21_QC5_Charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_QC5_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113162212.png" class="lightbox" data-gallery="quarto-lightbox-gallery-236" title="QC5.0対応充電器とEXP21の付属3Aケーブルの組み合わせで充電 EXP21は約50分で20％→100％まで充電された。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113162212.png" class="img-fluid figure-img"></a></p>
<figcaption>QC5.0対応充電器とEXP21の付属3Aケーブルの組み合わせで充電<br>EXP21は約50分で20％→100％まで充電された。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_QC5_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;99: Baseus 100W PD 充電器 CCGAN100CS使用時の電圧及び電流の変動
</figcaption>
</figure>
</div>
<p>電流及び電圧変動のグラフ(図&nbsp;99)を見ると最大24W、電流は最大2.7Aで充電されていることがわかった。また、上記の結果は同様に20％から100％充電するまでのものであるため、0％→20％の充電速度に関しては分からない。</p>
<p>純正のACアダプタを使って20％から100％まで充電するのに52分かかったのに対しQC5.0でも52分と変わらない結果となった。</p>
<p>純正のACアダプタが実測で最大45Wを出しているのに対し、QC5.0では最大でも25W程であるにも関わらず、同じ時間で20％から100％まで充電が行えているのは驚きだ。<strong>充電速度は最大W数ではないということを実感した。</strong></p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
</section>
<section id="サードパーティ製の充電器モバイルバッテリーを使った場合普通のusb-pd" class="level5">
<h5 class="anchored" data-anchor-id="サードパーティ製の充電器モバイルバッテリーを使った場合普通のusb-pd">サードパーティ製の充電器・モバイルバッテリーを使った場合(普通のUSB PD)</h5>
<p>USB PD PPSならともかく普通のUSB PDは最も広く普及している急速充電規格と考えられるため、普通のUSB PDで充電した場合の充電速度も調べてみた。</p>
<p>出先での充電速度を調べるなら、PD対応のモバイルバッテリーを用いて検証を行い検証を行うべきだったのだが、「90WのPD充電ではどうなるのだろう」という好奇心にとらわれてしまい、うっかり(持ち歩きには不向きな)大きいAC充電器でしか測定を行っていなかった。</p>
<p>まあ、測定結果を見るに90WのUSB PDだろうと30WのUSB PDだろうと変わらないことが予想出来るのだが…</p>
<p>ということで、言い訳が長くなったがUSB PD PPSではなく普通のUSB PDで充電した結果を記す。</p>
<p>今回使用したのは、(ステマによってAmazonからBANされたことで有名な)RAVPowerの90W充電器 RP-PC128だ。この製品はTypeCポートが2つあり、片方のみで使用した際は20V⎓4.5Aで充電できるらしい。</p>
<p>使用したケーブルは最大スペックを引き出すために3Aではなく5Aのものを使用している。</p>
<p>5A対応のケーブルに対して充電器側は20.00V⎓4.50AのPDOを通知し、それに対し最大9V⎓2AをEXP21がリクエストした。</p>
<div id="fig-EXP21_USBPD_PDO" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_USBPD_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113182642.png" class="lightbox" data-gallery="quarto-lightbox-gallery-237" title="RP-PC128のPDO通知 ちなみに3Aケーブルの場合は4.5Aは通知しない。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113182642.png" class="img-fluid figure-img"></a></p>
<figcaption>RP-PC128のPDO通知<br>ちなみに3Aケーブルの場合は4.5Aは通知しない。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig quarto-uncaptioned" id="fig-EXP21_USBPD_PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;100
</figcaption>
</figure>
</div>
<div id="fig-EXP21_USBPD_Charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_USBPD_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113182653.png" class="lightbox" data-gallery="quarto-lightbox-gallery-238" title="EXP21は約60分で20％→100％まで充電された。"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113182653.png" class="img-fluid figure-img"></a></p>
<figcaption>EXP21は約60分で20％→100％まで充電された。</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_USBPD_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;101: USB PD対応充電器と5Aケーブルの組み合わせで充電した際の電圧及び電流の変動
</figcaption>
</figure>
</div>
<p>電流及び電圧変動のグラフ(図&nbsp;101)を見ると最大16W、電流は最大1.9Aで充電されていることがわかった。また、上記の結果は同様に20％から100％充電するまでのものであるため、0％→20％の充電速度に関しては分からない。</p>
<p>純正のACアダプタを使って20％から100％まで充電するのに約50分かかったのに対しUSB PDでも約60分と変わらない結果となった。</p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
<p>実測の結果、90W対応のUSB PD充電器でもEXP21側が9V⎓2Aで18W程度しかリクエストしていないことから、30WのUSB PDモバイルバッテリーでも充電速度は変わらないと予想できる。(とは言え、モバイルバッテリーは自身のバッテリー残量が低下すると出力も低下するものが多いため、きっちり同じではないかもしれないが…)</p>
</section>
<section id="サードパーティ製の充電器モバイルバッテリーを使った場合quick-charge3.0" class="level5">
<h5 class="anchored" data-anchor-id="サードパーティ製の充電器モバイルバッテリーを使った場合quick-charge3.0">サードパーティ製の充電器・モバイルバッテリーを使った場合(Quick Charge3.0)</h5>
<p>USB PD以外で最も普及している急速充電規格は、おそらくQualcommのQuick Charge3.0だろう。(と筆者は勝手に考えている)</p>
<p>そのため、Quick Charge3.0を使っての充電速度も調べてみた。</p>
<p>検証に使用したのはSatechi Type-C 75W トラベルチャージャー ST-MCTCAMである。</p>
<p><a href="https://www.amazon.co.jp/gp/product/B078864F15/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&amp;psc=1">www.amazon.co.jp</a></p>
<p>ケーブルはEXP21の付属品(3A)を用いた。</p>
<p>出来るなら、外出先を想定しモバイルバッテリーないしコンパクトなAC充電器を用いたかったのだが、あいにく手元にあるモバイルバッテリーで純粋なQuick Charge3.0対応のものが、これくらいしかなかったのだ。(AnkerのPowerIQやRAVPowerのよく分からない急速充電規格のものはゴロゴロ転がっているが…)</p>
<div id="fig-EXP21_QC3_Charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_QC3_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113172257.png" class="lightbox" data-gallery="quarto-lightbox-gallery-239" title="QC3.0対応充電器とEXP21の付属3Aケーブルの組み合わせで充電 EXP21は約55分で20％→100％まで充電された"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113172257.png" class="img-fluid figure-img"></a></p>
<figcaption>QC3.0対応充電器とEXP21の付属3Aケーブルの組み合わせで充電<br>EXP21は約55分で20％→100％まで充電された</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_QC3_Charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;102: Quick Charge3.0充電時の電圧及び電流の変動
</figcaption>
</figure>
</div>
<p>電流及び電圧変動のグラフ(図&nbsp;102)を見ると最大約17W、電流は最大1.9Aで充電されていることがわかった。また、上記の結果は同様に20％から100％充電するまでのものであるため、0％→20％の充電速度に関しては分からない。</p>
<p>USB PDではないので、PDOのパケット等は取得出来なかった。</p>
<p>純正のACアダプタを使って充電するのに約50分かかったのに対し、Quick Charge3.0でも約55分と大差なく、一般的なモバイルバッテリーを使っても十分な速度で充電できそうなのは嬉しい。</p>
<p>※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
</section>
<section id="充電まとめ-exp21の充電速度は20100の範囲ならどの充電規格でも大差ない" class="level5">
<h5 class="anchored" data-anchor-id="充電まとめ-exp21の充電速度は20100の範囲ならどの充電規格でも大差ない">充電まとめ: EXP21の充電速度は20％→100％の範囲なら、どの充電規格でも大差ない</h5>
<p>ASUS独自のHyperCharge65やQualcomm Quick Charge5.0でも20％から100％まで充電するのに約50分、一般的な急速充電規格USB PD(PPS)やQuick Charge3.0だと約60分かかった。※なお、充電速度は満充電（100％）に近づく程遅くなっている。実用に際して「絶対に100％まで充電したい！」ということは少なく、95％程度で良しとするならもっと早く済む。</p>
<p>最大W数はまちまちだが、充電速度だけを見れば(少なくとも20%から100％まで充電するのには)大差ない。今回は測定・検証していないが、発熱という観点や0％からの充電速度、あるいは90％を超えたあたりの充電速度では、また違った結果になるかもしれない。</p>
<p>余談だが、ASUSの独自充電規格HyperChargeにはHyperCharge65とROG Phone3で用いられているHyperCharge30がある。</p>
<p>HyperCharge30というドマイナーな規格で充電した結果は「蛇足その2:EXP21の充電規格詳細」をご覧いただきたい。結論から言うとやっぱり大差なく最大23Wで20％から100％まで55分程だった。</p>
<p>目次に戻る</p>
</section>
</section>
<section id="exp21の生体認証について指紋認証の精度は良いが設計がダメ顔認証はマスクでも可能" class="level3">
<h3 class="anchored" data-anchor-id="exp21の生体認証について指紋認証の精度は良いが設計がダメ顔認証はマスクでも可能">EXP21の生体認証について:指紋認証の精度は良いが設計がダメ。顔認証はマスクでも可能。</h3>
<p>EXP21は指紋と顔の2つの生体認証に対応している。指紋センサーは背面に取り付けられている。見ての通り指紋センサーと背面は一体化しておりほとんど凹凸がない。</p>
<div id="fig-EXP21_BackFPS" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_BackFPS-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130010.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-240" title="図&nbsp;103: 今どき珍しい背面に指紋センサ"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130010.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_BackFPS-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;103: 今どき珍しい背面に指紋センサ
</figcaption>
</figure>
</div>
<section id="指紋認証について" class="level4">
<h4 class="anchored" data-anchor-id="指紋認証について">指紋認証について</h4>
<p>指紋認証の精度自体はすこぶる良い。0.1秒、人差し指で弾くだけで認識されるし、濡れた指でも問題はなかった。</p>
<p>(同じく背面に指紋センサーを搭載しているZenFone6と速度を比較した動画を<a href="https://drive.google.com/file/d/1xHoEKCK7Wa8YGH0pP4VjPofRrDgmkZPR/view?usp=sharing">Google Driveにアップロードしている</a>ため、気になる方はそちらをご覧いただきたい。)</p>
<p>動画の通り、速度は問題ないのだ。速度は。</p>
<p>しかし、EXP21の指紋認証には致命的な欠点がある。それが、背面指紋センサーなのに、指紋センサーの位置の目印となる凹凸がないことだ。普通いちいち背面を見ながらロックを解除するなんて煩わしいことはしないので、人差し指は当てずっぽうで指紋センサーと思わしき場所をタッチすることとなる。当てずっぽうなので、指がクリーンヒットすることは少なく、結果として指のごく一部のみが指紋センサーに触れ、読み取り不良でロックが解除出来ないという悲劇が起こる。</p>
<p>どうして指紋センサー部を凹凸にしなかったのか。フラットな形状にしたかったのであれば、せめてSnapdragonのロゴと同じ大きさにして指の当たる確率を上げてくれなかったのか。</p>
<p>これは筆者の勝手な推測だが、指紋センサー部を凹ますことは、内部設計上余裕がなく実現が出来ず、指紋センサーの面積を大きくすることはQualcommが許さなかったのだろう。Qualcommはこの指紋センサーに自信をもっておりこの大きさで十分と考えているはずだ。指紋センサーが見えない画面内指紋認証なら兎も角、Snapdragonのロゴが霞むようなデカデカとした指紋センサーなど、付けたくなかったに違いない。まあ、確かに鳴り物入りのQualcomm3DSonicSensor Gen 2で、でっかい指紋センサーなどつけられたら、自信がないように見えてしまう。</p>
<p>これは筆者の勝手な妄想だが、なんとなくそんな理由なのではないかと思えないだろうか。</p>
<p>いや、何故画面内指紋認証センサーにしなかったのか…。 画面内指紋認証センサーにすれば、全てが丸く収まったのではないだろうか。センサーが内部設計上収まらなかったのだろうか…</p>
</section>
<section id="顔認証について" class="level4">
<h4 class="anchored" data-anchor-id="顔認証について">顔認証について</h4>
<p>スマホを持ち上げて、ちらっと見ればOKなので非常に快適だ。<a href="https://drive.google.com/file/d/1TezjTeIaPjg-43Y6vFx3VGziHPx7pH1F/view?usp=sharing">比較動画はGoogle Driveにアップロードしている</a>が、なんとROG Phone5よりも認証が速い。</p>
<p>また、マスクを着用していない状態で登録しても、顔認証を行う際にはマスクを着けたままでも認識される。</p>
<p>（マスクを着けた状態だと）じっとカメラを見つめるという間があるが、ワンテンポ遅れるだけなのでストレスにはならない。</p>
<p>&nbsp;</p>
<p>目次に戻る</p>
</section>
</section>
<section id="使い勝手についてexp21は確かにasusスマホだがasusスマホの良さが消されている" class="level3">
<h3 class="anchored" data-anchor-id="使い勝手についてexp21は確かにasusスマホだがasusスマホの良さが消されている">使い勝手について:EXP21は確かにASUSスマホだが、ASUSスマホの良さが消されている</h3>
<p>ASUS製のスマートフォンには独自のカスタマイズがされているのだが、EXP21はその独自機能の多くが取り除かれ、ピュアなAndroidに近づいている。</p>
<p>一般的にはAOSP、つまりピュアなAndroidの方がスマホを買い替えた際(あるいは複数台使うときに)戸惑わないし、何より余計なカスタマイズがない分OSアップデートが早い(だろう)ため、好ましいこととされるが、便利な機能が無くなったのは事実である。</p>
<p>EXP21は特殊なスマートフォンなので、2台目のスマホとして非ASUSユーザーから選ばれることも十分想定される。そのためASUSがそれを見込んであえてピュアなAndroidに近づけたのか、それとも取り除かれた機能がQualcommの意向に沿わないものだったからなのかは分からない。</p>
<p>あくまで筆者の推測だが、おそらく後者であろう。というのも、最近のASUSスマホは(種類をハイエンドに絞ったため)アップデートを頻繁に行っており、なおかつZenUIも以前よりAOSPライクになっているから、カスタマイズされた機能は負担にならないというのが1つ目の論拠である。それに、EXP21もピュアAndroidっぽいとは言え使いやすいASUS独自機能も多々残っている。ダブルタップでスリープなどがその典型だ。</p>
<div id="fig-EXP21_Useful" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_Useful-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116170926.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-241" title="ダブルタップでスクリーンオフするとても使いやすい機能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116170926.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ダブルタップでスクリーンオフするとても使いやすい機能</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_Useful-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;104: AOSPライクになったEXP21に残された便利機能
</figcaption>
</figure>
</div>
<p>2つ目の論拠が、取り除かれた機能の性質だ。次のセクションで詳しく説明するが、マニュアル撮影(≒Intelligent Photographyを推すQualcommの意向に反する)や、ゲームマクロ機能(≒チート)などは、Qualcomm的にNGだったのだろう。</p>
<section id="asusスマホにはあってexp21にはない機能" class="level4">
<h4 class="anchored" data-anchor-id="asusスマホにはあってexp21にはない機能">ASUSスマホにはあってEXP21にはない機能</h4>
<ul>
<li>純正カメラアプリにおける「Proモード(マニュアル撮影機能)」</li>
<li>Twinアプリ(同じアプリを複数インストール出来る機能)</li>
<li>Game Genie(マクロ機能やゲーム中の通知・着信をブロックする機能)</li>
</ul>
<p>筆者が特に痛いと感じたのはこの3つだ。</p>
<p>特に、マニュアル撮影機能はQualcommの意向、つまりオート撮影で誰でも簡単に綺麗な写真をスマホが撮ってくれるというビジョンに反するだろう。少なくとも製品ページではIntelligent Photographyが謳われている。（また、<a href="https://www.youtube.com/watch?v=3vX5g3iLE48">Snapdragon888の紹介ビデオで真っ先に触れられるのがカメラ(ISP)</a>であり、<a href="https://www.youtube.com/watch?v=phOrx2OodKs">AIの紹介ビデオでもやはり画像処理を最初にしている</a>。）</p>
<p>Game GenieやTwinアプリもちょっとQualcommの意向には反するかもしれない。マクロ機能(つまり、自動で操作を入力してくれる機能)はゲームによってはチート、つまり規約違反として扱われる。</p>
<div id="fig-ASUS_GameGenie" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ASUS_GameGenie-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162716.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-242" title="Game Genieは便利だっただけに惜しい"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162716.jpg" class="img-fluid figure-img"></a></p>
<figcaption>Game Genieは便利だっただけに惜しい</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162713.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-243" title="マクロは仕方ないとしてもGame Genieそのものは残して欲しかった"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116162713.jpg" class="img-fluid figure-img"></a></p>
<figcaption>マクロは仕方ないとしてもGame Genieそのものは残して欲しかった</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ASUS_GameGenie-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;105: ASUSの非ゲーミングスマホ(ZenFoneシリーズ)にも標準搭載のGameGenie
</figcaption>
</figure>
</div>
<p>複数アカウントでの操作を容易にするTwinアプリ機能もゲームによってはよろしくない。例えば、Pokemon Goなどは複数アカウントを禁止していることで有名だ。通常、複数アカウントでプレイするには複数台のスマホが必要なところを、この機能は1台で済ませてしまうのだ。(尤も、Twinとついているように2アカウントまでのサポートとなる)</p>
<p>Androidの画面分割機能を使えば、画面上側でPokemon Goをしながら画面下側でも別のアカウントでPokemon Goなんてことも可能だ。</p>
<p>Game Genieのマクロ機能やツインアプリでの複数アカウント所持は、ユーザーに判断が委ねられるものであるものの、やはりQualcommとしてはよろしくないのだろう。</p>
<p>その他、取り除かれた機能は以下の通りだ。</p>
<ul>
<li>背面指紋センサをスワイプして通知バーを呼び出す機能</li>
</ul>
<p>もちろん、上記以外にも取り除かれた機能はあるだろうが、筆者が確認出来たのは以上である。</p>
</section>
<section id="exp21の独自機能について" class="level4">
<h4 class="anchored" data-anchor-id="exp21の独自機能について">EXP21の独自機能について</h4>
<p>EXP21はASUSスマートフォンに搭載された便利機能のいくつかが取り除かれてしまったが、逆にEXP21だけに搭載された特別な機能もある。</p>
<section id="アドバンスドモードでの詳細設定" class="level5">
<h5 class="anchored" data-anchor-id="アドバンスドモードでの詳細設定">「アドバンスドモード」での詳細設定</h5>
<p>EXP21は動作モードを選ぶことが出来る。ここまではあまり珍しいない機能だ。動作モードは「高性能」「ダイナミック(バランスをとる推奨設定)」「省電力」「超省電力」「アドバンスド」から選べる。</p>
<div id="fig-EXP21_AdvMode" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_AdvMode-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130343.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-244" title="図&nbsp;106: EXP21動作モード"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130343.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130345.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-245" title="図&nbsp;106: EXP21動作モード"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130345.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_AdvMode-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;106: EXP21動作モード
</figcaption>
</figure>
</div>
<p>そのうち動作モードを「アドバンスド」に設定した際には、パフォーマンス調整機能でCPU,GPU,RAMパフォーマンスを「低」「中」「高」の3段階、同じく温度上限(つまりサーマルスロットリングの基準)も「低」「中」「高」の3段階から設定することが可能だ。</p>
<div id="fig-EXP21_AdvMode2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_AdvMode2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130348.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-246" title="図&nbsp;107: アドバンスドモードの詳細設定"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130348.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_AdvMode2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;107: アドバンスドモードの詳細設定
</figcaption>
</figure>
</div>
<p>なお、動作モードを「高性能」に設定した際は(おそらく全ての設定がハイパフォーマンスになっているため)設定を変えることが出来ない。</p>
<p>動作モード自体はZenfoneシリーズやROG Phoneシリーズでも選択が可能だったが、動作モードでここまで詳細に本体のパフォーマンス設定を変えられるのはEXP21だけだ。なお、ROG PhoneシリーズであればArmoury Crateという専用アプリで、各アプリ(ゲーム)ごとにこのCPUや温度上限のパフォーマンスを変えることが出来る。</p>
<p>ROG PhoneシリーズとEXP21の設定の違いは、アプリごとなのか一括して本体のパフォーマンスをチューニングするか、ということになる。</p>
</section>
<section id="elite-gamingオプション" class="level5">
<h5 class="anchored" data-anchor-id="elite-gamingオプション">「Elite Gamingオプション」</h5>
<p>Elite Gamingオプションでは、ROG PhoneシリーズでいうArmoury Crateのように、設定したアプリを実行する際のプロファイルを設定することが出来る。</p>
<p>::: {#fig-EXP21_Elite Gaming layout=“[1,1]”}</p>
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130401.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-247"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130401.jpg" class="img-fluid"></a></p>
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130404.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-248"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130404.jpg" class="img-fluid"></a></p>
<p>EXP21のElite Gamingオプション :::</p>
<p>::: {#fig-EXP21_Elite Gaming_Option layout=“[1,1]”}</p>
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130406.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-249"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130406.jpg" class="img-fluid"></a></p>
<p>EXP21のElite Gamingオプション詳細設定 ::: &nbsp;</p>
<p>前述の通り、ROG PhoneシリーズではここでCPUや温度上限を細かく設定出来たが、EXP21で設定できるのは、グラフィック機能だけとなる。</p>
<p>具体的には写真の通りだが、アンチエイリアスやテクスチャなどの描画設定、リフレッシュレートの設定が可能だ。</p>
<p>正直なところ、パフォーマンスに関する設定が2つに分かれているのは面倒なので、ROG Phoneのスタイルに寄せてほしいところだ。</p>
</section>
<section id="背面ロゴの照明エフェクト" class="level5">
<h5 class="anchored" data-anchor-id="背面ロゴの照明エフェクト">背面ロゴの「照明エフェクト」</h5>
<p>背面のロゴのオン・オフ、そしてオンにしたときの光らせ方を「固定」か、緩やかに点いたり消えたりする「呼吸」から選べる。</p>
<div id="fig-EXP21_SD_Logo" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_SD_Logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130352.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-250" title="図&nbsp;108: EXP21の背面ロゴの光らせ方"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211114/20211114130352.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_SD_Logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;108: EXP21の背面ロゴの光らせ方
</figcaption>
</figure>
</div>
<p>通知が来たら光るといった便利な機能はなく、ただただバッテリーを浪費するだけである。ROG Phoneシリーズのようにカラフルに光ってなおかつ通知に合わせて色を変えるなんてことが出来たら良いのだが、色も白一色である。</p>
<div id="fig-ROG_Logo" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ROG_Logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082628.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-251" title="図&nbsp;109: ROG Phoneシリーズでは背面のロゴを通知に合わせて光らせることが可能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082628.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082631.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-252" title="図&nbsp;109: ROG Phoneシリーズでは背面のロゴを通知に合わせて光らせることが可能"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20211116/20211116082631.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ROG_Logo-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;109: ROG Phoneシリーズでは背面のロゴを通知に合わせて光らせることが可能
</figcaption>
</figure>
</div>
<p>よほどのSnapdragon信者でなければ無駄に思うだけだろう。まあ、筆者はSnapdragonの「呼吸」を感じたかったのでオンにしたのだが。</p>
<p>&nbsp;</p>
<p>目次に戻る</p>
<p>▷蛇足を飛ばして結論を読む</p>
</section>
</section>
</section>
<section id="蛇足その1usb性能の検証" class="level3">
<h3 class="anchored" data-anchor-id="蛇足その1usb性能の検証">蛇足その1:USB性能の検証</h3>
<p>結論が出なかった以上、蛇足となってしまうが、EXP21のUSB端子の規格の話をしたい。これが結構曲者で、映像出力の観点からUSB規格を推測した際にはUSB3.1 Gen2であると考えれられるが、実際にファイル転送をしてみるとEXP21のTypeCポートはUSB2.0並の速度になってしまうのだ。ベンチマークテストの際に測定したように、EXP21のストレージはRead(Input)が1985MB/s, Write(Output)が785MB/sと超高速であるにもかかわらず、だ。</p>
<section id="exp21の映像出力について" class="level4">
<h4 class="anchored" data-anchor-id="exp21の映像出力について">EXP21の映像出力について</h4>
<p>映像出力の観点からUSB規格を推測した際にはUSB3.1 Gen2であると考えた。 これは外部ディスプレイに出力した際に「リフレッシュレートは120Hzに設定されています」との表示が出たからである。これは、同社のROG Phone5 Ultimateと同じ挙動であり、EXP21が120Hzの映像出力に対応していることを伺わせるものだ。ちなみに、ROG Phoneシリーズを外部ディスプレイに接続した際には出力可能なFPSとスマートフォン側のリフレッシュレートをなるべく一致させようという挙動が見られることから、EXP21でも同様の挙動であると推測した。なお、接続したディスプレイは75Hzまでにしか対応していなかったため実際のところ何Hzで出力可能なのかは分からない。仮に2,448×1,080ドットを(8bitで)120Hzで出力できるとすれば9.6Gbpsの転送速度に対応していることになるため、USB 3.1 Gen2(10Gbps)だと断定できるのだが…</p>
<p>(ちなみに、144Hzで出力するには11Gbpsの転送速度が必要になるため、USB3.1Gen2ではまかない切れない。そのため、144Hzの映像出力が可能なROG Phone3シリーズとTwinView Dock 3の組み合わせでは、USB3.1 Gen1ポートと独自のポートを用いてTwinView Dock 3に映像を出力しているものと見られる。ROG Phone3単体で映像出力する際は90Hzに制限されるのも、ひとえにUSB3.1 Gen1では追いつかないからだろう。なお、ROG Phone3の解像度で90Hzを出力した際には6.82Gbps必要になるのでその差分はどこから来るのだろうかという話になってしまうのだが…)</p>
<p>※映像出力の帯域幅は<a href="https://k.kramerav.com/support/bwcalculator.asp">こちらの計算ツールを用いた</a>。</p>
</section>
<section id="exp21のファイル転送速度について" class="level4">
<h4 class="anchored" data-anchor-id="exp21のファイル転送速度について">EXP21のファイル転送速度について</h4>
<p>次にファイルの転送速度でUSB規格を考えてみる。前提条件として、EXP21のストレージ速度はRead(Input)が1985MB/s, Write(Output)が785MB/sである。つまり、ストレージ速度的にはUSB 3.1 Gen2(10Gbps)に対応していておかしくないスペックである。</p>
<p>続いて接続したパソコンだが、Read・Write共に3000MB/s超え≒24Gbps、PC側のTypeCポート及び接続したケーブルはUSB 3.2 Gen2（10Gbps）となっているため、10Gbps内であればボトルネックは発生しない。※USB 3.2 Gen2はUSB3.1 Gen2と同じ10Gbpsの転送速度である</p>
<p>それにも関わらず、EXP21のTypeCポートはUSB2.0並の速度であった。</p>
<div id="fig-EXP21_File_Tf" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_File_Tf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114153131.png" class="lightbox" data-gallery="quarto-lightbox-gallery-253" title="図&nbsp;110: EXP21とROG Phone5のファイル転送速度"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114153131.png" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_File_Tf-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;110: EXP21とROG Phone5のファイル転送速度
</figcaption>
</figure>
</div>
<p>結果は<a href="https://docs.google.com/spreadsheets/d/1J4mbV6Pj1T6iWw01vG4RXyw44F-5kSKPVqaHfLZ-p8U/edit?usp=sharing">Google Drive</a>にもアップロードしている。</p>
<p>EXP21のTypeCポートがUSB3.1 Gen1(5Gbps)なのかUSB3.1 Gen2(10Gbps)なのか検証しようと思ったら、USB2.0並の速度しか出なかったのは驚きだ。</p>
<p>ちなみに、今回比較に挙げたROG Phone5はサイドのUSB 3.1ポート(こちらも詳細不明)と底面のUSB2.0ポートと2つのポートを備えるのだが、まさしくそのUSB2.0側のポートと同じような速度であった。何度試そうと、ファイルサイズを変えようとROG Phone5 Ultimateのサイドポートと比べて明らかに遅いのだ。内蔵ストレージの性能的には大差がないのに、有線接続した際の転送速度に明らかな差があるので、ROG Phone5 Ultimateに比べてUSBの規格が劣ると考えられる。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="cs" dir="ltr">
PC→EXP21 10GB <a href="https://t.co/flM1LI3vtw">pic.twitter.com/flM1LI3vtw</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1470926737299357696?ref_src=twsrc%5Etfw">December 15, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>なおEXP21のストレージはほとんど使っていないため、ストレージ容量の圧迫による速度低下はないと考えられる。</p>
</section>
<section id="exp21のusb規格は分からなかった" class="level4">
<h4 class="anchored" data-anchor-id="exp21のusb規格は分からなかった">EXP21のUSB規格は分からなかった。</h4>
<p>DisplayPort Alt Modeを使ってTypeCケーブル1本で映像出力が可能なディスプレイ(LG <a href="https://www.lg.com/jp/monitor/lg-34wp65g-b">34WP65G-B</a>)に映像出力が可能であったため、<del>EXP21はUSB 3.1に対応していることがわかるが</del>、実際にファイルを転送してみるとUSB3.1どころか、USB2.0並の転送速度であった。USB3.1 Gen1なのかUSB3.1 Gen2なのか確かめようと思っていたのにますます混乱が深まる結果となった。</p>
<blockquote class="blockquote">
<p>「DisplayPort Alt ModeはUSB 3.x以上が必須である」という認識は半分正しく、半分誤っています。USBやDisplayPortの仕様では、DP Alt Modeをサポートする場合にUSB 3.x以上もサポートすることは特に要件になっていないため、DP Alt Modeをサポートするデバイスが必ずしもUSB 3.x以上をサポートする必要はありません。一方で、DP Alt Modeの信号はUSB 3.x用の信号線 (SSRX/SSTX) を使ってモニターに伝送されるため、ケーブルについてはUSB 3.x以上をサポートしている必要があります <span class="citation" data-cites="hanpen">(@Hanpenblog 2024)</span></p>
</blockquote>
<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
2024/07/08 追記
</div>
</div>
<div class="callout-body-container callout-body">
<p>DisplayPort Alt Modeについて、古い認識のままであったため、当該箇所に打ち消し線を入れた他、引用を追記しました。</p>
</div>
</div>
<p>目次に戻る</p>
</section>
</section>
<section id="蛇足その2exp21の充電規格詳細" class="level3">
<h3 class="anchored" data-anchor-id="蛇足その2exp21の充電規格詳細">蛇足その2:EXP21の充電規格詳細</h3>
<p>ROG PhoneⅡ及びROG Phone3はASUSの独自充電規格HyperCharge30に対応している。Qualcommの意向が強いEXP21もHyperCharge30に対応しており、ROG Phone3の付属充電器で充電すると「HyperCharge30」充電アイコンは「⚡⚡」と表示された。</p>
<div id="fig-EXP21_HC30_icon" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_HC30_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113185452.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-254" title="HyperCharge30"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113185452.jpg" class="img-fluid figure-img"></a></p>
<figcaption>HyperCharge30</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_HC30_icon-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;111: ROG Phone3の付属充電器で充電した際の表示
</figcaption>
</figure>
</div>
<p>筆者は充電周りに詳しくないため、その筋の方からのご意見を伺いたいが、どうもHyperCharge65やHyperCharge30の充電器とEXP21は独自のパケットをやりとりしているように見える。</p>
<div id="fig-EXP21_HyperCharge30" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_HyperCharge30-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113184605.png" class="lightbox" data-gallery="quarto-lightbox-gallery-255" title="図&nbsp;112: ROG Phone3の付属充電器で充電した際のPDOパケットと電圧及び電流の推移"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113184605.png" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113184619.png" class="lightbox" data-gallery="quarto-lightbox-gallery-256" title="図&nbsp;112: ROG Phone3の付属充電器で充電した際のPDOパケットと電圧及び電流の推移"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220113/20220113184619.png" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_HyperCharge30-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;112: ROG Phone3の付属充電器で充電した際のPDOパケットと電圧及び電流の推移
</figcaption>
</figure>
</div>
<p>ROG Phone3の充電器とEXP21の付属3Aケーブルの組み合わせで充電<br>
EXP21は約55分で20％→100％まで充電された。</p>
<p>EXP21の充電周りを見ると、EXP21には「HyperCharge65(⚡⚡アイコン)」、「HyperCharge30(⚡⚡アイコン)」、Quick Charge5.0で充電を行った際の「⚡⚡」アイコンと「急速充電」、USB PD（含むPPS）やQuick Charge3.0時の「⚡」アイコン1つの「急速充電」、そして今まで紹介していなかったが、(低速)「充電中」という表示及び充電アイコン「🔋」がある。</p>
<div id="fig-EXP21_LowSpeadCharge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-EXP21_LowSpeadCharge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114100127.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-257" title="図&nbsp;113: （低速な）充電中"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20220114/20220114100127.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-EXP21_LowSpeadCharge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;113: （低速な）充電中
</figcaption>
</figure>
</div>
<p>興味深いのが、HyperChargeとQuick Charge5.0の挙動だろう。同じ「⚡⚡」アイコンなのに「HyperCharge65」と「急速充電中」と表示が分かれることから、それぞれ別の基準があることが伺える。加えて言えば、どうやってHyperChargeと見分けているのかも気になる。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
独学だから正しくお喋りの内容を理解出来てるか分からんが、ROG Phone5及びEXP21は最初共通言語でPDOのやり取りして、その後オリジナル言語でなんかやり取りして、その後にUSB PD PPS使って充電してるな。その後、しつこくスマホ側から電力のリクエストしてる。ように思える。 <a href="https://t.co/dN2phCEXpN">pic.twitter.com/dN2phCEXpN</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1450761913676099586?ref_src=twsrc%5Etfw">October 20, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>おそらく先に挙げたように、独自のパケットでやりとりしていると思われるが、Snapdragonの代紋を背負った製品で、しかもQuick Charge5.0のロゴが入った充電器でよくもまあQualcommの推進している充電規格を押しのけて独自の充電規格を使ったものだと感心すら覚えた。</p>
<p>ここからは筆者の勝手な想像だが、付属品だけでなく、EXP21本体の充電ICないし充電規格を認識するソフトもROG Phone5と同じものを使っているのではないだろうか。もちろん、ROG Phone5が6000mAhなのに対しEXP21は4000mAhであるから、処理が全く同じというわけではないのだろうが、(実際ROG Phone5ではHyperCharge65充電時に18V3Aで54Wくらい出ている)Hyper ChargeというASUS独自の充電規格を認識出来るということは使いまわしをしている可能性が極めて高い。</p>
<p>これは使いまわしを責めているのではない。コストを抑えるための工夫であると考えており、そのコストを盾に独自の充電規格を優先させることを認めさせたのだろう。</p>
<p>EXP21はSmartphone for Snapdragon Insiders製品であり、本来はQualcomm Snapdragon(この記事の公開が遅くなってしまったせいで、Qualcomm Snapdragonという言い方は正しくなくなったが)の技術を体感してもらう場だ。にも関わらず、Qualcommの充電規格Quick Charge 5.0のロゴまで入った付属品でQuick Charge 5.0ではなくASUSの独自充電規格HyperCharge65が行われるというのは、そうした事情があったのだろうと筆者は見ている。</p>
<p>加えて言えば、ASUSの独自充電規格HyperCharge 65の実態がUSB PD PPSやQualcomm Quick Charge 5.0にちょっと余計な独自パケットを挟んだだけで実質あまり変わらないのでQualcomm的にもオッケーとかそういうアレもあるのかもしれないが、ここらへんは全く分からないので言及はしない。HyperChargeって何なんだろうか。</p>
<p>&nbsp;</p>
</section>
<section id="総評qualcommの全てを詰め込んだキワモノスマホゲーム性能ならrog-phone5シリーズを使い勝手ならzenfone8を買えわかってる人だけが買うべき" class="level3">
<h3 class="anchored" data-anchor-id="総評qualcommの全てを詰め込んだキワモノスマホゲーム性能ならrog-phone5シリーズを使い勝手ならzenfone8を買えわかってる人だけが買うべき">総評:Qualcommの全てを詰め込んだ「キワモノ」スマホ。ゲーム性能ならROG Phone5シリーズを、使い勝手ならZenfone8を買え。「わかってる」人だけが買うべき。</h3>
<p>製品提供を（自分からお願いし）受けていながら、「これは買うな！」と言うのは中々に勇気がいる。しかし、これだけは伝えておきたい。「わかって」ないなら、買うな。</p>
<p>誤解を恐れず言うなら、「rootも外せない人はよく考えて買うべき。EXP21は検証機と思え」とまで言い切れる。</p>
<p>これは確かに素晴らしいスマホであり、このスマホであれば16万円超えという価格に納得もいく。</p>
<p>しかし、使い勝手やゲーム性能を求めて買うべきではない。適材適所という言葉の通りである。使い勝手ならZenfone8を、ゲーム性能ならROG Phone5を強く勧める。本当にEXP21を「分かって」買わないと、逆にこれ程尖った作品に仕上げたASUSとQualcommに失礼だ。</p>
<p>最後になるが、このレビューを書けて、そしてこうして公開出来ることに幸せと誇りを感じる。</p>
<p><strong>自分から製品提供を申し込んでおいて、「買うな」と書かれた記事をASUS Japanは通した。</strong>ASUSは健全な会社である。そして、製品に自信があるからこそ、それを許している。</p>
<p>ASUS信者としてこれは誇らしく、そして喜ばしいことである。</p>
<p>使い込んで分かったことだが、このスマホは<strong>「一般人はやめておけ」と言えるくらい変態で優等生なスマートフォンである。</strong></p>
<p>せっかく積み上げてきたZenUIに手を加え、Qualcommの要望通りの仕様に仕上げるには数しれない苦労があっただろう。ハードウェア的にもソフトウェア的にもQualcommの要望を満たしたASUSの変態さ。これはマザボメーカーのトップを走り、そして長年スマートフォンを作ってきたASUSだからこそ出来たことだと確信する。そして、だからこそ「一般人はやめておけ」と言えるのだ。これを誇りに思わずして何を誇りに思おうか。ASUSはやってみせたのだ。</p>
<p>ありがとう、ASUS。そしてありがとうASUS Japan。私は幸せだ。</p>
<hr>
<blockquote class="blockquote">
<p>以上です。5万9000字以上と、アホみたいな分量になってしまいました。読みにくかったと思います、ごめんなさい。</p>
<p>そして、ASUS JAPAN様、締め切りが無いとは言え公開が遅くなってしまいごめんなさい。次はもっと早く、そしてもう少し簡潔にレビューするので、これからも何卒よろしくお願いします。</p>
<p>2022年1月14日 Pottal</p>
</blockquote>
</section>
</section>
<section id="参考文献" class="level2">
<h2 class="anchored" data-anchor-id="参考文献">参考文献</h2>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" data-line-spacing="2">
<div id="ref-SDM888" class="csl-entry">
Andrei Frumusanu (2020)“Qualcomm details the snapdragon 888: 3rd gen 5G &amp; cortex-X1 on 5nm”, <em>AnandTech</em>, December 2, 2020 Accessed February 25, 2024 <a href="https://www.anandtech.com/show/16271/qualcomm-snapdragon-888-deep-dive">https://www.anandtech.com/show/16271/qualcomm-snapdragon-888-deep-dive</a>
</div>
<div id="ref-Anker" class="csl-entry">
Anker (2022) 「スマホの充電は正しくできてる？みんなが気になるバッテリーの疑問10選」、 <em>AnkerMagazine</em>、2022年9月5日、閲覧日 2024年2月24日、 <a href="https://www.ankerjapan.com/blogs/magazine/tips-of-battery">https://www.ankerjapan.com/blogs/magazine/tips-of-battery</a>
</div>
<div id="ref-FUJITSU" class="csl-entry">
FUJITSU (2014) 「バッテリーは劣化する！ムダな劣化を防ぐ4つのポイント」、 <em>FUJITSU</em>、2014年10月22日、閲覧日 2024年2月24日、 <a href="https://azby.fmworld.net/usage/closeup/20141022/">https://azby.fmworld.net/usage/closeup/20141022/</a>
</div>
<div id="ref-YouTube_ROG5" class="csl-entry">
ROG (2021)“ROG phone 5 launch event | for those who dare”, <em>YouTube</em>, March 10, 2021 Accessed February 25, 2024 <a href="https://www.youtube.com/live/xX30P5kbHcE?si=VHO2SL1aEXeOPInI&amp;t=1290">https://www.youtube.com/live/xX30P5kbHcE?si=VHO2SL1aEXeOPInI&amp;t=1290</a>
</div>
<div id="ref-YouTube_EXP21" class="csl-entry">
Snapdragon (2021)“Smartphone for snapdragon insiders: A 5G phone designed by ASUS”, <em>YouTube</em>, July 8, 2021 Accessed February 25, 2024 <a href="https://youtu.be/e_BF3KMUZWs?si=41IjZASj3uY1dwIn&amp;t=16">https://youtu.be/e_BF3KMUZWs?si=41IjZASj3uY1dwIn&amp;t=16</a>
</div>
<div id="ref-YouTube_QC5" class="csl-entry">
Qualcomm (2020)“Announcing the world’s fastest commercial charging solution: Qualcomm quick charge 5”, <em>YouTube</em>, July 29, 2020 Accessed February 25, 2024 <a href="https://youtu.be/AlrFF-lJwhA?si=b58e6dQTPnAUBJbB&amp;t=181">https://youtu.be/AlrFF-lJwhA?si=b58e6dQTPnAUBJbB&amp;t=181</a>
</div>
<div id="ref-ROG3_Heatsink" class="csl-entry">
ASUS 「ROG Phone3」、 <em>ASUS JAPAN</em>、閲覧日 2024年2月25日、 <a href="https://rog.asus.com/jp/phones/rog-phone-3-model/">https://rog.asus.com/jp/phones/rog-phone-3-model/</a>
</div>
<div id="ref-YouTube_Zen8" class="csl-entry">
ASUS (2021)“ASUS zenfone 8 series launch event”, <em>YouTube</em>, May 13, 2021 Accessed February 25, 2024 <a href="https://www.youtube.com/live/WenbzGTVK18?si=c0JOstVYRZ8yG-2G&amp;t=2079">https://www.youtube.com/live/WenbzGTVK18?si=c0JOstVYRZ8yG-2G&amp;t=2079</a>
</div>
<div id="ref-EXP21_Spec" class="csl-entry">
Qualcomm“Snapdragon smartphone specs”, <em>Qualcomm</em>, Accessed February 25, 2024 <a href="https://www.qualcomm.com/snapdragoninsiders/smartphone/specs">https://www.qualcomm.com/snapdragoninsiders/smartphone/specs</a>
</div>
<div id="ref-SoftBank" class="csl-entry">
SoftBank 「USIM 動作確認済み機種一覧」、 <em>SoftBank</em>、閲覧日 2024年2月25日、 <a href="https://www.softbank.jp/mobile/products/sim/usim-card-device/">https://www.softbank.jp/mobile/products/sim/usim-card-device/</a>
</div>
<div id="ref-Soumu" class="csl-entry">
総務省 (2019) 「ローカル５Ｇ導入に関するガイドライン案」、 <em>総務省</em>、2019年、閲覧日 2024年2月25日、 <a href="https://www.soumu.go.jp/main_content/000646534.pdf">https://www.soumu.go.jp/main_content/000646534.pdf</a>
</div>
<div id="ref-hanpen" class="csl-entry">
@hanpenblog (2024) 「<span class="nocase">iPhone 15 充電仕様調査</span>」、 <em>HanpenBlog</em>、2024年3月20日、閲覧日 2024年7月8日、 <a href="https://hanpenblog.com/18595#:~:text=USB%E3%82%84DisplayPort%E3%81%AE%E4%BB%95%E6%A7%98%E3%81%A7%E3%81%AF%E3%80%81DP%20Alt%20Mode%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%ABUSB%203.x%E4%BB%A5%E4%B8%8A%E3%82%82%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E7%89%B9%E3%81%AB%E8%A6%81%E4%BB%B6%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%81%9F%E3%82%81%E3%80%81DP%20Alt%20Mode%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%8C%E5%BF%85%E3%81%9A%E3%81%97%E3%82%82USB%203.x%E4%BB%A5%E4%B8%8A%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%E4%B8%80%E6%96%B9%E3%81%A7%E3%80%81DP%20Alt%20Mode%E3%81%AE%E4%BF%A1%E5%8F%B7%E3%81%AFUSB%203.x%E7%94%A8%E3%81%AE%E4%BF%A1%E5%8F%B7%E7%B7%9A%20(SSRX/SSTX)%20%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%81%AB%E4%BC%9D%E9%80%81%E3%81%95%E3%82%8C%E3%82%8B%E3%81%9F%E3%82%81%E3%80%81%E3%82%B1%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AFUSB%203.x%E4%BB%A5%E4%B8%8A%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82">https://hanpenblog.com/18595#:~:text=USB%E3%82%84DisplayPort%E3%81%AE%E4%BB%95%E6%A7%98%E3%81%A7%E3%81%AF%E3%80%81DP%20Alt%20Mode%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%ABUSB%203.x%E4%BB%A5%E4%B8%8A%E3%82%82%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E7%89%B9%E3%81%AB%E8%A6%81%E4%BB%B6%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%81%9F%E3%82%81%E3%80%81DP%20Alt%20Mode%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%8C%E5%BF%85%E3%81%9A%E3%81%97%E3%82%82USB%203.x%E4%BB%A5%E4%B8%8A%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%E4%B8%80%E6%96%B9%E3%81%A7%E3%80%81DP%20Alt%20Mode%E3%81%AE%E4%BF%A1%E5%8F%B7%E3%81%AFUSB%203.x%E7%94%A8%E3%81%AE%E4%BF%A1%E5%8F%B7%E7%B7%9A%20(SSRX/SSTX)%20%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%81%AB%E4%BC%9D%E9%80%81%E3%81%95%E3%82%8C%E3%82%8B%E3%81%9F%E3%82%81%E3%80%81%E3%82%B1%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AFUSB%203.x%E4%BB%A5%E4%B8%8A%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82</a>
</div>
</div>


</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a> ]]></description>
  <category>ASUS</category>
  <category>スマートフォン</category>
  <category>レビュー</category>
  <category>Refresh</category>
  <category>おすすめ記事</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Refresh/exp21.html</guid>
  <pubDate>Sun, 07 Jul 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/EXP21%E3%82%B5%E3%83%A0%E3%83%8D%E7%94%A8.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Pottal-Portal 3.0 におけるGoogle AdSenseを用いた自動広告を廃止しました</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Stop_GoogleAds.html</link>
  <description><![CDATA[ 




<p><a href="../post_images/G-Ads-Stop_UFO.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/G-Ads-Stop_UFO.png" class="img-fluid"></a></p>
<section id="google-adsense-自動広告廃止のお知らせ" class="level2">
<h2 class="anchored" data-anchor-id="google-adsense-自動広告廃止のお知らせ">Google AdSense 自動広告廃止のお知らせ</h2>
<p>2024年4月16日より、Pottal-Portal 3.0 にGoogle AdSenseの自動広告を導入・配信しておりましたが、これを取りやめることに致しました。</p>
<section id="自動広告廃止の背景" class="level3">
<h3 class="anchored" data-anchor-id="自動広告廃止の背景">自動広告廃止の背景</h3>
<p>Pottal-Portal 3.0 では、広告の導入にあたって<a href="https://www.pottal-portal.com/PtPr3/posts/Ad_start.html">ユーザー体験を損なわないことをお約束しておりました</a>。特に、広告位置やその広告内容には細心の注意を払っておりましたが、ゾーニングされていない悪質な広告の排除や広告位置の調節に難儀しており、余計な仕事を増やされるくらいなら広告など要らないなぁと思いGoogle AdSenseの自動広告を廃止することに致しました。</p>
<section id="広告位置について" class="level4">
<h4 class="anchored" data-anchor-id="広告位置について">広告位置について</h4>
<p>美しくない・ユーザーを混乱させてしまうといった理由から、ファーストビュー(ページの最上部やタイトル前後など最初に表示される一等地)に広告を設置しないように努めておりましたが、Google AdSenseの除外エリア設定では、そもそも除外エリアに指定できない箇所の広告はブロックできないため、ファーストビューに広告が設置されてしまうケースが何件か確認されました。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
ここの位置に広告表示したくないのに、GoogleAdSenseの除外エリアに指定できなくて泣いてる <a href="https://t.co/NTmyFVl2Ek">pic.twitter.com/NTmyFVl2Ek</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">@Pottal_MDS</span>) <a href="https://twitter.com/Pottal_MDS/status/1802922252276756913?ref_src=twsrc%5Etfw">June 18, 2024</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>これがきっかけで、Google AdSenseの自動広告を廃止することに決めました。</p>
</section>
<section id="ゾーニングされていない悪質な広告について" class="level4">
<h4 class="anchored" data-anchor-id="ゾーニングされていない悪質な広告について">ゾーニングされていない悪質な広告について</h4>
<p>Google AdSenseの設定でブロックしてもブロックしても湧いてくるゾーニングされていない広告と戦うのに疲れました。無理です。</p>
</section>
</section>
</section>
<section id="pottal-portal-3.0-の現状と今後について" class="level2">
<h2 class="anchored" data-anchor-id="pottal-portal-3.0-の現状と今後について">Pottal-Portal 3.0 の現状と今後について</h2>
<p>はてなブログ・Wordpress時代と違い、Google AdSenseで収益がろくすっぽ発生しなくなったため赤字となっているPottal-Portal 3.0 ですが、この度、唯一の収益源であるGoogle AdSenseによる自動広告も廃止したため、黒字化の目処はありません。 また、Googleのインデックスにもかかりにくくなっており、検索経由でのアクセスが激減しています。(はてなブログ・Wordpressに出戻りする気はありません。)</p>
<p>元から、収益のためにやっているわけではなく、完全に趣味で続けている(続けている…?)ため、特に別の収益化手段は講じておりませんが、2024年6月24日現在、本物のニートであり、ドメイン代やサーバー代くらいは稼げないと続けられません。</p>
<p>とりあえず、今後としては</p>
<ol type="1">
<li><a href="https://note.com/pottal_portal">note</a>に、記事の要旨を載せることでnote経由でのアクセス開拓</li>
<li>アフィリエイト(アソシエイト)による収益</li>
<li>広告案件による収益</li>
</ol>
<p>の3つを考えていますが、収益を出すことが目的ではないため、どこまで頑張るかはわかりません。</p>
<section id="その他" class="level3">
<h3 class="anchored" data-anchor-id="その他">その他</h3>
<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<p>というコールアウトを、記事1つ1つに手動で入れているのですが、(Markdownなので一括置換できるとは言え)レンダリングが面倒なので、今後も継続していきます。 また、Google AdSenseの自動広告は廃止したものの、Google AdSenseの収益資格自体は持っておきたいので、<code>ads.txt</code>ファイル自体は残しておきます。そのため、<a href="https://chromewebstore.google.com/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg">wappalyzer</a>等の拡張機能でサイトのバックグラウンドを表示した際には、Google AdSenseが表示されると思います(図&nbsp;1)。</p>
<div id="fig-wappalyzer" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-wappalyzer-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/G-Ads-Stop_wappalyzer.png" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="図&nbsp;1: wappalyzerで表示した本サイトの背景技術"><img src="https://pottal-portal.com/PtPr3/post_images/G-Ads-Stop_wappalyzer.png" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-wappalyzer-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: <a href="https://chromewebstore.google.com/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg">wappalyzer</a>で表示した本サイトの背景技術
</figcaption>
</figure>
</div>
</section>
</section>
<section id="最後に" class="level2">
<h2 class="anchored" data-anchor-id="最後に">最後に</h2>
<p>広告配信を停止するための、背中の一押しをしてくださった<a href="https://x.com/kir1ca">キリカ様(<span class="citation" data-cites="kir1ca">@kir1ca</span>)</a>に、この場を借りて厚く御礼申し上げます。 ちなみに、<a href="https://gadget-shot.com/">ガジェットショット</a>のようにパープルを基調とした美しいサイトに憧れてこのサイト(Pottal-Portal 3.0 )をデザインしました。</p>


</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a> ]]></description>
  <category>お知らせ</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Stop_GoogleAds.html</guid>
  <pubDate>Sun, 23 Jun 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/G-Ads-Stop_UFO.png" medium="image" type="image/png" height="144" width="144"/>
</item>
<item>
  <title>JSON CanvasからMarkdownへ変換するPythonスクリプトを作成しました</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/JSON_Canvas_to_Markdown_py.html</link>
  <description><![CDATA[ 




<p><a href="../post_images/Canvas2MD.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD.png" class="img-fluid"></a></p>
<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<section id="要旨" class="level2">
<h2 class="anchored" data-anchor-id="要旨">要旨</h2>
<p>JSON Canvasと呼ばれるオープンソースの無限キャンバスツールで作成された<code>.canvas</code>データをMarkdownファイルに変換するPythonスクリプトを作成し、<a href="https://github.com/Pottal/JSON_Canvas_to_Markdown">GitHubで公開しました</a>。 無限キャンバスツールは小説やゲームのシナリオなどに関するメモを二次元空間に自由に配置し、メモ同士を線や矢印で繋ぐことでプロットを作成するのに便利ですが、そのプロットをファイルとして出力することは容易ではありませんでした。 本スクリプトではノードとエッジの情報をローカルで解析し、矢印で繋がれたメインストーリー, それに関するメモ, そして孤立したメモの3つに分類したあと、それらを1つのMarkdownファイルにまとめて出力します。 これにより、無限キャンバスの内容をテキストファイルに落とし込むという事務作業から開放され、より一層創作活動に専念できるようになります。</p>
</section>
<section id="背景" class="level2">
<h2 class="anchored" data-anchor-id="背景">背景</h2>
<p>無限キャンバスツールは目新しいものではないものの、近年、急速に普及が進み、また多くのサービスが提供されています<span class="citation" data-cites="infinitecanvas">(Arun and Muse 2022)</span>。例えば、<a href="https://miro.com/about/">Miro</a>や、<a href="https://www.figma.com/">Figma</a>などは一度は耳にしたことがあるのではないでしょうか。他にも、<a href="https://arc.net/">Arc</a>というブラウザアプリはイーゼルと呼ばれる無限キャンバスを内蔵していますし<span class="citation" data-cites="ArcEasel">(Arc 2022)</span>、AppleではiPhone, iPad, Mac向けにFreeform(日本ではフリーボード)と呼ばれるアプリを提供しており<span class="citation" data-cites="AppleFreeform">(Apple Japan 広報部 2022)</span>、iPadにはそれが内蔵されています。今回紹介するObsidianにも古くからコミュニティプラグイン(有志による拡張機能)という形で<a href="https://github.com/excalidraw/excalidraw">Excalidraw</a>が提供されています。</p>
<p>こうした無限キャンバスツールは大きなホワイトボードのようなものなので、付箋をペタペタ貼ったり、ラフなアイデアを落書きしてみたりといった形で頭の中に眠っていたアイデアをアウトプットし、整理するのにはとても便利です(図&nbsp;1)。無限キャンバスという名前の通り無限にスペースを広げられ、制約もありません。</p>
<div id="fig-corkboard" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-corkboard-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_DALL·E 2024-05-29 17.12.37 - A realistic corkboard filled with pinned evidence, connected by red strings. The board features real-looking photographs of people, newspaper clipping.webp" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="生成AIDALL-E 3で作成"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_DALL·E 2024-05-29 17.12.37 - A realistic corkboard filled with pinned evidence, connected by red strings. The board features real-looking photographs of people, newspaper clipping.webp" class="img-fluid figure-img"></a></p>
<figcaption>生成AI<a href="https://openai.com/index/dall-e-3/">DALL-E 3</a>で作成</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_Miro_1.png" class="lightbox" data-gallery="quarto-lightbox-gallery-3" title="Miroより筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_Miro_1.png" class="img-fluid figure-img"></a></p>
<figcaption><a href="https://miro.com/about/">Miro</a>より筆者引用</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_Miro_2.png" class="lightbox" data-gallery="quarto-lightbox-gallery-4" title="Miroより筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_Miro_2.png" class="img-fluid figure-img"></a></p>
<figcaption><a href="https://miro.com/about/">Miro</a>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-corkboard-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: 無限キャンバスツールのイメージ
</figcaption>
</figure>
</div>
<p>しかし、その無限に発散したアイデアを1つに収束させ形にする必要がでた時、人によっては苦痛にもなる作業――つまり、情報を取捨選択し筋道立てて再構成し、メモを転記するというアクション――が発生します。もちろん、キャンバスの内容はある程度整理しているはずですし、アウトプットするという過程も、思考を深めるには大事な行為であることは理解していますが、メモをコピペしている瞬間というのは退屈で出来れば自動化したい時間です。</p>
<p>話は変わりますが、筆者は現在、同人ゲームを一人で開発しています。いわゆるノベルゲーと呼ばれる物語を中心としたゲームのため、プロットを考え, その情景を詳細に想像し, 背景やキャラの立ち絵・表情の変化などを考え, セリフや文章・画面演出を練って脚本を書き, それを元にスクリプトを書いています。また、用語集を使ったWikiを作成しアイデアとアイデアを結びつけるといったこともしています(図&nbsp;2)。そういう時に役立つのが、<a href="https://obsidian.md/">Obsidian</a>というツールです。</p>
<div id="fig-Obsidian_Sample" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Obsidian_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_Obsidian_sample.png" class="lightbox" data-gallery="quarto-lightbox-gallery-5" title="中身は筆者の勉強ノート"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_Obsidian_sample.png" class="img-fluid figure-img"></a></p>
<figcaption>中身は筆者の勉強ノート</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Obsidian_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;2: Obsidianで作成したWikiのイメージ
</figcaption>
</figure>
</div>
<p>Obsidianを使うことで無限キャンバスを使ったプロット作成や、Markdown形式<sup>1</sup>で絵や演出案(スクリプト)を含めた脚本執筆が行える他、自分用のWikiも簡単に作ることが出来ています。Markdown形式で書かれた脚本やWikiは、言ってしまえば単なるテキストデータのため簡単に他の形式(HTMLやPDFなど)に変換することができます。また、脚本から必要な地の文, 話者・セリフを取り出すことも工夫次第ではできるため、筆者は脚本からゲームのスクリプト(<code>.ks</code>ファイル)を作成しています。</p>
<p>やや話が逸れてしまいましたが、要するにMarkdownファイル(<code>.md</code>)は扱いやすいという話です。無限キャンバスで書かれたアイデアもこんな感じで自動的にMarkdownファイルに出来れば便利だと思いませんか？</p>
<section id="json-canvasとは何か" class="level3">
<h3 class="anchored" data-anchor-id="json-canvasとは何か">JSON Canvasとは何か</h3>
<p>JSON Canvasは、Obsidianが2024年3月にリリースしたオープンソースの無限キャンバス機能です<span class="citation" data-cites="JSON_Canvas">(Kepano 2024)</span>。無限に広がるキャンバス上にノードとエッジを配置し、自由に結びつけることでネットワーク状の情報構造を表現できます。ノードにはテキストやファイル、リンクなどを埋め込むことができ、それらをエッジ(線や矢印)で繋げることで関係性を可視化できます(図&nbsp;3)。</p>
<div id="fig-ObsidianCanvas_Sample" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ObsidianCanvas_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Canvas2MD_SampleCanvas.png" class="lightbox" data-gallery="quarto-lightbox-gallery-6" title="図&nbsp;3: Obsidian Canvasで作成したサンプル"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_SampleCanvas.png" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ObsidianCanvas_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;3: Obsidian Canvasで作成したサンプル
</figcaption>
</figure>
</div>
<p>オープンソースのため、仕様も明確ですし、これから対応サービスが増えていくことが予想されます。なお、2024年5月現在、対応サービスは<a href="https://obsidian.md/">Obsidian</a>, <a href="https://kinopio.club/">Kinopio</a>, <a href="https://flowchart.fun/">Flowchart Fun</a>, <a href="https://hi-canvas.marknoteapp.com/">hi-canvas</a>となっています。</p>
<p>また、JSON Canvas(<code>.cavas</code>)のデータ形式は、拡張子こそ見慣れないものの、その中身は一般的なJSON形式(<code>.json</code>)が採用されています。 JSON形式はAIにとって分かりやすい書式なので、(試していませんが)そのまま生成AIに渡せばいい感じに処理してくれると考えられます。 しかし、未発表の作品を生成AIに渡してしまうのは躊躇われることでしょう。学習されてしまったり、謎の倫理観によってセンシティブ判定されてしまったり、あるいは単純にコストの問題もあります。</p>
<section id="sec-Obsidian" class="level4">
<h4 class="anchored" data-anchor-id="sec-Obsidian">Obsidianとは何か</h4>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
余談です
</div>
</div>
<div class="callout-body-container callout-body">
<p>このコラムは筆者がObsidianを布教するためのものです。 読み飛ばしても問題ありません。いつか、別の記事でちゃんと解説したいと思っています。</p>
</div>
</div>
<p>Obsidianは個人用ナレッジマネジメントシステムとして設計されたノートテイキングアプリケーションです。 その特徴は大きく5つほどあり、①ローカルで動作・管理されること(クラウド同期・マルチデバイスにも対応), ②Markdownを用いることで頑強かつ汎用性があること, ③メモ同士を繋ぐグラフビューによる可視化が可能なこと, ④マウスホバーによるインライン表示が可能なこと, ⑤コミュニティプラグインと呼ばれる有志による拡張機能が豊富なことが挙げられ、特に①~③の特徴から、「第二の脳(Second Brain)」のツールとして着目されています。</p>
<p>例えば、クラウド上のメモサービス(Evernote, Notion, Google Keepなど)は、あくまで<strong>オンラインが前提</strong>であり、またサービスが終了してしまった場合、自分でデータをエクスポートしないとデータはおそらく消えてしまうことでしょう。また、データ検索もサーバーや回線の具合によってはうまくいかないことがあります。その点、Obsidianはオフライン(ローカル環境)が前提のアプリで、メモは全てデバイス上にMarkdownファイルとして保存されます。 Markdown(<code>.md</code>)はシンプルで読みやすいテキストベースのマークアップ言語であり、広く普及しているため、たとえObsidianがサービス終了したとしても問題なく他のアプリやテキストエディタ上で読むことができます。</p>
<aside id="footnotes" class="footnotes footnotes-end-of-section">
<hr>
<ol>
<li id="fn1"><p>Markdown(<code>.md</code>)は、シンプルで読みやすいテキストベースのマークアップ言語。プレーンテキスト(要するに<code>.txt</code>ファイル)にわずかな記号(<code>#</code>や<code>*</code>, <code>-</code>など)を追加することで、見出しや箇条書き、リンクなどの書式を表現でます。HTMLと比べると覚えることが少なく、素早く記述できるのが特徴で、GitHubのREADME(説明書)にも用いられています。ファイルサイズも小さいため、バージョン管理にも適しています。↩︎</p></li>
</ol>
</aside>
</section>
</section>
<section id="動機" class="level3">
<h3 class="anchored" data-anchor-id="動機">動機</h3>
<p>前述の通り、筆者は同人ゲームを一人で制作しており、プロットも脚本も自分で考え、それをスクリプトに落とし込む必要があります。以前は何も考えずに無限キャンバスサービスのMiroを使っていたのですが、<em>何だがそのうち面倒になってしまい</em> 今ではプロットを書かずに時系列に沿って思いつきでシナリオを書いています。 この、なんだか面倒というのは多分創作活動において良くないことで、こうした摩擦を減らして如何にストレス無くアイデアを形にするかが大事なんだと思います。</p>
<p>そんなことを漠然と考えながら、創作もせずダラダラとTwitterを見ていたところ、<a href="https://x.com/dddrill">碌星らせん(<code>@dddrill</code>)さん</a>の以下のTweetを受けて、「確かにホワイトボード(無限キャンバスツール)に貼った付箋や落書きを良しなにテキストに出力できたら楽だろうなぁ」と思った次第であります。もちろん、筆者は創作作業から逃げてダラダラとTwitterをしている人間ですので、そんなツールがあればいいなぁと漠然と思うだけで、そんなツールがないかを自分で調べたりすることもなく、酔生夢死な日々を送っていました。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
うーん、ひとまずメモ書きを二次元空間に自由に配置できて、メモ書き同士を線で繋げて、順番が決まったらくっつけて出力できるツールがあればいいのか。
</p>
— 碌星らせん（ろくせい・らせん） (<span class="citation" data-cites="dddrill">(<strong>dddrill?</strong>)</span>) <a href="https://twitter.com/dddrill/status/1655208519786987521?ref_src=twsrc%5Etfw">May 7, 2023</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>何となく、何かないかなぁと頭の片隅で燻り続けて約1年。なぜか唐突に火がつき、「Obsidian CanvasはJSONファイルだから簡単に構造を把握して取り出せるはず！」と突貫工事で作業を開始した次第であります。</p>
</section>
<section id="このスクリプトが目指すものこのスクリプトで何ができるか" class="level3">
<h3 class="anchored" data-anchor-id="このスクリプトが目指すものこのスクリプトで何ができるか">このスクリプトが目指すもの(このスクリプトで何ができるか)</h3>
<p>このスクリプト(スクリプト&nbsp;1)ではJSON Canvas(<code>.canvas</code>)ファイルを読み込み、その構造を元に、矢印で繋がれたメインストーリー, それに関するメモ, そして孤立したメモの3つに分類し、矢印の順番に沿ってメインストーリーの内容をMarkdownに変換, それに関するメモを脚注として変換, 孤立したメモを水平線で区切ってその下にMarkdownとして変換し、1つのファイルにします。</p>
<div id="fig-Sample_Structure" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Sample_Structure-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Sample_Structure" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Sample_Structure_mermaid" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-Sample_Structure_mermaid-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 193.2421875 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-1" height="480">
<style>#mermaid-figure-1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-1 .error-icon{fill:#552222;}#mermaid-figure-1 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-1 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-1 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-1 .marker.cross{stroke:#333333;}#mermaid-figure-1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-1 .cluster-label text{fill:#333;}#mermaid-figure-1 .cluster-label span,#mermaid-figure-1 p{color:#333;}#mermaid-figure-1 .label text,#mermaid-figure-1 span,#mermaid-figure-1 p{fill:#333;color:#333;}#mermaid-figure-1 .node rect,#mermaid-figure-1 .node circle,#mermaid-figure-1 .node ellipse,#mermaid-figure-1 .node polygon,#mermaid-figure-1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-1 .flowchart-label text{text-anchor:middle;}#mermaid-figure-1 .node .label{text-align:center;}#mermaid-figure-1 .node.clickable{cursor:pointer;}#mermaid-figure-1 .arrowheadPath{fill:#333333;}#mermaid-figure-1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-1 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-1 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-1 .cluster text{fill:#333;}#mermaid-figure-1 .cluster span,#mermaid-figure-1 p{color:#333;}#mermaid-figure-1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,30.879557291666668,143.2634084157837C36.751302083333336,151.86015016490072,48.494791666666664,160.7203003298014,54.366536458333336,165.15037541225175L60.23828125,169.58045049470212"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M80.67578125,202L80.67578125,206.16666666666666C80.67578125,210.33333333333334,80.67578125,218.66666666666666,80.67578125,227C80.67578125,235.33333333333334,80.67578125,243.66666666666666,80.67578125,247.83333333333334L80.67578125,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M80.67578125,286L80.67578125,290.1666666666667C80.67578125,294.3333333333333,80.67578125,302.6666666666667,80.67578125,311C80.67578125,319.3333333333333,80.67578125,327.6666666666667,80.67578125,331.8333333333333L80.67578125,336"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Csub LE-C" id="L-Csub-C-0" d="M136.34375,118L136.34375,122.16666666666667C136.34375,126.33333333333333,136.34375,134.66666666666666,130.47200520833334,143.2634084157837C124.60026041666667,151.86015016490072,112.85677083333333,160.7203003298014,106.98502604166667,165.15037541225175L101.11328125,169.58045049470212"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-16" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(80.67578125, 185)" id="flowchart-C-18" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(80.67578125, 269)" id="flowchart-D-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(80.67578125, 353)" id="flowchart-E-20" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(136.34375, 101)" id="flowchart-Csub-21" class="node default default flowchart-label"><rect height="34" width="81.796875" y="-17" x="-40.8984375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-33.3984375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="66.796875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2_sub1</span>
</div>
</foreignobject></g></g><g transform="translate(117.328125, 17)" id="flowchart-Z-23" class="node default default flowchart-label"><rect height="34" width="34.625" y="-17" x="-17.3125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-9.8125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="19.625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">iso</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-Sample_Structure_mermaid-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 簡易化した構造
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Sample_Structure" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Sample_Structure_canvas" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-Sample_Structure_canvas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Canvas2MD_Simple_Canvas.png" class="lightbox" data-gallery="fig-Sample_Structure" title="図&nbsp;4&nbsp;(b): 実際のJSON Canvasファイル"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_Simple_Canvas.png" class="img-fluid figure-img" data-ref-parent="fig-Sample_Structure"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-Sample_Structure_canvas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 実際のJSON Canvasファイル
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Sample_Structure-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;4: Canvasファイルのサンプル
</figcaption>
</figure>
</div>
<p>上記のような構造(図&nbsp;4)のJSON Canvasファイルがあった場合、</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>"Canvas2MD_Sample.md</strong></pre>
</div>
<div class="sourceCode" id="cb1" data-filename="&quot;Canvas2MD_Sample.md" style="background: #f1f3f5;"><pre class="sourceCode Markdown code-with-copy"><code class="sourceCode markdown"><span id="cb1-1"></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## Start</span></span>
<span id="cb1-3">Start!</span>
<span id="cb1-4"></span>
<span id="cb1-5"></span>
<span id="cb1-6"></span>
<span id="cb1-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## Ep1</span></span>
<span id="cb1-8">hoge</span>
<span id="cb1-9"></span>
<span id="cb1-10"></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## Ep2</span></span>
<span id="cb1-13">fuga</span>
<span id="cb1-14"></span>
<span id="cb1-15"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[^sub_id]</span></span>
<span id="cb1-16"></span>
<span id="cb1-17"></span>
<span id="cb1-18"></span>
<span id="cb1-19"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## Ep3</span></span>
<span id="cb1-20">piyo</span>
<span id="cb1-21"><span class="al" style="color: #AD0000;
background-color: null;
font-style: inherit;">![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaurYTaUrM5OOaHR_jJACQIGz1jARLQGOZh_OqtnQu8AD9zVbrZ_dcPmmXjMwWGQRHnJ0g1-6evmC0mFhwp_A4kd1uUKeO9lS5wPSKtM34Ey7TWqN8Unhomh3dMm7uVsAb78ry4rcT1gY/s400/animal_mark_hiyoko.png)</span></span>
<span id="cb1-22"></span>
<span id="cb1-23"></span>
<span id="cb1-24"></span>
<span id="cb1-25"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## End</span></span>
<span id="cb1-26">The End</span>
<span id="cb1-27"></span>
<span id="cb1-28"></span>
<span id="cb1-29"></span>
<span id="cb1-30"></span>
<span id="cb1-31"></span>
<span id="cb1-32"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[^sub_id]</span>:</span>
<span id="cb1-33"></span>
<span id="cb1-34"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    ## Ep2_sub</span></span>
<span id="cb1-35"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Hoge, fuga</span></span>
<span id="cb1-36"><span class="in" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    </span></span>
<span id="cb1-37"></span>
<span id="cb1-38"></span>
<span id="cb1-39">---</span>
<span id="cb1-40"></span>
<span id="cb1-41"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">## iso</span></span>
<span id="cb1-42">isolation</span>
<span id="cb1-43"></span>
<span id="cb1-44"></span>
<span id="cb1-45">---</span></code></pre></div>
</div>
<p>というMarkdownに変換します。 Markdownのプレビューはどのアプリを使うかによって若干の違いが出ますが、図&nbsp;5のような仕上がりになります。</p>
<div id="fig-MD_Sample" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-MD_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_SampleMD_VSCodeMPE.png" class="lightbox" data-gallery="quarto-lightbox-gallery-8" title="VS Code + Markdown Preview Enhancedによるプレビュー"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_SampleMD_VSCodeMPE.png" class="img-fluid figure-img"></a></p>
<figcaption>VS Code + Markdown Preview Enhancedによるプレビュー</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_SampleMD_Quarto.png" class="lightbox" data-gallery="quarto-lightbox-gallery-9" title="Quarto(ver1.5.39)によるプレビュー"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_SampleMD_Quarto.png" class="img-fluid figure-img"></a></p>
<figcaption>Quarto(ver1.5.39)によるプレビュー</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 33.3%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_SampleMD_Obsidian.png" class="lightbox" data-gallery="quarto-lightbox-gallery-10" title="Obsidian(ver1.5.12)によるプレビュー(筆者によってCSSがゴリゴリにカスタマイズされている)"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_SampleMD_Obsidian.png" class="img-fluid figure-img"></a></p>
<figcaption>Obsidian(ver1.5.12)によるプレビュー(筆者によってCSSがゴリゴリにカスタマイズされている)</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-MD_Sample-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;5: 上記のMarkdownファイルを各アプリでプレビューした結果
</figcaption>
</figure>
</div>
</section>
</section>
<section id="材料と方法" class="level2">
<h2 class="anchored" data-anchor-id="材料と方法">材料と方法</h2>
<p>このスクリプト(スクリプト&nbsp;1)は、(今のところ)特定の構造を保ったJSON Canvasファイル(<code>.canvas</code>)に対して、適切なMarkdownファイル(<code>.md</code>)を作成します。それ以外のファイルでの動作は保証していません。</p>
<ol type="1">
<li><code>canvas_file (line 154)</code> において、読み込むJSON Canvasファイルをフルパスで入力します。</li>
<li><code>output_markdown_file (line 155)</code> において、Markdownファイルの出力先を指定します。Canvasファイルと違うディレクトリの場合、JSON Canvas中に埋め込んだMarkdownファイルや画像がうまく表示されない場合があります。</li>
<li><code>Canvas2MD.py</code>を実行することで、指定したJSON Canavsファイル(<code>.canvas</code>)を指定した場所にMarkdownを出力します。</li>
</ol>
<div id="lst-Canvas2MD" class="py listing quarto-float quarto-figure quarto-figure-left anchored" data-filename="Canvas2MD.py" data-code-line-numbers="true">
<figure class="quarto-float quarto-float-lst figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-lst" id="lst-Canvas2MD-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
スクリプト&nbsp;1: JSON CanvasファイルからMarkdownへと変換するスクリプト
</figcaption>
<div aria-describedby="lst-Canvas2MD-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>Canvas2MD.py</strong></pre>
</div>
<div class="sourceCode" id="lst-Canvas2MD" data-filename="Canvas2MD.py" style="background: #f1f3f5;"><pre class="sourceCode numberSource py number-lines code-with-copy"><code class="sourceCode python"><span id="lst-Canvas2MD-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> json</span>
<span id="lst-Canvas2MD-2"></span>
<span id="lst-Canvas2MD-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># メインストーリー(main_story)の定義: ノード同士が一方向矢印で結ばれた一連のノード</span></span>
<span id="lst-Canvas2MD-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># サブストーリー(sub_story)の定義: メインストーリーのノードに対して矢印ではなく**線**で結ばれた**1つの**ノード</span></span>
<span id="lst-Canvas2MD-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># セレクトストーリー(select_story)の定義: メインストーリー中の分岐した**1つの**ノード</span></span>
<span id="lst-Canvas2MD-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 孤立したノード(isolated nodes)の定義: どのノードとも結びついていない孤立したノード</span></span>
<span id="lst-Canvas2MD-7"></span>
<span id="lst-Canvas2MD-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load_canvas(file_path):</span>
<span id="lst-Canvas2MD-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(file_path, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'r'</span>, encoding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>:</span>
<span id="lst-Canvas2MD-10">        data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json.load(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>)</span>
<span id="lst-Canvas2MD-11">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data</span>
<span id="lst-Canvas2MD-12"></span>
<span id="lst-Canvas2MD-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> find_starting_nodes(edges):</span>
<span id="lst-Canvas2MD-14">    to_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges}</span>
<span id="lst-Canvas2MD-15">    from_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges}</span>
<span id="lst-Canvas2MD-16">    start_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> from_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> to_nodes</span>
<span id="lst-Canvas2MD-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(start_nodes)</span>
<span id="lst-Canvas2MD-18"></span>
<span id="lst-Canvas2MD-19"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> find_story_path(start_node, edges, follow_arrows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>):</span>
<span id="lst-Canvas2MD-20">    path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [start_node]</span>
<span id="lst-Canvas2MD-21">    current_node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start_node</span>
<span id="lst-Canvas2MD-22">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="lst-Canvas2MD-23">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> follow_arrows:</span>
<span id="lst-Canvas2MD-24">            next_edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> current_node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'arrow'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'arrow'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>]</span>
<span id="lst-Canvas2MD-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="lst-Canvas2MD-26">            next_edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> current_node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> (edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromEnd'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toEnd'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>)]</span>
<span id="lst-Canvas2MD-27">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> next_edges:</span>
<span id="lst-Canvas2MD-28">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span></span>
<span id="lst-Canvas2MD-29">        next_node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> next_edges[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>]</span>
<span id="lst-Canvas2MD-30">        path.append(next_node)</span>
<span id="lst-Canvas2MD-31">        current_node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> next_node</span>
<span id="lst-Canvas2MD-32">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> path</span>
<span id="lst-Canvas2MD-33"></span>
<span id="lst-Canvas2MD-34"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> extract_stories(data):</span>
<span id="lst-Canvas2MD-35">    nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'id'</span>]: node <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'nodes'</span>]}</span>
<span id="lst-Canvas2MD-36">    edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'edges'</span>, [])</span>
<span id="lst-Canvas2MD-37"></span>
<span id="lst-Canvas2MD-38">    main_story_edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'arrow'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'arrow'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>]</span>
<span id="lst-Canvas2MD-39">    sub_story_edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">or</span> edge.get(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toEnd'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'none'</span>]</span>
<span id="lst-Canvas2MD-40"></span>
<span id="lst-Canvas2MD-41">    start_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> find_starting_nodes(main_story_edges)</span>
<span id="lst-Canvas2MD-42">    main_stories <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [find_story_path(start_node, main_story_edges) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> start_node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> start_nodes]</span>
<span id="lst-Canvas2MD-43"></span>
<span id="lst-Canvas2MD-44">    main_story_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {node <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_stories <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> story}</span>
<span id="lst-Canvas2MD-45"></span>
<span id="lst-Canvas2MD-46">    sub_stories <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="lst-Canvas2MD-47">    visited_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(main_story_nodes)</span>
<span id="lst-Canvas2MD-48">    sub_story_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="lst-Canvas2MD-49">    select_stories <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="lst-Canvas2MD-50">    </span>
<span id="lst-Canvas2MD-51">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_edges:</span>
<span id="lst-Canvas2MD-52">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> visited_nodes:</span>
<span id="lst-Canvas2MD-53">            sub_story <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> find_story_path(edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>], sub_story_edges, follow_arrows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="lst-Canvas2MD-54">            sub_story <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [node_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_story_nodes]</span>
<span id="lst-Canvas2MD-55">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sub_story:</span>
<span id="lst-Canvas2MD-56">                sub_stories.append(sub_story)</span>
<span id="lst-Canvas2MD-57">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_map:</span>
<span id="lst-Canvas2MD-58">                    sub_story_map[edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>]] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="lst-Canvas2MD-59">                sub_story_map[edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>]].append(sub_story[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="lst-Canvas2MD-60">                visited_nodes.update(sub_story)</span>
<span id="lst-Canvas2MD-61">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> visited_nodes:</span>
<span id="lst-Canvas2MD-62">            sub_story <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> find_story_path(edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>], sub_story_edges, follow_arrows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="lst-Canvas2MD-63">            sub_story <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [node_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_story_nodes]</span>
<span id="lst-Canvas2MD-64">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sub_story:</span>
<span id="lst-Canvas2MD-65">                sub_stories.append(sub_story)</span>
<span id="lst-Canvas2MD-66">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_map:</span>
<span id="lst-Canvas2MD-67">                    sub_story_map[edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>]] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="lst-Canvas2MD-68">                sub_story_map[edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>]].append(sub_story[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>])</span>
<span id="lst-Canvas2MD-69">                visited_nodes.update(sub_story)</span>
<span id="lst-Canvas2MD-70"></span>
<span id="lst-Canvas2MD-71">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_stories:</span>
<span id="lst-Canvas2MD-72">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> story:</span>
<span id="lst-Canvas2MD-73">            connected_edges <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_story_edges <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> node_id]</span>
<span id="lst-Canvas2MD-74">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(connected_edges) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>:</span>
<span id="lst-Canvas2MD-75">                select_stories[node_id] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> connected_edges]</span>
<span id="lst-Canvas2MD-76"></span>
<span id="lst-Canvas2MD-77">    connected_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fromNode'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges).union(edge[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'toNode'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> edge <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> edges)</span>
<span id="lst-Canvas2MD-78">    isolated_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'id'</span>] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> nodes.values() <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'id'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> connected_nodes]</span>
<span id="lst-Canvas2MD-79"></span>
<span id="lst-Canvas2MD-80">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># セレクトストーリーのノードIDを取得</span></span>
<span id="lst-Canvas2MD-81">    select_story_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {node_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_ids <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_stories.values() <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> node_ids}</span>
<span id="lst-Canvas2MD-82"></span>
<span id="lst-Canvas2MD-83">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># セレクトストーリーがメインストーリーに含まれている場合、それを除外する</span></span>
<span id="lst-Canvas2MD-84">    main_stories <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [[node_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> story <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_story_nodes] <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_stories]</span>
<span id="lst-Canvas2MD-85"></span>
<span id="lst-Canvas2MD-86">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> main_stories, sub_stories, isolated_nodes, sub_story_map, select_stories, select_story_nodes</span>
<span id="lst-Canvas2MD-87"></span>
<span id="lst-Canvas2MD-88"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> sort_nodes_by_position(node_ids, nodes):</span>
<span id="lst-Canvas2MD-89">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sorted</span>(node_ids, key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> node_id: (nodes[node_id][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span>], nodes[node_id][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span>]))</span>
<span id="lst-Canvas2MD-90"></span>
<span id="lst-Canvas2MD-91"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> node_to_markdown(node, indent_level<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, add_sub_ref_ids<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>, is_select_story<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>):</span>
<span id="lst-Canvas2MD-92">    indent <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"  "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> indent_level</span>
<span id="lst-Canvas2MD-93">    content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="lst-Canvas2MD-94">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> is_select_story:</span>
<span id="lst-Canvas2MD-95">        content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'&lt;a id="</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"id"</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"&gt;&lt;/a&gt;</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="lst-Canvas2MD-96">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'type'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>:</span>
<span id="lst-Canvas2MD-97">        content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>indent<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{</span>node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>replace(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>indent<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="lst-Canvas2MD-98">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'type'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>:</span>
<span id="lst-Canvas2MD-99">        content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>indent<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">![](</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'file'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="lst-Canvas2MD-100">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> add_sub_ref_ids:</span>
<span id="lst-Canvas2MD-101">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sub_ref_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> add_sub_ref_ids:</span>
<span id="lst-Canvas2MD-102">            content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>indent<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">[^sub_</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>sub_ref_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">]</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="lst-Canvas2MD-103">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="lst-Canvas2MD-104"></span>
<span id="lst-Canvas2MD-105"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> generate_markdown(data):</span>
<span id="lst-Canvas2MD-106">    nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {node[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'id'</span>]: node <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'nodes'</span>]}</span>
<span id="lst-Canvas2MD-107">    main_stories, sub_stories, isolated_nodes, sub_story_map, select_stories, select_story_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> extract_stories(data)</span>
<span id="lst-Canvas2MD-108">    </span>
<span id="lst-Canvas2MD-109">    markdown_lines <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="lst-Canvas2MD-110"></span>
<span id="lst-Canvas2MD-111">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># サブストーリーを変換するための辞書を作成</span></span>
<span id="lst-Canvas2MD-112">    sub_story_content_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {}</span>
<span id="lst-Canvas2MD-113">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sub_story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_stories:</span>
<span id="lst-Canvas2MD-114">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sub_story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> sub_story[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_story_nodes:</span>
<span id="lst-Canvas2MD-115">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story:</span>
<span id="lst-Canvas2MD-116">                node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nodes[node_id]</span>
<span id="lst-Canvas2MD-117">                sub_story_content_map[node_id] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> node_to_markdown(node, indent_level<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)</span>
<span id="lst-Canvas2MD-118"></span>
<span id="lst-Canvas2MD-119">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> main_story <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_stories:</span>
<span id="lst-Canvas2MD-120">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> main_story:</span>
<span id="lst-Canvas2MD-121">            node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nodes[node_id]</span>
<span id="lst-Canvas2MD-122">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># セレクトストーリーでないサブストーリーの参照IDのみ追加</span></span>
<span id="lst-Canvas2MD-123">            add_sub_ref_ids <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ref_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> ref_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_map.get(node_id, []) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> ref_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_story_nodes]</span>
<span id="lst-Canvas2MD-124">            markdown_lines.append(node_to_markdown(node, add_sub_ref_ids<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>add_sub_ref_ids))</span>
<span id="lst-Canvas2MD-125">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_stories:</span>
<span id="lst-Canvas2MD-126">                sorted_select_nodes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sort_nodes_by_position(select_stories[node_id], nodes)</span>
<span id="lst-Canvas2MD-127">                markdown_lines.append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-128">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> idx, select_node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(sorted_select_nodes, start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="lst-Canvas2MD-129">                    markdown_lines.append(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"[セレクトストーリー_</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>idx<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">にとぶ](#</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>select_node_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">)</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-130">                markdown_lines.append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-131">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> select_node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sorted_select_nodes:</span>
<span id="lst-Canvas2MD-132">                    select_node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nodes[select_node_id]</span>
<span id="lst-Canvas2MD-133">                    add_select_sub_ref_ids <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [ref_id <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> ref_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_map.get(select_node_id, []) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> ref_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> select_story_nodes]</span>
<span id="lst-Canvas2MD-134">                    markdown_lines.append(node_to_markdown(select_node, is_select_story<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>, add_sub_ref_ids<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>add_select_sub_ref_ids))</span>
<span id="lst-Canvas2MD-135">                    markdown_lines.append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-136">        markdown_lines.append(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-137"></span>
<span id="lst-Canvas2MD-138">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># サブストーリーの内容を脚注として追加</span></span>
<span id="lst-Canvas2MD-139">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id, content <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sub_story_content_map.items():</span>
<span id="lst-Canvas2MD-140">        markdown_lines.append(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">[^sub_</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>node_id<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">]:"</span>)</span>
<span id="lst-Canvas2MD-141">        markdown_lines.append(content)</span>
<span id="lst-Canvas2MD-142"></span>
<span id="lst-Canvas2MD-143">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> node_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> isolated_nodes:</span>
<span id="lst-Canvas2MD-144">        node <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> nodes[node_id]</span>
<span id="lst-Canvas2MD-145">        markdown_lines.append(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"---</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>node_to_markdown(node)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">---"</span>)</span>
<span id="lst-Canvas2MD-146"></span>
<span id="lst-Canvas2MD-147">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>.join(markdown_lines)</span>
<span id="lst-Canvas2MD-148"></span>
<span id="lst-Canvas2MD-149"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> save_markdown(content, file_path):</span>
<span id="lst-Canvas2MD-150">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">open</span>(file_path, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'w'</span>, encoding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>) <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>:</span>
<span id="lst-Canvas2MD-151">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span>.write(content)</span>
<span id="lst-Canvas2MD-152"></span>
<span id="lst-Canvas2MD-153"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">__name__</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"__main__"</span>:</span>
<span id="lst-Canvas2MD-154">    canvas_file <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Canvas2MD_SampleCanvas.canvas'</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 読み込むJSON Canvasファイルのパスを入力してください。</span></span>
<span id="lst-Canvas2MD-155">    output_markdown_file <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sample_Canvas.md'</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 作成するMarkdownファイルの出力先を指定してください。</span></span>
<span id="lst-Canvas2MD-156">                                                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Canvasファイルと違うディレクトリの場合、JSON Canvas中に埋め込んだMarkdownファイルや画像がうまく表示されない場合があります。</span></span>
<span id="lst-Canvas2MD-157">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="lst-Canvas2MD-158">        canvas_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_canvas(canvas_file)</span>
<span id="lst-Canvas2MD-159">        markdown_content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> generate_markdown(canvas_data)</span>
<span id="lst-Canvas2MD-160">        save_markdown(markdown_content, output_markdown_file)</span>
<span id="lst-Canvas2MD-161">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Markdown file generated and saved as </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>output_markdown_file<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="lst-Canvas2MD-162">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">Exception</span> <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> e:</span>
<span id="lst-Canvas2MD-163">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"An error occurred: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>e<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span></code></pre></div>
</div>
</div>
</figure>
</div>
<section id="動作条件" class="level3">
<h3 class="anchored" data-anchor-id="動作条件">動作条件</h3>
<ul>
<li>メインストーリー(一方向の矢印で結ばれたノード)が、一方通行であり,なおかつ(分岐した場合は)分岐が続くことなくメインストーリーに合流すること(図&nbsp;6)</li>
<li>サブストーリー(メインストーリーのノードと<strong>線で結ばれた</strong>ノード)に矢印や他のノードがついていないこと(図&nbsp;7)</li>
</ul>
<div id="fig-QA_Structure_main" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-QA_Structure_main-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_main" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-QA_Structure_main_OK-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_main_OK-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 66.015625 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-11" height="480">
<style>#mermaid-figure-11{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-11 .error-icon{fill:#552222;}#mermaid-figure-11 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-11 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-11 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-11 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-11 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-11 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-11 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-11 .marker.cross{stroke:#333333;}#mermaid-figure-11 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-11 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-11 .cluster-label text{fill:#333;}#mermaid-figure-11 .cluster-label span,#mermaid-figure-11 p{color:#333;}#mermaid-figure-11 .label text,#mermaid-figure-11 span,#mermaid-figure-11 p{fill:#333;color:#333;}#mermaid-figure-11 .node rect,#mermaid-figure-11 .node circle,#mermaid-figure-11 .node ellipse,#mermaid-figure-11 .node polygon,#mermaid-figure-11 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-11 .flowchart-label text{text-anchor:middle;}#mermaid-figure-11 .node .label{text-align:center;}#mermaid-figure-11 .node.clickable{cursor:pointer;}#mermaid-figure-11 .arrowheadPath{fill:#333333;}#mermaid-figure-11 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-11 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-11 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-11 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-11 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-11 .cluster text{fill:#333;}#mermaid-figure-11 .cluster span,#mermaid-figure-11 p{color:#333;}#mermaid-figure-11 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-11 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-11 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,25.0078125,143C25.0078125,151.33333333333334,25.0078125,159.66666666666666,25.0078125,163.83333333333334L25.0078125,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M25.0078125,202L25.0078125,206.16666666666666C25.0078125,210.33333333333334,25.0078125,218.66666666666666,25.0078125,227C25.0078125,235.33333333333334,25.0078125,243.66666666666666,25.0078125,247.83333333333334L25.0078125,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M25.0078125,286L25.0078125,290.1666666666667C25.0078125,294.3333333333333,25.0078125,302.6666666666667,25.0078125,311C25.0078125,319.3333333333333,25.0078125,327.6666666666667,25.0078125,331.8333333333333L25.0078125,336"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-10" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-11" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 185)" id="flowchart-C-12" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 269)" id="flowchart-D-13" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 353)" id="flowchart-E-14" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_main_OK-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) OK
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_main" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-QA_Structure_main_OK-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_main_OK-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 150.3125 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-10" height="480">
<style>#mermaid-figure-10{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-10 .error-icon{fill:#552222;}#mermaid-figure-10 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-10 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-10 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-10 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-10 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-10 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-10 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-10 .marker.cross{stroke:#333333;}#mermaid-figure-10 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-10 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-10 .cluster-label text{fill:#333;}#mermaid-figure-10 .cluster-label span,#mermaid-figure-10 p{color:#333;}#mermaid-figure-10 .label text,#mermaid-figure-10 span,#mermaid-figure-10 p{fill:#333;color:#333;}#mermaid-figure-10 .node rect,#mermaid-figure-10 .node circle,#mermaid-figure-10 .node ellipse,#mermaid-figure-10 .node polygon,#mermaid-figure-10 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-10 .flowchart-label text{text-anchor:middle;}#mermaid-figure-10 .node .label{text-align:center;}#mermaid-figure-10 .node.clickable{cursor:pointer;}#mermaid-figure-10 .arrowheadPath{fill:#333333;}#mermaid-figure-10 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-10 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-10 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-10 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-10 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-10 .cluster text{fill:#333;}#mermaid-figure-10 .cluster span,#mermaid-figure-10 p{color:#333;}#mermaid-figure-10 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-10 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-10 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M66.515625,34L66.515625,38.166666666666664C66.515625,42.333333333333336,66.515625,50.666666666666664,66.515625,59C66.515625,67.33333333333333,66.515625,75.66666666666667,66.515625,79.83333333333333L66.515625,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M47.86495535714286,118L43.29371279761906,122.16666666666667C38.72247023809524,126.33333333333333,29.57998511904762,134.66666666666666,25.00874255952381,143C20.4375,151.33333333333334,20.4375,159.66666666666666,20.4375,163.83333333333334L20.4375,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M20.4375,202L20.4375,206.16666666666666C20.4375,210.33333333333334,20.4375,218.66666666666666,25.00874255952381,227C29.57998511904762,235.33333333333334,38.72247023809524,243.66666666666666,43.29371279761906,247.83333333333334L47.86495535714286,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M66.515625,286L66.515625,290.1666666666667C66.515625,294.3333333333333,66.515625,302.6666666666667,66.515625,311C66.515625,319.3333333333333,66.515625,327.6666666666667,66.515625,331.8333333333333L66.515625,336"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-F" id="L-B-F-0" d="M85.16629464285714,118L89.73753720238095,122.16666666666667C94.30877976190476,126.33333333333333,103.45126488095237,134.66666666666666,108.02250744047619,143C112.59375,151.33333333333334,112.59375,159.66666666666666,112.59375,163.83333333333334L112.59375,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-F LE-D" id="L-F-D-0" d="M112.59375,202L112.59375,206.16666666666666C112.59375,210.33333333333334,112.59375,218.66666666666666,108.02250744047619,227C103.45126488095237,235.33333333333334,94.30877976190476,243.66666666666666,89.73753720238095,247.83333333333334L85.16629464285714,252"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(66.515625, 17)" id="flowchart-A-16" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(66.515625, 101)" id="flowchart-B-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(20.4375, 185)" id="flowchart-C-18" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(66.515625, 269)" id="flowchart-D-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(66.515625, 353)" id="flowchart-E-20" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(112.59375, 185)" id="flowchart-F-22" class="node default default flowchart-label"><rect height="34" width="43.4375" y="-17" x="-21.71875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-14.21875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="28.4375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_main_OK-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) OK
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_main" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_main_NG-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_main_NG-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 164.578125 470" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-9" height="480">
<style>#mermaid-figure-9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-9 .error-icon{fill:#552222;}#mermaid-figure-9 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-9 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-9 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-9 .marker.cross{stroke:#333333;}#mermaid-figure-9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-9 .cluster-label text{fill:#333;}#mermaid-figure-9 .cluster-label span,#mermaid-figure-9 p{color:#333;}#mermaid-figure-9 .label text,#mermaid-figure-9 span,#mermaid-figure-9 p{fill:#333;color:#333;}#mermaid-figure-9 .node rect,#mermaid-figure-9 .node circle,#mermaid-figure-9 .node ellipse,#mermaid-figure-9 .node polygon,#mermaid-figure-9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-9 .flowchart-label text{text-anchor:middle;}#mermaid-figure-9 .node .label{text-align:center;}#mermaid-figure-9 .node.clickable{cursor:pointer;}#mermaid-figure-9 .arrowheadPath{fill:#333333;}#mermaid-figure-9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-9 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-9 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-9 .cluster text{fill:#333;}#mermaid-figure-9 .cluster span,#mermaid-figure-9 p{color:#333;}#mermaid-figure-9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M70.08203125,34L70.08203125,38.166666666666664C70.08203125,42.333333333333336,70.08203125,50.666666666666664,70.08203125,59C70.08203125,67.33333333333333,70.08203125,75.66666666666667,70.08203125,79.83333333333333L70.08203125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M49.987816220238095,118L45.06276351686508,122.16666666666667C40.13771081349206,126.33333333333333,30.287605406746035,134.66666666666666,25.362552703373016,145.83333333333334C20.4375,157,20.4375,171,20.4375,185C20.4375,199,20.4375,213,20.4375,224.16666666666666C20.4375,235.33333333333334,20.4375,243.66666666666666,20.4375,247.83333333333334L20.4375,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M20.4375,286L20.4375,290.1666666666667C20.4375,294.3333333333333,20.4375,302.6666666666667,25.362552703373016,311C30.287605406746035,319.3333333333333,40.13771081349206,327.6666666666667,45.06276351686508,331.8333333333333L49.987816220238095,336"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M70.08203125,370L70.08203125,374.1666666666667C70.08203125,378.3333333333333,70.08203125,386.6666666666667,70.08203125,395C70.08203125,403.3333333333333,70.08203125,411.6666666666667,70.08203125,415.8333333333333L70.08203125,420"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-F" id="L-B-F-0" d="M90.1762462797619,118L95.10129898313492,122.16666666666667C100.02635168650794,126.33333333333333,109.87645709325398,134.66666666666666,114.80150979662699,143C119.7265625,151.33333333333334,119.7265625,159.66666666666666,119.7265625,163.83333333333334L119.7265625,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-F LE-G" id="L-F-G-0" d="M119.7265625,202L119.7265625,206.16666666666666C119.7265625,210.33333333333334,119.7265625,218.66666666666666,119.7265625,227C119.7265625,235.33333333333334,119.7265625,243.66666666666666,119.7265625,247.83333333333334L119.7265625,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-G LE-D" id="L-G-D-0" d="M119.7265625,286L119.7265625,290.1666666666667C119.7265625,294.3333333333333,119.7265625,302.6666666666667,114.80150979662699,311C109.87645709325398,319.3333333333333,100.02635168650794,327.6666666666667,95.10129898313492,331.8333333333333L90.1762462797619,336"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(70.08203125, 17)" id="flowchart-A-18" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(70.08203125, 101)" id="flowchart-B-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(20.4375, 269)" id="flowchart-C-20" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(70.08203125, 353)" id="flowchart-D-21" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(70.08203125, 437)" id="flowchart-E-22" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(119.7265625, 185)" id="flowchart-F-24" class="node default default flowchart-label"><rect height="34" width="43.4375" y="-17" x="-21.71875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-14.21875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="28.4375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’</span>
</div>
</foreignobject></g></g><g transform="translate(119.7265625, 269)" id="flowchart-G-25" class="node default default flowchart-label"><rect height="34" width="57.703125" y="-17" x="-28.8515625" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-21.3515625, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="42.703125">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’-2</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_main_NG-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) NG(分岐したノードが続いているため)
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_main" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_main_NG-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_main_NG-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 178.84375 470" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-8" height="480">
<style>#mermaid-figure-8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-8 .error-icon{fill:#552222;}#mermaid-figure-8 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-8 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-8 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-8 .marker.cross{stroke:#333333;}#mermaid-figure-8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-8 .cluster-label text{fill:#333;}#mermaid-figure-8 .cluster-label span,#mermaid-figure-8 p{color:#333;}#mermaid-figure-8 .label text,#mermaid-figure-8 span,#mermaid-figure-8 p{fill:#333;color:#333;}#mermaid-figure-8 .node rect,#mermaid-figure-8 .node circle,#mermaid-figure-8 .node ellipse,#mermaid-figure-8 .node polygon,#mermaid-figure-8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-8 .flowchart-label text{text-anchor:middle;}#mermaid-figure-8 .node .label{text-align:center;}#mermaid-figure-8 .node.clickable{cursor:pointer;}#mermaid-figure-8 .arrowheadPath{fill:#333333;}#mermaid-figure-8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-8 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-8 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-8 .cluster text{fill:#333;}#mermaid-figure-8 .cluster span,#mermaid-figure-8 p{color:#333;}#mermaid-figure-8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M80.78125,34L80.78125,38.166666666666664C80.78125,42.333333333333336,80.78125,50.666666666666664,80.78125,59C80.78125,67.33333333333333,80.78125,75.66666666666667,80.78125,79.83333333333333L80.78125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M60.34375,117.13155190133608L54.881510416666664,121.44295991778006C49.419270833333336,125.75436793422405,38.494791666666664,134.37718396711202,33.032552083333336,142.85525865022268C27.5703125,151.33333333333334,27.5703125,159.66666666666666,27.5703125,163.83333333333334L27.5703125,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-C2" id="L-C-C2-0" d="M27.5703125,202L27.5703125,206.16666666666666C27.5703125,210.33333333333334,27.5703125,218.66666666666666,27.5703125,227C27.5703125,235.33333333333334,27.5703125,243.66666666666666,27.5703125,247.83333333333334L27.5703125,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C2 LE-D" id="L-C2-D-0" d="M27.5703125,286L27.5703125,290.1666666666667C27.5703125,294.3333333333333,27.5703125,302.6666666666667,33.032552083333336,311.14474134977735C38.494791666666664,319.622816032888,49.419270833333336,328.24563206577596,54.881510416666664,332.55704008221994L60.34375,336.8684480986639"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M80.78125,370L80.78125,374.1666666666667C80.78125,378.3333333333333,80.78125,386.6666666666667,80.78125,395C80.78125,403.3333333333333,80.78125,411.6666666666667,80.78125,415.8333333333333L80.78125,420"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-F" id="L-B-F-0" d="M101.21875,117.13155190133608L106.68098958333333,121.44295991778006C112.14322916666667,125.75436793422405,123.06770833333333,134.37718396711202,128.52994791666666,142.85525865022268C133.9921875,151.33333333333334,133.9921875,159.66666666666666,133.9921875,163.83333333333334L133.9921875,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-F LE-G" id="L-F-G-0" d="M133.9921875,202L133.9921875,206.16666666666666C133.9921875,210.33333333333334,133.9921875,218.66666666666666,133.9921875,227C133.9921875,235.33333333333334,133.9921875,243.66666666666666,133.9921875,247.83333333333334L133.9921875,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-G LE-D" id="L-G-D-0" d="M133.9921875,286L133.9921875,290.1666666666667C133.9921875,294.3333333333333,133.9921875,302.6666666666667,128.52994791666666,311.14474134977735C123.06770833333333,319.622816032888,112.14322916666667,328.24563206577596,106.68098958333333,332.55704008221994L101.21875,336.8684480986639"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(80.78125, 17)" id="flowchart-A-20" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(80.78125, 101)" id="flowchart-B-21" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(27.5703125, 185)" id="flowchart-C-22" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(27.5703125, 269)" id="flowchart-C2-23" class="node default default flowchart-label"><rect height="34" width="55.140625" y="-17" x="-27.5703125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-20.0703125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="40.140625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2-2</span>
</div>
</foreignobject></g></g><g transform="translate(80.78125, 353)" id="flowchart-D-24" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(80.78125, 437)" id="flowchart-E-25" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(133.9921875, 185)" id="flowchart-F-27" class="node default default flowchart-label"><rect height="34" width="43.4375" y="-17" x="-21.71875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-14.21875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="28.4375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’</span>
</div>
</foreignobject></g></g><g transform="translate(133.9921875, 269)" id="flowchart-G-28" class="node default default flowchart-label"><rect height="34" width="57.703125" y="-17" x="-28.8515625" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-21.3515625, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="42.703125">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’-2</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_main_NG-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(d) NG(分岐したノードが続いているため)
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_main" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_main_NG-3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_main_NG-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 150.4921875 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-7" height="480">
<style>#mermaid-figure-7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-7 .error-icon{fill:#552222;}#mermaid-figure-7 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-7 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-7 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-7 .marker.cross{stroke:#333333;}#mermaid-figure-7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-7 .cluster-label text{fill:#333;}#mermaid-figure-7 .cluster-label span,#mermaid-figure-7 p{color:#333;}#mermaid-figure-7 .label text,#mermaid-figure-7 span,#mermaid-figure-7 p{fill:#333;color:#333;}#mermaid-figure-7 .node rect,#mermaid-figure-7 .node circle,#mermaid-figure-7 .node ellipse,#mermaid-figure-7 .node polygon,#mermaid-figure-7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-7 .flowchart-label text{text-anchor:middle;}#mermaid-figure-7 .node .label{text-align:center;}#mermaid-figure-7 .node.clickable{cursor:pointer;}#mermaid-figure-7 .arrowheadPath{fill:#333333;}#mermaid-figure-7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-7 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-7 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-7 .cluster text{fill:#333;}#mermaid-figure-7 .cluster span,#mermaid-figure-7 p{color:#333;}#mermaid-figure-7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M66.6953125,34L66.6953125,38.166666666666664C66.6953125,42.333333333333336,66.6953125,50.666666666666664,66.6953125,59C66.6953125,67.33333333333333,66.6953125,75.66666666666667,66.6953125,79.83333333333333L66.6953125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M48.04464285714286,118L43.47340029761906,122.16666666666667C38.90215773809524,126.33333333333333,29.75967261904762,134.66666666666666,25.18843005952381,143C20.6171875,151.33333333333334,20.6171875,159.66666666666666,20.6171875,163.83333333333334L20.6171875,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M20.6171875,202L20.6171875,206.16666666666666C20.6171875,210.33333333333334,20.6171875,218.66666666666666,20.6171875,227C20.6171875,235.33333333333334,20.6171875,243.66666666666666,20.6171875,247.83333333333334L20.6171875,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M20.6171875,286L20.6171875,290.1666666666667C20.6171875,294.3333333333333,20.6171875,302.6666666666667,20.6171875,311C20.6171875,319.3333333333333,20.6171875,327.6666666666667,20.6171875,331.8333333333333L20.6171875,336"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-F" id="L-B-F-0" d="M85.34598214285714,118L89.91722470238095,122.16666666666667C94.48846726190476,126.33333333333333,103.63095238095237,134.66666666666666,108.20219494047619,143C112.7734375,151.33333333333334,112.7734375,159.66666666666666,112.7734375,163.83333333333334L112.7734375,168"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(66.6953125, 17)" id="flowchart-A-14" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(66.6953125, 101)" id="flowchart-B-15" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(20.6171875, 185)" id="flowchart-C-16" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(20.6171875, 269)" id="flowchart-D-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(20.6171875, 353)" id="flowchart-E-18" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(112.7734375, 185)" id="flowchart-F-20" class="node default default flowchart-label"><rect height="34" width="43.4375" y="-17" x="-21.71875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-14.21875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="28.4375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2’</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_main_NG-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(e) NG(分岐したノードがメインストーリーに合流していないため)
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-QA_Structure_main-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;6: メインストーリーの構造
</figcaption>
</figure>
</div>
<div id="fig-QA_Structure_sub" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-QA_Structure_sub-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_sub" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_sub_OK-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_sub_OK-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 160.1953125 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-6" height="480">
<style>#mermaid-figure-6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-6 .error-icon{fill:#552222;}#mermaid-figure-6 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-6 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-6 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-6 .marker.cross{stroke:#333333;}#mermaid-figure-6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-6 .cluster-label text{fill:#333;}#mermaid-figure-6 .cluster-label span,#mermaid-figure-6 p{color:#333;}#mermaid-figure-6 .label text,#mermaid-figure-6 span,#mermaid-figure-6 p{fill:#333;color:#333;}#mermaid-figure-6 .node rect,#mermaid-figure-6 .node circle,#mermaid-figure-6 .node ellipse,#mermaid-figure-6 .node polygon,#mermaid-figure-6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-6 .flowchart-label text{text-anchor:middle;}#mermaid-figure-6 .node .label{text-align:center;}#mermaid-figure-6 .node.clickable{cursor:pointer;}#mermaid-figure-6 .arrowheadPath{fill:#333333;}#mermaid-figure-6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-6 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-6 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-6 .cluster text{fill:#333;}#mermaid-figure-6 .cluster span,#mermaid-figure-6 p{color:#333;}#mermaid-figure-6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,29.710813492063494,143C34.41381448412698,151.33333333333334,43.81981646825397,159.66666666666666,48.52281746031746,163.83333333333334L53.22581845238095,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M72.4140625,202L72.4140625,206.16666666666666C72.4140625,210.33333333333334,72.4140625,218.66666666666666,72.4140625,227C72.4140625,235.33333333333334,72.4140625,243.66666666666666,72.4140625,247.83333333333334L72.4140625,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M72.4140625,286L72.4140625,290.1666666666667C72.4140625,294.3333333333333,72.4140625,302.6666666666667,72.4140625,311C72.4140625,319.3333333333333,72.4140625,327.6666666666667,72.4140625,331.8333333333333L72.4140625,336"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Z LE-C" id="L-Z-C-0" d="M119.8203125,118L119.8203125,122.16666666666667C119.8203125,126.33333333333333,119.8203125,134.66666666666666,115.1173115079365,143C110.41431051587301,151.33333333333334,101.00830853174602,159.66666666666666,96.30530753968254,163.83333333333334L91.60230654761905,168"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-14" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-15" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(72.4140625, 185)" id="flowchart-C-16" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(72.4140625, 269)" id="flowchart-D-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(72.4140625, 353)" id="flowchart-E-18" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(119.8203125, 101)" id="flowchart-Z-19" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub1</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_sub_OK-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) OK
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_sub" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_sub_OK-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_sub_OK-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 257.29296875 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-5" height="480">
<style>#mermaid-figure-5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-5 .error-icon{fill:#552222;}#mermaid-figure-5 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-5 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-5 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-5 .marker.cross{stroke:#333333;}#mermaid-figure-5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-5 .cluster-label text{fill:#333;}#mermaid-figure-5 .cluster-label span,#mermaid-figure-5 p{color:#333;}#mermaid-figure-5 .label text,#mermaid-figure-5 span,#mermaid-figure-5 p{fill:#333;color:#333;}#mermaid-figure-5 .node rect,#mermaid-figure-5 .node circle,#mermaid-figure-5 .node ellipse,#mermaid-figure-5 .node polygon,#mermaid-figure-5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-5 .flowchart-label text{text-anchor:middle;}#mermaid-figure-5 .node .label{text-align:center;}#mermaid-figure-5 .node.clickable{cursor:pointer;}#mermaid-figure-5 .arrowheadPath{fill:#333333;}#mermaid-figure-5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-5 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-5 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-5 .cluster text{fill:#333;}#mermaid-figure-5 .cluster span,#mermaid-figure-5 p{color:#333;}#mermaid-figure-5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,29.937515500992063,59C34.86721850198413,67.33333333333333,44.72662450396825,75.66666666666667,49.65632750496032,79.83333333333333L54.58603050595238,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M74.69921875,118L74.69921875,122.16666666666667C74.69921875,126.33333333333333,74.69921875,134.66666666666666,79.4022197420635,143C84.10522073412699,151.33333333333334,93.51122271825398,159.66666666666666,98.21422371031746,163.83333333333334L102.91722470238095,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M122.10546875,202L122.10546875,206.16666666666666C122.10546875,210.33333333333334,122.10546875,218.66666666666666,122.10546875,227C122.10546875,235.33333333333334,122.10546875,243.66666666666666,122.10546875,247.83333333333334L122.10546875,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M122.10546875,286L122.10546875,290.1666666666667C122.10546875,294.3333333333333,122.10546875,302.6666666666667,126.8084697420635,311C131.511470734127,319.3333333333333,140.91747271825398,327.6666666666667,145.62047371031747,331.8333333333333L150.32347470238096,336"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Z LE-B" id="L-Z-B-0" d="M124.390625,34L124.390625,38.166666666666664C124.390625,42.333333333333336,124.390625,50.666666666666664,119.46092199900794,59C114.53121899801586,67.33333333333333,104.67181299603175,75.66666666666667,99.74210999503968,79.83333333333333L94.81240699404762,84"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Y LE-C" id="L-Y-C-0" d="M169.51171875,118L169.51171875,122.16666666666667C169.51171875,126.33333333333333,169.51171875,134.66666666666666,164.8087177579365,143C160.105716765873,151.33333333333334,150.69971478174602,159.66666666666666,145.99671378968253,163.83333333333334L141.29371279761904,168"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-X LE-E" id="L-X-E-0" d="M216.91796875,286L216.91796875,290.1666666666667C216.91796875,294.3333333333333,216.91796875,302.6666666666667,212.2149677579365,311C207.511966765873,319.3333333333333,198.10596478174602,327.6666666666667,193.40296378968253,331.8333333333333L188.69996279761904,336"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-22" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 101)" id="flowchart-B-23" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(122.10546875, 185)" id="flowchart-C-24" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(122.10546875, 269)" id="flowchart-D-25" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(169.51171875, 353)" id="flowchart-E-26" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(124.390625, 17)" id="flowchart-Z-27" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub1</span>
</div>
</foreignobject></g></g><g transform="translate(169.51171875, 101)" id="flowchart-Y-29" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub2</span>
</div>
</foreignobject></g></g><g transform="translate(216.91796875, 269)" id="flowchart-X-31" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub3</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_sub_OK-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) OK
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_sub" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-QA_Structure_sub_OK-3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_sub_OK-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 258.9453125 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-4" height="480">
<style>#mermaid-figure-4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-4 .error-icon{fill:#552222;}#mermaid-figure-4 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-4 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-4 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-4 .marker.cross{stroke:#333333;}#mermaid-figure-4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-4 .cluster-label text{fill:#333;}#mermaid-figure-4 .cluster-label span,#mermaid-figure-4 p{color:#333;}#mermaid-figure-4 .label text,#mermaid-figure-4 span,#mermaid-figure-4 p{fill:#333;color:#333;}#mermaid-figure-4 .node rect,#mermaid-figure-4 .node circle,#mermaid-figure-4 .node ellipse,#mermaid-figure-4 .node polygon,#mermaid-figure-4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-4 .flowchart-label text{text-anchor:middle;}#mermaid-figure-4 .node .label{text-align:center;}#mermaid-figure-4 .node.clickable{cursor:pointer;}#mermaid-figure-4 .arrowheadPath{fill:#333333;}#mermaid-figure-4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-4 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-4 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-4 .cluster text{fill:#333;}#mermaid-figure-4 .cluster span,#mermaid-figure-4 p{color:#333;}#mermaid-figure-4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,37.403645833333336,144.32443419028786C49.799479166666664,153.98220171390903,74.59114583333333,164.96440342781807,86.98697916666667,170.4555042847726L99.3828125,175.9466051417271"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M119.8203125,202L119.8203125,206.16666666666666C119.8203125,210.33333333333334,119.8203125,218.66666666666666,119.8203125,227C119.8203125,235.33333333333334,119.8203125,243.66666666666666,119.8203125,247.83333333333334L119.8203125,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M119.8203125,286L119.8203125,290.1666666666667C119.8203125,294.3333333333333,119.8203125,302.6666666666667,119.8203125,311C119.8203125,319.3333333333333,119.8203125,327.6666666666667,119.8203125,331.8333333333333L119.8203125,336"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Y LE-C" id="L-Y-C-0" d="M119.8203125,118L119.8203125,122.16666666666667C119.8203125,126.33333333333333,119.8203125,134.66666666666666,119.8203125,143C119.8203125,151.33333333333334,119.8203125,159.66666666666666,119.8203125,163.83333333333334L119.8203125,168"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Z LE-C" id="L-Z-C-0" d="M218.5703125,118L218.5703125,122.16666666666667C218.5703125,126.33333333333333,218.5703125,134.66666666666666,205.51822916666666,144.38459915611813C192.46614583333334,154.1025316455696,166.36197916666666,165.20506329113923,153.30989583333334,170.75632911392404L140.2578125,176.30759493670885"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-18" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(119.8203125, 185)" id="flowchart-C-20" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(119.8203125, 269)" id="flowchart-D-21" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(119.8203125, 353)" id="flowchart-E-22" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(119.8203125, 101)" id="flowchart-Y-23" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub2</span>
</div>
</foreignobject></g></g><g transform="translate(218.5703125, 101)" id="flowchart-Z-25" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub1</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_sub_OK-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) OK
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_sub" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-QA_Structure_sub_NG-1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_sub_NG-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 164.765625 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-3" height="480">
<style>#mermaid-figure-3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-3 .error-icon{fill:#552222;}#mermaid-figure-3 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-3 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-3 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-3 .marker.cross{stroke:#333333;}#mermaid-figure-3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-3 .cluster-label text{fill:#333;}#mermaid-figure-3 .cluster-label span,#mermaid-figure-3 p{color:#333;}#mermaid-figure-3 .label text,#mermaid-figure-3 span,#mermaid-figure-3 p{fill:#333;color:#333;}#mermaid-figure-3 .node rect,#mermaid-figure-3 .node circle,#mermaid-figure-3 .node ellipse,#mermaid-figure-3 .node polygon,#mermaid-figure-3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-3 .flowchart-label text{text-anchor:middle;}#mermaid-figure-3 .node .label{text-align:center;}#mermaid-figure-3 .node.clickable{cursor:pointer;}#mermaid-figure-3 .arrowheadPath{fill:#333333;}#mermaid-figure-3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-3 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-3 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-3 .cluster text{fill:#333;}#mermaid-figure-3 .cluster span,#mermaid-figure-3 p{color:#333;}#mermaid-figure-3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,29.937515500992063,143C34.86721850198413,151.33333333333334,44.72662450396825,159.66666666666666,49.65632750496032,163.83333333333334L54.58603050595238,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M74.69921875,202L74.69921875,206.16666666666666C74.69921875,210.33333333333334,74.69921875,218.66666666666666,74.69921875,227C74.69921875,235.33333333333334,74.69921875,243.66666666666666,74.69921875,247.83333333333334L74.69921875,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M74.69921875,286L74.69921875,290.1666666666667C74.69921875,294.3333333333333,74.69921875,302.6666666666667,74.69921875,311C74.69921875,319.3333333333333,74.69921875,327.6666666666667,74.69921875,331.8333333333333L74.69921875,336"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Y LE-Z" id="L-Y-Z-0" d="M124.390625,34L124.390625,38.166666666666664C124.390625,42.333333333333336,124.390625,50.666666666666664,124.390625,59C124.390625,67.33333333333333,124.390625,75.66666666666667,124.390625,79.83333333333333L124.390625,84"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Z LE-C" id="L-Z-C-0" d="M124.390625,118L124.390625,122.16666666666667C124.390625,126.33333333333333,124.390625,134.66666666666666,119.46092199900794,143C114.53121899801586,151.33333333333334,104.67181299603175,159.66666666666666,99.74210999503968,163.83333333333334L94.81240699404762,168"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-16" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 185)" id="flowchart-C-18" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 269)" id="flowchart-D-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 353)" id="flowchart-E-20" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(124.390625, 17)" id="flowchart-Y-21" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub2</span>
</div>
</foreignobject></g></g><g transform="translate(124.390625, 101)" id="flowchart-Z-22" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub1</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_sub_NG-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(d) NG(サブストーリーに他のノードが付いているため)
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-QA_Structure_sub" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-QA_Structure_sub_NG-2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-QA_Structure_sub_NG-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<svg aria-roledescription="flowchart-v2" viewbox="-8 -8 164.765625 386" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="240" id="mermaid-figure-2" height="480">
<style>#mermaid-figure-2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-figure-2 .error-icon{fill:#552222;}#mermaid-figure-2 .error-text{fill:#552222;stroke:#552222;}#mermaid-figure-2 .edge-thickness-normal{stroke-width:2px;}#mermaid-figure-2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-figure-2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-figure-2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-figure-2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-figure-2 .marker{fill:#333333;stroke:#333333;}#mermaid-figure-2 .marker.cross{stroke:#333333;}#mermaid-figure-2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-figure-2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-figure-2 .cluster-label text{fill:#333;}#mermaid-figure-2 .cluster-label span,#mermaid-figure-2 p{color:#333;}#mermaid-figure-2 .label text,#mermaid-figure-2 span,#mermaid-figure-2 p{fill:#333;color:#333;}#mermaid-figure-2 .node rect,#mermaid-figure-2 .node circle,#mermaid-figure-2 .node ellipse,#mermaid-figure-2 .node polygon,#mermaid-figure-2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-figure-2 .flowchart-label text{text-anchor:middle;}#mermaid-figure-2 .node .label{text-align:center;}#mermaid-figure-2 .node.clickable{cursor:pointer;}#mermaid-figure-2 .arrowheadPath{fill:#333333;}#mermaid-figure-2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-figure-2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-figure-2 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-figure-2 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-figure-2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-figure-2 .cluster text{fill:#333;}#mermaid-figure-2 .cluster span,#mermaid-figure-2 p{color:#333;}#mermaid-figure-2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-figure-2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-figure-2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style>
<g><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="10" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointEnd"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 0 L 10 5 L 0 10 z"></path></marker><marker orient="auto" markerheight="12" markerwidth="12" markerunits="userSpaceOnUse" refy="5" refx="0" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-pointStart"><path style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 0 5 L 10 10 L 10 0 z"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="11" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleEnd"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5" refx="-1" viewbox="0 0 10 10" class="marker flowchart" id="flowchart-circleStart"><circle style="stroke-width: 1; stroke-dasharray: 1, 0;" class="arrowMarkerPath" r="5" cy="5" cx="5"></circle></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="12" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossEnd"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><marker orient="auto" markerheight="11" markerwidth="11" markerunits="userSpaceOnUse" refy="5.2" refx="-1" viewbox="0 0 11 11" class="marker cross flowchart" id="flowchart-crossStart"><path style="stroke-width: 2; stroke-dasharray: 1, 0;" class="arrowMarkerPath" d="M 1,1 l 9,9 M 10,1 l -9,9"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-A LE-B" id="L-A-B-0" d="M25.0078125,34L25.0078125,38.166666666666664C25.0078125,42.333333333333336,25.0078125,50.666666666666664,25.0078125,59C25.0078125,67.33333333333333,25.0078125,75.66666666666667,25.0078125,79.83333333333333L25.0078125,84"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-B LE-C" id="L-B-C-0" d="M25.0078125,118L25.0078125,122.16666666666667C25.0078125,126.33333333333333,25.0078125,134.66666666666666,29.937515500992063,143C34.86721850198413,151.33333333333334,44.72662450396825,159.66666666666666,49.65632750496032,163.83333333333334L54.58603050595238,168"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-C LE-D" id="L-C-D-0" d="M74.69921875,202L74.69921875,206.16666666666666C74.69921875,210.33333333333334,74.69921875,218.66666666666666,74.69921875,227C74.69921875,235.33333333333334,74.69921875,243.66666666666666,74.69921875,247.83333333333334L74.69921875,252"></path><path marker-end="url(#flowchart-pointEnd)" style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-D LE-E" id="L-D-E-0" d="M74.69921875,286L74.69921875,290.1666666666667C74.69921875,294.3333333333333,74.69921875,302.6666666666667,74.69921875,311C74.69921875,319.3333333333333,74.69921875,327.6666666666667,74.69921875,331.8333333333333L74.69921875,336"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Y LE-Z" id="L-Y-Z-0" d="M124.390625,34L124.390625,38.166666666666664C124.390625,42.333333333333336,124.390625,50.666666666666664,124.390625,59C124.390625,67.33333333333333,124.390625,75.66666666666667,124.390625,79.83333333333333L124.390625,84"></path><path style="fill:none;" class="edge-thickness-normal edge-pattern-solid flowchart-link LS-Z LE-C" id="L-Z-C-0" d="M124.390625,118L124.390625,122.16666666666667C124.390625,126.33333333333333,124.390625,134.66666666666666,119.46092199900794,143C114.53121899801586,151.33333333333334,104.67181299603175,159.66666666666666,99.74210999503968,163.83333333333334L94.81240699404762,168"></path></g><g class="edgeLabels"><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g><g class="edgeLabel"><g transform="translate(0, 0)" class="label"><foreignobject height="0" width="0">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="edgeLabel"></span>
</div>
</foreignobject></g></g></g><g class="nodes"><g transform="translate(25.0078125, 17)" id="flowchart-A-16" class="node default default flowchart-label"><rect height="34" width="50.015625" y="-17" x="-25.0078125" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-17.5078125, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="35.015625">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Start</span>
</div>
</foreignobject></g></g><g transform="translate(25.0078125, 101)" id="flowchart-B-17" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep1</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 185)" id="flowchart-C-18" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep2</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 269)" id="flowchart-D-19" class="node default default flowchart-label"><rect height="34" width="40.875" y="-17" x="-20.4375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-12.9375, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="25.875">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Ep3</span>
</div>
</foreignobject></g></g><g transform="translate(74.69921875, 353)" id="flowchart-E-20" class="node default default flowchart-label"><rect height="34" width="41.234375" y="-17" x="-20.6171875" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-13.1171875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="26.234375">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">End</span>
</div>
</foreignobject></g></g><g transform="translate(124.390625, 17)" id="flowchart-Y-21" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub2</span>
</div>
</foreignobject></g></g><g transform="translate(124.390625, 101)" id="flowchart-Z-22" class="node default default flowchart-label"><rect height="34" width="48.75" y="-17" x="-24.375" ry="0" rx="0" style="" class="basic label-container"></rect><g transform="translate(-16.875, -9.5)" style="" class="label"><rect></rect><foreignobject height="19" width="33.75">
<div style="display: inline-block; white-space: nowrap;" data-xmlns="http://www.w3.org/1999/xhtml">
<span class="nodeLabel">Sub1</span>
</div>
</foreignobject></g></g></g></g></g>
</svg>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-QA_Structure_sub_NG-2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(e) NG(サブストーリーに他のノードが付いているため)
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-QA_Structure_sub-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;7: サブストーリーの構造
</figcaption>
</figure>
</div>
</section>
<section id="必要なもの動作環境" class="level3">
<h3 class="anchored" data-anchor-id="必要なもの動作環境">必要なもの(動作環境)</h3>
<ul>
<li>Pythonが編集できるテキストエディタ(VS Codeを推奨)</li>
<li>Python 3.12.3 以降(Python 3.12.3以外での動作は確認しておりません)</li>
<li>JSON Canvasファイル</li>
</ul>
</section>
</section>
<section id="結果" class="level2">
<h2 class="anchored" data-anchor-id="結果">結果</h2>
<p>このスクリプト(スクリプト&nbsp;1)を用いることで、図&nbsp;8のような複雑な無限キャンバスも図&nbsp;9のように1つのMarkdownファイルに変換できます。</p>
<div id="fig-Canvas2MD_DEMO_Canvas" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Canvas2MD_DEMO_Canvas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Canvas2MD_SampleCanvas.png" class="lightbox" data-gallery="quarto-lightbox-gallery-11" title="図&nbsp;8: サンプルJSON Canvas(デモのために敢えてとっ散らかったものにした)"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_SampleCanvas.png" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Canvas2MD_DEMO_Canvas-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;8: サンプルJSON Canvas(デモのために敢えてとっ散らかったものにした)
</figcaption>
</figure>
</div>
<div id="fig-Canvas2MD_DEMO_MD" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Canvas2MD_DEMO_MD-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Canvas2MD_Sample.png" class="lightbox" data-gallery="quarto-lightbox-gallery-12" title="図&nbsp;9: スクリプト&nbsp;1の実行結果(VS CodeのMarkdown Preview Enhancedでプレビュー)"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_Sample.png" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Canvas2MD_DEMO_MD-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;9: スクリプト&nbsp;1の実行結果(VS CodeのMarkdown Preview Enhancedでプレビュー)
</figcaption>
</figure>
</div>
<p>なお、<a href="https://obsidian.md/changelog/2024-05-22-desktop-v1.6.1/">Obsidianはversion 1.6 からマウスホバーによる脚注のポップアップ表示に対応しました</a>。そのため、変換されたMarkdownファイルをObsidianで開くと快適に閲覧できます(図&nbsp;10)。</p>
<p>(2024年6月5日現在、Early access権を持つユーザーのみに解放されているバージョンですが、数日から数週間以内には、全てのユーザーが使えるようになります)</p>
<div id="fig-Popup" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Popup-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Canvas2MD_popup_image.png" class="lightbox" data-gallery="quarto-lightbox-gallery-13" title="Obsidian ver 1.6 以降は内部リンクのように脚注でもポップアップ表示が可能になる予定"><img src="https://pottal-portal.com/PtPr3/post_images/Canvas2MD_popup_image.png" class="img-fluid figure-img"></a></p>
<figcaption>Obsidian ver 1.6 以降は内部リンクのように脚注でもポップアップ表示が可能になる予定</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Popup-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;10: Obsidianにおけるマウスホバーによるポップアップ表示の例
</figcaption>
</figure>
</div>
</section>
<section id="課題と展望" class="level2">
<h2 class="anchored" data-anchor-id="課題と展望">課題と展望</h2>
<p>現在のスクリプトにはJSON Canvasが特定の構造でないと正しくMarkdownに変換されないという課題があり、JSON Canvasの解析方法もベストであるとは言えません。 将来的にはこれを改善したいと思ってはいます。思っているだけですが… どなたかサポートしてくれると嬉しいです。</p>
<section id="現在の課題" class="level3">
<h3 class="anchored" data-anchor-id="現在の課題">現在の課題</h3>
<ul class="task-list">
<li><label><input type="checkbox">サブストーリーを数珠繫ぎにできない</label>
<ul>
<li>サブストーリーを脚注という扱いにしている以上、脚注に脚注をつける形になる(Quartoなど一部のアプリでは正しく表示できない)</li>
</ul></li>
<li><label><input type="checkbox">分岐(セレクトストーリー)ノードに脚注(サブストーリー)以外のノードが紐づけられず、すぐにメインストーリーに戻る必要がある(図&nbsp;6 (d))</label></li>
<li><label><input type="checkbox">分岐(セレクトストーリー)ノードがメインストーリーに合流する必要がある(図&nbsp;6 (e))</label></li>
<li><label><input type="checkbox">メインストーリー, サブストーリーの識別ロジックが多分ベストではない</label></li>
<li><label><input type="checkbox">ノード間をテキストエッジで繋いだ際に、そのテキストがMarkdownに反映されない</label></li>
</ul>
</section>
<section id="展望" class="level3">
<h3 class="anchored" data-anchor-id="展望">展望</h3>
<p>ツールは作っただけでは意味はなく、使わなければなりません。自分のために作ったツールですので、自分が一番活用してやりたいものです。今のところ、以下のように活用したいと思っております。</p>
<ul>
<li>同人ゲームのプロットや脚本作り</li>
<li>知的生産の技術でいうござね法</li>
</ul>
<section id="同人ゲームへの活用" class="level4">
<h4 class="anchored" data-anchor-id="同人ゲームへの活用">同人ゲームへの活用</h4>
<p>このツールを作る動機となったのが、ホワイトボード(無限キャンバス)上のアイデアをテキストに変換し、ゲーム作りを楽にしたいというものでした。</p>
<p>このプロットを直接使ってゲームのスクリプトに変換するということはしませんが、全体のプロットや章や節ごとのプロットを脚本に落とし込むのに使えればと思っています。</p>
<p>筆者の作りたいノベルゲームにおいては選択肢などによる分岐がとても重要になるので、スクリプトの改良を進めて本格的な分岐に対応できるようにしたいです。</p>
</section>
<section id="知的生産の技術-こざね法への活用" class="level4">
<h4 class="anchored" data-anchor-id="知的生産の技術-こざね法への活用">知的生産の技術 こざね法への活用</h4>
<p>『知的生産の技術』<span class="citation" data-cites="Umesao_1969">(梅棹 1969)</span>というとても古い本があります。筆者は高校3年生の頃にこの本に出会い、以来ずっと読んだ時の感銘が熾火のように胸に残っており、同時にそこから学んだ知的生産の技術を活用・実行できていない悔しさや劣等感といったものが火傷のように心を苛んでいます。 1969年のものなので、とっくに時代遅れになってもおかしくない本なのですが、なんと2023年になっても色褪せておらず<a href="https://www.lib.u-tokyo.ac.jp/sites/default/files/2023-05/310-academic_skills_2023.pdf">「アカデミックスキルズ図書リスト」（東京大学駒場図書館所蔵2023）</a>の、しかもトップにこの本がリストアップされているようです<span class="citation" data-cites="Yamamoto_2023">(山本 2023)</span>。ちなみに、それを知ったのはObsidianで知的生産の技術を活用したいと思って文献を読み漁っていたからです。</p>
<p>『知的生産の技術』<span class="citation" data-cites="Umesao_1969">(梅棹 1969)</span>の何が今も輝いているのでしょうか。筆者は、それを「カード法」と「こざね法」にあると考えています。「カード法」は、同年代にドイツで活躍されていたニクラス・ルーマンのZettelkasten(ツェッテルカステン)メソッドに通じるものがあり、そちらの方が有名だと思います。このカード法(Zettelkasten)は、Obsidianが得意とするところであり、Obsidianを世に広めたい筆者としては声高らかに解説したいところなのですが、話の本筋から外れてしまうため、今回は「こざね法」の紹介だけにとどめておきます。</p>
<section id="こざね法とは" class="level5">
<h5 class="anchored" data-anchor-id="こざね法とは">こざね法とは</h5>
<p>『知的生産の技術』<span class="citation" data-cites="Umesao_1969">(梅棹 1969)</span>の中で梅棹が紹介していた、考えをまとめ文章を構築する方法がこざね法です。</p>
<blockquote class="blockquote">
<p>その紙きれ(B8判の小さな紙)に、いまの主題に関係のあることがらを、単語、句、またはみじかい文章で、一枚に一項目ずつ、かいてゆくのである。おもいつくままに、順序かまわず、どんどんかいてゆく。すでにたくわえられているカードも、きりぬき資料も、本からの知識も、つかえそうなものはすべて一ど、この紙きれにかいてみる。ひととおり出つくしたとおもったら、その紙きれを、机のうえ、またはタタミのうえにならべてみる。これで、その主題について、あなたの頭のなかにある素材のすべてが、さらけだされたことになる。 つぎは、この紙きれを一枚ずつみながら、それとつながりのある紙きれがほかにないか、さがす。あれば、それをいっしょにならべる。このとき、けっして紙きれを分類してはいけない。カードのしまいかたのところでも注意したことだが、知的生産の目的は分類ではない。分類という作業には、あらかじめ設定されたワクが必要である。既存のワクに素材を分類してみたところで、なんの思想もでてこない。 分類するのではなく、論理的につながりがありそうだ、とおもわれる紙きれを、まとめてゆくのである。何枚かまとまったら、論理的にすじがとおるとおもわれる順序に、その一群の紙きれをならべてみる。そして、その端をかさねて、それをホッチキスでとめる。これで、ひとつの思想が定着したのである。<span class="citation" data-cites="Umesao_1969">(梅棹 1969 括弧内引用者)</span></p>
</blockquote>
<p>上記のこざね法を、Obsidian Canvasで実践しようというのが本項の意図するところであります。短いこざね(Obsidian Canvasで言うノード)を、まずはCanvasに思いつくままに作成し、何となくまとめます。</p>
<blockquote class="blockquote">
<p>こざねの列がいくつもできたところで、さらにそれらのこざねどうしの関係をかんがえる。そして、論理的につながっているものを、しだいにあつめてゆく。場合によれば、こざねを解体して、くみかえることもある。ホッチキスでとめてあるだけだから、すぐちぎれ、またとめなおすことができる。この作業をつづけているうちに、あたらしい素材をおもいついたら、どんどんこざねを追加する。 こうして、論理的にまとまりのある一群のこざねの列ができると、それをクリップでとめて、それに見だしの紙きれをつける。あとは、こういうふうにしてできたこざねの列を、何本もならべて、見だしをみながら、文章全体としての構成をかんがえるのである。ここで、いわゆる起承転結ふうにならべることもできるし、もっと破格な配列をかんがえることもできよう。文章全体のバランスも、具体的にかんがえることができる。ここまでくれば、もう、かくべき内容がかたまっただけでなく、かくべき文章の構成も、ほぼできあがっているのである。あとは、かさねられたこざねの列を、上から順番に、一枚ずつとりあげてみながら、その内容を文章にかきおろしてゆけばよいのである。<span class="citation" data-cites="Umesao_1969">(梅棹 1969)</span></p>
</blockquote>
<p>それを、矢印で繋いでしまえば、あとは保存してスクリプト(スクリプト&nbsp;1)にかけるだけ、といった寸法です。</p>
</section>
</section>
</section>
</section>
<section id="感想" class="level2">
<h2 class="anchored" data-anchor-id="感想">感想</h2>
<ul>
<li>ふと思い立ってこのプロジェクトに取り掛かったので、もしかしたら先行例があるかもしれないなぁと終わってから思いました。
<ul>
<li>もっと賢いロジックで上手い事変換してくれるスクリプトがあって欲しいです。</li>
</ul></li>
<li>今回もChatGPT-4oの力を借りてPythonスクリプトを作成しました。</li>
<li>これで誰かの創作活動等のお役に立てれば幸いです。
<ul>
<li>ちなみに、筆者は全く捗っていません。</li>
</ul></li>
</ul>
</section>
<section id="参考文献" class="level2">
<h2 class="anchored" data-anchor-id="参考文献">参考文献</h2>
<div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" data-line-spacing="2">
<div id="ref-infinitecanvas" class="csl-entry">
Arun and Muse (2022)“<span class="nocase">Infinite Canvas Tools that work the way we think</span>”, <em><span>Infinite Canvas Tools that work the way we think</span></em>, 2022 Accessed May 29, 2024 <a href="https://infinitecanvas.tools/">https://infinitecanvas.tools/</a>
</div>
<div id="ref-ArcEasel" class="csl-entry">
Arc (2022)“<span>Easels: Capture &amp; Create</span>”, <em><span>Arc</span></em>, 2022 Accessed May 29, 2024 <a href="https://resources.arc.net/hc/en-us/articles/19231142050071-Easels-Capture-Create">https://resources.arc.net/hc/en-us/articles/19231142050071-Easels-Capture-Create</a>
</div>
<div id="ref-AppleFreeform" class="csl-entry">
Apple Japan 広報部 (2022) 「<span>Apple、フリーボードを発表：クリエイティブなブレインストーミングと共同作業のために設計されたパワフルな新しいアプリケーション</span>」、 <em><span>Apple</span></em>、2022年、閲覧日 2024年5月29日、 <a href="https://nr.apple.com/DH2c8p7EB4">https://nr.apple.com/DH2c8p7EB4</a>
</div>
<div id="ref-JSON_Canvas" class="csl-entry">
kepano (2024)“<span class="nocase">Announcing JSON Canvas: an open file format for infinite canvas data</span>”, <em><span>Obsidian Blog</span></em>, March 11, 2024 Accessed May 29, 2024 <a href="https://obsidian.md/blog/json-canvas/">https://obsidian.md/blog/json-canvas/</a>
</div>
<div id="ref-Umesao_1969" class="csl-entry">
梅棹忠夫 (1969) 『<a href="https://amzn.asia/d/ba6QTfC"><span>知的生産の技術(岩波新書)</span></a>』、 岩波書店
</div>
<div id="ref-Yamamoto_2023" class="csl-entry">
山本明正 (2023) 『<a href="https://amzn.asia/d/1ckLCyt"><span>Obsidian 次世代型のメモアプリ: Zettelkasten 知的生産の技術を超えて</span></a>』、 Akimasa Net
</div>
<div id="ref-Masui_2023" class="csl-entry">
増井敏克 (2023) 『<a href="https://amzn.asia/d/fsCt26s"><span>Obsidianで<span>“育てる”</span>最強ノート術 —— あらゆる情報をつなげて整理しよう</span></a>』、 技術評論社
</div>
<div id="ref-Pouhon_2023" class="csl-entry">
Pouhon (2023) 『<a href="https://amzn.asia/d/48Ew2YY"><span>Obsidianでつなげる情報管理術【完成版】</span></a>』、 Kindle
</div>
</div>


</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a> ]]></description>
  <category>スクリプト</category>
  <category>How2</category>
  <category>おすすめ記事</category>
  <guid>https://pottal-portal.com/PtPr3/posts/JSON_Canvas_to_Markdown_py.html</guid>
  <pubDate>Tue, 04 Jun 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/Canvas2MD.png" medium="image" type="image/png" height="75" width="144"/>
</item>
<item>
  <title>Google Fitに集約した睡眠データをローカル環境で可視化するJupyter Notebookを作成しました</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Sleep_Analyze_JupyterNotebook.html</link>
  <description><![CDATA[ 




<p><a href="../post_images/Sleep_Ana.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana.png" class="img-fluid"></a></p>
<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<section id="要旨" class="level2">
<h2 class="anchored" data-anchor-id="要旨">1. 要旨</h2>
<p>Google Fitに集約された睡眠データをダウンロードし、ローカル環境で分析をしたいと思い<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>を作成しました。 このノートブックでは、事前にダウンロードした睡眠データ(<code>.json</code>ファイル)を用いて、四半期ごとあるいは任意の期間のダブルプロットアクトグラム(+睡眠ステージ), 四半期ごとの睡眠時間及び質の推移, 四半期ごとの曜日別睡眠時間及び睡眠の質, 任意の日付の睡眠ステージの推移を可視化することが出来ます。 このノートブックの新規性として、複数デバイスによる観測に対応していること, 一般的な睡眠分析アプリには見られない「ダブルプロットのアクトグラム」を採用し、なおかつ色分けにより睡眠ステージが分かるようになっているという2つが挙げられます。特にダブルプロットアクトグラムを採用することで、従来の睡眠記録の可視化手法では難しかった、昼寝を含む全ての睡眠を直感的に理解しやすい形で表現することができます。</p>
</section>
<section id="背景" class="level2">
<h2 class="anchored" data-anchor-id="背景">2. 背景</h2>
<p>筆者はガジェットオタクであり、両腕に付けていたスマートウォッチや、睡眠マットなど、様々な機器で睡眠記録を(半ば自動的に)記録しGoogle Fitに集約していました。</p>
<p>しかし、Google Fitの睡眠可視化機能は複数のデバイスからの記録を想定しておらず、またクラウドに保存しているせいかレスポンスも非常に悪く使いにくさを感じています。</p>
<p>そのため、睡眠分析に興味はあったもののそのデータを活用するという気が起きなかったのですが、<a href="https://www.pokemonsleep.net/">Pokémon Sleep</a>に触発され、もっとしっかり自分の睡眠を分析したいという気持ちが芽生えたためこのプロジェクトを立ち上げました。</p>
<section id="動機" class="level3">
<h3 class="anchored" data-anchor-id="動機">2-1. 動機</h3>
<p>睡眠データを記録するデバイス・アプリは数多くあります。例えば、<a href="https://sleep.urbandroid.org/">Sleep as Android</a>や<a href="https://www.pokemonsleep.net/">Pokémon Sleep</a>など、スマートフォンをセンサーにするタイプのものは手軽な反面、手動で睡眠記録の測定を行う必要があったり(寝落ちして忘れることも)、バッテリー消費が激しいためスマートフォンを充電し続ける必要があります。</p>
<p>スマートウォッチ・スマートバンドを持っている場合、たいていのものは睡眠記録を自動で付けてくれるため更に手軽(寝落ちして忘れる心配もない)ですが、途中でバッテリーが切れてしまったり、睡眠に本腰をいれてないのか、精度が低かったり分析アプリのデザインがイマイチだったりします<sup>1</sup>。</p>
<p>その点、<a href="https://www.pokemonsleep.net/">Pokémon Sleep</a>で言うところの<code>Pokémon GO Plus +</code>や、Withingsの睡眠マット(<code>Withings Sleep WSM02-ALL-JP</code>)は、精度が良くアプリも見やすくて良いですが、睡眠のためのデバイスを買うぞという覚悟(と投資)が必要です。</p>
<p>…と、ここまで長々と筆者の睡眠デバイスの経歴を語ってしまいましたが、これらは基本的に独自の手法・基準でデータ分析を行い可視化します。</p>
<p>筆者のように、複数のデバイスを使っている場合、それぞれのデバイスとセットで提供されるアプリを見比べることになるのですが、アプリが違うのでデザイン(測定項目・グラフなど)は全く統一されておらず、比較は困難です。</p>
<p>また、睡眠分析アプリは昼寝に対応しているものが少なく、可視化の際に昼寝が表示されない・あるいは昼寝を可視化に含めたせいでグラフのX軸が広くなってしまい見にくくなることを不満にも思っていました。</p>
<p>幸い、ほとんどのアプリは睡眠記録をGoogle Fitに自動でアップロードしてくれるので、Google Fitを使えば昼寝の件はともかく複数デバイス問題は解決する…ように思えたのですが、前述の通りGoogle Fitは複数のデバイスで同時に睡眠を記録することは想定しておらず、記録自体は保存してくれるのですが、睡眠記録を確認(可視化)する際に、デバイスAの結果を採用する日もあればデバイスBの記録を採用する日もあるといった感じです。というか、表示できればまだ良い方で、大抵の場合(複数デバイスのせいで)エラーが出るのかタイムアウトしてしまい、結果が見れないことのほうが多いです。</p>
<p>このような背景から、だったら自分で(複数デバイスで記録した)睡眠データを可視化・分析するツールを作ろうと思い立ちました。</p>
<aside id="footnotes" class="footnotes footnotes-end-of-section">
<hr>
<ol>
<li id="fn1"><p>筆者はこれまで、ASUS ZenWatchシリーズ(WearOS), Xiaomi MiBandシリーズ(独自OS), Fossil Hybrid HR(独自OS), SONY Wena3(独自OS)と数多のスマートウォッチ・スマートバンドを試してきましたが、睡眠分析という意味ではどれもイマイチでした。↩︎</p></li>
</ol>
</aside>
</section>
<section id="技術的背景" class="level3">
<h3 class="anchored" data-anchor-id="技術的背景">2-2. 技術的背景</h3>
<p>2024年5月現在、筆者の睡眠データは図&nbsp;1のように記録・可視化され、集約されています。使用デバイス・アプリこそ違えど、Google Fitにデータを集約している方はこのようなワークフローでデータをエクスポートしているはずです。</p>
<p>肝となるのは、各デバイスで計測した睡眠データを各アプリがGoogle Fit APIに基づいてJSON形式に加工しているという点です。これによりデバイスが違っても同じフォーマットでデータを取り扱うことができます。</p>
<div id="fig-SleepData_Flow" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-SleepData_Flow-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_SleepData_Flow.png" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="図内の画像出典は記載の通り 一部筆者出典(主にスクリーンショット)"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_SleepData_Flow.png" class="img-fluid figure-img"></a></p>
<figcaption>図内の画像出典は記載の通り 一部筆者出典(主にスクリーンショット)</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-SleepData_Flow-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: 睡眠データのワークフロー
</figcaption>
</figure>
</div>
<section id="google-fit-apiについて" class="level4">
<h4 class="anchored" data-anchor-id="google-fit-apiについて">2-2-1. Google Fit APIについて</h4>
<p>各アプリ・デバイスで計測した生データは、(Google Fitと連携させた場合)<a href="https://developers.google.com/fit/scenarios/read-sleep-data">Google Fit API</a>を使ってJSON形式でアップロードされます。</p>
<p>データには睡眠ステージ, その睡眠ステージの開始時刻, 終了時刻が含まれています。睡眠ステージの判断は大元である各デバイス・アプリに任せられているようです。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>サンプルJSONデータ.json</strong></pre>
</div>
<div class="sourceCode" id="cb1" data-filename="サンプルJSONデータ.json" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"Data Source"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"raw:com.google.sleep.segment:com.hoge"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"Data Points"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb1-4">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fitValue"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"value"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"intVal"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"originDataSourceId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"endTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620291780000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"dataTypeName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com.google.sleep.segment"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"startTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620285780000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiedTimeMillis"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1624604115227</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rawTimestampNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-5">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fitValue"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"value"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"intVal"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"originDataSourceId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"endTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620338280000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"dataTypeName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com.google.sleep.segment"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"startTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620313260000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiedTimeMillis"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1624604115227</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rawTimestampNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-6">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fitValue"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"value"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"intVal"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"originDataSourceId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"endTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620379200000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"dataTypeName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com.google.sleep.segment"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"startTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620367020000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiedTimeMillis"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1624604115227</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rawTimestampNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fitValue"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"value"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"intVal"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"originDataSourceId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"endTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620435480000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"dataTypeName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com.google.sleep.segment"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"startTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620412740000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiedTimeMillis"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1624604117511</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rawTimestampNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-8">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"fitValue"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"value"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:{</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"intVal"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"originDataSourceId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"endTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620450300000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"dataTypeName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com.google.sleep.segment"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"startTimeNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1620443520000000000</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiedTimeMillis"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1624604117511</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rawTimestampNanos"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-9">    <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb1-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
</div>
<p>睡眠ステージの内訳は以下の通りです<span class="citation" data-cites="GoogleFitAPI">(Google for Developers 2023)</span>。</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>睡眠ステージのタイプ</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>覚醒（睡眠サイクル中）</td>
<td>1</td>
</tr>
<tr class="even">
<td>睡眠</td>
<td>2</td>
</tr>
<tr class="odd">
<td>ベッド外</td>
<td>3</td>
</tr>
<tr class="even">
<td>浅い睡眠</td>
<td>4</td>
</tr>
<tr class="odd">
<td>深い睡眠</td>
<td>5</td>
</tr>
<tr class="even">
<td>レム睡眠</td>
<td>6</td>
</tr>
</tbody>
</table>
<p>懸念事項として、Google Fit APIが終了しHealth Connect API(?)へと移行されること<span class="citation" data-cites="GoogleFitAPI">(Google for Developers 2023)</span>が挙げられます。今後、睡眠データはGoogle FitではなくHealth Connectに集約されることとなるでしょう。データのフォーマットが変わってしまうと、このノートブックの前提が崩れてしまうので、詳細が分かり次第対応していきたいと思います。</p>
</section>
<section id="python及びjupyter-notebookの採用理由" class="level4">
<h4 class="anchored" data-anchor-id="python及びjupyter-notebookの採用理由">2-2-2. Python及びJupyter Notebookの採用理由</h4>
<p>何を使って睡眠データの可視化・分析ツールを作るかは少し悩みました。R言語は、必要最低限の読み書きができるものの、ChatGPTをはじめとする生成AIの支援を受けにくいこと, 自分以外の人が使う際に配布・再現しにくいことがネックだったため、Pythonを採用しました。</p>
<p>Pythonは <code>print("Hello World!")</code> くらいしか知らないためChatGPTにあれこれ聞き、最終的にPythonというかJupyter Notebookを採用することになりました。</p>
<p>データの読み込み, データ属性の入力, 日付やデータ期間の選択といった作業を、スクリプトを書き換えるのではなくユーザーが直感的に分かりやすくボタン操作などで行える点(図&nbsp;2)が、筆者の持つPython並びにJupyter Notebookへの苦手意識を上回ったからです。</p>
<div id="fig-GUI" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-GUI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/SleepAna_1_FileInport.png" class="lightbox" data-gallery="quarto-lightbox-gallery-3" title="ファイルの読み込み"><img src="https://pottal-portal.com/PtPr3/post_images/SleepAna_1_FileInport.png" class="img-fluid figure-img"></a></p>
<figcaption>ファイルの読み込み</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/SleepAna_2_FileSelect.png" class="lightbox" data-gallery="quarto-lightbox-gallery-4" title="手動記録の識別"><img src="https://pottal-portal.com/PtPr3/post_images/SleepAna_2_FileSelect.png" class="img-fluid figure-img"></a></p>
<figcaption>手動記録の識別</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/SleepAna_3_DateSelect.png" class="lightbox" data-gallery="quarto-lightbox-gallery-5" title="期間の選択"><img src="https://pottal-portal.com/PtPr3/post_images/SleepAna_3_DateSelect.png" class="img-fluid figure-img"></a></p>
<figcaption>期間の選択</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-GUI-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;2: グラフィカルなUI
</figcaption>
</figure>
</div>
</section>
</section>
<section id="可視化手法" class="level3">
<h3 class="anchored" data-anchor-id="可視化手法">2-3. 可視化手法</h3>
<p>前述の通り、既存の睡眠分析・可視化アプリには、昼寝に対応しているものが少なく、可視化の際に昼寝が表示されない・あるいは昼寝を可視化に含めたせいでグラフのX軸が広くなってしまい見にくくなる(図&nbsp;3)という問題がありました。</p>
<div id="fig-Sleep_Vis_problem_1" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Sleep_Vis_problem_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_Withings_1.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-6" title="昼寝は表示されないためグラフは見やすい"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Withings_1.jpg" class="img-fluid figure-img"></a></p>
<figcaption>昼寝は表示されないためグラフは見やすい</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_Withings_2_nap.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-7" title="昼寝(?)は別項目となり可視化されない"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Withings_2_nap.jpg" class="img-fluid figure-img"></a></p>
<figcaption>昼寝(?)は別項目となり可視化されない</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-figure-spacer quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<p>&nbsp;</p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_Notify.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-8" title="昼寝のせいでグラフが見にくくなっている"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Notify.jpg" class="img-fluid figure-img"></a></p>
<figcaption>昼寝のせいでグラフが見にくくなっている</figcaption>
</figure>
</div>
</div>
<div class="quarto-figure-spacer quarto-layout-cell" style="flex-basis: 25.0%;justify-content: flex-start;">
<p>&nbsp;</p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Sleep_Vis_problem_1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;3: 既存の睡眠可視化手法の問題点1<br>図中、上段は<a href="https://amzn.asia/d/932PuRu">Withings Sleep</a>の睡眠可視化,下段はXiaomi MiBand8のサードパーティアプリ<a href="https://mibandnotify.com/">Notify</a>
</figcaption>
</figure>
</div>
<p>他にも、例えば<a href="https://www.pokemonsleep.net/">Pokémon Sleep</a>や<a href="https://sleep.urbandroid.org/">Sleep as Android</a>の睡眠周期の可視化手法には、軸が24時間以下なのでイレギュラーな睡眠に弱く、その範囲を超えてしまうと見切れてしまうという問題があります(図&nbsp;4)。</p>
<div id="fig-Sleep_Vis_problem_2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Sleep_Vis_problem_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_SleepAsAndroid.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-9" title="昼寝が見切れている"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_SleepAsAndroid.jpg" class="img-fluid figure-img"></a></p>
<figcaption>昼寝が見切れている</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_PokemonSleep.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-10" title="(試してないが)3交代制などで15時前に寝た場合グラフが見切れることが予想される"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_PokemonSleep.jpg" class="img-fluid figure-img"></a></p>
<figcaption>(試してないが)3交代制などで15時前に寝た場合グラフが見切れることが予想される</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Sleep_Vis_problem_2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;4: 既存の睡眠可視化手法の問題点2<br>図中、左は<a href="https://sleep.urbandroid.org/">Sleep as Android</a>, 右は<a href="https://www.pokemonsleep.net/">Pokémon Sleep</a>
</figcaption>
</figure>
</div>
<p>こうした問題(図&nbsp;3, 図&nbsp;4)を解決する可視化手法が、ダブルプロットされたアクトグラム(+睡眠ステージも色で表示した筆者オリジナルのもの)です(図&nbsp;5)。</p>
<div id="fig-My_Actogram" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-My_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_MyActogram.png" class="lightbox" data-gallery="quarto-lightbox-gallery-11" title="詳細は添付したJupyter Notebook(.ipynbファイル)を参照"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_MyActogram.png" class="img-fluid figure-img"></a></p>
<figcaption>詳細は添付した<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>を参照</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-My_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;5: ダブルプロットアクトグラム(Double-plotted actogram)を改良したもの
</figcaption>
</figure>
</div>
<p>筆者は生物学を専攻していたこともあり、このアクトグラムというものを概日リズム(サーカディアンリズム; circadian rhythm)の説明の中で知りました。</p>
<p>概日リズムというのは要するに体内時計のことで、恒常環境下(例えばずっと真っ暗闇な状態)でも約24時間の周期を示し, (光)同調性を持ち(光によってリセットされ), 温度補償性を持っているものとされています<span class="citation" data-cites="Johnson2003">(Carl Hirschie Johnson &amp; Foster 2003)</span>。概日リズム自体はそれ以前より何となく知られていたものではありましたが、概日リズムの基礎となったのはモデル生物であるショウジョウバエを使った研究で、そのルーツは時間生物学(chronobiology)の創立者の一人であるコリン・ピッテンドリー(Colin Pittendrigh)であると言えるでしょう<span class="citation" data-cites="Tataroglu2014">(Tataroglu &amp; Emery 2014)</span>。</p>
<p>概日リズムやそれを司る時計遺伝子<sup>2</sup>に関しては興味があればググっていただくとして、ここでは概日リズムの可視化に用いられる手法の1つであるアクトグラムについて解説していきます。</p>
<p>アクトグラムは1926年にメイナード ジョンソン(Maynard Johnson)によって導入されたと言われています<span class="citation" data-cites="Refinetti2007">(Refinetti et al.<em> </em> 2007)</span>。彼の発明したアクトグラムという可視化手法は活動のリズムが視覚的に分かりやすいという点で優れています(図&nbsp;6)。 しかし、彼の発明したアクトグラムは24時間(1日区切り)であったため、24時間を超えるリズムに気付きにくいという欠点がありました。学術的な意味合いはともかく、筆者が実現したかった昼寝や3交代制など不規則な睡眠を見切れることなく表示するには24時間の軸では足りません。</p>
<p>これを解決するのが、24時間のアクトグラムを2つ並べたDouble-plotted actogramで、(少なくとも筆者の調べた限り)1960年にコリン・ピッテンドリー(Colin Pittendrigh)が”Circadian Rhythms and the Circadian Organization of Living Systems”という論文<span class="citation" data-cites="Colin1960_circadian">(Pittendrigh 1960)</span>で用いたものが初出だと思います(図&nbsp;7)。</p>
<div id="fig-First_Actogram" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-First_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_First_Actogram_1_Johnson1926.png" class="lightbox" data-gallery="quarto-lightbox-gallery-12" title="[@Johnson1926]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_First_Actogram_1_Johnson1926.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Johnson1926">(Johnson 1926)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_First_Actogram_2_Johnson1926.png" class="lightbox" data-gallery="quarto-lightbox-gallery-13" title="[@Johnson1926]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_First_Actogram_2_Johnson1926.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Johnson1926">(Johnson 1926)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-First_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;6: メイナード ジョンソンが世界で初めて導入したアクトグラム
</figcaption>
</figure>
</div>
<div id="fig-First_DoublePlottedActogram" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-First_DoublePlottedActogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_Double-plotted-actogram_Colin1960.png" class="lightbox" data-gallery="quarto-lightbox-gallery-14" title="[@Colin1960_circadian]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Double-plotted-actogram_Colin1960.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Colin1960_circadian">(Pittendrigh 1960)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-First_DoublePlottedActogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;7: おそらく世界で初めてコリン・ピッテンドリーが導入したダブルプロットのアクトグラム
</figcaption>
</figure>
</div>
<p>ということで、今回はダブルプロットのアクトグラムを筆者なりに改良した可視化手法で睡眠の周期を分析することにしました(図&nbsp;5)。</p>
<aside id="footnotes-2" class="footnotes footnotes-end-of-section">
<hr>
<ol start="2">
<li id="fn2"><p>時計遺伝子である<em>per</em>遺伝子は、一部生物学者から神のように崇められているベンザー(Seymour Benzer)によって発見され、「Period(ピリオド)」と名付けられました。この<em>per</em>遺伝子は<em>tim</em>遺伝子(こちらはTimelessとこれまたカッコいい名前がついています)と共に二量体を形成し、他の転写因子と相互作用をします。長くなるので割愛しますが、この二量体が体内で分解されてまた作られるという周期がちょうど約24時間周期のため時計遺伝子として働きます。↩︎</p></li>
</ol>
</aside>
</section>
</section>
<section id="材料と方法" class="level2">
<h2 class="anchored" data-anchor-id="材料と方法">3. 材料と方法</h2>
<p>この<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>は、<a href="https://takeout.google.com/">Google Fitからダウンロード</a>した睡眠データ(<code>.json</code>), VS Code及びPython, Jupyterの拡張機能を必要とします。Google Colabでは動作しません。また、それ以外の環境では検証していません。</p>
<p>VS Codeで実行することで、</p>
<ul>
<li>睡眠データの分析は全てローカル環境で実行される
<ul>
<li>大容量のデータも扱える</li>
<li>データが外部にアップロードされることがない というメリットが生まれます。</li>
</ul></li>
</ul>
<p>この<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>はモジュール式となっているため、個別の可視化手法を必要に応じて実行することが可能です。</p>
<p>今のところ、四半期ごとのアクトグラム(図&nbsp;8), 任意の期間のアクトグラム及びミッドスリープタイム(図&nbsp;9), 四半期ごとの睡眠時間及び睡眠の質の推移の可視化(図&nbsp;10 (a))及び四半期の範囲で曜日別の睡眠時間及び睡眠の質の可視化(図&nbsp;10 (b)), 任意の日付の睡眠記録(睡眠ステージのサイクル)の可視化(図&nbsp;11)が行えます。</p>
<div id="fig-Quarterly_Actogram" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Quarterly_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Sleep_Ana_Quarterly_actogram.png" class="lightbox" data-gallery="quarto-lightbox-gallery-15" title="図&nbsp;8: 四半期ごとのアクトグラム"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Quarterly_actogram.png" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Quarterly_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;8: 四半期ごとのアクトグラム
</figcaption>
</figure>
</div>
<div id="fig-Manual_Actogram" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Manual_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Sleep_Ana_MyActogram.png" class="lightbox" data-gallery="quarto-lightbox-gallery-16" title="図&nbsp;9: 任意の期間のアクトグラム+ミッドスリープタイム"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_MyActogram.png" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Manual_Actogram-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;9: 任意の期間のアクトグラム+ミッドスリープタイム
</figcaption>
</figure>
</div>
<div id="fig-Quarterly_Analyze" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Quarterly_Analyze-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Quarterly_Analyze" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-line" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-line-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Sleep_Ana_Quarterly_line.png" class="lightbox" data-gallery="fig-Quarterly_Analyze" title="図&nbsp;10&nbsp;(a): 睡眠時間及び質の推移"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Quarterly_line.png" class="img-fluid figure-img" data-ref-parent="fig-Quarterly_Analyze"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-line-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 睡眠時間及び質の推移
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Quarterly_Analyze" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-boxplot" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-boxplot-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Sleep_Ana_Quarterly_Boxplot.png" class="lightbox" data-gallery="fig-Quarterly_Analyze" title="図&nbsp;10&nbsp;(b): 四半期ごとの曜日別睡眠時間及び質"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Quarterly_Boxplot.png" class="img-fluid figure-img" data-ref-parent="fig-Quarterly_Analyze"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-boxplot-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 四半期ごとの曜日別睡眠時間及び質
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Quarterly_Analyze-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;10: 四半期ごとの統計
</figcaption>
</figure>
</div>
<div id="fig-Sleep-Cycle" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Sleep-Cycle-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row quarto-layout-valign-bottom">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_SleepCycle.png" class="lightbox" data-gallery="quarto-lightbox-gallery-19" title="筆者のデータの場合、複数のデバイスで記録しているため透明度が自動的に下がっている"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_SleepCycle.png" class="img-fluid figure-img"></a></p>
<figcaption>筆者のデータの場合、複数のデバイスで記録しているため透明度が自動的に下がっている</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Sleep-Cycle-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;11: 任意の日付の睡眠サイクル
</figcaption>
</figure>
</div>
<section id="必要なもの" class="level3">
<h3 class="anchored" data-anchor-id="必要なもの">3-1. 必要なもの</h3>
<p>前述の通り、この<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>は以下のものを必要とします。</p>
<ul>
<li><a href="https://github.com/Pottal/Sleep_Analyze">GitHubからダウンロード</a>したJupyter Notebook(<code>.ipynb</code>ファイル)</li>
<li><a href="https://takeout.google.com/">Google Fitからダウンロード</a>した睡眠データ(<code>.json</code>ファイル)</li>
<li>VS Code(Google Colabでは実行できません)
<ul>
<li>Python拡張機能</li>
<li>Jupyter拡張機能</li>
</ul></li>
</ul>
</section>
<section id="実行方法" class="level3">
<h3 class="anchored" data-anchor-id="実行方法">3-2. 実行方法</h3>
<p><a href="https://takeout.google.com/">Google データ エクスポート</a>にアクセスしGoogle Fitのデータをダウンロードした後(データのエクスポートをリクエストしてからダウンロード可能になるまで、数時間~数日かかります)、<a href="../../PtPr3/Add_files/Sleep_Analyze_Jupyter_Notebook/Sleep_Analyze_Notebook_JP_version.html">Jupyter Notebook(<code>.ipynb</code>ファイル)</a>を、1セルずつ順番に実行してください(Step by Stepでファイルの読み込みや期間の設定をするため <strong>「すべてを実行」で一括して行うことはできません。</strong>)</p>
<section id="google-fit-からデータをダウンロードする方法" class="level4">
<h4 class="anchored" data-anchor-id="google-fit-からデータをダウンロードする方法">3-2-1. Google Fit からデータをダウンロードする方法</h4>
<ol type="1">
<li><p><a href="https://takeout.google.com/">Google データ エクスポート</a>にアクセスします。</p></li>
<li><p><code>追加するデータの選択</code> にて<code>選択をすべて解除</code>します(余計なデータが多すぎるため)。</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/takeout_google_1_deselect_All.png?raw=true" width="320px" alt="Access Google data export and deselect All"></p></li>
<li><p><code>Fit</code>(Google Fit)のみを選択します。</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/takeout_google_2_Select_Fit.png?raw=true" width="320px" alt="Select Google Fit"></p></li>
<li><p>一番下までスクロールし、<code>次のステップ</code>をクリックします。</p></li>
<li><p>ファイル形式、エクスポート回数、エクスポート先の選択をします。</p>
<ul>
<li><code>エクスポート先</code> は <code>ダウンロードリンクをメールで送信</code>を選択します</li>
<li><code>頻度</code>は<code>1回エクスポート</code>を選択します</li>
<li><code>ファイル形式</code>は<code>.zip</code>を選択します</li>
<li><code>ファイルサイズ</code>は<code>50GB</code>を選択します(念の為)</li>
<li>上記を確認した後、<code>エクスポートを作成</code>をクリックします</li>
</ul>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/takeout_google_3_export.png?raw=true" width="320px" alt="Select Google Fit"></p></li>
<li><p>データのエクスポートが処理され、ダウンロードリンクがメールで送られていくるまで数時間から数日かかります。気長に待ちます(ページを閉じても大丈夫です)。</p>
<ul>
<li>進捗は<a href="https://takeout.google.com/">Google データ エクスポート</a>にて確認できます</li>
<li>メールはデータのエクスポートをリクエストしたGoogleアカウント宛(gmail)に届きます</li>
</ul></li>
<li><p>ダウンロードリンクが書かれたメールを開き、ダウンロードページに跳びます(<code>ファイルをダウンロード</code>をクリックします)。</p>
<ul>
<li>メールの件名は<code>Google データをダウンロードできるようになりました</code>でした</li>
</ul>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/takeout_mail.png?raw=true" width="320px" alt="Select Google Fit"></p></li>
<li><p>Googleアカウントのパスワードを入力後、データをダウンロードします。</p>
<ul>
<li>筆者の場合、エラーが含まれていました(が、どうしようもないので続行します)</li>
</ul>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/takeout_DL.png?raw=true" width="320px" alt="Select Google Fit"></p></li>
</ol>
<p>以上で、Google Fitデータのダウンロードは終了です。</p>
</section>
<section id="データ分析の流れ" class="level4">
<h4 class="anchored" data-anchor-id="データ分析の流れ">3-2-2. データ分析の流れ</h4>
<ol type="1">
<li><p>モジュールのインポート</p></li>
<li><p>データの取り込み</p></li>
<li><p>(手動の睡眠記録がある場合)データセットの選択</p></li>
<li><p>(必要であれば)データをCSVファイルとしてエクスポート</p></li>
<li><p>アクトグラムを用いた四半期ごとの睡眠記録の可視化</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/Sample_Actogram.png?raw=true" width="320px" alt="Access Google data export and deselect All"></p></li>
<li><p>四半期ごとの統計</p></li>
<li><p>任意の日付の睡眠記録の可視化</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/Sample_Sleep_cycle.png?raw=true" width="320px" alt="Access Google data export and deselect All"></p></li>
</ol>
<section id="モジュールのインポート" class="level5">
<h5 class="anchored" data-anchor-id="モジュールのインポート">3-2-2-1. モジュールのインポート</h5>
<p>以下のセルを実行し、(もしそのモジュールがない場合、自動で)必要なモジュールをインポートします。</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> subprocess</span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> sys</span>
<span id="cb2-3"></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 必要なライブラリをリストにまとめる</span></span>
<span id="cb2-5">required_libraries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb2-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'json'</span>,</span>
<span id="cb2-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'pandas'</span>,</span>
<span id="cb2-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'matplotlib'</span>,</span>
<span id="cb2-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'pytz'</span>,</span>
<span id="cb2-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ipywidgets'</span>,</span>
<span id="cb2-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'numpy'</span>,</span>
<span id="cb2-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'seaborn'</span>,</span>
<span id="cb2-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ipyfilechooser'</span>,</span>
<span id="cb2-14">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'plotly'</span></span>
<span id="cb2-15">]</span>
<span id="cb2-16"></span>
<span id="cb2-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ライブラリのインストール関数</span></span>
<span id="cb2-18"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> install_and_import(library):</span>
<span id="cb2-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="cb2-20">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__import__</span>(library)</span>
<span id="cb2-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">ImportError</span>:</span>
<span id="cb2-22">        subprocess.check_call([sys.executable, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"-m"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pip"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"install"</span>, library])</span>
<span id="cb2-23">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__import__</span>(library)</span>
<span id="cb2-24"></span>
<span id="cb2-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各ライブラリのインストールとインポート</span></span>
<span id="cb2-26"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> library <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> required_libraries:</span>
<span id="cb2-27">    install_and_import(library)</span>
<span id="cb2-28"></span>
<span id="cb2-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># インポート文</span></span>
<span id="cb2-30"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> json</span>
<span id="cb2-31"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb2-32"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb2-33"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb2-34">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'font.family'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Yu Mincho'</span>, <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#'Hiragino Kaku Gothic ProN', #'Meiryo', #'Noto Sans CJK JP'</span></span>
<span id="cb2-35"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.dates <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> mdates</span>
<span id="cb2-36"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pytz</span>
<span id="cb2-37"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ipywidgets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> widgets</span>
<span id="cb2-38"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb2-39"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb2-40"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.graph_objects <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> go</span>
<span id="cb2-41"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.express <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> px</span>
<span id="cb2-42"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.io <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pio</span>
<span id="cb2-43"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> ipywidgets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> DatePicker, Button, HBox</span>
<span id="cb2-44"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> matplotlib.lines <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Line2D</span>
<span id="cb2-45"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> pytz <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> timezone</span>
<span id="cb2-46"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> IPython.display <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> display, clear_output</span>
<span id="cb2-47"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> ipyfilechooser <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> FileChooser</span>
<span id="cb2-48"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> datetime <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> datetime</span>
<span id="cb2-49"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> datetime <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> timedelta</span>
<span id="cb2-50"></span>
<span id="cb2-51"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"All libraries are installed and imported successfully."</span>)</span></code></pre></div>
</section>
<section id="データの取り込み" class="level5">
<h5 class="anchored" data-anchor-id="データの取り込み">3-2-2-2. データの取り込み</h5>
<p>以下のセルを実行し、</p>
<ol type="1">
<li>データの読み込み</li>
<li>データの変換 を行います。</li>
</ol>
<p>VS Codeで実行している場合、<strong>睡眠データの分析は全てローカル環境で実行されます。</strong> また、<strong>データが外部にアップロードされることはありません</strong>のでご安心ください。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>睡眠データの読み込み</strong></pre>
</div>
<div class="sourceCode" id="cb3" data-filename="睡眠データの読み込み" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイルアップロードウィジェットの作成</span></span>
<span id="cb3-2">uploader <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.FileUpload(</span>
<span id="cb3-3">    accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.json'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># JSONファイルのみを許可</span></span>
<span id="cb3-4">    multiple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 複数のファイルをアップロード可能</span></span>
<span id="cb3-5">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Upload JSON files'</span></span>
<span id="cb3-6">)</span>
<span id="cb3-7"></span>
<span id="cb3-8">file_loading_flag <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb3-9"></span>
<span id="cb3-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードされたデータを処理する関数</span></span>
<span id="cb3-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> process_uploaded_files(change):</span>
<span id="cb3-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">global</span> file_loading_flag</span>
<span id="cb3-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 処理中メッセージを表示</span></span>
<span id="cb3-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb3-15">        clear_output()</span>
<span id="cb3-16">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの処理中です。次のセルには進まないでください。"</span>)</span>
<span id="cb3-17">        sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb3-18"></span>
<span id="cb3-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="cb3-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> file_info <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>]:</span>
<span id="cb3-21">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Processing </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>file_info[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb3-22">            sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb3-23">            content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_info[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'content'</span>]</span>
<span id="cb3-24">            import_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json.loads(content.tobytes().decode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb3-25">            df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_and_process_sleep_data(import_data, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type of Sleep'</span>)</span>
<span id="cb3-26">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの読み込みが完了しました。次のセルに進んでください"</span>)</span>
<span id="cb3-27">        file_loading_flag <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb3-28"></span>
<span id="cb3-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb3-30">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> file_loading_flag <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb3-31">                clear_output()</span>
<span id="cb3-32">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの読み込みが完了しました。次のセルに進んでください。"</span>)</span>
<span id="cb3-33">                sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb3-34"></span>
<span id="cb3-35">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">Exception</span> <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> e:</span>
<span id="cb3-36">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb3-37">            clear_output()</span>
<span id="cb3-38">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"エラーが発生しました: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>e<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb3-39">            sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb3-40"></span>
<span id="cb3-41"></span>
<span id="cb3-42"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># JSONデータをDataFrameに変換するための関数</span></span>
<span id="cb3-43"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load_and_process_sleep_data(import_data, type_value):</span>
<span id="cb3-44">    data_source <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> import_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Data Source'</span>]</span>
<span id="cb3-45">    data_points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> import_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Data Points'</span>]</span>
<span id="cb3-46">    df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame([{</span>
<span id="cb3-47">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>: data_source,</span>
<span id="cb3-48">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time_ns'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'startTimeNanos'</span>],</span>
<span id="cb3-49">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time_ns'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'endTimeNanos'</span>],</span>
<span id="cb3-50">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fitValue'</span>][<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'intVal'</span>],</span>
<span id="cb3-51">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'modified_time_ms'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'modifiedTimeMillis'</span>],</span>
<span id="cb3-52">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>: type_value</span>
<span id="cb3-53">    } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> dp <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> data_points])</span>
<span id="cb3-54">    df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time_ns'</span>], unit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ns'</span>)</span>
<span id="cb3-55">    df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time_ns'</span>], unit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ns'</span>)</span>
<span id="cb3-56">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> df</span>
<span id="cb3-57"></span>
<span id="cb3-58"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力ウィジェットの作成</span></span>
<span id="cb3-59">output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Output()</span>
<span id="cb3-60"></span>
<span id="cb3-61"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 初期メッセージの表示</span></span>
<span id="cb3-62"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb3-63">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの処理が完了するまで、次のセルには進まないでください"</span>)</span>
<span id="cb3-64"></span>
<span id="cb3-65"></span>
<span id="cb3-66"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードイベントに関数をバインド</span></span>
<span id="cb3-67">uploader.observe(process_uploaded_files, names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>)</span>
<span id="cb3-68"></span>
<span id="cb3-69"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの表示</span></span>
<span id="cb3-70">display(uploader)</span>
<span id="cb3-71">display(output)</span></code></pre></div>
</div>
<p>この際に、<code>ファイルの読み込みが完了しました。次のセルに進んでください</code>と表示されるまでは次のセルに進まないでください。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>睡眠データのフォーマット関数など</strong></pre>
</div>
<div class="sourceCode" id="cb4" data-filename="睡眠データのフォーマット関数など" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> parse_datetime_with_format(dt_series):</span>
<span id="cb4-2">    dt_series_with_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dt_series[dt_series.astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.contains(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r"\.\d+"</span>)]</span>
<span id="cb4-3">    dt_series_without_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dt_series[<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>dt_series.astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.contains(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r"\.\d+"</span>)]</span>
<span id="cb4-4">    parsed_with_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(dt_series_with_ms, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M:%S.</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%f</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coerce'</span>)</span>
<span id="cb4-5">    parsed_without_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(dt_series_without_ms, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M:%S'</span>, errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coerce'</span>)</span>
<span id="cb4-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.concat([parsed_with_ms, parsed_without_ms]).sort_index()</span>
<span id="cb4-7"></span>
<span id="cb4-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードされたファイル名とデータの取得</span></span>
<span id="cb4-9">uploaded_files <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> uploader.value</span></code></pre></div>
</div>
</section>
<section id="手動で記録されたデータセットの指定" class="level5">
<h5 class="anchored" data-anchor-id="手動で記録されたデータセットの指定">3-2-2-3. 手動で記録されたデータセットの指定</h5>
<p>睡眠記録は、スマートウォッチや睡眠マットを使っている場合は自動で記録されますが、そうではない場合はスマートフォンのアプリ等を使って、手動で睡眠記録を開始・終了しているはずです。</p>
<p>手動で睡眠記録を開始・終了することで、布団(ベッド)に入った時刻が確実に分かるため、睡眠潜時(就寝してから入眠するまでにかかる時間)が算出できるため、手動・自動を区別しています。</p>
<p>以下のスクリプトでは、チェックボックスにチェックを入れることで、(手動で記録されたものがある場合)そのデータが手動か自動かを識別します。</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Sleep_Ana_Auto_or_Manual.png" class="lightbox" data-gallery="quarto-lightbox-gallery-20" title="例(筆者のデータの場合)"><img src="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana_Auto_or_Manual.png" class="img-fluid figure-img" alt="例(筆者のデータの場合)"></a></p>
<figcaption>例(筆者のデータの場合)</figcaption>
</figure>
</div>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>手動睡眠記録の識別</strong></pre>
</div>
<div class="sourceCode" id="cb5" data-filename="手動睡眠記録の識別" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1"></span>
<span id="cb5-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 説明文を表示</span></span>
<span id="cb5-3">description_label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'もし手動で睡眠記録を開始/停止したデータセットがあれば該当するものにチェックを入れてください。'</span>)</span>
<span id="cb5-4">display(description_label)</span>
<span id="cb5-5"></span>
<span id="cb5-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 空のデータフレームを初期化</span></span>
<span id="cb5-7">combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame()</span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイルと対応するチェックボックスを表示</span></span>
<span id="cb5-10">checkboxes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb5-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> file_details <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> uploader.value:</span>
<span id="cb5-12">    cb <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Checkbox(</span>
<span id="cb5-13">        value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>,</span>
<span id="cb5-14">        description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span>,  </span>
<span id="cb5-15">        disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb5-16">    )</span>
<span id="cb5-17">    label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>])  </span>
<span id="cb5-18">    box <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.HBox([cb, label])  </span>
<span id="cb5-19">    checkboxes.append(cb)</span>
<span id="cb5-20">    display(box)</span>
<span id="cb5-21"></span>
<span id="cb5-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># プロセスボタンを作成</span></span>
<span id="cb5-23">process_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"決定(データを処理)"</span>)</span>
<span id="cb5-24"></span>
<span id="cb5-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ボタンのイベントハンドラー</span></span>
<span id="cb5-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_button_clicked(b):</span>
<span id="cb5-27">    clear_output(wait<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb5-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">global</span> combined_data</span>
<span id="cb5-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> cb, file_details <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(checkboxes, uploader.value):</span>
<span id="cb5-30">        filename <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>]</span>
<span id="cb5-31">        content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'content'</span>]</span>
<span id="cb5-32">        sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json.loads(content.tobytes().decode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb5-33"></span>
<span id="cb5-34">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># チェックボックスの値に応じてデータタイプを設定</span></span>
<span id="cb5-35">        type_column_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Manual'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> cb.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Auto'</span></span>
<span id="cb5-36">        data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_and_process_sleep_data(sleep_data, type_column_value)</span>
<span id="cb5-37">        combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.concat([combined_data, data], ignore_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb5-38"></span>
<span id="cb5-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データ処理後の状態を表示</span></span>
<span id="cb5-40">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Data processing complete. Dataframe contains:"</span>, combined_data.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rows."</span>)</span>
<span id="cb5-41">    </span>
<span id="cb5-42">process_button.on_click(on_button_clicked)</span>
<span id="cb5-43">display(process_button)</span></code></pre></div>
</div>
</section>
<section id="データをcsvとしてエクスポート" class="level5">
<h5 class="anchored" data-anchor-id="データをcsvとしてエクスポート">3-2-2-4. データをCSVとしてエクスポート</h5>
<p>もし、他のツール(例えばChatGPTなど)で分析を行ないたい場合、Google Fitからダウンロードしたファイル(<code>.json</code>形式)をそのまま用いるよりも、CSVファイルの方が便利です。</p>
<p>CSVファイルとしてデータをエクスポートしたい場合は、以下のセルを実行してください。<code>Select</code>ボタンを押して保存するフォルダを指定し、再度<code>Select</code>ボタンを押し、その下の<code>✔Save</code>ボタンを押すことで、保存が行えます。 なお、このセルは任意(オプション)のため、実行しなくても問題ありません。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>CSVとしてエクスポート</strong></pre>
</div>
<div class="sourceCode" id="cb6" data-filename="CSVとしてエクスポート" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># CSVを保存する関数</span></span>
<span id="cb6-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ユーザーのデスクトップパスを取得</span></span>
<span id="cb6-3">desktop_path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> os.path.join(os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'USERPROFILE'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Desktop'</span>)</span>
<span id="cb6-4"></span>
<span id="cb6-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># CSVを保存する関数</span></span>
<span id="cb6-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> save_csv(sleep_data, path):</span>
<span id="cb6-7">    sleep_data.to_csv(path, index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb6-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'CSVファイルを </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">に保存しました。'</span></span>
<span id="cb6-9"></span>
<span id="cb6-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 「Save」ボタンの動作を定義</span></span>
<span id="cb6-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_save_button_clicked(b):</span>
<span id="cb6-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb6-13">        clear_output()</span>
<span id="cb6-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> fc.selected:</span>
<span id="cb6-15">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CSVファイルの保存先を選択してください"</span>)</span>
<span id="cb6-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb6-17">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ここでDataFrameを保存</span></span>
<span id="cb6-18">            result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> save_csv(sleep_data, fc.selected)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># dfは保存したいDataFrameの変数名</span></span>
<span id="cb6-19">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(result)</span>
<span id="cb6-20"></span>
<span id="cb6-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイル選択ダイアログを設定</span></span>
<span id="cb6-22">fc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FileChooser(desktop_path)</span>
<span id="cb6-23">fc.default_filename <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_data.csv'</span></span>
<span id="cb6-24">fc.use_dir_icons <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb6-25"></span>
<span id="cb6-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 「Save」ボタンの作成</span></span>
<span id="cb6-27">save_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(</span>
<span id="cb6-28">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Save'</span>,</span>
<span id="cb6-29">    button_style<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span>,</span>
<span id="cb6-30">    tooltip<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Click to save the CSV file'</span>,</span>
<span id="cb6-31">    icon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'check'</span></span>
<span id="cb6-32">)</span>
<span id="cb6-33">save_button.on_click(on_save_button_clicked)</span>
<span id="cb6-34"></span>
<span id="cb6-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力エリアを設定</span></span>
<span id="cb6-36">output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Output()</span>
<span id="cb6-37"></span>
<span id="cb6-38"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットを表示</span></span>
<span id="cb6-39">display(fc, save_button, output)</span></code></pre></div>
</div>
<p>CSVファイルの構造は以下の通りです。</p>
<ul>
<li><code>data_source</code>: インポートしたデータセットの名前です(基本的にはGoogle Fitから取得されたデバイスの名前です)
<ul>
<li><code>Mid_sleep_time</code>: 算出されたミッドスリープタイム</li>
</ul></li>
<li><code>Type</code>: 基本的には<code>Auto</code>か<code>Manual</code>のどちらかが入ります
<ul>
<li><code>Auto</code>: 自動で睡眠記録が開始・停止していることを意味します</li>
<li><code>Manual</code>: 手動で睡眠記録が開始・停止していることを意味します</li>
<li><code>Other</code>: 算出されたミッドスリープタイムであることを意味します</li>
</ul></li>
<li><code>in_bed_time</code>: 手動で睡眠記録を開始している場合、その開始時刻が入ります</li>
<li><code>start_time</code>: 各睡眠ステージが開始された時刻で、協定世界時(UTC)となっています(日本標準時ではないことに注意してください)</li>
<li><code>end_time</code>: 各睡眠ステージが終了した時刻で、協定世界時(UTC)となっています(日本標準時ではないことに注意してください)</li>
<li><code>sleep_state</code>: [Google Fit](https://developers.google.com/fit/scenarios/read-sleep-data?hl=ja#sleep_stage_valuesで定められた睡眠ステージの値(1~6)と、算出したミッドスリープタイム(10)が入ります</li>
<li><code>session_id</code>: 1回の睡眠ごとに割り振られたIDです(<code>end_time</code>から次の<code>start_time</code>までの間が2時間以上離れている場合、別の睡眠とみなしています)</li>
</ul>
<p>睡眠ステージは以下の通りです。</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>睡眠ステージのタイプ</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>覚醒（睡眠サイクル中）</td>
<td>1</td>
</tr>
<tr class="even">
<td>睡眠</td>
<td>2</td>
</tr>
<tr class="odd">
<td>ベッド外</td>
<td>3</td>
</tr>
<tr class="even">
<td>浅い睡眠</td>
<td>4</td>
</tr>
<tr class="odd">
<td>深い睡眠</td>
<td>5</td>
</tr>
<tr class="even">
<td>レム睡眠</td>
<td>6</td>
</tr>
<tr class="odd">
<td>ミッドスリープタイム</td>
<td>10</td>
</tr>
</tbody>
</table>
<p>(おそらくですが)睡眠ステージ2はデータの信頼性が低く使われていない傾向にあります ミッドスリープタイムはオリジナル(Google Fitのデータ)にはない項目です</p>
</section>
<section id="アクトグラムを用いた四半期ごとの睡眠記録の可視化" class="level5">
<h5 class="anchored" data-anchor-id="アクトグラムを用いた四半期ごとの睡眠記録の可視化">3-2-2-5. アクトグラムを用いた四半期ごとの睡眠記録の可視化</h5>
<p>以下のセルを実行することで、アクトグラムの可視化を行えます。</p>
<ul>
<li><strong>JSONファイルに含まれていたデータ期間に応じて</strong>、四半期(3ヶ月)ごとにアクトグラムがプロットされます</li>
<li><strong>1年につき4枚グラフが出る</strong>ので、含まれているデータ期間が長い場合は、全部のグラフが出力されるまで時間がかかります</li>
<li>任意の期間のアクトグラムを表示することも可能です</li>
</ul>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>アクトグラムの表示を準備するセル</strong></pre>
</div>
<div class="sourceCode" id="cb7" data-filename="アクトグラムの表示を準備するセル" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb7-1"></span>
<span id="cb7-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  日またぎを処理する関数</span></span>
<span id="cb7-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> adjust_end_time(start, end):</span>
<span id="cb7-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> start:</span>
<span id="cb7-5">        end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 翌日にまたがる場合は24時間分（分）を加算</span></span>
<span id="cb7-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> end</span>
<span id="cb7-7"></span>
<span id="cb7-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_to_jst_if_needed(column):</span>
<span id="cb7-9">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報を確認し、必要に応じて変換を行う</span></span>
<span id="cb7-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> column.dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb7-11">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報がない場合、UTCとして解釈し、JSTに変換</span></span>
<span id="cb7-12">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.to_datetime(column, utc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb7-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>:</span>
<span id="cb7-14">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがUTCであれば、JSTに変換</span></span>
<span id="cb7-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb7-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>:</span>
<span id="cb7-17">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがJSTでない他のタイムゾーンであれば、JSTに変換</span></span>
<span id="cb7-18">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb7-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb7-20">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 既にJSTであればそのまま返す</span></span>
<span id="cb7-21">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column</span>
<span id="cb7-22"></span>
<span id="cb7-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_sleep_data_to_jst(sleep_data):</span>
<span id="cb7-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_dataをコピーしてタイムゾーンを変換</span></span>
<span id="cb7-25">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.copy()</span>
<span id="cb7-26">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb7-27">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>])</span>
<span id="cb7-28">    </span>
<span id="cb7-29">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 明示的に datetime64[ns, Asia/Tokyo] にキャスト</span></span>
<span id="cb7-30">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb7-31">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb7-32">    </span>
<span id="cb7-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> jst_sleep_data</span>
<span id="cb7-34"></span>
<span id="cb7-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_actogram(sleep_data, start_date, end_date):</span>
<span id="cb7-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン変換後のデータを取得</span></span>
<span id="cb7-37">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb7-38"></span>
<span id="cb7-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 指定された期間でデータをフィルタリング</span></span>
<span id="cb7-40">    filtered_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[</span>
<span id="cb7-41">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb7-42">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> pd.Timestamp(end_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb7-43">    ].copy()</span>
<span id="cb7-44">    </span>
<span id="cb7-45">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> filtered_data.empty:</span>
<span id="cb7-46">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"No data available to plot between </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> and </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span>
<span id="cb7-47">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb7-48"></span>
<span id="cb7-49">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日またぎを考慮した時間の計算</span></span>
<span id="cb7-50">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> dt: dt.hour <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> dt.minute)</span>
<span id="cb7-51">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb7-52">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> row: adjust_end_time(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).seconds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>), axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb7-53"></span>
<span id="cb7-54">    color_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#b3e5fc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'yellow'</span>}</span>
<span id="cb7-55">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">map</span>(color_map)</span>
<span id="cb7-56"></span>
<span id="cb7-57">    num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, (pd.Timestamp(end_date) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date)).days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb7-58">    fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span>))</span>
<span id="cb7-59">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> filtered_data.iterrows():</span>
<span id="cb7-60">        day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)).days</span>
<span id="cb7-61">        ax.plot([row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>]], [day_of_week, day_of_week], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>)</span>
<span id="cb7-62">        ax.plot([row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>, row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>], [day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>)</span>
<span id="cb7-63"></span>
<span id="cb7-64">    ax.set_xlim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2880</span>)</span>
<span id="cb7-65">    ax.set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, num_days)</span>
<span id="cb7-66">    ax.set_yticks(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days))</span>
<span id="cb7-67">    ax.set_yticklabels([(pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x)).strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)])</span>
<span id="cb7-68">    ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time'</span>)</span>
<span id="cb7-69">    ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Days from Start Date'</span>)</span>
<span id="cb7-70">    plt.title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Actogram from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb7-71">    plt.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb7-72">    plt.xticks(ticks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)], labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>(i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:02d}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">:00'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)], rotation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span>)</span>
<span id="cb7-73">    plt.show()</span>
<span id="cb7-74"></span>
<span id="cb7-75"></span>
<span id="cb7-76"></span>
<span id="cb7-77"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データセットの範囲確認</span></span>
<span id="cb7-78">jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb7-79">start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb7-80">end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb7-81"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"This dataset contains data from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span></code></pre></div>
</div>
<p>上記のセルを実行すると、 &gt; This dataset contains data from <code>YYYY-MM-DD</code> to <code>YYYY-MM-DD</code> と表示されます。ここに表示される期間がデータセットに含まれていた期間です。</p>
<p>全てのデータを可視化する場合は、以下のセルを実行してください(このセルを飛ばし、任意の期間だけを可視化することも可能です)。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>全ての期間を対象に四半期ごとにアクトグラムをプロット</strong></pre>
</div>
<div class="sourceCode" id="cb8" data-filename="全ての期間を対象に四半期ごとにアクトグラムをプロット" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期毎にデータをプロット</span></span>
<span id="cb8-2">start_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.year.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>()</span>
<span id="cb8-3">end_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.year.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb8-4">last_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb8-5"></span>
<span id="cb8-6"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> year <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(start_year, end_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="cb8-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> quarter <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>):</span>
<span id="cb8-8">        start_month <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> quarter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb8-9">        end_month <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> quarter</span>
<span id="cb8-10">        quarter_start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.Timestamp(year<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>year, month<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>start_month, day<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb8-11">        quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.Timestamp(year<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>year, month<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>end_month, day<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.DateOffset(months<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.DateOffset(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb8-12">        </span>
<span id="cb8-13">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> quarter_start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> last_date:</span>
<span id="cb8-14">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># この四半期の開始日がデータセットの最後の日を超えている場合はスキップ</span></span>
<span id="cb8-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> last_date:</span>
<span id="cb8-16">            quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> last_date  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期の終了日がデータセットの最後の日を超えている場合は調整</span></span>
<span id="cb8-17"></span>
<span id="cb8-18">        plot_actogram(jst_sleep_data, quarter_start_date.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>), quarter_end_date.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>))</span></code></pre></div>
</div>
<p>任意の期間を選択し、可視化したい場合は以下のセルを実行してください。</p>
<ul>
<li>以下のセルを実行することで、任意の期間に絞ったアクトグラムを<strong>ブラウザ上に</strong>表示できます</li>
<li>データの期間は四半期(3ヶ月)を推奨しています
<ul>
<li>四半期より長い期間を選択した場合、Y軸の文字が潰れてしまいます</li>
</ul></li>
<li>このセルでは、ミッドスリープタイムも併せて表示しています</li>
<li>このセルを実行しなくても問題はありません</li>
</ul>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>任意の期間に絞ったアクトグラムのプロット</strong></pre>
</div>
<div class="sourceCode" id="cb9" data-filename="任意の期間に絞ったアクトグラムのプロット" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 任意の期間のアクトグラム</span></span>
<span id="cb9-2"></span>
<span id="cb9-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_interactive_actogram(sleep_data, start_date, end_date):</span>
<span id="cb9-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン変換後のデータを取得</span></span>
<span id="cb9-5">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb9-6"></span>
<span id="cb9-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 指定された期間でデータをフィルタリング</span></span>
<span id="cb9-8">    filtered_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[</span>
<span id="cb9-9">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb9-10">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> pd.Timestamp(end_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb9-11">    ].copy()</span>
<span id="cb9-12"></span>
<span id="cb9-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> filtered_data.empty:</span>
<span id="cb9-14">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"No data available to plot between </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> and </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span>
<span id="cb9-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb9-16"></span>
<span id="cb9-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日またぎを考慮した時間の計算</span></span>
<span id="cb9-18">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> dt: dt.hour <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> dt.minute)</span>
<span id="cb9-19">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb9-20">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> row: adjust_end_time(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).seconds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>), axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb9-21"></span>
<span id="cb9-22">    color_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb9-23">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 覚醒（睡眠サイクル中）</span></span>
<span id="cb9-24">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#b3e5fc'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠</span></span>
<span id="cb9-25">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ベッド外</span></span>
<span id="cb9-26">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 浅い睡眠</span></span>
<span id="cb9-27">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠</span></span>
<span id="cb9-28">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>,   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レム睡眠</span></span>
<span id="cb9-29">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'black'</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイム（色を強調）</span></span>
<span id="cb9-30">    }</span>
<span id="cb9-31">    sleep_stage_labels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb9-32">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'覚醒（睡眠サイクル中）'</span>,</span>
<span id="cb9-33">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'睡眠'</span>,</span>
<span id="cb9-34">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ベッド外'</span>,</span>
<span id="cb9-35">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'浅い睡眠'</span>,</span>
<span id="cb9-36">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'深い睡眠'</span>,</span>
<span id="cb9-37">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'レム睡眠'</span>,</span>
<span id="cb9-38">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ミッドスリープタイム'</span></span>
<span id="cb9-39">    }</span>
<span id="cb9-40">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">map</span>(color_map)</span>
<span id="cb9-41"></span>
<span id="cb9-42">    num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, (pd.Timestamp(end_date) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date)).days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb9-43">    fig <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> go.Figure()</span>
<span id="cb9-44"></span>
<span id="cb9-45">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sleep_state, color <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> color_map.items():</span>
<span id="cb9-46">        sleep_state_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> sleep_state]</span>
<span id="cb9-47">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> sleep_state_data.empty:</span>
<span id="cb9-48">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_state_data.iterrows():</span>
<span id="cb9-49">                day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)).days</span>
<span id="cb9-50">                line_width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.5</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムの場合は線の太さを15に設定</span></span>
<span id="cb9-51">                y_offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムの場合はy座標をさらにオフセット</span></span>
<span id="cb9-52">                opacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイム以外は透明度を0.3に設定</span></span>
<span id="cb9-53">                fig.add_trace(go.Scatter(</span>
<span id="cb9-54">                    x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>]],</span>
<span id="cb9-55">                    y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset],</span>
<span id="cb9-56">                    mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lines'</span>,</span>
<span id="cb9-57">                    line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>line_width),</span>
<span id="cb9-58">                    name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>sleep_stage_labels[sleep_state],</span>
<span id="cb9-59">                    text<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>,</span>
<span id="cb9-60">                    hoverinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>,</span>
<span id="cb9-61">                    opacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>opacity</span>
<span id="cb9-62">                ))</span>
<span id="cb9-63">                fig.add_trace(go.Scatter(</span>
<span id="cb9-64">                    x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>, row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>],</span>
<span id="cb9-65">                    y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset],</span>
<span id="cb9-66">                    mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lines'</span>,</span>
<span id="cb9-67">                    line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>line_width),</span>
<span id="cb9-68">                    name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>sleep_stage_labels[sleep_state],</span>
<span id="cb9-69">                    text<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>,</span>
<span id="cb9-70">                    hoverinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>,</span>
<span id="cb9-71">                    opacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>opacity</span>
<span id="cb9-72">                ))</span>
<span id="cb9-73"></span>
<span id="cb9-74">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 凡例を統合</span></span>
<span id="cb9-75">    unique_labels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>()</span>
<span id="cb9-76">    fig.for_each_trace(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> trace: trace.update(showlegend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> trace.name <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> unique_labels <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> unique_labels.add(trace.name))</span>
<span id="cb9-77"></span>
<span id="cb9-78">    fig.update_layout(</span>
<span id="cb9-79">        title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Interactive Actogram from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>,</span>
<span id="cb9-80">        xaxis_title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time'</span>,</span>
<span id="cb9-81">        yaxis_title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Days from Start Date'</span>,</span>
<span id="cb9-82">        xaxis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb9-83">            tickmode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'array'</span>,</span>
<span id="cb9-84">            tickvals<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)],</span>
<span id="cb9-85">            ticktext<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>(i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:02d}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">:00'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)],</span>
<span id="cb9-86">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2880</span>]</span>
<span id="cb9-87">        ),</span>
<span id="cb9-88">        yaxis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb9-89">            tickvals<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)),</span>
<span id="cb9-90">            ticktext<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[(pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x)).strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)],</span>
<span id="cb9-91">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, num_days],</span>
<span id="cb9-92">            tickfont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Y軸ラベルの文字サイズを小さく</span></span>
<span id="cb9-93">        ),</span>
<span id="cb9-94">        hovermode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'closest'</span>,</span>
<span id="cb9-95">        legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb9-96">            itemsizing<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'constant'</span></span>
<span id="cb9-97">        )</span>
<span id="cb9-98">    )</span>
<span id="cb9-99"></span>
<span id="cb9-100">    pio.write_html(fig, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_data_plot.html'</span>, auto_open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb9-101"></span>
<span id="cb9-102"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの作成</span></span>
<span id="cb9-103">start_date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.DatePicker(</span>
<span id="cb9-104">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Start Date'</span>,</span>
<span id="cb9-105">    disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb9-106">)</span>
<span id="cb9-107">end_date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.DatePicker(</span>
<span id="cb9-108">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'End Date'</span>,</span>
<span id="cb9-109">    disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb9-110">)</span>
<span id="cb9-111">interactive_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(</span>
<span id="cb9-112">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Plot Interactive Actogram'</span>,</span>
<span id="cb9-113">    button_style<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'info'</span>,</span>
<span id="cb9-114">    tooltip<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Click to plot the interactive actogram'</span>,</span>
<span id="cb9-115">    icon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'line-chart'</span></span>
<span id="cb9-116">)</span>
<span id="cb9-117">notice_label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(</span>
<span id="cb9-118">    value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'データ範囲は四半期(3ヶ月)程度にしてください。それ以上の期間を指定すると文字が潰れて読めなくなります。また、グラフの作成には少し時間がかかります。'</span></span>
<span id="cb9-119">)</span>
<span id="cb9-120"></span>
<span id="cb9-121"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ボタンがクリックされたときの動作</span></span>
<span id="cb9-122"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_button_clicked(b):</span>
<span id="cb9-123">    start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start_date_picker.value</span>
<span id="cb9-124">    end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_date_picker.value</span>
<span id="cb9-125">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> start_date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> end_date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb9-126">        plot_interactive_actogram(sleep_data, start_date, end_date)</span>
<span id="cb9-127">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb9-128">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Please select both start and end dates."</span>)</span>
<span id="cb9-129"></span>
<span id="cb9-130">interactive_button.on_click(on_button_clicked)</span>
<span id="cb9-131"></span>
<span id="cb9-132"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの表示</span></span>
<span id="cb9-133">display(notice_label, start_date_picker, end_date_picker, interactive_button)</span></code></pre></div>
</div>
</section>
<section id="睡眠の統計分析" class="level5">
<h5 class="anchored" data-anchor-id="睡眠の統計分析">3-2-2-6. 睡眠の統計分析</h5>
<p>以下のセルでは、</p>
<ol type="1">
<li>四半期ごとの睡眠時間及び睡眠の質の推移の可視化(折れ線グラフ)
<ul>
<li>1枚</li>
</ul></li>
<li>四半期の範囲で曜日別の睡眠時間及び睡眠の質の可視化(箱ひげ図)
<ul>
<li>1年につき4枚 を行います。</li>
</ul></li>
</ol>
<p>含まれているデータ期間が長い場合は、全部のグラフが出力されるまで時間がかかります。 そのため、実行せず次のセルに進んでも構いません。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>睡眠の統計</strong></pre>
</div>
<div class="sourceCode" id="cb10" data-filename="睡眠の統計" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_sleep_quality(sleep_data):</span>
<span id="cb10-3">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各セッションの睡眠時間を計算</span></span>
<span id="cb10-4">    session_start_end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).agg(</span>
<span id="cb10-5">        start_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>),</span>
<span id="cb10-6">        end_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'max'</span>)</span>
<span id="cb10-7">    ).reset_index()</span>
<span id="cb10-8">    session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).dt.total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span></span>
<span id="cb10-9">    </span>
<span id="cb10-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠の割合を計算</span></span>
<span id="cb10-11">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).dt.total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span></span>
<span id="cb10-12">    deep_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠</span></span>
<span id="cb10-13">    deep_sleep_duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> deep_sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>().reset_index()</span>
<span id="cb10-14">    </span>
<span id="cb10-15">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 列名を変更</span></span>
<span id="cb10-16">    deep_sleep_duration.rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_deep'</span>}, inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb10-17">    </span>
<span id="cb10-18">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(session_start_end, deep_sleep_duration, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, how<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'left'</span>)</span>
<span id="cb10-19">    sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_deep'</span>].fillna(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>]</span>
<span id="cb10-20">    </span>
<span id="cb10-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sleep_quality[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>]]</span>
<span id="cb10-22"></span>
<span id="cb10-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_quarterly_sleep_stats(sleep_data):</span>
<span id="cb10-24">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data)</span>
<span id="cb10-25">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb10-26">    </span>
<span id="cb10-27">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb10-28">    quarterly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>).agg(</span>
<span id="cb10-29">        avg_sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>),</span>
<span id="cb10-30">        avg_sleep_quality<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>)</span>
<span id="cb10-31">    ).reset_index()</span>
<span id="cb10-32">    </span>
<span id="cb10-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> quarterly_stats</span>
<span id="cb10-34"></span>
<span id="cb10-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_quarterly_sleep_stats(quarterly_stats):</span>
<span id="cb10-36">    fig, ax1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb10-37"></span>
<span id="cb10-38">    ax1.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Quarter'</span>)</span>
<span id="cb10-39">    ax1.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average Sleep Time (hours)'</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>)</span>
<span id="cb10-40">    ax1.plot(quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>), quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'avg_sleep_time'</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>, marker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'o'</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Avg Sleep Time'</span>)</span>
<span id="cb10-41">    ax1.tick_params(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span>, labelcolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>)</span>
<span id="cb10-42"></span>
<span id="cb10-43">    ax2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ax1.twinx()</span>
<span id="cb10-44">    ax2.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average Sleep Quality'</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>)</span>
<span id="cb10-45">    ax2.plot(quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>), quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'avg_sleep_quality'</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>, marker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'o'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Avg Sleep Quality'</span>)</span>
<span id="cb10-46">    ax2.tick_params(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span>, labelcolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>)</span>
<span id="cb10-47"></span>
<span id="cb10-48">    fig.tight_layout()</span>
<span id="cb10-49">    fig.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'upper left'</span>, bbox_to_anchor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9</span>))</span>
<span id="cb10-50">    plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Quarterly Average Sleep Time and Quality'</span>)</span>
<span id="cb10-51">    plt.show()</span>
<span id="cb10-52"></span>
<span id="cb10-53"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_weekly_sleep_stats(sleep_data):</span>
<span id="cb10-54">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data)</span>
<span id="cb10-55">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb10-56">    </span>
<span id="cb10-57">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb10-58">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.day_name()</span>
<span id="cb10-59">    weekly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>]).agg(</span>
<span id="cb10-60">        avg_sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>),</span>
<span id="cb10-61">        avg_sleep_quality<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>)</span>
<span id="cb10-62">    ).reset_index()</span>
<span id="cb10-63">    </span>
<span id="cb10-64">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> weekly_stats</span>
<span id="cb10-65"></span>
<span id="cb10-66"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_weekly_sleep_stats_boxplot(sleep_data_jst):</span>
<span id="cb10-67">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data_jst)</span>
<span id="cb10-68">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data_jst, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb10-69">    </span>
<span id="cb10-70">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb10-71">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.day_name()</span>
<span id="cb10-72">    weekdays <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Monday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tuesday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Wednesday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Thursday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Friday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Saturday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sunday'</span>]</span>
<span id="cb10-73">    weekday_colors <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e74c3c'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e74c3c'</span>]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 平日は青、土日は赤</span></span>
<span id="cb10-74">    weekday_palette <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(weekdays, weekday_colors))</span>
<span id="cb10-75"></span>
<span id="cb10-76">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> quarter <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].unique():</span>
<span id="cb10-77">        quarter_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> quarter]</span>
<span id="cb10-78">        </span>
<span id="cb10-79">        fig, (ax1, ax2) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>))</span>
<span id="cb10-80">        </span>
<span id="cb10-81">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠時間の箱ひげ図</span></span>
<span id="cb10-82">        sns.boxplot(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>quarter_data, order<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekdays, palette<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekday_palette, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax1, hue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, dodge<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb10-83">        ax1.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Weekly Sleep Duration for </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>quarter<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb10-84">        ax1.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Weekday'</span>)</span>
<span id="cb10-85">        ax1.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sleep Duration (hours)'</span>)</span>
<span id="cb10-86">        ax1.legend([],[], frameon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レジェンドを非表示にする</span></span>
<span id="cb10-87"></span>
<span id="cb10-88">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠の質の箱ひげ図</span></span>
<span id="cb10-89">        sns.boxplot(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>quarter_data, order<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekdays, palette<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekday_palette, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax2, hue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, dodge<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb10-90">        ax2.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Weekly Sleep Quality for </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>quarter<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb10-91">        ax2.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Weekday'</span>)</span>
<span id="cb10-92">        ax2.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sleep Quality'</span>)</span>
<span id="cb10-93">        ax2.legend([],[], frameon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レジェンドを非表示にする</span></span>
<span id="cb10-94">        </span>
<span id="cb10-95">        plt.tight_layout()</span>
<span id="cb10-96">        plt.show()</span>
<span id="cb10-97"></span>
<span id="cb10-98"></span>
<span id="cb10-99"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データの準備</span></span>
<span id="cb10-100">sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb10-101"></span>
<span id="cb10-102"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期ごとの統計を計算</span></span>
<span id="cb10-103">quarterly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_quarterly_sleep_stats(sleep_data_jst)</span>
<span id="cb10-104"></span>
<span id="cb10-105"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結果をプロット</span></span>
<span id="cb10-106">plot_quarterly_sleep_stats(quarterly_stats)</span>
<span id="cb10-107"></span>
<span id="cb10-108"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 曜日別の統計を計算</span></span>
<span id="cb10-109">weekly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_weekly_sleep_stats(sleep_data_jst)</span>
<span id="cb10-110"></span>
<span id="cb10-111"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結果を箱ひげ図でプロット</span></span>
<span id="cb10-112">plot_weekly_sleep_stats_boxplot(sleep_data_jst)</span></code></pre></div>
</div>
</section>
<section id="任意の日付の睡眠記録の可視化" class="level5">
<h5 class="anchored" data-anchor-id="任意の日付の睡眠記録の可視化">3-2-2-7. 任意の日付の睡眠記録の可視化</h5>
<p>以下のセルを実行することで、ユーザーが指定した日付の睡眠セッション分析し、睡眠ステージの推移をグラフに表示することができます。</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>任意の日付の睡眠記録の可視化</strong></pre>
</div>
<div class="sourceCode" id="cb11" data-filename="任意の日付の睡眠記録の可視化" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_to_jst_if_needed(column):</span>
<span id="cb11-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報を確認し、必要に応じて変換を行う</span></span>
<span id="cb11-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> column.dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb11-4">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報がない場合、UTCとして解釈し、JSTに変換</span></span>
<span id="cb11-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.to_datetime(column, utc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>:</span>
<span id="cb11-7">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがUTCであれば、JSTに変換</span></span>
<span id="cb11-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>:</span>
<span id="cb11-10">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがJSTでない他のタイムゾーンであれば、JSTに変換</span></span>
<span id="cb11-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-13">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 既にJSTであればそのまま返す</span></span>
<span id="cb11-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column</span>
<span id="cb11-15"></span>
<span id="cb11-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_sleep_data_to_jst(sleep_data):</span>
<span id="cb11-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_dataをコピーしてタイムゾーンを変換</span></span>
<span id="cb11-18">    sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.copy()</span>
<span id="cb11-19">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb11-20">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>])</span>
<span id="cb11-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_data.columns:</span>
<span id="cb11-22">        sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>])</span>
<span id="cb11-23">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-24">        sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb11-25">        </span>
<span id="cb11-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 明示的に datetime64[ns, Asia/Tokyo] にキャスト</span></span>
<span id="cb11-27">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb11-28">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb11-29">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb11-30">    </span>
<span id="cb11-31">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sleep_data_jst</span>
<span id="cb11-32"></span>
<span id="cb11-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_session_data(sleep_data_jst):</span>
<span id="cb11-34">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各セッションの最終 'end_time' を取得して日付に変換</span></span>
<span id="cb11-35">    session_dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().dt.date</span>
<span id="cb11-36">    session_dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_dates.reset_index()</span>
<span id="cb11-37">    session_dates.rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_date'</span>}, inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb11-38">    </span>
<span id="cb11-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠時間と睡眠潜時の計算</span></span>
<span id="cb11-40">    sleep_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).agg(</span>
<span id="cb11-41">        sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> x: (x.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>()).total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span>),</span>
<span id="cb11-42">        start_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>)</span>
<span id="cb11-43">    )</span>
<span id="cb11-44">    sleep_times.reset_index(inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb11-45"></span>
<span id="cb11-46">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠潜時の計算</span></span>
<span id="cb11-47">    sleep_latency <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb11-48">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> group: calculate_sleep_latency(group[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>]]),</span>
<span id="cb11-49">        include_groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 追加: グループ化列を適用操作から除外</span></span>
<span id="cb11-50">    ).reset_index(name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>)</span>
<span id="cb11-51"></span>
<span id="cb11-52">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結合して全データを含むデータフレームを作成</span></span>
<span id="cb11-53">    full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(session_dates, sleep_times[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_time'</span>]], on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb11-54">    full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(full_session_data, sleep_latency, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb11-55">    </span>
<span id="cb11-56">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> full_session_data</span>
<span id="cb11-57"></span>
<span id="cb11-58"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_sleep_latency(group):</span>
<span id="cb11-59">    group <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> group.sort_values(by<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>)</span>
<span id="cb11-60">    auto_sleep_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> group[(group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Auto'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>)]</span>
<span id="cb11-61">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> auto_sleep_times.empty:</span>
<span id="cb11-62">        auto_sleep_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auto_sleep_times[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb11-63">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pd.notna(group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]:</span>
<span id="cb11-64">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (auto_sleep_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]).total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span></span>
<span id="cb11-65">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.nan</span>
<span id="cb11-66"></span>
<span id="cb11-67">sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb11-68">full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> create_session_data(sleep_data_jst)</span>
<span id="cb11-69"></span>
<span id="cb11-70"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日付選択ウィジェット</span></span>
<span id="cb11-71">date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> DatePicker(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Select Date'</span>, disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb11-72"></span>
<span id="cb11-73"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_prev_clicked(b):</span>
<span id="cb11-74">    date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date_picker.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb11-75"></span>
<span id="cb11-76"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_next_clicked(b):</span>
<span id="cb11-77">    date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date_picker.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb11-78"></span>
<span id="cb11-79">button_prev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Previous Day"</span>)</span>
<span id="cb11-80">button_next <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Next Day"</span>)</span>
<span id="cb11-81">button_prev.on_click(on_prev_clicked)</span>
<span id="cb11-82">button_next.on_click(on_next_clicked)</span>
<span id="cb11-83"></span>
<span id="cb11-84">display(HBox([button_prev, button_next]))</span>
<span id="cb11-85">display(date_picker)</span>
<span id="cb11-86"></span>
<span id="cb11-87"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンを確認して適切に日付を表示する関数</span></span>
<span id="cb11-88"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> set_plot_title(ax, session_id, sleep_data_jst):</span>
<span id="cb11-89">    jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pytz.timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-90"></span>
<span id="cb11-91">    session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb11-92">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> session_data.empty:</span>
<span id="cb11-93">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz:</span>
<span id="cb11-94">            start_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().astimezone(jst)</span>
<span id="cb11-95">            end_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().astimezone(jst)</span>
<span id="cb11-96">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-97">            start_time_utc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().replace(tzinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>pytz.utc)</span>
<span id="cb11-98">            end_time_utc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().replace(tzinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>pytz.utc)</span>
<span id="cb11-99">            start_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start_time_utc.astimezone(jst)</span>
<span id="cb11-100">            end_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_time_utc.astimezone(jst)</span>
<span id="cb11-101"></span>
<span id="cb11-102">        title <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Sleep Session from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_time_jst<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_time_jst<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb11-103">        ax.set_title(title)</span>
<span id="cb11-104">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-105">        ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No data available for this session"</span>)</span>
<span id="cb11-106"></span>
<span id="cb11-107"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># キャプションを追加する関数</span></span>
<span id="cb11-108"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_caption(ax, session_id, full_session_data):</span>
<span id="cb11-109">    record <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> full_session_data[full_session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb11-110">    </span>
<span id="cb11-111">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># キャプションの初期部分</span></span>
<span id="cb11-112">    caption <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"睡眠時間: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> 時間</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb11-113">    </span>
<span id="cb11-114">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_latencyがNaNやマイナスでない場合のみ追加</span></span>
<span id="cb11-115">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pd.notna(record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>]) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb11-116">        caption <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"睡眠潜時(布団に入ってから寝付くまでの時間): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> 分"</span></span>
<span id="cb11-117">    </span>
<span id="cb11-118">    ax.text(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.95</span>, caption, transform<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax.transAxes, fontsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, verticalalignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'top'</span>)</span>
<span id="cb11-119"></span>
<span id="cb11-120"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠データをプロットする関数</span></span>
<span id="cb11-121"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_sleep_data(session_id, sleep_data_jst, full_session_data):</span>
<span id="cb11-122">    session_info <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> full_session_data[full_session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb11-123">    session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb11-124"></span>
<span id="cb11-125">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> session_data.empty:</span>
<span id="cb11-126">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日時データのタイムゾーンを確認し、日本時間に設定</span></span>
<span id="cb11-127">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb11-128">            session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-129">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb11-130">            session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].dt.tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb11-131"></span>
<span id="cb11-132">        fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>))</span>
<span id="cb11-133">        stage_height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>}</span>
<span id="cb11-134">        stage_colors <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>:<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'yellow'</span>}</span>
<span id="cb11-135">        data_sources <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>].unique()</span>
<span id="cb11-136">        source_count <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(data_sources)</span>
<span id="cb11-137">        alpha_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> source_count <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> source_count <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb11-138"></span>
<span id="cb11-139">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># プロットの時間を日本時間に合わせて設定</span></span>
<span id="cb11-140">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> index, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> session_data.iterrows():</span>
<span id="cb11-141">            start_pos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mdates.date2num(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb11-142">            duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mdates.date2num(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start_pos</span>
<span id="cb11-143">            ax.bar(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>start_pos, height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>stage_height[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>]], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>duration,</span>
<span id="cb11-144">                   color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>stage_colors.get(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#FFFFFF'</span>), edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'black'</span>,</span>
<span id="cb11-145">                   align<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'edge'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alpha_value)</span>
<span id="cb11-146"></span>
<span id="cb11-147">        ax.xaxis_date(tz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb11-148">        ax.xaxis.set_major_locator(mdates.HourLocator(interval<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb11-149">        ax.xaxis.set_major_formatter(mdates.DateFormatter(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%H:%M'</span>, tz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)))</span>
<span id="cb11-150">        ax.set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>)</span>
<span id="cb11-151">        ax.set_yticks([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>])</span>
<span id="cb11-152">        ax.set_yticklabels([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Deep Sleep'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'REM'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Light Sleep'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Awake'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Out-of-bed'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Mid Sleep Time'</span>])</span>
<span id="cb11-153">        ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time of Day'</span>)</span>
<span id="cb11-154">        set_plot_title(ax, session_id, sleep_data_jst)</span>
<span id="cb11-155">        add_caption(ax, session_id, session_info)</span>
<span id="cb11-156">        plt.tight_layout()</span>
<span id="cb11-157">        plt.show()</span>
<span id="cb11-158">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-159">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No sleep data available for this session."</span>)</span>
<span id="cb11-160"></span>
<span id="cb11-161"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日付変更時のイベントハンドラ</span></span>
<span id="cb11-162"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_date_change(change):</span>
<span id="cb11-163">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb11-164">        selected_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>]).date()</span>
<span id="cb11-165">        session_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">next</span>((sid <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sid, date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> full_session_data.set_index(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_date'</span>].items() <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> selected_date), <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>)</span>
<span id="cb11-166">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb11-167">            plot_sleep_data(session_id, sleep_data_jst, full_session_data)</span>
<span id="cb11-168">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb11-169">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No sessions found for this date."</span>)</span>
<span id="cb11-170"></span>
<span id="cb11-171">date_picker.observe(on_date_change, names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>)</span></code></pre></div>
</div>
</section>
</section>
</section>
</section>
<section id="課題と展望" class="level2">
<h2 class="anchored" data-anchor-id="課題と展望">4. 課題と展望</h2>
<p>複数デバイスからのデータを元に可視化や統計を行う際、現状ではそれぞれのデータを等価であると仮定していますが、実際には精度の低いデータセット(デバイス)が存在しています。</p>
<p>データの読み込みはユーザーに任せているので、そもそも精度の低いデータは読み込まなければいいだけの話なのですが、可視化してみて初めて精度の低さに気付くということもあるかと思います。せっかくモジュール式の仕組みを採用しているのだから、最初の可視化で得た気付き(このデバイスはダメそうといった判断)をフィードバックできればいいなぁと考えています。</p>
<p>もう1つ大きな課題として、特定の日の睡眠サイクルを可視化する際に、昼寝が可視化できないというのがあります。アクトグラムを使った睡眠リズムの可視化の際には昼寝がちゃんと可視化されているのに、その詳細は分からないというのは超ベリーバッドです。なんとかしたいです。</p>
<p>今後の展望としては、上記の課題の他に、英語と日本以外のタイムゾーンへの対応, 統計及びその可視化の見直し, ミッドスリープタイムの(アクトグラム以外の)可視化などを考えています。 また、睡眠に関する論文を漁り、何を可視化しどのように分析をすべきかをちゃんと勉強したいです。</p>
<section id="課題" class="level3">
<h3 class="anchored" data-anchor-id="課題">4-1. 課題</h3>
<ul>
<li>統計や可視化の際に、対象とするデータセットを選べない
<ul>
<li>チェックボックス等で使用するデータセットを選べるようにする</li>
</ul></li>
<li>特定の日付の睡眠サイクルを可視化する際に、昼寝が可視化されない
<ul>
<li>メインの睡眠に昼寝を統合してしまうとスケールが狂うので、現在の日付単位でのセレクト(<code>前日</code>・<code>翌日</code>)から、睡眠単位のセレクト(<code>前の睡眠</code>・<code>次の睡眠</code>)へと切り替える</li>
</ul></li>
<li>特定の日付の睡眠サイクルを可視化する際に、睡眠データが存在しない日も選択画面(カレンダー)に表示されてしまう
<ul>
<li>睡眠データが存在しない日をカレンダーに表示しない・もしくは選べないようにする</li>
</ul></li>
<li>任意の期間のアクトグラムを表示する際に、ミッドスリープタイムが1回の睡眠で2回以上表示されることがある
<ul>
<li>原因を詳しく調査し、ミッドスリープタイムの算出方法がおかしいのか、表示方法がおかしいのか、確かめ改善する</li>
</ul></li>
<li>ユーザーのタイムゾーンが日本時間であると仮定し分析や可視化を行っており、ユーザーがタイムゾーンを選べない(日本時間を強制している)
<ul>
<li>タイムゾーンの変換スクリプトを見直し、決め打ちではなくユーザーが選べるようにする
<ul>
<li>なんなら、現在、タイムゾーンの変換時をそれぞれの可視化関数で行っているのでこれをどうにかしたい</li>
<li>タイムゾーンの変換も様々な書き方で行っているため、置換が効かない</li>
</ul></li>
</ul></li>
</ul>
</section>
<section id="展望" class="level3">
<h3 class="anchored" data-anchor-id="展望">4-2. 展望</h3>
<ul>
<li>英語への対応</li>
<li>任意のタイムゾーンを選べるようにする</li>
<li>統計方法の見直し</li>
<li>可視化手法の見直し</li>
<li>ミッドスリープタイムの可視化</li>
<li>Health Connect APIへの対応</li>
</ul>
</section>
</section>
<section id="感想" class="level2">
<h2 class="anchored" data-anchor-id="感想">5. 感想</h2>
<ul>
<li>疲れました。</li>
<li>PythonもJupyter Notebookも初心者かつ苦手意識がある中でなんとか世に公開できるものが出来たのは、ChatGPT-4(及び途中からGPT-4o)とClaude 3 Opusのおかげです。メインはGPT-4oでしたが、スクリプトのエラーが解決しない時はGPT-4に切り替えて、それでも解決しない時はClaude 3 Opusを使いました。Claude 3 Opusの方が解決力が高いようで、今のところClaude 3 Opusで解決できずにChatGPT-4系が解決できたという問題はありませんでした。</li>
<li>ChatGPT-4とやりとりしているうちに、どんな関数があれば良くて、引数は多分こんな感じで戻り値に何が欲しくてといった仕様が見えてきたので、それをまるっと伝えるといい感じに書いてくれたのが良かったです。</li>
<li>とりあえず、最初に要望を伝え企画書・仕様書を作らせ、それを元に雛形を作ってもらい、自分で必要な関数を考え、それを書いてもらうという流れでやればいいという発見を得たのが収穫でした。</li>
<li>恥ずかしながら、Git(及びGitHub)に対する知識がなく、バージョン管理がめちゃくちゃになってしまいました。ちゃんと勉強したいと思いました。</li>
<li>4月25日にこのプロジェクトを立ち上げ、Jupyter Notebookを完成させるまでに73時間, この記事を書いたり(論文漁ったり)GitHubに公開する準備をしたりするのに20時間くらいかかりました。4月から正真正銘のニートになったので、時間はいくらでもあったとは言え、ちょっとかけすぎたと感じています。あと右手の小指とその筋がとても痛くなりました。多分腱鞘炎です。</li>
<li>抗うつ薬が切れた後は起きていたくないので、18時くらいに就寝をして7時くらいに起きるという限界生活をしているのですが、それを図&nbsp;8や図&nbsp;9で晒すことになってしまい読者の方にドン引かれてないか心配です。そもそも読者がいるのか怪しいですが。</li>
<li>疲れました。</li>
</ul>
</section>
<section id="付録" class="level2">
<h2 class="anchored" data-anchor-id="付録">6. 付録</h2>
<p>以下に、Jupyter Notebook(.ipynb)ファイルを貼ります。</p>
<hr>
<section id="sleep-analyze-jupyter-notebook" class="level3 quarto-embed-nb-cell">
<h3 class="anchored" data-anchor-id="sleep-analyze-jupyter-notebook">Sleep Analyze Jupyter Notebook</h3>
<p>このスクリプトは<a href="https://github.com/Pottal/Sleep_Analyze">GitHub</a>からダウンロードできます。</p>
<section id="はじめに" class="level4">
<h4 class="anchored" data-anchor-id="はじめに">はじめに</h4>
<ul>
<li>このノートブックでは、Google Fitのデータを元に睡眠データを分析します</li>
<li><a href="https://takeout.google.com/">Google Fitからデータをダウンロード</a>してください
<ul>
<li>Google Fitからデータをダウンロードする方法が分からない方は<a href="https://github.com/Pottal/Sleep_Analyze/blob/main/How_to_Download_Sleep_data_from_GoogleFit.md">以下のドキュメント(Google Fitからデータをダウンロードする方法)</a>をご覧ください。</li>
</ul></li>
<li>このノートブックは、筆者のような<strong>複数のデバイスを使って</strong>睡眠記録をつけている方でも問題なく分析が行えます</li>
<li>セルは<strong>一括で実行せず、1つずつ実行してください</strong></li>
</ul>
</section>
<section id="データ分析の流れ-1" class="level4">
<h4 class="anchored" data-anchor-id="データ分析の流れ-1">データ分析の流れ</h4>
<ol type="1">
<li><p>モジュールのインポート</p></li>
<li><p>データの取り込み</p></li>
<li><p>(手動の睡眠記録がある場合)データセットの選択</p></li>
<li><p>(必要であれば)データをCSVファイルとしてエクスポート</p></li>
<li><p>アクトグラムを用いた四半期ごとの睡眠記録の可視化</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/Sample_Actogram.png?raw=true" width="320px" alt="Access Google data export and deselect All"></p></li>
<li><p>四半期ごとの統計</p></li>
<li><p>任意の日付の睡眠記録の可視化</p>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/Sample_Sleep_cycle.png?raw=true" width="320px" alt="Access Google data export and deselect All"></p></li>
</ol>
<div id="cell-1" class="cell">
<div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> subprocess</span>
<span id="cb12-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> sys</span>
<span id="cb12-3"></span>
<span id="cb12-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 必要なライブラリをリストにまとめる</span></span>
<span id="cb12-5">required_libraries <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [</span>
<span id="cb12-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'json'</span>,</span>
<span id="cb12-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'pandas'</span>,</span>
<span id="cb12-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'matplotlib'</span>,</span>
<span id="cb12-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'pytz'</span>,</span>
<span id="cb12-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ipywidgets'</span>,</span>
<span id="cb12-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'numpy'</span>,</span>
<span id="cb12-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'seaborn'</span>,</span>
<span id="cb12-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ipyfilechooser'</span>,</span>
<span id="cb12-14">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'plotly'</span></span>
<span id="cb12-15">]</span>
<span id="cb12-16"></span>
<span id="cb12-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ライブラリのインストール関数</span></span>
<span id="cb12-18"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> install_and_import(library):</span>
<span id="cb12-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="cb12-20">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__import__</span>(library)</span>
<span id="cb12-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">ImportError</span>:</span>
<span id="cb12-22">        subprocess.check_call([sys.executable, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"-m"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"pip"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"install"</span>, library])</span>
<span id="cb12-23">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__import__</span>(library)</span>
<span id="cb12-24"></span>
<span id="cb12-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各ライブラリのインストールとインポート</span></span>
<span id="cb12-26"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> library <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> required_libraries:</span>
<span id="cb12-27">    install_and_import(library)</span>
<span id="cb12-28"></span>
<span id="cb12-29"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># インポート文</span></span>
<span id="cb12-30"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> json</span>
<span id="cb12-31"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb12-32"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> os</span>
<span id="cb12-33"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.pyplot <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> plt</span>
<span id="cb12-34">plt.rcParams[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'font.family'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Yu Mincho'</span>, <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#'Hiragino Kaku Gothic ProN', #'Meiryo', #'Noto Sans CJK JP'</span></span>
<span id="cb12-35"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> matplotlib.dates <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> mdates</span>
<span id="cb12-36"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pytz</span>
<span id="cb12-37"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ipywidgets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> widgets</span>
<span id="cb12-38"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> numpy <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> np</span>
<span id="cb12-39"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> seaborn <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> sns</span>
<span id="cb12-40"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.graph_objects <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> go</span>
<span id="cb12-41"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.express <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> px</span>
<span id="cb12-42"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> plotly.io <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pio</span>
<span id="cb12-43"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> ipywidgets <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> DatePicker, Button, HBox</span>
<span id="cb12-44"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> matplotlib.lines <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Line2D</span>
<span id="cb12-45"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> pytz <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> timezone</span>
<span id="cb12-46"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> IPython.display <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> display, clear_output</span>
<span id="cb12-47"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> ipyfilechooser <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> FileChooser</span>
<span id="cb12-48"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> datetime <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> datetime</span>
<span id="cb12-49"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> datetime <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> timedelta</span>
<span id="cb12-50"></span>
<span id="cb12-51"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"All libraries are installed and imported successfully."</span>)</span></code></pre></div>
</div>
</section>
<section id="睡眠データの選択" class="level4">
<h4 class="anchored" data-anchor-id="睡眠データの選択">睡眠データの選択</h4>
<ol type="1">
<li><p>GoogleからダウンロードしたZipファイルを解凍します。</p>
<ul>
<li><code>takeout-YYYYMMDDxxxxxx.zip</code> のような名前のZipファイルです</li>
</ul></li>
<li><p><code>Takeout</code>&gt; <code>Fit</code> &gt; <code>すべてのデータ</code> の中に<code>raw_com.google.sleep.segment</code>という文字列を含むJSONファイルがあるはずなので、それらをすべて任意のフォルダーにコピーします。</p>
<ul>
<li><code>raw_com.google.sleep.segment</code>をフォルダ内検索すると便利です</li>
</ul>
<p><img src="https://github.com/Pottal/Sleep_Analyze/blob/main/How_to_find_sleep_data.png?raw=true" width="850px" alt="How to find your sleep data"></p></li>
<li><p>任意のフォルダーにある、<strong>全ての睡眠データ</strong>(<code>raw_com.google.sleep.segment</code>)を以下のセルで読み込みます。</p>
<ul>
<li>あるいは直接、解凍したtakeoutファイルから、<code>Takeout</code>&gt; <code>Fit</code> &gt; <code>すべてのデータ</code>と進み、<code>raw_com.google.sleep.segment</code>という文字列を含むJSONファイルを選択します(フォルダ内検索を推奨します)</li>
</ul></li>
</ol>
<div id="cell-3" class="cell">
<div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイルアップロードウィジェットの作成</span></span>
<span id="cb13-2">uploader <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.FileUpload(</span>
<span id="cb13-3">    accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.json'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># JSONファイルのみを許可</span></span>
<span id="cb13-4">    multiple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>,   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 複数のファイルをアップロード可能</span></span>
<span id="cb13-5">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Upload JSON files'</span></span>
<span id="cb13-6">)</span>
<span id="cb13-7"></span>
<span id="cb13-8">file_loading_flag <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb13-9"></span>
<span id="cb13-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードされたデータを処理する関数</span></span>
<span id="cb13-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> process_uploaded_files(change):</span>
<span id="cb13-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">global</span> file_loading_flag</span>
<span id="cb13-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 処理中メッセージを表示</span></span>
<span id="cb13-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb13-15">        clear_output()</span>
<span id="cb13-16">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの処理中です。次のセルには進まないでください。"</span>)</span>
<span id="cb13-17">        sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb13-18"></span>
<span id="cb13-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span>:</span>
<span id="cb13-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> file_info <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>]:</span>
<span id="cb13-21">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Processing </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>file_info[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb13-22">            sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb13-23">            content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_info[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'content'</span>]</span>
<span id="cb13-24">            import_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json.loads(content.tobytes().decode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb13-25">            df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_and_process_sleep_data(import_data, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type of Sleep'</span>)</span>
<span id="cb13-26">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの読み込みが完了しました。次のセルに進んでください"</span>)</span>
<span id="cb13-27">        file_loading_flag <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb13-28"></span>
<span id="cb13-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb13-30">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> file_loading_flag <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>:</span>
<span id="cb13-31">                clear_output()</span>
<span id="cb13-32">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの読み込みが完了しました。次のセルに進んでください。"</span>)</span>
<span id="cb13-33">                sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb13-34"></span>
<span id="cb13-35">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">except</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">Exception</span> <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> e:</span>
<span id="cb13-36">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb13-37">            clear_output()</span>
<span id="cb13-38">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"エラーが発生しました: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>e<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb13-39">            sys.stdout.flush()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力を即座にフラッシュ</span></span>
<span id="cb13-40"></span>
<span id="cb13-41"></span>
<span id="cb13-42"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># JSONデータをDataFrameに変換するための関数</span></span>
<span id="cb13-43"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> load_and_process_sleep_data(import_data, type_value):</span>
<span id="cb13-44">    data_source <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> import_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Data Source'</span>]</span>
<span id="cb13-45">    data_points <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> import_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Data Points'</span>]</span>
<span id="cb13-46">    df <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame([{</span>
<span id="cb13-47">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>: data_source,</span>
<span id="cb13-48">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time_ns'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'startTimeNanos'</span>],</span>
<span id="cb13-49">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time_ns'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'endTimeNanos'</span>],</span>
<span id="cb13-50">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'fitValue'</span>][<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>][<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'intVal'</span>],</span>
<span id="cb13-51">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'modified_time_ms'</span>: dp[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'modifiedTimeMillis'</span>],</span>
<span id="cb13-52">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>: type_value</span>
<span id="cb13-53">    } <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> dp <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> data_points])</span>
<span id="cb13-54">    df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time_ns'</span>], unit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ns'</span>)</span>
<span id="cb13-55">    df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(df[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time_ns'</span>], unit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ns'</span>)</span>
<span id="cb13-56">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> df</span>
<span id="cb13-57"></span>
<span id="cb13-58"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力ウィジェットの作成</span></span>
<span id="cb13-59">output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Output()</span>
<span id="cb13-60"></span>
<span id="cb13-61"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 初期メッセージの表示</span></span>
<span id="cb13-62"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb13-63">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ファイルの処理が完了するまで、次のセルには進まないでください"</span>)</span>
<span id="cb13-64"></span>
<span id="cb13-65"></span>
<span id="cb13-66"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードイベントに関数をバインド</span></span>
<span id="cb13-67">uploader.observe(process_uploaded_files, names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>)</span>
<span id="cb13-68"></span>
<span id="cb13-69"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの表示</span></span>
<span id="cb13-70">display(uploader)</span>
<span id="cb13-71">display(output)</span>
<span id="cb13-72"></span>
<span id="cb13-73"></span></code></pre></div>
</div>
<div id="cell-4" class="cell">
<div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> parse_datetime_with_format(dt_series):</span>
<span id="cb14-2">    dt_series_with_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dt_series[dt_series.astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.contains(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r"\.\d+"</span>)]</span>
<span id="cb14-3">    dt_series_without_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dt_series[<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>dt_series.astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>.contains(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">r"\.\d+"</span>)]</span>
<span id="cb14-4">    parsed_with_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(dt_series_with_ms, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M:%S.</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%f</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>, errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coerce'</span>)</span>
<span id="cb14-5">    parsed_without_ms <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(dt_series_without_ms, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">format</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M:%S'</span>, errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coerce'</span>)</span>
<span id="cb14-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.concat([parsed_with_ms, parsed_without_ms]).sort_index()</span>
<span id="cb14-7"></span>
<span id="cb14-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># アップロードされたファイル名とデータの取得</span></span>
<span id="cb14-9">uploaded_files <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> uploader.value</span></code></pre></div>
</div>
</section>
<section id="手動睡眠記録の選択" class="level4">
<h4 class="anchored" data-anchor-id="手動睡眠記録の選択">手動睡眠記録の選択</h4>
<ul>
<li>睡眠記録には、自動で睡眠を検知するタイプ(主にスマートウォッチや睡眠マットなど)のものと、スマートフォンアプリなどを用いて手動で睡眠記録の開始・停止をするものの2種類があります
<ul>
<li>(このノートブックは、両者に対応しているだけでなく、複数のデバイスを用いて睡眠記録をつけている場合でも問題なく分析を行うことができます)</li>
</ul></li>
<li>もし、手動で睡眠記録を開始・停止している場合、以下のセルでその睡眠データにチェックを入れてください
<ul>
<li>(よく分からない場合は特に何もせず、「決定(データを処理)」ボタンを押してください)</li>
</ul></li>
</ul>
<div id="cell-6" class="cell">
<div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb15-1"></span>
<span id="cb15-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 説明文を表示</span></span>
<span id="cb15-3">description_label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'もし手動で睡眠記録を開始/停止したデータセットがあれば該当するものにチェックを入れてください。'</span>)</span>
<span id="cb15-4">display(description_label)</span>
<span id="cb15-5"></span>
<span id="cb15-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 空のデータフレームを初期化</span></span>
<span id="cb15-7">combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame()</span>
<span id="cb15-8"></span>
<span id="cb15-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイルと対応するチェックボックスを表示</span></span>
<span id="cb15-10">checkboxes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb15-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> file_details <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> uploader.value:</span>
<span id="cb15-12">    cb <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Checkbox(</span>
<span id="cb15-13">        value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>,</span>
<span id="cb15-14">        description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span>,  </span>
<span id="cb15-15">        disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb15-16">    )</span>
<span id="cb15-17">    label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>])  </span>
<span id="cb15-18">    box <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.HBox([cb, label])  </span>
<span id="cb15-19">    checkboxes.append(cb)</span>
<span id="cb15-20">    display(box)</span>
<span id="cb15-21"></span>
<span id="cb15-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># プロセスボタンを作成</span></span>
<span id="cb15-23">process_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"決定(データを処理)"</span>)</span>
<span id="cb15-24"></span>
<span id="cb15-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ボタンのイベントハンドラー</span></span>
<span id="cb15-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_button_clicked(b):</span>
<span id="cb15-27">    clear_output(wait<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb15-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">global</span> combined_data</span>
<span id="cb15-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> cb, file_details <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(checkboxes, uploader.value):</span>
<span id="cb15-30">        filename <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'name'</span>]</span>
<span id="cb15-31">        content <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> file_details[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'content'</span>]</span>
<span id="cb15-32">        sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> json.loads(content.tobytes().decode(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'utf-8'</span>))</span>
<span id="cb15-33"></span>
<span id="cb15-34">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># チェックボックスの値に応じてデータタイプを設定</span></span>
<span id="cb15-35">        type_column_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Manual'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> cb.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Auto'</span></span>
<span id="cb15-36">        data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> load_and_process_sleep_data(sleep_data, type_column_value)</span>
<span id="cb15-37">        combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.concat([combined_data, data], ignore_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb15-38"></span>
<span id="cb15-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データ処理後の状態を表示</span></span>
<span id="cb15-40">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Data processing complete. Dataframe contains:"</span>, combined_data.shape[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"rows."</span>)</span>
<span id="cb15-41">    </span>
<span id="cb15-42">process_button.on_click(on_button_clicked)</span>
<span id="cb15-43">display(process_button)</span></code></pre></div>
</div>
<div id="cell-7" class="cell">
<div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb16-1"></span>
<span id="cb16-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日時データの解析</span></span>
<span id="cb16-3">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> parse_datetime_with_format(combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb16-4">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> parse_datetime_with_format(combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>])</span>
<span id="cb16-5"></span>
<span id="cb16-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データを時系列順にソート</span></span>
<span id="cb16-7">combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data.sort_values(by<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>)</span>
<span id="cb16-8"></span>
<span id="cb16-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各睡眠データポイントの次の開始時刻を計算</span></span>
<span id="cb16-10">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'next_start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].shift(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb16-11"></span>
<span id="cb16-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ギャップを計算（分単位）</span></span>
<span id="cb16-13">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gap'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'next_start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]).dt.total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span></span>
<span id="cb16-14"></span>
<span id="cb16-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 新しいセッションの開始を示すフラグを設定（ギャップが120分以上の場合）</span></span>
<span id="cb16-16">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new_session_flag'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'gap'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">119</span>).astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb16-17"></span>
<span id="cb16-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># session_idを累積和で割り当て</span></span>
<span id="cb16-19">combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new_session_flag'</span>].shift(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).fillna(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>).cumsum().astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>)</span>
<span id="cb16-20"></span>
<span id="cb16-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 'Type'が'Manual'のデータを抽出して、各セッションの最初のstart_timeをin_bed_timeとして定義</span></span>
<span id="cb16-22">manual_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data[combined_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Manual'</span>]</span>
<span id="cb16-23">in_bed_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> manual_sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).first().reset_index()</span>
<span id="cb16-24">in_bed_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> in_bed_times[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]]</span>
<span id="cb16-25">in_bed_times.rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>}, inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb16-26"></span>
<span id="cb16-27"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 全データにin_bed_timeをマージ</span></span>
<span id="cb16-28">combined_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data.merge(in_bed_times, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, how<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'left'</span>)</span>
<span id="cb16-29"></span>
<span id="cb16-30"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Extract relevant columns: 'in_bed_time', 'expanded_start_time', 'expanded_end_time', 'majority_sleep_state'</span></span>
<span id="cb16-31">selected_columns_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>]]</span>
<span id="cb16-32"></span>
<span id="cb16-33"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># DataFrameを直接次のステップで使用</span></span>
<span id="cb16-34">sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> selected_columns_data  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># これが分析や可視化に使われるデータフレーム</span></span>
<span id="cb16-35"></span>
<span id="cb16-36"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各セッションの最初のstart_timeと最後のend_timeを取得</span></span>
<span id="cb16-37">session_start_end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> combined_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).agg({<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'first'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'last'</span>}).reset_index()</span>
<span id="cb16-38"></span>
<span id="cb16-39"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムを計算</span></span>
<span id="cb16-40">session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb16-41"></span>
<span id="cb16-42"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムの期間を1分に設定</span></span>
<span id="cb16-43">one_minute <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> timedelta(minutes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb16-44">session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_start'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> one_minute <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb16-45">session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_end'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> one_minute <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb16-46"></span>
<span id="cb16-47"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムのデータフレームを作成</span></span>
<span id="cb16-48">mid_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.DataFrame({</span>
<span id="cb16-49">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Mid_sleep_time'</span>,</span>
<span id="cb16-50">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Other'</span>,</span>
<span id="cb16-51">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>: pd.NaT,</span>
<span id="cb16-52">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>: session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_start'</span>],</span>
<span id="cb16-53">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>: session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mid_sleep_end'</span>],</span>
<span id="cb16-54">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>,</span>
<span id="cb16-55">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>: session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>]</span>
<span id="cb16-56">})</span>
<span id="cb16-57"></span>
<span id="cb16-58"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_dataにミッドスリープタイムのデータを追加</span></span>
<span id="cb16-59">sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.concat([sleep_data, mid_sleep_data], ignore_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span></code></pre></div>
</div>
</section>
<section id="睡眠データをcsvファイルとして保存する任意項目-保存しなくても問題ありません" class="level4">
<h4 class="anchored" data-anchor-id="睡眠データをcsvファイルとして保存する任意項目-保存しなくても問題ありません">睡眠データをCSVファイルとして保存する(任意項目: 保存しなくても問題ありません)</h4>
<ul>
<li>以下のセルを実行することで、睡眠データをCSVファイルとして保存することが可能です</li>
<li>保存しなくとも分析に問題はありません</li>
<li>CSVファイルは以下の構成となっています
<ul>
<li><code>data_source</code>: インポートしたデータセットの名前です(基本的にはGoogle Fitから取得されたデバイスの名前です)
<ul>
<li><code>Mid_sleep_time</code>: 算出されたミッドスリープタイム</li>
</ul></li>
<li><code>Type</code>: 基本的には<code>Auto</code>か<code>Manual</code>のどちらかが入ります
<ul>
<li><code>Auto</code>: 自動で睡眠記録が開始・停止していることを意味します</li>
<li><code>Manual</code>: 手動で睡眠記録が開始・停止していることを意味します</li>
<li><code>Other</code>: 算出されたミッドスリープタイムであることを意味します</li>
</ul></li>
<li><code>in_bed_time</code>: 手動で睡眠記録を開始している場合、その開始時刻が入ります</li>
<li><code>start_time</code>: 各睡眠ステージが開始された時刻で、協定世界時(UTC)となっています(日本標準時ではないことに注意してください)</li>
<li><code>end_time</code>: 各睡眠ステージが終了した時刻で、協定世界時(UTC)となっています(日本標準時ではないことに注意してください)</li>
<li><code>sleep_state</code>: <a href="https://developers.google.com/fit/scenarios/read-sleep-data?hl=ja#sleep_stage_values">Google Fit</a>で定められた睡眠ステージの値(1~6)と、算出したミッドスリープタイム(10)が入ります</li>
<li><code>session_id</code>: 1回の睡眠ごとに割り振られたIDです(<code>end_time</code>から次の<code>start_time</code>までの間が2時間以上離れている場合、別の睡眠とみなしています)</li>
</ul></li>
</ul>
</section>
<section id="睡眠ステージについて" class="level4">
<h4 class="anchored" data-anchor-id="睡眠ステージについて">睡眠ステージについて</h4>
<table class="caption-top table">
<thead>
<tr class="header">
<th>睡眠ステージのタイプ</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>覚醒（睡眠サイクル中）</td>
<td>1</td>
</tr>
<tr class="even">
<td>睡眠</td>
<td>2</td>
</tr>
<tr class="odd">
<td>ベッド外</td>
<td>3</td>
</tr>
<tr class="even">
<td>浅い睡眠</td>
<td>4</td>
</tr>
<tr class="odd">
<td>深い睡眠</td>
<td>5</td>
</tr>
<tr class="even">
<td>レム睡眠</td>
<td>6</td>
</tr>
<tr class="odd">
<td>ミッドスリープタイム</td>
<td>10</td>
</tr>
</tbody>
</table>
<p>(おそらくですが)睡眠ステージ2はデータの信頼性が低く使われていない傾向にあります ミッドスリープタイムはオリジナル(Google Fitのデータ)にはない項目です</p>
<div id="cell-9" class="cell">
<div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb17-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># CSVを保存する関数</span></span>
<span id="cb17-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ユーザーのデスクトップパスを取得</span></span>
<span id="cb17-3">desktop_path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> os.path.join(os.environ[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'USERPROFILE'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Desktop'</span>)</span>
<span id="cb17-4"></span>
<span id="cb17-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># CSVを保存する関数</span></span>
<span id="cb17-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> save_csv(sleep_data, path):</span>
<span id="cb17-7">    sleep_data.to_csv(path, index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb17-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'CSVファイルを </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>path<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">に保存しました。'</span></span>
<span id="cb17-9"></span>
<span id="cb17-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 「Save」ボタンの動作を定義</span></span>
<span id="cb17-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_save_button_clicked(b):</span>
<span id="cb17-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> output:</span>
<span id="cb17-13">        clear_output()</span>
<span id="cb17-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> fc.selected:</span>
<span id="cb17-15">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"CSVファイルの保存先を選択してください"</span>)</span>
<span id="cb17-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb17-17">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ここでDataFrameを保存</span></span>
<span id="cb17-18">            result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> save_csv(sleep_data, fc.selected)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># dfは保存したいDataFrameの変数名</span></span>
<span id="cb17-19">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(result)</span>
<span id="cb17-20"></span>
<span id="cb17-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ファイル選択ダイアログを設定</span></span>
<span id="cb17-22">fc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FileChooser(desktop_path)</span>
<span id="cb17-23">fc.default_filename <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_data.csv'</span></span>
<span id="cb17-24">fc.use_dir_icons <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span></span>
<span id="cb17-25"></span>
<span id="cb17-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 「Save」ボタンの作成</span></span>
<span id="cb17-27">save_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(</span>
<span id="cb17-28">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Save'</span>,</span>
<span id="cb17-29">    button_style<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span>,</span>
<span id="cb17-30">    tooltip<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Click to save the CSV file'</span>,</span>
<span id="cb17-31">    icon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'check'</span></span>
<span id="cb17-32">)</span>
<span id="cb17-33">save_button.on_click(on_save_button_clicked)</span>
<span id="cb17-34"></span>
<span id="cb17-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 出力エリアを設定</span></span>
<span id="cb17-36">output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Output()</span>
<span id="cb17-37"></span>
<span id="cb17-38"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットを表示</span></span>
<span id="cb17-39">display(fc, save_button, output)</span></code></pre></div>
</div>
</section>
<section id="アクトグラムを表示するための準備を行うセル" class="level4">
<h4 class="anchored" data-anchor-id="アクトグラムを表示するための準備を行うセル">アクトグラムを表示するための準備を行うセル</h4>
<p>アクトグラムとは、睡眠周期を可視化するグラフのことです。</p>
<div id="cell-11" class="cell">
<div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb18-1"></span>
<span id="cb18-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#  日またぎを処理する関数</span></span>
<span id="cb18-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> adjust_end_time(start, end):</span>
<span id="cb18-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> start:</span>
<span id="cb18-5">        end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 翌日にまたがる場合は24時間分（分）を加算</span></span>
<span id="cb18-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> end</span>
<span id="cb18-7"></span>
<span id="cb18-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_to_jst_if_needed(column):</span>
<span id="cb18-9">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報を確認し、必要に応じて変換を行う</span></span>
<span id="cb18-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> column.dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb18-11">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報がない場合、UTCとして解釈し、JSTに変換</span></span>
<span id="cb18-12">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.to_datetime(column, utc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb18-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>:</span>
<span id="cb18-14">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがUTCであれば、JSTに変換</span></span>
<span id="cb18-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb18-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>:</span>
<span id="cb18-17">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがJSTでない他のタイムゾーンであれば、JSTに変換</span></span>
<span id="cb18-18">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb18-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb18-20">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 既にJSTであればそのまま返す</span></span>
<span id="cb18-21">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column</span>
<span id="cb18-22"></span>
<span id="cb18-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_sleep_data_to_jst(sleep_data):</span>
<span id="cb18-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_dataをコピーしてタイムゾーンを変換</span></span>
<span id="cb18-25">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.copy()</span>
<span id="cb18-26">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb18-27">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>])</span>
<span id="cb18-28">    </span>
<span id="cb18-29">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 明示的に datetime64[ns, Asia/Tokyo] にキャスト</span></span>
<span id="cb18-30">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb18-31">    jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb18-32">    </span>
<span id="cb18-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> jst_sleep_data</span>
<span id="cb18-34"></span>
<span id="cb18-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_actogram(sleep_data, start_date, end_date):</span>
<span id="cb18-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン変換後のデータを取得</span></span>
<span id="cb18-37">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb18-38"></span>
<span id="cb18-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 指定された期間でデータをフィルタリング</span></span>
<span id="cb18-40">    filtered_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[</span>
<span id="cb18-41">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb18-42">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> pd.Timestamp(end_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb18-43">    ].copy()</span>
<span id="cb18-44">    </span>
<span id="cb18-45">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> filtered_data.empty:</span>
<span id="cb18-46">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"No data available to plot between </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> and </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span>
<span id="cb18-47">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb18-48"></span>
<span id="cb18-49">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日またぎを考慮した時間の計算</span></span>
<span id="cb18-50">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> dt: dt.hour <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> dt.minute)</span>
<span id="cb18-51">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb18-52">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> row: adjust_end_time(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).seconds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>), axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb18-53"></span>
<span id="cb18-54">    color_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#b3e5fc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'yellow'</span>}</span>
<span id="cb18-55">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">map</span>(color_map)</span>
<span id="cb18-56"></span>
<span id="cb18-57">    num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, (pd.Timestamp(end_date) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date)).days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb18-58">    fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.4</span>))</span>
<span id="cb18-59">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> filtered_data.iterrows():</span>
<span id="cb18-60">        day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)).days</span>
<span id="cb18-61">        ax.plot([row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>]], [day_of_week, day_of_week], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>)</span>
<span id="cb18-62">        ax.plot([row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>, row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>], [day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.7</span>)</span>
<span id="cb18-63"></span>
<span id="cb18-64">    ax.set_xlim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2880</span>)</span>
<span id="cb18-65">    ax.set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, num_days)</span>
<span id="cb18-66">    ax.set_yticks(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days))</span>
<span id="cb18-67">    ax.set_yticklabels([(pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x)).strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)])</span>
<span id="cb18-68">    ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time'</span>)</span>
<span id="cb18-69">    ax.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Days from Start Date'</span>)</span>
<span id="cb18-70">    plt.title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Actogram from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb18-71">    plt.grid(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb18-72">    plt.xticks(ticks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)], labels<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>(i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:02d}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">:00'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)], rotation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span>)</span>
<span id="cb18-73">    plt.show()</span>
<span id="cb18-74"></span>
<span id="cb18-75"></span>
<span id="cb18-76"></span>
<span id="cb18-77"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データセットの範囲確認</span></span>
<span id="cb18-78">jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb18-79">start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb18-80">end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb18-81"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"This dataset contains data from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span>
<span id="cb18-82"></span></code></pre></div>
</div>
<p>↑ に表示されたのが、JSONファイルから読み込まれたデータ範囲です。</p>
<blockquote class="blockquote">
<p>This dataset contains data from <code>YYYY-MM-DD</code> to <code>YYYY-MM-DD</code></p>
</blockquote>
<p>以下のセルでは、 - <strong>JSONファイルに含まれていたデータ期間に応じて</strong>、四半期(3ヶ月)ごとにアクトグラムがプロットされます - <strong>1年につき4枚グラフが出る</strong>ので、含まれているデータ期間が長い場合は、全部のグラフが出力されるまで時間がかかります - 任意の期間のアクトグラムを表示することも可能です</p>
<p>アクトグラムを表示せず、次のセルに進んでも構いません。</p>
<div id="cell-13" class="cell">
<div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb19-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期毎にデータをプロット</span></span>
<span id="cb19-2">start_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.year.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>()</span>
<span id="cb19-3">end_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.year.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb19-4">last_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>()</span>
<span id="cb19-5"></span>
<span id="cb19-6"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> year <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(start_year, end_year <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>):</span>
<span id="cb19-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> quarter <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>):</span>
<span id="cb19-8">        start_month <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> quarter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb19-9">        end_month <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> quarter</span>
<span id="cb19-10">        quarter_start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.Timestamp(year<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>year, month<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>start_month, day<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb19-11">        quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.Timestamp(year<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>year, month<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>end_month, day<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.DateOffset(months<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.DateOffset(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb19-12">        </span>
<span id="cb19-13">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> quarter_start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> last_date:</span>
<span id="cb19-14">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># この四半期の開始日がデータセットの最後の日を超えている場合はスキップ</span></span>
<span id="cb19-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> last_date:</span>
<span id="cb19-16">            quarter_end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> last_date  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期の終了日がデータセットの最後の日を超えている場合は調整</span></span>
<span id="cb19-17"></span>
<span id="cb19-18">        plot_actogram(jst_sleep_data, quarter_start_date.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>), quarter_end_date.strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>))</span></code></pre></div>
</div>
</section>
<section id="任意の期間に絞ったアクトグラム" class="level4">
<h4 class="anchored" data-anchor-id="任意の期間に絞ったアクトグラム">任意の期間に絞ったアクトグラム</h4>
<ul>
<li>任意の期間に絞ったアクトグラムを、ブラウザ上に表示するセルです</li>
<li>データの期間は四半期(3ヶ月)を推奨しています
<ul>
<li>四半期より長い期間を選択した場合、Y軸の文字が潰れてしまいます</li>
</ul></li>
<li>このセルを実行しなくても問題はありません</li>
</ul>
<div id="cell-15" class="cell">
<div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb20-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 任意の期間のアクトグラム</span></span>
<span id="cb20-2"></span>
<span id="cb20-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_interactive_actogram(sleep_data, start_date, end_date):</span>
<span id="cb20-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン変換後のデータを取得</span></span>
<span id="cb20-5">    jst_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb20-6"></span>
<span id="cb20-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 指定された期間でデータをフィルタリング</span></span>
<span id="cb20-8">    filtered_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> jst_sleep_data[</span>
<span id="cb20-9">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span></span>
<span id="cb20-10">        (jst_sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> pd.Timestamp(end_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb20-11">    ].copy()</span>
<span id="cb20-12"></span>
<span id="cb20-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> filtered_data.empty:</span>
<span id="cb20-14">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"No data available to plot between </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> and </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">."</span>)</span>
<span id="cb20-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb20-16"></span>
<span id="cb20-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日またぎを考慮した時間の計算</span></span>
<span id="cb20-18">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> dt: dt.hour <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> dt.minute)</span>
<span id="cb20-19">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb20-20">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> row: adjust_end_time(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).seconds <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span>), axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb20-21"></span>
<span id="cb20-22">    color_map <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb20-23">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 覚醒（睡眠サイクル中）</span></span>
<span id="cb20-24">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#b3e5fc'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠</span></span>
<span id="cb20-25">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ベッド外</span></span>
<span id="cb20-26">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 浅い睡眠</span></span>
<span id="cb20-27">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠</span></span>
<span id="cb20-28">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>,   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レム睡眠</span></span>
<span id="cb20-29">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'black'</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイム（色を強調）</span></span>
<span id="cb20-30">    }</span>
<span id="cb20-31">    sleep_stage_labels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb20-32">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'覚醒（睡眠サイクル中）'</span>,</span>
<span id="cb20-33">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'睡眠'</span>,</span>
<span id="cb20-34">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ベッド外'</span>,</span>
<span id="cb20-35">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'浅い睡眠'</span>,</span>
<span id="cb20-36">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'深い睡眠'</span>,</span>
<span id="cb20-37">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'レム睡眠'</span>,</span>
<span id="cb20-38">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ミッドスリープタイム'</span></span>
<span id="cb20-39">    }</span>
<span id="cb20-40">    filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">map</span>(color_map)</span>
<span id="cb20-41"></span>
<span id="cb20-42">    num_days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, (pd.Timestamp(end_date) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date)).days <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb20-43">    fig <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> go.Figure()</span>
<span id="cb20-44"></span>
<span id="cb20-45">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sleep_state, color <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> color_map.items():</span>
<span id="cb20-46">        sleep_state_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> filtered_data[filtered_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> sleep_state]</span>
<span id="cb20-47">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> sleep_state_data.empty:</span>
<span id="cb20-48">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_state_data.iterrows():</span>
<span id="cb20-49">                day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)).days</span>
<span id="cb20-50">                line_width <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">7.5</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムの場合は線の太さを15に設定</span></span>
<span id="cb20-51">                y_offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイムの場合はy座標をさらにオフセット</span></span>
<span id="cb20-52">                opacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> sleep_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ミッドスリープタイム以外は透明度を0.3に設定</span></span>
<span id="cb20-53">                fig.add_trace(go.Scatter(</span>
<span id="cb20-54">                    x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>], row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>]],</span>
<span id="cb20-55">                    y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset],</span>
<span id="cb20-56">                    mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lines'</span>,</span>
<span id="cb20-57">                    line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>line_width),</span>
<span id="cb20-58">                    name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>sleep_stage_labels[sleep_state],</span>
<span id="cb20-59">                    text<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>,</span>
<span id="cb20-60">                    hoverinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>,</span>
<span id="cb20-61">                    opacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>opacity</span>
<span id="cb20-62">                ))</span>
<span id="cb20-63">                fig.add_trace(go.Scatter(</span>
<span id="cb20-64">                    x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>, row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_minutes'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1440</span>],</span>
<span id="cb20-65">                    y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset, day_of_week <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y_offset],</span>
<span id="cb20-66">                    mode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lines'</span>,</span>
<span id="cb20-67">                    line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'color'</span>], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>line_width),</span>
<span id="cb20-68">                    name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>sleep_stage_labels[sleep_state],</span>
<span id="cb20-69">                    text<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>,</span>
<span id="cb20-70">                    hoverinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'text'</span>,</span>
<span id="cb20-71">                    opacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>opacity</span>
<span id="cb20-72">                ))</span>
<span id="cb20-73"></span>
<span id="cb20-74">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 凡例を統合</span></span>
<span id="cb20-75">    unique_labels <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>()</span>
<span id="cb20-76">    fig.for_each_trace(<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> trace: trace.update(showlegend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> trace.name <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> unique_labels <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> unique_labels.add(trace.name))</span>
<span id="cb20-77"></span>
<span id="cb20-78">    fig.update_layout(</span>
<span id="cb20-79">        title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Interactive Actogram from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_date<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>,</span>
<span id="cb20-80">        xaxis_title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time'</span>,</span>
<span id="cb20-81">        yaxis_title<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Days from Start Date'</span>,</span>
<span id="cb20-82">        xaxis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb20-83">            tickmode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'array'</span>,</span>
<span id="cb20-84">            tickvals<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)],</span>
<span id="cb20-85">            ticktext<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>(i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:02d}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">:00'</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">49</span>)],</span>
<span id="cb20-86">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2880</span>]</span>
<span id="cb20-87">        ),</span>
<span id="cb20-88">        yaxis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb20-89">            tickvals<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)),</span>
<span id="cb20-90">            ticktext<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[(pd.Timestamp(start_date).tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>x)).strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> x <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(num_days)],</span>
<span id="cb20-91">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, num_days],</span>
<span id="cb20-92">            tickfont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Y軸ラベルの文字サイズを小さく</span></span>
<span id="cb20-93">        ),</span>
<span id="cb20-94">        hovermode<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'closest'</span>,</span>
<span id="cb20-95">        legend<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(</span>
<span id="cb20-96">            itemsizing<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'constant'</span></span>
<span id="cb20-97">        )</span>
<span id="cb20-98">    )</span>
<span id="cb20-99"></span>
<span id="cb20-100">    pio.write_html(fig, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">file</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_data_plot.html'</span>, auto_open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb20-101"></span>
<span id="cb20-102"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの作成</span></span>
<span id="cb20-103">start_date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.DatePicker(</span>
<span id="cb20-104">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Start Date'</span>,</span>
<span id="cb20-105">    disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb20-106">)</span>
<span id="cb20-107">end_date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.DatePicker(</span>
<span id="cb20-108">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'End Date'</span>,</span>
<span id="cb20-109">    disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span></span>
<span id="cb20-110">)</span>
<span id="cb20-111">interactive_button <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Button(</span>
<span id="cb20-112">    description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Plot Interactive Actogram'</span>,</span>
<span id="cb20-113">    button_style<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'info'</span>,</span>
<span id="cb20-114">    tooltip<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Click to plot the interactive actogram'</span>,</span>
<span id="cb20-115">    icon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'line-chart'</span></span>
<span id="cb20-116">)</span>
<span id="cb20-117">notice_label <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> widgets.Label(</span>
<span id="cb20-118">    value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'データ範囲は四半期(3ヶ月)程度にしてください。それ以上の期間を指定すると文字が潰れて読めなくなります。また、グラフの作成には少し時間がかかります。'</span></span>
<span id="cb20-119">)</span>
<span id="cb20-120"></span>
<span id="cb20-121"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ボタンがクリックされたときの動作</span></span>
<span id="cb20-122"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_button_clicked(b):</span>
<span id="cb20-123">    start_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start_date_picker.value</span>
<span id="cb20-124">    end_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_date_picker.value</span>
<span id="cb20-125">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> start_date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> end_date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb20-126">        plot_interactive_actogram(sleep_data, start_date, end_date)</span>
<span id="cb20-127">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb20-128">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Please select both start and end dates."</span>)</span>
<span id="cb20-129"></span>
<span id="cb20-130">interactive_button.on_click(on_button_clicked)</span>
<span id="cb20-131"></span>
<span id="cb20-132"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ウィジェットの表示</span></span>
<span id="cb20-133">display(notice_label, start_date_picker, end_date_picker, interactive_button)</span></code></pre></div>
</div>
</section>
<section id="睡眠の統計分析を行うセル" class="level4">
<h4 class="anchored" data-anchor-id="睡眠の統計分析を行うセル">睡眠の統計分析を行うセル</h4>
<p>以下のセルでは、 1. 四半期ごとの睡眠時間及び睡眠の質の推移の可視化(折れ線グラフ) - 1枚 2. 四半期の範囲で曜日別の睡眠時間及び睡眠の質の可視化(箱ひげ図) - 1年につき4枚 を行います。</p>
<p>含まれているデータ期間が長い場合は、全部のグラフが出力されるまで時間がかかります。 そのため、実行せず、次のセルに進んでも構いません。</p>
<div id="cell-17" class="cell">
<div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb21-1"></span>
<span id="cb21-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_sleep_quality(sleep_data):</span>
<span id="cb21-3">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各セッションの睡眠時間を計算</span></span>
<span id="cb21-4">    session_start_end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).agg(</span>
<span id="cb21-5">        start_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>),</span>
<span id="cb21-6">        end_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'max'</span>)</span>
<span id="cb21-7">    ).reset_index()</span>
<span id="cb21-8">    session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> session_start_end[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).dt.total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span></span>
<span id="cb21-9">    </span>
<span id="cb21-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠の割合を計算</span></span>
<span id="cb21-11">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>]).dt.total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span></span>
<span id="cb21-12">    deep_sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 深い睡眠</span></span>
<span id="cb21-13">    deep_sleep_duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> deep_sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">sum</span>().reset_index()</span>
<span id="cb21-14">    </span>
<span id="cb21-15">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 列名を変更</span></span>
<span id="cb21-16">    deep_sleep_duration.rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_deep'</span>}, inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb21-17">    </span>
<span id="cb21-18">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(session_start_end, deep_sleep_duration, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, how<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'left'</span>)</span>
<span id="cb21-19">    sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_deep'</span>].fillna(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> sleep_quality[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>]</span>
<span id="cb21-20">    </span>
<span id="cb21-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sleep_quality[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>]]</span>
<span id="cb21-22"></span>
<span id="cb21-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_quarterly_sleep_stats(sleep_data):</span>
<span id="cb21-24">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data)</span>
<span id="cb21-25">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb21-26">    </span>
<span id="cb21-27">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb21-28">    quarterly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>).agg(</span>
<span id="cb21-29">        avg_sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>),</span>
<span id="cb21-30">        avg_sleep_quality<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>)</span>
<span id="cb21-31">    ).reset_index()</span>
<span id="cb21-32">    </span>
<span id="cb21-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> quarterly_stats</span>
<span id="cb21-34"></span>
<span id="cb21-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_quarterly_sleep_stats(quarterly_stats):</span>
<span id="cb21-36">    fig, ax1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>))</span>
<span id="cb21-37"></span>
<span id="cb21-38">    ax1.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Quarter'</span>)</span>
<span id="cb21-39">    ax1.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average Sleep Time (hours)'</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>)</span>
<span id="cb21-40">    ax1.plot(quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>), quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'avg_sleep_time'</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>, marker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'o'</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Avg Sleep Time'</span>)</span>
<span id="cb21-41">    ax1.tick_params(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span>, labelcolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:blue'</span>)</span>
<span id="cb21-42"></span>
<span id="cb21-43">    ax2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ax1.twinx()</span>
<span id="cb21-44">    ax2.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average Sleep Quality'</span>, color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>)</span>
<span id="cb21-45">    ax2.plot(quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].astype(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>), quarterly_stats[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'avg_sleep_quality'</span>], color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>, marker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'o'</span>, linestyle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'--'</span>, label<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Avg Sleep Quality'</span>)</span>
<span id="cb21-46">    ax2.tick_params(axis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span>, labelcolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'tab:orange'</span>)</span>
<span id="cb21-47"></span>
<span id="cb21-48">    fig.tight_layout()</span>
<span id="cb21-49">    fig.legend(loc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'upper left'</span>, bbox_to_anchor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9</span>))</span>
<span id="cb21-50">    plt.title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Quarterly Average Sleep Time and Quality'</span>)</span>
<span id="cb21-51">    plt.show()</span>
<span id="cb21-52"></span>
<span id="cb21-53"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_weekly_sleep_stats(sleep_data):</span>
<span id="cb21-54">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data)</span>
<span id="cb21-55">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb21-56">    </span>
<span id="cb21-57">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb21-58">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.day_name()</span>
<span id="cb21-59">    weekly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.groupby([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>]).agg(</span>
<span id="cb21-60">        avg_sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>),</span>
<span id="cb21-61">        avg_sleep_quality<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'mean'</span>)</span>
<span id="cb21-62">    ).reset_index()</span>
<span id="cb21-63">    </span>
<span id="cb21-64">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> weekly_stats</span>
<span id="cb21-65"></span>
<span id="cb21-66"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_weekly_sleep_stats_boxplot(sleep_data_jst):</span>
<span id="cb21-67">    sleep_quality <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_sleep_quality(sleep_data_jst)</span>
<span id="cb21-68">    sleep_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(sleep_data_jst, sleep_quality, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb21-69">    </span>
<span id="cb21-70">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.to_period(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Q'</span>)</span>
<span id="cb21-71">    sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.day_name()</span>
<span id="cb21-72">    weekdays <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Monday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Tuesday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Wednesday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Thursday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Friday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Saturday'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sunday'</span>]</span>
<span id="cb21-73">    weekday_colors <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#3498db'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e74c3c'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e74c3c'</span>]  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 平日は青、土日は赤</span></span>
<span id="cb21-74">    weekday_palette <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">dict</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">zip</span>(weekdays, weekday_colors))</span>
<span id="cb21-75"></span>
<span id="cb21-76">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> quarter <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>].unique():</span>
<span id="cb21-77">        quarter_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data[sleep_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'quarter'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> quarter]</span>
<span id="cb21-78">        </span>
<span id="cb21-79">        fig, (ax1, ax2) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>))</span>
<span id="cb21-80">        </span>
<span id="cb21-81">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠時間の箱ひげ図</span></span>
<span id="cb21-82">        sns.boxplot(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_duration_total'</span>, data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>quarter_data, order<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekdays, palette<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekday_palette, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax1, hue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, dodge<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb21-83">        ax1.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Weekly Sleep Duration for </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>quarter<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb21-84">        ax1.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Weekday'</span>)</span>
<span id="cb21-85">        ax1.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sleep Duration (hours)'</span>)</span>
<span id="cb21-86">        ax1.legend([],[], frameon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レジェンドを非表示にする</span></span>
<span id="cb21-87"></span>
<span id="cb21-88">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠の質の箱ひげ図</span></span>
<span id="cb21-89">        sns.boxplot(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_quality'</span>, data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>quarter_data, order<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekdays, palette<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>weekday_palette, ax<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax2, hue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'weekday'</span>, dodge<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb21-90">        ax2.set_title(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f'Weekly Sleep Quality for </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>quarter<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span>)</span>
<span id="cb21-91">        ax2.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Weekday'</span>)</span>
<span id="cb21-92">        ax2.set_ylabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sleep Quality'</span>)</span>
<span id="cb21-93">        ax2.legend([],[], frameon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># レジェンドを非表示にする</span></span>
<span id="cb21-94">        </span>
<span id="cb21-95">        plt.tight_layout()</span>
<span id="cb21-96">        plt.show()</span>
<span id="cb21-97"></span>
<span id="cb21-98"></span>
<span id="cb21-99"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># データの準備</span></span>
<span id="cb21-100">sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb21-101"></span>
<span id="cb21-102"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 四半期ごとの統計を計算</span></span>
<span id="cb21-103">quarterly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_quarterly_sleep_stats(sleep_data_jst)</span>
<span id="cb21-104"></span>
<span id="cb21-105"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結果をプロット</span></span>
<span id="cb21-106">plot_quarterly_sleep_stats(quarterly_stats)</span>
<span id="cb21-107"></span>
<span id="cb21-108"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 曜日別の統計を計算</span></span>
<span id="cb21-109">weekly_stats <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> calculate_weekly_sleep_stats(sleep_data_jst)</span>
<span id="cb21-110"></span>
<span id="cb21-111"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結果を箱ひげ図でプロット</span></span>
<span id="cb21-112">plot_weekly_sleep_stats_boxplot(sleep_data_jst)</span></code></pre></div>
</div>
</section>
<section id="任意の日付による睡眠セッションの可視化" class="level4">
<h4 class="anchored" data-anchor-id="任意の日付による睡眠セッションの可視化">任意の日付による、睡眠セッションの可視化</h4>
<p>以下のセルでは、ユーザーが指定した日付の睡眠セッション分析し、睡眠ステージの推移をグラフに表示します。</p>
<div id="cell-19" class="cell">
<div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb22-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_to_jst_if_needed(column):</span>
<span id="cb22-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報を確認し、必要に応じて変換を行う</span></span>
<span id="cb22-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> column.dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb22-4">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーン情報がない場合、UTCとして解釈し、JSTに変換</span></span>
<span id="cb22-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> pd.to_datetime(column, utc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>:</span>
<span id="cb22-7">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがUTCであれば、JSTに変換</span></span>
<span id="cb22-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>(column.dt.tz) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>:</span>
<span id="cb22-10">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンがJSTでない他のタイムゾーンであれば、JSTに変換</span></span>
<span id="cb22-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column.dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-13">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 既にJSTであればそのまま返す</span></span>
<span id="cb22-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> column</span>
<span id="cb22-15"></span>
<span id="cb22-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> convert_sleep_data_to_jst(sleep_data):</span>
<span id="cb22-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_dataをコピーしてタイムゾーンを変換</span></span>
<span id="cb22-18">    sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data.copy()</span>
<span id="cb22-19">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb22-20">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>])</span>
<span id="cb22-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sleep_data.columns:</span>
<span id="cb22-22">        sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_to_jst_if_needed(sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>])</span>
<span id="cb22-23">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-24">        sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb22-25">        </span>
<span id="cb22-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 明示的に datetime64[ns, Asia/Tokyo] にキャスト</span></span>
<span id="cb22-27">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb22-28">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb22-29">    sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].astype(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'datetime64[ns, Asia/Tokyo]'</span>)</span>
<span id="cb22-30">    </span>
<span id="cb22-31">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sleep_data_jst</span>
<span id="cb22-32"></span>
<span id="cb22-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> create_session_data(sleep_data_jst):</span>
<span id="cb22-34">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 各セッションの最終 'end_time' を取得して日付に変換</span></span>
<span id="cb22-35">    session_dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().dt.date</span>
<span id="cb22-36">    session_dates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_dates.reset_index()</span>
<span id="cb22-37">    session_dates.rename(columns<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_date'</span>}, inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb22-38">    </span>
<span id="cb22-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠時間と睡眠潜時の計算</span></span>
<span id="cb22-40">    sleep_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).agg(</span>
<span id="cb22-41">        sleep_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> x: (x.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> x.<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>()).total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3600</span>),</span>
<span id="cb22-42">        start_time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'min'</span>)</span>
<span id="cb22-43">    )</span>
<span id="cb22-44">    sleep_times.reset_index(inplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb22-45"></span>
<span id="cb22-46">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠潜時の計算</span></span>
<span id="cb22-47">    sleep_latency <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst.groupby(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>).<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">apply</span>(</span>
<span id="cb22-48">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> group: calculate_sleep_latency(group[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>]]),</span>
<span id="cb22-49">        include_groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 追加: グループ化列を適用操作から除外</span></span>
<span id="cb22-50">    ).reset_index(name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>)</span>
<span id="cb22-51"></span>
<span id="cb22-52">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 結合して全データを含むデータフレームを作成</span></span>
<span id="cb22-53">    full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(session_dates, sleep_times[[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_time'</span>]], on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb22-54">    full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.merge(full_session_data, sleep_latency, on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)</span>
<span id="cb22-55">    </span>
<span id="cb22-56">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> full_session_data</span>
<span id="cb22-57"></span>
<span id="cb22-58"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> calculate_sleep_latency(group):</span>
<span id="cb22-59">    group <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> group.sort_values(by<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>)</span>
<span id="cb22-60">    auto_sleep_times <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> group[(group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Type'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Auto'</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>)]</span>
<span id="cb22-61">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> auto_sleep_times.empty:</span>
<span id="cb22-62">        auto_sleep_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auto_sleep_times[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb22-63">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pd.notna(group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]:</span>
<span id="cb22-64">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> (auto_sleep_time <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> group[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'in_bed_time'</span>].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]).total_seconds() <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">60</span></span>
<span id="cb22-65">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> np.nan</span>
<span id="cb22-66"></span>
<span id="cb22-67">sleep_data_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> convert_sleep_data_to_jst(sleep_data)</span>
<span id="cb22-68">full_session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> create_session_data(sleep_data_jst)</span>
<span id="cb22-69"></span>
<span id="cb22-70"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日付選択ウィジェット</span></span>
<span id="cb22-71">date_picker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> DatePicker(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Select Date'</span>, disabled<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">False</span>)</span>
<span id="cb22-72"></span>
<span id="cb22-73"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_prev_clicked(b):</span>
<span id="cb22-74">    date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date_picker.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb22-75"></span>
<span id="cb22-76"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_next_clicked(b):</span>
<span id="cb22-77">    date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> date_picker.value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> pd.Timedelta(days<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date_picker.value <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb22-78"></span>
<span id="cb22-79">button_prev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Previous Day"</span>)</span>
<span id="cb22-80">button_next <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Button(description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Next Day"</span>)</span>
<span id="cb22-81">button_prev.on_click(on_prev_clicked)</span>
<span id="cb22-82">button_next.on_click(on_next_clicked)</span>
<span id="cb22-83"></span>
<span id="cb22-84">display(HBox([button_prev, button_next]))</span>
<span id="cb22-85">display(date_picker)</span>
<span id="cb22-86"></span>
<span id="cb22-87"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># タイムゾーンを確認して適切に日付を表示する関数</span></span>
<span id="cb22-88"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> set_plot_title(ax, session_id, sleep_data_jst):</span>
<span id="cb22-89">    jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pytz.timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-90"></span>
<span id="cb22-91">    session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb22-92">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> session_data.empty:</span>
<span id="cb22-93">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz:</span>
<span id="cb22-94">            start_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().astimezone(jst)</span>
<span id="cb22-95">            end_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().astimezone(jst)</span>
<span id="cb22-96">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-97">            start_time_utc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">min</span>().replace(tzinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>pytz.utc)</span>
<span id="cb22-98">            end_time_utc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>().replace(tzinfo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>pytz.utc)</span>
<span id="cb22-99">            start_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start_time_utc.astimezone(jst)</span>
<span id="cb22-100">            end_time_jst <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end_time_utc.astimezone(jst)</span>
<span id="cb22-101"></span>
<span id="cb22-102">        title <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Sleep Session from </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>start_time_jst<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> to </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>end_time_jst<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>strftime(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%Y-%m-</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%d</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> %H:%M'</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb22-103">        ax.set_title(title)</span>
<span id="cb22-104">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-105">        ax.set_title(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No data available for this session"</span>)</span>
<span id="cb22-106"></span>
<span id="cb22-107"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># キャプションを追加する関数</span></span>
<span id="cb22-108"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> add_caption(ax, session_id, full_session_data):</span>
<span id="cb22-109">    record <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> full_session_data[full_session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id].iloc[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]</span>
<span id="cb22-110">    </span>
<span id="cb22-111">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># キャプションの初期部分</span></span>
<span id="cb22-112">    caption <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"睡眠時間: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_time'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> 時間</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb22-113">    </span>
<span id="cb22-114">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># sleep_latencyがNaNやマイナスでない場合のみ追加</span></span>
<span id="cb22-115">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> pd.notna(record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>]) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>:</span>
<span id="cb22-116">        caption <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"睡眠潜時(布団に入ってから寝付くまでの時間): </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>record[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_latency'</span>]<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:.2f}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;"> 分"</span></span>
<span id="cb22-117">    </span>
<span id="cb22-118">    ax.text(<span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.01</span>, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.95</span>, caption, transform<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ax.transAxes, fontsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, verticalalignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'top'</span>)</span>
<span id="cb22-119"></span>
<span id="cb22-120"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 睡眠データをプロットする関数</span></span>
<span id="cb22-121"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> plot_sleep_data(session_id, sleep_data_jst, full_session_data):</span>
<span id="cb22-122">    session_info <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> full_session_data[full_session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb22-123">    session_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sleep_data_jst[sleep_data_jst[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> session_id]</span>
<span id="cb22-124"></span>
<span id="cb22-125">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> session_data.empty:</span>
<span id="cb22-126">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日時データのタイムゾーンを確認し、日本時間に設定</span></span>
<span id="cb22-127">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb22-128">            session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>].dt.tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-129">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].dt.tz <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb22-130">            session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>].dt.tz_localize(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'UTC'</span>).dt.tz_convert(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)</span>
<span id="cb22-131"></span>
<span id="cb22-132">        fig, ax <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> plt.subplots(figsize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>))</span>
<span id="cb22-133">        stage_height <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>}</span>
<span id="cb22-134">        stage_colors <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#e0ffff'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ff5252'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#03a9f4'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#303f9f'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>: <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#ab47bc'</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>:<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'yellow'</span>}</span>
<span id="cb22-135">        data_sources <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> session_data[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'data_source'</span>].unique()</span>
<span id="cb22-136">        source_count <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(data_sources)</span>
<span id="cb22-137">        alpha_value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> source_count <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> source_count <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb22-138"></span>
<span id="cb22-139">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># プロットの時間を日本時間に合わせて設定</span></span>
<span id="cb22-140">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> index, row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> session_data.iterrows():</span>
<span id="cb22-141">            start_pos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mdates.date2num(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'start_time'</span>])</span>
<span id="cb22-142">            duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mdates.date2num(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'end_time'</span>]) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> start_pos</span>
<span id="cb22-143">            ax.bar(x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>start_pos, height<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>stage_height[row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>]], width<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>duration,</span>
<span id="cb22-144">                   color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>stage_colors.get(row[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'sleep_state'</span>], <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'#FFFFFF'</span>), edgecolor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'black'</span>,</span>
<span id="cb22-145">                   align<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'edge'</span>, alpha<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>alpha_value)</span>
<span id="cb22-146"></span>
<span id="cb22-147">        ax.xaxis_date(tz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>))</span>
<span id="cb22-148">        ax.xaxis.set_major_locator(mdates.HourLocator(interval<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>))</span>
<span id="cb22-149">        ax.xaxis.set_major_formatter(mdates.DateFormatter(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'%H:%M'</span>, tz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>timezone(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Asia/Tokyo'</span>)))</span>
<span id="cb22-150">        ax.set_ylim(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>)</span>
<span id="cb22-151">        ax.set_yticks([<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>])</span>
<span id="cb22-152">        ax.set_yticklabels([<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Deep Sleep'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'REM'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Light Sleep'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Awake'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Out-of-bed'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Mid Sleep Time'</span>])</span>
<span id="cb22-153">        ax.set_xlabel(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Time of Day'</span>)</span>
<span id="cb22-154">        set_plot_title(ax, session_id, sleep_data_jst)</span>
<span id="cb22-155">        add_caption(ax, session_id, session_info)</span>
<span id="cb22-156">        plt.tight_layout()</span>
<span id="cb22-157">        plt.show()</span>
<span id="cb22-158">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-159">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No sleep data available for this session."</span>)</span>
<span id="cb22-160"></span>
<span id="cb22-161"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 日付変更時のイベントハンドラ</span></span>
<span id="cb22-162"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> on_date_change(change):</span>
<span id="cb22-163">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb22-164">        selected_date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pd.to_datetime(change[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'new'</span>]).date()</span>
<span id="cb22-165">        session_id <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">next</span>((sid <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sid, date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> full_session_data.set_index(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_id'</span>)[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'session_date'</span>].items() <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> date <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> selected_date), <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>)</span>
<span id="cb22-166">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> session_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb22-167">            plot_sleep_data(session_id, sleep_data_jst, full_session_data)</span>
<span id="cb22-168">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb22-169">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No sessions found for this date."</span>)</span>
<span id="cb22-170"></span>
<span id="cb22-171">date_picker.observe(on_date_change, names<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'value'</span>)</span></code></pre></div>
</div>
</section>
</section>
</section>
<section id="おわりに" class="level2">
<h2 class="anchored" data-anchor-id="おわりに">7. おわりに</h2>
<p>この記事及びJupyter Notebookが誰かのお役に立てれば幸いです。</p>



</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a><div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">参考文献</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" data-line-spacing="2">
<div id="ref-GoogleFitAPI" class="csl-entry">
Google for Developers (2023)“<span>Read Sleep Data</span>”, <em><span>Google for Developers</span></em>, 2023 Accessed May 23, 2024 <a href="https://developers.google.com/fit/scenarios/read-sleep-data">https://developers.google.com/fit/scenarios/read-sleep-data</a>
</div>
<div id="ref-Johnson2003" class="csl-entry">
Jeffrey A. Elliott Carl Hirschie Johnson &amp; Russell Foster (2003)“<a href="https://doi.org/10.1081/CBI-120024211">Entrainment of circadian programs</a>”, <em>Chronobiology International</em>, vol. 20, No. 5, pp. 741–774
</div>
<div id="ref-Tataroglu2014" class="csl-entry">
Ozgur Tataroglu &amp; Patrick Emery (2014)“<a href="https://doi.org/10.1016/j.ymeth.2014.01.001">Studying circadian rhythms in drosophila melanogaster</a>”, <em>Methods</em>, vol. 68, No. 1, pp. 140–150
</div>
<div id="ref-Refinetti2007" class="csl-entry">
Roberto Refinetti, Germaine Corné Lissen &amp; Franz Halberg (2007)“<a href="https://doi.org/10.1080/09291010600903692">Procedures for numerical analysis of circadian rhythms</a>”, <em>Biological Rhythm Research</em>, vol. 38, No. 4, pp. 275–325
</div>
<div id="ref-Colin1960_circadian" class="csl-entry">
Colin S Pittendrigh (1960)“<a href="https://doi.org/10.1101/sqb.1960.025.01.015">Circadian rhythms and the circadian organization of living systems</a>”, <em>Cold Spring Harbor Symposia on Quantitative Biology</em>, vol. 25, pp. 159–184
</div>
<div id="ref-Johnson1926" class="csl-entry">
M. S. Johnson (1926)“<a href="https://doi.org/10.2307/1373575"><span class="nocase">Activity and Distribution of Certain Wild Mice in Relation to Biotic Communities1</span></a>”, <em>Journal of Mammalogy</em>, vol. 7, No. 4, pp. 245–277
</div>
</div></section></div> ]]></description>
  <category>スクリプト</category>
  <category>How2</category>
  <category>おすすめ記事</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Sleep_Analyze_JupyterNotebook.html</guid>
  <pubDate>Wed, 22 May 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/Sleep_Ana.png" medium="image" type="image/png" height="75" width="144"/>
</item>
<item>
  <title>Pottal-Portal 3.0 にGoogle AdSenseを用いた広告を導入しました</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Ad_start.html</link>
  <description><![CDATA[ 




<div class="callout callout-style-default callout-important callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
2024/06/24をもって広告を停止しました
</div>
</div>
<div class="callout-body-container callout-body">
<p>Google AdSenseの自動広告による広告設置を取りやめました。 そのため、この記事はアーカイブとなります。詳細については、<a href="https://www.pottal-portal.com/PtPr3/posts/Stop_GoogleAds.html">以下の記事</a>をご覧ください。</p>
</div>
</div>
<section id="広告設置のお知らせ" class="level2">
<h2 class="anchored" data-anchor-id="広告設置のお知らせ">広告設置のお知らせ</h2>
<ul>
<li>Pottal-Portal 3.0 に広告を導入しました。</li>
<li>ユーザー体験を損なわないように以下のように広告を設置しています。
<ul>
<li>全画面広告はユーザー体験を大きく損なうため、排除しています。</li>
<li>戻るボタンをHackするような広告もユーザー体験を損なうので排除しています。</li>
<li>ページ内に表示される広告数を最小限に抑えています。</li>
<li>ファーストビュー(ページの最上部やタイトル前後など最初に表示される一等地)への広告は美しくないので排除しています。(2024/04/17 追記)</li>
<li>【PC・タブレット向け】 ページ左右の余白に広告を表示しています。</li>
<li>【その他】 ページ分割はユーザー体験を損なうものであるため、導入しておりません。記事の最後までスクロールでご覧いただけます。</li>
</ul></li>
<li>悪質な広告がございましたら、<a href="https://forms.gle/vcYNXJB1M4dXK2bFA">こちらのフォーム</a>より、お知らせいただけると幸いです。</li>
<li>広告の位置や頻度について、細心の注意を払ってはおりますが、万が一お気づきの点がございましたら、<a href="https://forms.gle/vcYNXJB1M4dXK2bFA">こちらのフォーム</a>より、お知らせいただけると幸いです。</li>
</ul>
<section id="アーカイブ記事について" class="level3">
<h3 class="anchored" data-anchor-id="アーカイブ記事について">アーカイブ記事について</h3>
<p>アーカイブ記事(Pottal-Portal時代)の記事に関しては、流石に手が回らないのでファーストビューに広告が表示されてしまう場合がございます。 全画面広告に関しては全面的にブロックしているので表示されないはずです。 (2024/04/17 追記)</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
更新履歴
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<div style="text-align: left;">
<p>2024/04/16: 初稿<br> 2024/04/17: ファーストビューへの広告非表示について、およびアーカイブ記事の扱いについて追記<br> 2024/06/24: Google AdSenseを用いた自動広告を廃止したため、この記事をアーカイブとしました</p>
</div>
</div>
</div>
</div>


</section>
</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a> ]]></description>
  <category>お知らせ</category>
  <category>Archive</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Ad_start.html</guid>
  <pubDate>Mon, 15 Apr 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/cover_Lite.png" medium="image" type="image/png" height="144" width="144"/>
</item>
<item>
  <title>Anker Prime Power Bank 27650mAh 250Wモデル レビュー</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Anker_Prime_Power_Bank_250W.html</link>
  <description><![CDATA[ 




<p><a href="../post_images/Anker250W.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W.png" class="img-fluid"></a></p>
<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>

<section id="要旨" class="level2">
<h2 class="anchored" data-anchor-id="要旨">要旨</h2>
<p>Anker Prime Power Bank(27650mAh 250Wモデル)を購入したためレビューします。本機種はUSB-C1ポート単体出力140W, USB-C2ポートとの同時使用時にもUSB-C1は140W, C2は100Wというハイスペックな仕様のせいか、筆者の検証した限り、<strong>TypeCポート(USB-C1,C2)のみを使っている場合は</strong>、再ネゴシエーションによる瞬断(瞬停; 瞬間停止)が起こらないという地味に嬉しい仕様になっています。また、USB-C1とC2の<strong>同時入力</strong>にも対応しており、最大170W(39分)で本機を充電することが可能です。100W出力可能なACアダプターないし充電器を2台持っていることが前提にはなりますが、27650mAh(99.54Wh)という機内持ち込みギリギリのサイズ<span class="citation" data-cites="ANA">(ANA)</span>のモバイルバッテリーが40分かからずに充電できるのは素晴らしいですね。500mLのペットボトルより小さく、そして665gと僅かに重い程度なので自分としては十分許容範囲です。攻守ともに最強の大容量モバイルバッテリーが自販機のペットボトル程度の感覚で持ち運べるなんていい時代になったなぁと感じます。なお、筆者は2024年4月からニートになったのでモバイルバッテリーを使う機会はないのですが…</p>
</section>
<section id="背景" class="level2">
<h2 class="anchored" data-anchor-id="背景">背景</h2>
<p>以前使っていたCIOのモバイルバッテリー『SMARTCOBY 20000mAh 60W』が壊れたので、新しいモバイルバッテリーを探していました。CIOのこのモバイルバッテリーは、3A(60Wまで対応)のケーブルに対して5AのPDOを出力を通知するというUSB PDの仕様に違反する代物<span class="citation" data-cites="HanpenBlog">(@Hanpenblog 2021)</span>だったため、早いところ買い替えたかったのですが、どうせ買うなら、中途半端なスペックのモバイルバッテリーではなく最強のモバイルバッテリーが欲しいと思っておりました。</p>
<p>2023年の夏に<a href="https://www.ankerjapan.com/blogs/news/426">「Anker Prime Power Bank (27650mAh, 250W)」が発表</a><span class="citation" data-cites="AnkerJapan2023">(アンカー・ジャパン株式会社 2023a)</span>されてから、発売予定である「2023年秋ごろ」を一日千秋の想いで待ち続けていたのですが、「2024年1月発売予定」、「2024年春ごろ発売予定」と延期に延期を重ね、2024年の2月2日にひっそりと発売されていたことに3月まで気付かず、値引きされてないものをAmazon新生活SALEで買いました。(Ankerの新商品は一定数量までは値引きされて販売されていることが多く、この製品もセールでは19900円だったのですが、正規価格の24990円で買うことになりました)</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
</p><p>今見たら更に延期して2024年春になってた。諦めるかぁ。<a href="https://t.co/5m4Ym9gTfz">https://t.co/5m4Ym9gTfz</a> <a href="https://t.co/hmaEPMeLLW">pic.twitter.com/hmaEPMeLLW</a></p>
<p></p>
<p>— ポッタル (<span class="citation" data-cites="Pottal_MDS">(<strong>Pottal_MDS?</strong>)</span>) <a href="https://twitter.com/Pottal_MDS/status/1736633197038031174?ref_src=twsrc%5Etfw">December 18, 2023</a></p>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</section>
<section id="whats-this" class="level2">
<h2 class="anchored" data-anchor-id="whats-this">What’s this?</h2>
<p>単ポート140W, 2ポート240Wの出力ができ、170Wで本体も充電可能という攻守最強の27650mAhモバイルバッテリー</p>
</section>
<section id="開封の儀" class="level2">
<h2 class="anchored" data-anchor-id="開封の儀">開封の儀</h2>
<div id="fig-box" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_DSC0091.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="図&nbsp;1: 外装"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0091.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: 外装
</figcaption>
</figure>
</div>
<div id="fig-in_the_box" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-in_the_box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_DSC0093.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-3" title="ポーチ, 140W対応ケーブル(60cm), 説明書などが付属"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0093.jpg" class="img-fluid figure-img"></a></p>
<figcaption>ポーチ, 140W対応ケーブル(60cm), 説明書などが付属</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-in_the_box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;2: 付属品
</figcaption>
</figure>
</div>
<div id="fig-cable" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-cable-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-cable" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-cable-1" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-cable-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0098.jpg" class="lightbox" data-gallery="fig-cable" title="図&nbsp;3&nbsp;(a): 片側にはAnkerロゴが彫られている"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0098.jpg" class="img-fluid figure-img" data-ref-parent="fig-cable"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-cable-1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 片側にはAnkerロゴが彫られている
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-cable" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-140W" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-140W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0099.jpg" class="lightbox" data-gallery="fig-cable" title="図&nbsp;3&nbsp;(b): MAX 140Wという印字 実際には50V5A(250W)まで対応"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0099.jpg" class="img-fluid figure-img" data-ref-parent="fig-cable"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-140W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) MAX 140Wという印字 実際には50V5A(250W)まで対応
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-cable" style="flex-basis: 100.0%;justify-content: flex-start;">
<div id="fig-cable-3" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-cable-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_20240415_111427.jpg" class="lightbox" data-gallery="fig-cable" title="図&nbsp;3&nbsp;(c): 付属ケーブルは50V5A(250W)まで対応"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_20240415_111427.jpg" class="img-fluid figure-img" data-ref-parent="fig-cable"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-cable-3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) 付属ケーブルは50V5A(250W)まで対応
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-cable-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;3: 付属ケーブル<br>AVHzY CT-3を用いてケーブルを調べたところUSB2.0で50V5Aまで対応
</figcaption>
</figure>
</div>
<p>図&nbsp;3 (b)の通り、この付属ケーブルには「MAX 140W」という印字があります。しかし、AVHzY CT-3を用いてケーブルを調べたところ実際には50V5A(250W)まで対応しています。また、USB PD EPR対応ケーブルは(たとえソース側が140Wまでであろうと)50V5Aに対応していなければなりません<span class="citation" data-cites="USBTypeC2">(SpecWerkz &amp; Saunders 2023)</span>。わざわざMAX 140Wと印字している意味がわかりません。詳しくは後述します。</p>
<div id="fig-photo_review" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-photo_review-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-front" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0020.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(a): 正面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0020.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 正面
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-back" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0022.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(b): 背面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0022.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 背面
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-left" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-left-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0023.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(c): 左側面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0023.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-left-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) 左側面
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-right" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-right-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0021.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(d): 右側面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0021.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-right-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(d) 右側面
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-top" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-top-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0025.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(e): 上面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0025.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-top-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(e) 上面
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-photo_review" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-bottom" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-bottom-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0026.jpg" class="lightbox" data-gallery="fig-photo_review" title="図&nbsp;4&nbsp;(f): 底面"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0026.jpg" class="img-fluid figure-img" data-ref-parent="fig-photo_review"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-bottom-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(f) 底面
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-photo_review-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;4: Anker Prime Power Bank 27650mAh 250W本体
</figcaption>
</figure>
</div>
<div id="fig-weight" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-weight-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_DSC0088.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-13" title="図&nbsp;5: 重量は実測666g(公称値 約665g)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0088.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-weight-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;5: 重量は実測666g(公称値 約665g)
</figcaption>
</figure>
</div>
<div id="fig-size" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-size-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_DSC0194.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-14" title="図&nbsp;6: 500mLペットボトルとサイズ感の比較"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0194.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-size-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;6: 500mLペットボトルとサイズ感の比較
</figcaption>
</figure>
</div>
<section id="定格表示" class="level3">
<h3 class="anchored" data-anchor-id="定格表示">定格表示</h3>
<ul>
<li>Anker Prime 27,650mAh Power Bank (250W)</li>
<li>Model/品番: A1340</li>
<li>Battery Capacity: 3950mAh 25.2Vdc/99.54Wh</li>
<li>Cell/内蔵電池: 3950mAh*7pcs</li>
<li>定格電圧: 5Vdc</li>
<li>定格容量: 15500mAh</li>
<li>USB-C1/C2 Input/入力: 5V⎓3A / 9V⎓3A / 15V⎓3A / 20V⎓5A / 28V⎓5A</li>
<li>Chargin Base Input/入力: 21.5V⎓4.65A</li>
<li>USB-C1/C2 Output/出力: 5V⎓3A / 9V⎓3A / 12V⎓1.5A / 15V⎓3A / 20V⎓5A / 28V⎓5A</li>
<li>USB-A Output/出力: 5V⎓3A / 9V⎓2A / 10V⎓6.5A / 12V⎓1.5A</li>
<li>Total Output/合計出力: 250W Max</li>
<li>Anker Innovations Limited</li>
<li>Made in China</li>
<li>PSEマーク: 丸形 / アンカー・ジャパン株式会社</li>
</ul>
</section>
</section>
<section id="スペックについて" class="level2">
<h2 class="anchored" data-anchor-id="スペックについて">スペックについて</h2>
<p>カタログスペックではなく、実測した性能はこちらを御覧ください。</p>
<div id="tbl-Spec" class="quarto-float anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-Spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;1: スペック表 <span class="citation" data-cites="Anker250W">(アンカー・ジャパン株式会社 2024)</span>より筆者引用
</figcaption>
<div aria-describedby="tbl-Spec-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="table">
<colgroup>
<col style="width: 9%">
<col style="width: 90%">
</colgroup>
<thead>
<tr class="header">
<th>項目</th>
<th>スペック</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>サイズ</td>
<td>約162 x 57 x 50mm</td>
</tr>
<tr class="even">
<td>重さ</td>
<td>約665g</td>
</tr>
<tr class="odd">
<td>入力</td>
<td>USB-C1 / C2 入力：5V⎓3A / 9V⎓3A / 15V⎓3A / 20V⎓5A / 28V⎓5A (最大140W)<br>
専用充電スタンド (別売り)：21.5V⎓4.65A (最大99W)<br>
合計最大入力：170W</td>
</tr>
<tr class="even">
<td>出力</td>
<td>USB-C1 / C2 出力：5V⎓3A / 9V⎓3A / 12V⎓1.5A / 15V⎓3A / 20V⎓5A / 28V⎓5A (最大140W)<br>
USB-A出力：5V⎓3A / 9V⎓2A / 10V⎓6.5A / 12V⎓1.5A (最大65W)<br>
※USB-Aポートから最大65Wの出力にはOPPO対応機器と専用ケーブルが必要です</td>
</tr>
<tr class="odd">
<td>PowerIQ 出力</td>
<td>PowerIQ 3.0 (Gen2) 対応</td>
</tr>
<tr class="even">
<td>合計最大出力</td>
<td>250W</td>
</tr>
<tr class="odd">
<td>搭載ポート詳細</td>
<td>3 (USB-C × 2、USB-A × 1)</td>
</tr>
<tr class="even">
<td>バッテリー容量</td>
<td>27650mAh</td>
</tr>
<tr class="odd">
<td>パッケージ内容</td>
<td>Anker Prime Power Bank (27650mAh, 250W)、USB-C＆USB-Cケーブル (0.6m) 、取扱説明書、24ヶ月保証 + 6ヶ月 (Anker Japan 公式サイト会員登録後) 、カスタマーサポート</td>
</tr>
</tbody>
</table>
</div>
</figure>
</div>
<div id="fig-input_170W" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-input_170W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_input_170W.png" class="lightbox" data-gallery="quarto-lightbox-gallery-15" title="[@Anker250W]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_input_170W.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Anker250W">(アンカー・ジャパン株式会社 2024)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-input_170W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;7: 1ポート最大140W, 2ポート最大170Wで本体に充電可能
</figcaption>
</figure>
</div>
<div id="fig-output_fig" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-output_fig-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-output_fig" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-output_3port" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-output_3port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker_250W_output_3port.png" class="lightbox" data-gallery="fig-output_fig" title="図&nbsp;8&nbsp;(a): 3ポート同時利用時"><img src="https://pottal-portal.com/PtPr3/post_images/Anker_250W_output_3port.png" class="img-fluid figure-img" data-ref-parent="fig-output_fig"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-output_3port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) 3ポート同時利用時
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-output_fig" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-output_2port" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-output_2port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker_250W_output_2port.png" class="lightbox" data-gallery="fig-output_fig" title="図&nbsp;8&nbsp;(b): 2ポート同時利用時"><img src="https://pottal-portal.com/PtPr3/post_images/Anker_250W_output_2port.png" class="img-fluid figure-img" data-ref-parent="fig-output_fig"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-output_2port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) 2ポート同時利用時
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-output_fig" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-output_1port" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-output_1port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker_250W_output_1port.png" class="lightbox" data-gallery="fig-output_fig" title="図&nbsp;8&nbsp;(c): 1ポート利用時"><img src="https://pottal-portal.com/PtPr3/post_images/Anker_250W_output_1port.png" class="img-fluid figure-img" data-ref-parent="fig-output_fig"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-output_1port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) 1ポート利用時
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-output_fig-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;8: <span class="citation" data-cites="Anker250W">(アンカー・ジャパン株式会社 2024)</span>より筆者引用の出力表
</figcaption>
</figure>
</div>
</section>
<section id="良かったところ" class="level2">
<h2 class="anchored" data-anchor-id="良かったところ">良かったところ</h2>
<ul>
<li>◎: USB-C1, C2の同時利用でも240W(140+100W)出力可能</li>
<li>◎: (少なくとも筆者の試した限り)USB-Cのみの利用では瞬断しない</li>
<li>◎: ディスプレイでバッテリー残量・入出力が確認できる</li>
<li>◎: アプリ経由でUSB-C1ポートの入出力を切り替えられる</li>
<li>◎: 99.54Wh(27650mAh)という機内持ち込みに制限がないギリギリの容量</li>
<li>◎: 39分で満充電可能</li>
<li>◯: スマートフォンから音を鳴らして充電器を探せる(要Bluetooth接続)</li>
<li>◯: 出力はUSB PD PPS対応</li>
<li>◯: パススルー充電対応</li>
</ul>
<section id="usb-c1-c2の同時利用でも240w140100w出力可能" class="level4">
<h4 class="anchored" data-anchor-id="usb-c1-c2の同時利用でも240w140100w出力可能">◎: USB-C1, C2の同時利用でも240W(140+100W)出力可能</h4>
<p>残念ながら、筆者の手元にはUSB PD 140Wや100Wを要求するガジェットがないため検証はできませんが、カタログスペック上はこのAnker Prime Power Bank 27650mAh 250WはUSB-C1ポートで140W出力しながらUSB-C2ポートでも100Wの出力を行えます。</p>
<p>ゲーミングノートパソコンなどは100W以上の出力を持つACアダプターが同梱されているものが多いですが、それらは専用のポートを要し、USB PDは100Wまで対応という場合が多いため、現状140Wというフルパワー充電を行う相手が少ないという残念な状況です。手っ取り早く140W出力を試すには、もう一台Anker Prime Power Bank 27650mAh 250Wを用意しなければなりません<sup>1</sup>。</p>
<aside id="footnotes" class="footnotes footnotes-end-of-block">
<ol>
<li id="fn1"><p>MagSafe 3を搭載したMacbook Proでも140W充電は可能です。↩︎</p></li>
</ol>
</aside>
</section>
<section id="sec-6-2" class="level4">
<h4 class="anchored" data-anchor-id="sec-6-2">◎: (少なくとも筆者の試した限り)USB-Cのみの利用では瞬断しない</h4>
<p>少なくとも筆者の試した限りでは、USB Standard-A(以下USB-A)を使わない限り(=つまりUSB-C1,C2ポートだけを使う限り)、デバイスを接続しても再ネゴシエーションに伴う瞬断(瞬停: 瞬間停止)は確認されませんでした。これは、Anker Prime Power Bank 27650mAh 250WがUSB-C1ポートで140W出力しながらUSB-C2ポートでも100Wの出力を行えるので、PDO(供給できる電力のリスト)の再設定が必要ないからだと考えられます。 ただし、USB-C2ポートで140W充電をしている際にUSB-C1に100Wを要求した場合は瞬断が起こるかもしれません。(逆では起こらないと考えられます。)</p>
<p>筆者の試した限り、<strong>USB-Aを使わない限り瞬断は確認できませんでした</strong>。裏を返せば、USB-Aを使用すると一定の条件下で瞬断が生じました。早い話がUSB-C1(もしくはUSB-C2)とUSB-Aを使用している時に余っているUSB-C2(あるいはUSB-C1)を使用するとUSB-Aポートで瞬断を起こします。 バッテリーを搭載せず、USB給電で駆動する(=つまり、再ネゴシエーションによる瞬断が致命的になる)デバイスというのは多くの場合、USB-Aを使用していることが多い(ような気がする)ので<sup>2</sup>、この点には留意する必要があります。</p>
<aside id="footnotes-2" class="footnotes footnotes-end-of-block">
<ol start="2">
<li id="fn2"><p>逆に筆者の手元にある再ネゴシエーションが致命的なUSB-Cデバイスといえば、USBハブ, モバイルモニター, Chromecast with Google TVくらいでしょうか。USBハブとモバイルモニターに関してはわざわざUSB-AtoCで給電することはせず、CtoCで給電するので、実質、Chromecast with Google TVくらいですが、これをモバイルバッテリーに繋いで運用することはあるのでしょうか…?↩︎</p></li>
</ol>
</aside>
</section>
<section id="ディスプレイでバッテリー残量入出力が確認できる" class="level4">
<h4 class="anchored" data-anchor-id="ディスプレイでバッテリー残量入出力が確認できる">◎: ディスプレイでバッテリー残量・入出力が確認できる</h4>
<p>意外と便利だったのが、ディスプレイによるバッテリー残量や入出力の詳細表示でした。</p>
<div id="fig-display" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_display.png" class="lightbox" data-gallery="quarto-lightbox-gallery-19" title="[@Anker250W]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_display.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Anker250W">(アンカー・ジャパン株式会社 2024)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-display-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;9: 充電状況をリアルタイムで確認可能
</figcaption>
</figure>
</div>
<p>バッテリー残量はともかく、入出力のW(ワット)や電流・電圧が分かったところでユーザーがどうこうできるわけではありませんが、急速充電されていないことに気付けたり<sup>3</sup>、何より見ていて楽しいです。 また、あと何分くらいバッテリーが持つのか、あるいは(本機を充電している際には)何分くらいで100%まで充電されるかも分かります。</p>
<aside id="footnotes-3" class="footnotes footnotes-end-of-block">
<ol start="3">
<li id="fn3"><p>USB PDの設定をユーザー側で変えることは基本的にはできないので、W数や電圧・電流が分かったところでどうしようもないのですが、例えばUSB PDで60W(3A)を超える充電を行うには、5A対応のケーブルが必要になるので、確認事項にはなります。また、機器の設定によっては特定の時間帯は急速充電を行わないことでバッテリー寿命を延ばす機能が働くこともあるので、この設定を見直すこともできます。と、まあこのように何らかのアクションが取れることもあるので、丸っ切り無駄というわけでもありません。↩︎</p></li>
</ol>
</aside>
</section>
<section id="アプリ経由でusb-c1ポートの入出力を切り替えられる" class="level4">
<h4 class="anchored" data-anchor-id="アプリ経由でusb-c1ポートの入出力を切り替えられる">◎: アプリ経由でUSB-C1ポートの入出力を切り替えられる</h4>
<p>本機は賢いので、スマートフォン等を充電する際に、充電するつもりが逆に充電されていてスマホ側のバッテリーが減っているなんてことは起こらないのですが、入出力の切り替え機能はあるに越したことはありません。(実際、レビューのためにモバイルバッテリーでモバイルバッテリーを充電する際には役立ちました) 筆者はUSB PD対応のノートパソコンを手放してしまったので確かめられないのですが、ノートパソコンを充電する際などはこうした自体が生じやすいのできっと役立つと思います。</p>
</section>
<section id="wh27650mahという機内持ち込みに制限がないギリギリの容量" class="level4">
<h4 class="anchored" data-anchor-id="wh27650mahという機内持ち込みに制限がないギリギリの容量">◎: 99.54Wh(27650mAh)という機内持ち込みに制限がないギリギリの容量</h4>
<p><a href="https://ana-support.my.site.com/jajp/s/article/answers6174ja">ANAの「【国内・国際線／海外ツアー】リチウムイオン電池が内蔵された一般電子機器・モバイルバッテリーの取り扱いについて」というページ</a>には、</p>
<blockquote class="blockquote">
<p>リチウムイオン電池（バッテリー）はワット時定格量が100Wh以下のものは機内へお持ち込みできます。お預けはできません。 リチウムイオン電池（バッテリー）はワット時定格量が100Whを超え160Wh以下のものは2個まで機内持ち込みできます。お預けはできません。</p>
<p>※ワット時定格量（Wh）の記載がないモバイルバッテリーが多く流通しております。</p>
<p>　ワット時定格量（Wh）が不明な場合には、機内持ち込み・お預け共に不可となります。</p>
<p>　ご搭乗前にワット時定格量（Wh）を事前にお調べいただくようお願いいたします。</p>
</blockquote>
<p>という記載があります<span class="citation" data-cites="ANA">(ANA)</span>。</p>
<p>図&nbsp;4 (f)に示した通り、本機には99.54Whとワット時定格量(Wh)の記載があり、なおかつ100Wh以下のため、制約なく機内に持ち込むことが出来ます(預け入れは出来ません)。トラベル用途にもぴったりのギリギリを攻めた容量に設定したのはナイスです。</p>
</section>
<section id="分で満充電可能" class="level4">
<h4 class="anchored" data-anchor-id="分で満充電可能">◎: 39分で満充電可能</h4>
<p>100W級のACアダプター・モバイルバッテリーを2台持っていることが前提となりますが、Anker Prime Power Bank 27650mAh 250Wモデルは充電器を2つ(USB-C1, C2ポートにそれぞれ)繋いで、最大170Wで急速充電が行え、公称37分で0%→100%まで充電することができます。 筆者が実際に測定を行ったところ、公称値に近い39分で100%まで充電できました(図&nbsp;14)。 今回の測定では、29分(90%)時点で本機のバッテリー温度が46℃に達してしまったため充電速度に制限がかかってしまい、公称値である37分で100%充電することができませんでしたが、ファンの風を当てるなどして適切に冷やせれば達成できそうです。(他にも、USB電力メーターAVHzY CT-3の不調で瞬断が起き、電圧・電流の乱高下してしまった影響もあると思います)</p>
<p>充電時の発熱や、詳しい挙動はSection 8-1: 入力(バッテリーへの充電)についてにて紹介します。</p>
</section>
<section id="スマートフォンから音を鳴らして充電器を探せる要bluetooth接続" class="level4">
<h4 class="anchored" data-anchor-id="スマートフォンから音を鳴らして充電器を探せる要bluetooth接続">◯: スマートフォンから音を鳴らして充電器を探せる(要Bluetooth接続)</h4>
<p>Bluetoothで接続していないといけませんが、Anker Prime Power Bank 27650mAh 250Wモデルに搭載されているスピーカーから音を鳴らして、本機種を探すことができます。Bluetoothに接続していないといけませんが… 大事なことなので2回言いました。</p>
<p>地味に便利な機能ですが、Bluetooth接続していないと使えないので、部屋の中で探すくらいしか使い道がありません。AnkerはEufy Security SmartTrack Card (紛失防止トラッカー)を作っているので、やろうと思えばちゃんとした紛失防止機能を搭載することだって可能なはずなのに、どうしてこんな中途半端な仕事をするのか不思議でなりません。 せめて、最後に接続したときの(スマホの)位置情報くらい残せれば、どこに置き忘れたのか見当が付きますが、そういったこともできません。</p>
<p>ですが、まあ無いよりマシなので一応「◯」をつけました。</p>
<div id="fig-eufy" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-eufy-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_DSC0196.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-20" title="図&nbsp;10: Eufy Security SmartTrack Card (紛失防止トラッカー)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0196.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-eufy-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;10: Eufy Security SmartTrack Card (紛失防止トラッカー)
</figcaption>
</figure>
</div>
</section>
<section id="出力はusb-pd-pps対応" class="level4">
<h4 class="anchored" data-anchor-id="出力はusb-pd-pps対応">◯: 出力はUSB PD PPS対応</h4>
<p>TypeCポート(USB-C1, C2)ポートからは4.5-21V⎓5A(22.5-105W)の範囲でUSB PD PPS出力が行えます。 USB PD PPSは充電電圧と電流をより細かく制御できる仕様で、充電されるデバイスへの電力供給の効率を高めることができます。</p>
<p>USB PD PPS自体は別に充電速度を直接高める規格ではないのですが、例えば筆者の手元にあるGalaxy S22 Ultraなどは、USB PD(60W)では「超急速充電」にはならず、USB PD PPS(65W以上)でないと「超急速充電」と表示されません。ちなみに5Aケーブルを接続すると同じUSB PD PPS(65W)充電器でも「超急速充電2.0」と表示され、より速く充電することが可能です。 Galaxy S22 Ultraの充電(入力)は45WまでなのでUSB PD(60W)であっても問題はないはずなのですが、USB PD PPSでないと本気を出してくれないようです。 これは何も筆者の手元にある端末だけでなく、Galaxyシリーズ全体がそういう仕様なようです<span class="citation" data-cites="PCWatch">(山田 2019)</span>。</p>
<p>やや本筋から逸れてしまいましたが、USB PD PPSであればUSB PD以上に効率良く(機種によってはより高速に)充電できるので嬉しい限りです。 願わくば、出力だけでなく「入力」もUSB PD PPSに対応し、本機種(Anker Prime Power Bank 27650mAh 250Wモデル)を急速充電できれば嬉しいのですが… この話については、デメリットセクションの「✗:充電時の極端な温度制御」にてしたいと思います。</p>
</section>
<section id="パススルー充電対応" class="level4">
<h4 class="anchored" data-anchor-id="パススルー充電対応">◯: パススルー充電対応</h4>
<p>パススルー充電、つまり本機種を充電しながら本機種からの給電(接続デバイスへの充電)が行えます。 中途半端なパススルー対応機種だと、接続しているデバイスへの充電が終わらない限り自身への充電は行えないなんてことがありますが、本機種は、接続デバイスへの給電をしつつ余った電力で自身への充電も行えます。 <img src="https://latex.codecogs.com/png.latex?%0A%E8%87%AA%E8%BA%AB%E3%81%B8%E3%81%AE%E5%85%85%E9%9B%BB%E9%9B%BB%E5%8A%9B%20=%20%E6%9C%AC%E6%A9%9F%E7%A8%AE%E3%81%B8%E3%81%AE%E5%85%A5%E5%8A%9B%E9%9B%BB%E5%8A%9B%20-%20%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%9F%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%B8%E3%81%AE%E5%87%BA%E5%8A%9B%E9%9B%BB%E5%8A%9B%0A"> となるので、例えば本機種に100W電源を繋ぎつつ30Wで接続したデバイスへの給電を行った場合、70W余るのでその分を自身への充電に充てることができるというイメージです。</p>
</section>
</section>
<section id="イマイチなところ" class="level2">
<h2 class="anchored" data-anchor-id="イマイチなところ">イマイチなところ</h2>
<ul>
<li>✗: ディスプレイの盛り上がり</li>
<li>✗: 指紋が目立つディスプレイ</li>
<li>✗: 充電時のやや極端な温度制御</li>
<li>△: TypeAデバイスとの干渉を起こすポート配置</li>
<li>△: 付属ケーブルの意味不明な印字</li>
<li>△: (1つしかボタンがないので仕方がないとは言え)不便なUX</li>
</ul>
<section id="ディスプレイの盛り上がり" class="level4">
<h4 class="anchored" data-anchor-id="ディスプレイの盛り上がり">✗: ディスプレイの盛り上がり</h4>
<p>見てください、この無駄に盛り上がったディスプレイを(図&nbsp;11)。 物理的に傷が付きやすい凸型の形状です。むしろ少し周りを厚くしてディスプレイ部分を凹ませるべきでしょう。</p>
<div id="fig-non-flatdisplay" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-non-flatdisplay-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_DSC0087.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-21" title="図&nbsp;11: ディスプレイが盛り上がっており傷が付きやすい形状"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0087.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-non-flatdisplay-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;11: ディスプレイが盛り上がっており傷が付きやすい形状
</figcaption>
</figure>
</div>
<p>何を考えてこんな形にしたのか、理解に苦しみます。</p>
</section>
<section id="指紋が目立つディスプレイ" class="level4">
<h4 class="anchored" data-anchor-id="指紋が目立つディスプレイ">✗: 指紋が目立つディスプレイ</h4>
<p>モバイルバッテリーに何を望むことではないのかもしれませんが、ディスプレイ周りのガラスは指紋が目立つ仕上げとなっています。 美しくありません。</p>
</section>
<section id="sec-7-3" class="level4">
<h4 class="anchored" data-anchor-id="sec-7-3">✗: 充電時のやや極端な温度制御</h4>
<p>本機種を充電する際の仕様がピーキー過ぎます。本機種は、46℃以上でバッテリー保護のための充電制御を行うような挙動を見せるのですが、それまで(2ポート使い)160Wで充電していたところを、46℃で急に60Wに落とします。もしかするとさらに高温になればより入力を低下させるかもしれませんが、危険なのでこれ以上の検証は行っておりません。 46℃以上というのは、モバイルバッテリーにとって好ましくない温度で、Anker自身も</p>
<blockquote class="blockquote">
<p>最近のバッテリーはある程度の条件下でもしっかりと機能するように設計されていますが、極端な環境下での充電はやはりバッテリーに負荷がかかります。特にリチウムイオン電池は熱に敏感で、バッテリーの温度が約45℃以上になると劣化が始まり、劣化が進むと蓄えられる電力が低下するため、バッテリーの寿命にも影響が出ます。一般的に約5℃～45℃の環境では問題なく充電ができますが、約5℃を下回る寒い環境下はバッテリーに好ましくない影響を及ぼします。バッテリーの保管や使用は、約5℃～45℃の範囲が適切です。 <span class="citation" data-cites="AnkerMagazine">(アンカー・ジャパン株式会社 2022a)</span></p>
</blockquote>
<p>としています。45℃までが適切な温度であるならば、<strong>45℃を超える前に</strong>温度制御をするべきであり、46℃になってから慌てて行うのは(無いよりマシとは言え)イマイチな気がします。42℃程度までは本来の充電速度で充電し、42~45℃で少しブレーキをかけ45℃を超えないようにし、46℃以上でさらなる充電制御を行うという方が賢明に思えます。 「最大170Wで充電可能! これにより37分で満充電」と謳うために敢えてギリギリまで充電制限をしないようにしているのではないかと穿った見方をしてしまいそうになりますね。実際、170Wで充電すると45℃を超え充電速度が制限されてしまい、公称値である37分は達成できませんでした(図&nbsp;14)。</p>
<p>せっかく出力側はUSB PD PPSに対応しているのだから、本機種への入力もUSB PD PPSに対応し、発熱を抑えた充電ができるようになって欲しいものです。</p>
</section>
<section id="typeaデバイスとの干渉を起こすポート配置" class="level4">
<h4 class="anchored" data-anchor-id="typeaデバイスとの干渉を起こすポート配置">△: TypeAデバイスとの干渉を起こすポート配置</h4>
<p>どうしてこんな余計なことをしたのかわかりませんが、ポートの配置が旧モデルや下位モデルと変わっています(図&nbsp;12)。</p>
<div id="fig-port" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://www.ankerjapan.com/cdn/shop/products/A1289_0000_71Linf_GHuL._AC_SL1500.jpg?crop=center&amp;height=525&amp;v=1662468522&amp;width=525" class="lightbox" data-gallery="quarto-lightbox-gallery-22" title="[@Anker737]より筆者引用"><img src="https://www.ankerjapan.com/cdn/shop/products/A1289_0000_71Linf_GHuL._AC_SL1500.jpg?crop=center&amp;height=525&amp;v=1662468522&amp;width=525" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Anker737">(アンカー・ジャパン株式会社 2022b)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://f.hubspotusercontent20.net/hubfs/5012528/Products/AnkerPrimePowerBank20000/intro-4.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-23" title="[@Anker200W]より筆者引用"><img src="https://f.hubspotusercontent20.net/hubfs/5012528/Products/AnkerPrimePowerBank20000/intro-4.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Anker200W">(アンカー・ジャパン株式会社 2023b)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-port-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;12: 旧モデルや下位モデルのポート配置
</figcaption>
</figure>
</div>
<p>このせいで、TypeAポートに直接接続するタイプのデバイスではTypeCポートと干渉を起こしてしまいます(図&nbsp;13)。</p>
<div id="fig-port-position" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-port-position-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_DSC0199.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-24" title="図&nbsp;13: 幅広のUSB機器との干渉"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_DSC0199.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-port-position-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;13: 幅広のUSB機器との干渉
</figcaption>
</figure>
</div>
<p>どちらかと言えば、ポート幅を専有するこちらのデバイスの方が悪く、延長ケーブルを噛ませれば解決しますが、従来モデルや下位モデルのポート配置では起こらないため、余計なことをしてくれたなぁという悪印象を持ってしまいます。</p>
</section>
<section id="sec-7-5" class="level4">
<h4 class="anchored" data-anchor-id="sec-7-5">△: 付属ケーブルの意味不明な印字</h4>
<p>開封の儀で示した通り、本製品に付属するケーブルには「MAX 140W」という印字があります(図&nbsp;3 (b))。しかし、AVHzY CT-3を用いてケーブルを調べたところ実際には50V5A(250W)まで対応しています。また、USB PD EPR対応ケーブルは(たとえソース側が140Wまでであろうと)50V5Aに対応していなければなりません<span class="citation" data-cites="USBTypeC2">(SpecWerkz &amp; Saunders 2023)</span>。</p>
<blockquote class="blockquote">
<h5 id="electrical-requirements" class="anchored">3.11.1 Electrical Requirements</h5>
<p>Extended Power Range cables have additional requirements to assure that these cables can deliver the full defined voltage and current range for <em>USB PD</em> EPR operation.EPR cables <em>shall</em> functionally support a reported 50 V and 5 A operation. The minimum functional voltage that a cable <em>shall</em> support is 50.9 V. The electrical components potentially in the path of VBUS in an EPR cable, e.g., bypass capacitors, <em>should</em> be minimally rated for 63 V. <span class="citation" data-cites="USBTypeC2">(SpecWerkz &amp; Saunders 2023)</span></p>
</blockquote>
<p>ケーブルとしては正しくUSB PD 240W(USB PD EPRの上限は240W)まで対応しているのにもかかわらず、まるでケーブルが140Wまでしか対応していないような表記は誤解を招き不適切であると筆者は考えます。</p>
</section>
<section id="つしかボタンがないので仕方がないとは言え不便なux" class="level4">
<h4 class="anchored" data-anchor-id="つしかボタンがないので仕方がないとは言え不便なux">△: (1つしかボタンがないので仕方がないとは言え)不便なUX</h4>
<p>本製品の右側面にはボタンが1つ付いており(図&nbsp;4 (d))、これを押すことで画面の操作を行うことになります。ボタンは4方向に動いたりするわけではないので、クリック(単押し)か、素早くダブルクリック(2回押す)かで操作することになり、目的の画面にまで変遷し設定を変更するのが面倒です。幸い、Bluetoothのオンオフ以外の操作はアプリからも行えるので良いのですが…。</p>
</section>
</section>
<section id="sec-8" class="level2">
<h2 class="anchored" data-anchor-id="sec-8">性能について</h2>
<p>本製品(Anker Prime Power Bank 27650mAh 250Wモデル)への入力(充電)能力と、本製品からの出力(他のデバイスへの給電)能力について、詳しくレビューします。</p>
<section id="sec-8-1" class="level3">
<h3 class="anchored" data-anchor-id="sec-8-1">入力(バッテリーへの充電)について</h3>
<p>以下の表(表&nbsp;2)の通り、本製品にはUSB TypeCでのみ充電を行えます。</p>
<p>単ポートで最大140W(28V5A)の充電が行えますが、筆者は100Wまでの充電器しか持っていないため、充電速度や発熱具合についてはレビューできません。</p>
<p>また、珍しいことにTypeCポートを2つ使って本製品を充電することが可能で、その場合は合計で最大170Wの電力で充電することができ、公称37分(実測39分)で0→100%までの満充電が行えます(図&nbsp;14)。ただし、170W充電はバッテリーが55%以上まで充電された時のみ可能で、それまでは最大150W程度で充電されることを確認しています。</p>
<div id="tbl-input" class="quarto-float anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-input-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;2: 入力(バッテリーへの充電)スペック
</figcaption>
<div aria-describedby="tbl-input-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="table">
<colgroup>
<col style="width: 23%">
<col style="width: 17%">
<col style="width: 17%">
<col style="width: 38%">
</colgroup>
<thead>
<tr class="header">
<th>ポート</th>
<th>スペック</th>
<th>W数</th>
<th style="text-align: center;">備考</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>USB-C1 or USB-C2</td>
<td><p>5V⎓3A</p>
<p>9V⎓3A</p>
<p>15V⎓3A</p>
<p>20V⎓5A</p>
<p>28V⎓5A</p></td>
<td><p>15W</p>
<p>27W</p>
<p>45W</p>
<p>100W</p>
<p>140W</p></td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td>USB-C1 and USB-C2</td>
<td></td>
<td>170W</td>
<td style="text-align: center;">バッテリー残量55%以上から有効</td>
</tr>
</tbody>
</table>
</div>
</figure>
</div>
<p>まず初めに、「最大170W充電で最短37分で満充電可能」という謳い文句を試すために、<a href="https://amzn.asia/d/gJrEO2A">Baseus 100W PD 充電器CCGAN100CS</a>と<a href="https://amzn.asia/d/5IBX8WU">Baseus PowerCombo Pro 100W</a>を用いて本製品を充電してみることにしました。</p>
<p>電流及び電圧を表示するだけのUSB電力メーターはいくつか持っているのですが、これを記録できるのはあいにくAVHzY CT-3 1台しか持っていなかったので、USB-C1ポート側の電力(電流・電圧)を測定しました。その結果が図&nbsp;14です。また、Ankerアプリ側でのバッテリー温度の監視(図&nbsp;15)とサーマルカメラを使っての充電器、本製品の温度も測定しました(図&nbsp;16)。</p>
<p>結論から言うと、29分(90%)時点で本機のバッテリー温度が46℃に達してしまったため充電速度に制限がかかってしまい、公称値である37分で100%充電することができませんでしたが、それに近い39分で満充電が行えました。</p>
<div id="fig-39min_charge" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-39min_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_W150W.png" class="lightbox" data-gallery="quarto-lightbox-gallery-25" title="Anker Prime Power Bank(27650mAh 250Wモデル)170W充電 AVHzY CT-3を用いてUSB-C1ポート側を筆者測定 電圧・電流の乱高下はCT-3による影響(アーティファクトではない)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_W150W.png" class="img-fluid figure-img"></a></p>
<figcaption>Anker Prime Power Bank(27650mAh 250Wモデル)170W充電<br>AVHzY CT-3を用いてUSB-C1ポート側を筆者測定<br>電圧・電流の乱高下はCT-3による影響(アーティファクトではない)</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-39min_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;14: <a href="https://amzn.asia/d/gJrEO2A">Baseus 100W PD 充電器CCGAN100CS</a>と<a href="https://amzn.asia/d/5IBX8WU">Baseus PowerCombo Pro 100W</a>を用いて170W充電をした様子(片ポートのみのため、最大80W)
</figcaption>
</figure>
</div>
<div id="fig-170W_temp" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-170W_temp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_3.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-26" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_3.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_4.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-27" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_4.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_5.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-28" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_5.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_6.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-29" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_6.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_7.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-30" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_7.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_8.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-31" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_8.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_9.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-32" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_9.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 25.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_temp_170W_10.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-33" title="図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視 スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_temp_170W_10.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-170W_temp-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;15: Ankerアプリを使って充電状況とバッテリー温度を監視<br>スクショのタイミングで45℃と表示されてしまったが、90.69%時点で46℃に到達し、充電制限が始まった
</figcaption>
</figure>
</div>
<div id="fig-ThermalCam_170W" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ThermalCam_170W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-ThermalCam_170W" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-ThermalCam_170W_BaseusPro" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-ThermalCam_170W_BaseusPro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_ThermalCam_170W_1.jpg" class="lightbox" data-gallery="fig-ThermalCam_170W" title="図&nbsp;16&nbsp;(a): Baseus PowerCombo Pro 100W 48℃程度"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_ThermalCam_170W_1.jpg" class="img-fluid figure-img" data-ref-parent="fig-ThermalCam_170W"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-ThermalCam_170W_BaseusPro-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) Baseus PowerCombo Pro 100W 48℃程度
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-ThermalCam_170W" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-ThermalCam_170W_Baseus100" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-ThermalCam_170W_Baseus100-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_ThermalCam_170W_2.jpg" class="lightbox" data-gallery="fig-ThermalCam_170W" title="図&nbsp;16&nbsp;(b): Baseus 100W PD 充電器 57℃程度"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_ThermalCam_170W_2.jpg" class="img-fluid figure-img" data-ref-parent="fig-ThermalCam_170W"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-ThermalCam_170W_Baseus100-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) Baseus 100W PD 充電器 57℃程度
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-ThermalCam_170W" style="flex-basis: 33.3%;justify-content: flex-start;">
<div id="fig-ThermalCam_170W_Anker" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-ThermalCam_170W_Anker-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_ThermalCam_170W_3.jpg" class="lightbox" data-gallery="fig-ThermalCam_170W" title="図&nbsp;16&nbsp;(c): Anker Prime Power Bank 52℃程度"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_ThermalCam_170W_3.jpg" class="img-fluid figure-img" data-ref-parent="fig-ThermalCam_170W"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-ThermalCam_170W_Anker-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(c) Anker Prime Power Bank 52℃程度
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ThermalCam_170W-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;16: サーマルカメラ(FLIR ONE Gen3)を用いての測定
</figcaption>
</figure>
</div>
<p>図&nbsp;16 (c)を見ると、発熱は端子の近くで顕著であり、50℃を超えていることが分かります。分解してみないことには分かりませんが、おそらくこの付近に基板があり、その上にある様々なパーツが発熱しているだけであって、バッテリーそのものはもう少し低い温度が保たれているのではないかと考えられます。少なくとも、旧モデルではそれに近い構造となっていました<span class="citation" data-cites="Teardown">(ChargerLAB 2022)</span>。</p>
<p>2つのポートを使って170W充電をする際、気になるのが電力制御です。図&nbsp;15に示した通り、だいたい同じくらいの電力を要求し片方では18V4A, もう片方では19V4A程度で150W超える電力で充電されていました。 PDOは充電器側が提示した20V5Aを要求している様子を確認できました(図&nbsp;17)。</p>
<div id="fig-PDO" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Anker250W_PDO.png" class="lightbox" data-gallery="quarto-lightbox-gallery-37" title="図&nbsp;17: キャプチャしたPDO"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_PDO.png" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-PDO-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;17: キャプチャしたPDO
</figcaption>
</figure>
</div>
<p>続いて、<a href="https://amzn.asia/d/gJrEO2A">Baseus 100W PD 充電器CCGAN100CS</a>を用いて100Wで充電した時の電力推移と発熱です。 AVHzY CT-3が周期性を持った荒ぶりを見せたせいでグラフがすごいことになっていますが、この乱高下を無視すれば、一貫して19V4.8Aほどで充電されていることが分かります(図&nbsp;18)。また、0→100%の満充電までにかかった時間は1時間7分ほどでした。</p>
<p>ベッドの上という割と放熱的には酷い環境でしたが、本体温度も41.9℃ほどで(図&nbsp;19)、バッテリー温度も最大43℃と、当然とは言え170W充電時よりも低く抑えられています(図&nbsp;20)。 (図&nbsp;19と図&nbsp;20は同時に測定したわけではないこと、サーマルカメラの結果はあくまで目安であることを留意しておいてください。)</p>
<div id="fig-100W_charge" class="quarto-figure quarto-figure-center quarto-float anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_Baseus100W.png" class="lightbox" data-gallery="quarto-lightbox-gallery-38" title="Anker Prime Power Bank(27650mAh 250Wモデル)100W充電 AVHzY CT-3を用いて筆者測定 電圧・電流の乱高下はCT-3による影響(アーティファクトではない)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_Baseus100W.png" class="img-fluid figure-img"></a></p>
<figcaption>Anker Prime Power Bank(27650mAh 250Wモデル)100W充電<br>AVHzY CT-3を用いて筆者測定<br>電圧・電流の乱高下はCT-3による影響(アーティファクトではない)</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;18: <a href="https://amzn.asia/d/gJrEO2A">Baseus 100W PD 充電器CCGAN100CS</a>を用いて100W充電をした様子
</figcaption>
</figure>
</div>
<div id="fig-ThermalCam-100W_charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ThermalCam-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_ThermalCam_100W_1.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-39" title="図&nbsp;19: サーマルカメラ(FLIR ONE Gen3)を用いての測定(100W充電時)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_ThermalCam_100W_1.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Anker250W_ThermalCam_100W_2.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-40" title="図&nbsp;19: サーマルカメラ(FLIR ONE Gen3)を用いての測定(100W充電時)"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_ThermalCam_100W_2.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ThermalCam-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;19: サーマルカメラ(FLIR ONE Gen3)を用いての測定(100W充電時)
</figcaption>
</figure>
</div>
<div id="fig-temp-100W_charge" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-temp-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<a href="../post_images/Anker250W_100W.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-41" title="図&nbsp;20: Ankerアプリでの電力及び温度"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_100W.jpg" class="img-fluid figure-img"></a>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-temp-100W_charge-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;20: Ankerアプリでの電力及び温度
</figcaption>
</figure>
</div>
</section>
<section id="出力について" class="level3">
<h3 class="anchored" data-anchor-id="出力について">出力について</h3>
<p>AVHzY CT-3を用いて調べたところ、本製品(Anker Prime Power Bank 27650mAh 250Wモデル)は、以下の出力が可能だということが分かりました(表&nbsp;3)。公式サイトのスペックシートに乗っていませんが、<strong>USB PD PPSにも対応しています</strong>。</p>
<div id="tbl-output" class="quarto-float anchored">
<figure class="quarto-float quarto-float-tbl figure">
<figcaption class="quarto-float-caption-top quarto-float-caption quarto-float-tbl" id="tbl-output-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
表&nbsp;3: 出力(バッテリーからの充電)スペック
</figcaption>
<div aria-describedby="tbl-output-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="table">
<colgroup>
<col style="width: 22%">
<col style="width: 21%">
<col style="width: 17%">
<col style="width: 36%">
</colgroup>
<thead>
<tr class="header">
<th>ポート</th>
<th>スペック</th>
<th>W数</th>
<th style="text-align: center;">備考</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>USB-C1 or USB-C2</td>
<td><p>5V⎓3A</p>
<p>9V⎓3A</p>
<p>12V⎓1.5A</p>
<p>12V⎓3A</p>
<p>15V⎓3A</p>
<p>20V⎓5A</p>
<p>28V⎓5A</p>
<p>4.5-21V⎓5A(PPS)</p></td>
<td><p>15W</p>
<p>27W</p>
<p>18W</p>
<p>36W</p>
<p>45W</p>
<p>100W</p>
<p>140W</p>
<p>22.5-105W</p></td>
<td style="text-align: center;"><p>-</p>
<p>-</p>
<p>-</p>
<p>筆者確認</p>
<p>-</p>
<p>-</p>
<p>-</p>
<p>筆者確認</p></td>
</tr>
<tr class="even">
<td>USB-A</td>
<td><p>5V⎓3A</p>
<p>9V⎓2A</p>
<p>10V⎓6.5A</p>
<p>12V⎓1.5A</p></td>
<td><p>15W</p>
<p>18W</p>
<p>65W</p>
<p>18W</p></td>
<td style="text-align: center;"><p>-</p>
<p>-</p>
<p>要OPPO対応機器と専用ケーブル</p>
<p>-</p></td>
</tr>
</tbody>
</table>
</div>
</figure>
</div>
<div id="fig-output-typec-list" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-output-typec-list-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_20240415_110607.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-42" title="急速充電リスト"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_20240415_110607.jpg" class="img-fluid figure-img"></a></p>
<figcaption>急速充電リスト</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_20240415_110642.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-43" title="USB PD PDO"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_20240415_110642.jpg" class="img-fluid figure-img"></a></p>
<figcaption>USB PD PDO</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-output-typec-list-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;21: AVHzY CT-3を用いて調べたTypeCポートの出力スペック(付属のUSB PD EPR対応ケーブルでテスト)
</figcaption>
</figure>
</div>
<div id="fig-output-typeA-list" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-output-typeA-list-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Anker250W_20240415_110825.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-44" title="USB-Aポートの急速充電リスト"><img src="https://pottal-portal.com/PtPr3/post_images/Anker250W_20240415_110825.jpg" class="img-fluid figure-img"></a></p>
<figcaption>USB-Aポートの急速充電リスト</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-output-typeA-list-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;22: AVHzY CT-3を用いて調べたTypeAポートの出力スペック
</figcaption>
</figure>
</div>
<p>なお、上記の表は1ポートのみを使用した時のものです。図&nbsp;8に示した通り、複数ポートを利用する際にはUSB-C1ポートを除いて出力に制限がかかります。とは言っても、3ポート(つまり全てのポート)を利用した場合にUSB-C2ポートの最大出力が92Wまでに制限されること以外は制限らしい制限もなく、ほとんどの製品はフルパワーで充電されると思います。(USB-Aでの65W充電は、OPPOの一部の対応製品と専用ケーブルを使ってのみ可能なので考慮していません)</p>
<p>また、要旨やSection 6-2で述べた通り、<strong>USB-Aポートを使用しない限り</strong>機器の追加接続及び取り外しに伴う瞬断(瞬停)は発生しませんでした。これは、使用している機器が100W以下の電力しか要求せず、PDO(供給できる電力のリスト)の再設定が必要ないからだと考えられます。USB-C2ポートで140W充電をしている時にUSB-C1ポートを使用した場合どうなるかは分かりません。</p>
</section>
</section>
<section id="まとめ" class="level2">
<h2 class="anchored" data-anchor-id="まとめ">まとめ</h2>
<p>寸法もバッテリー容量も取り回しの良いギリギリのサイズを保ちつつ、USB-C1, C2で同時に140W, 100Wを出力可能というハイスペックな仕様で重さや細々とした欠点をすべて帳消しにする最強のモバイルバッテリー。また、大容量にもかかわらず超急速充電が可能で、100W級も充電器を使えば70分で満充電可能。(100W級の充電器を複数台持っている<em>逸般人</em>は2台使っての170W充電をすることで40分未満で満充電が可能)</p>
<p>スマートフォンとBluetooth接続して細かな設定が行える他、本製品を鳴らして探すことも可能ですが、Bluetooth接続していないと使えないため実用性は乏しく、同社の紛失防止トラッカーのような利便性はないのが残念。</p>
<p>最強のモバイルバッテリーとして強くオススメできる最高の1台ではあるものの、万人にオススメするには流石にオーバースペック。 これにロマンを感じ、お財布がそれを許すのであれば、後悔させることはないでしょう。</p>



</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a><div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">参考文献</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" data-line-spacing="2">
<div id="ref-ANA" class="csl-entry">
ANA 「【国内・国際線／海外ツアー】リチウムイオン電池が内蔵された一般電子機器・モバイルバッテリーの取り扱いについて」、 <em>ANA</em>、閲覧日 2024年3月10日、 <a href="https://ana-support.my.site.com/jajp/s/article/answers6174ja">https://ana-support.my.site.com/jajp/s/article/answers6174ja</a>
</div>
<div id="ref-HanpenBlog" class="csl-entry">
@hanpenblog (2021) 「<span>CIO SMARTCOBY 20000mAh 60Wは3Aケーブルでも5Aの出力を通知する仕様違反の製品</span>」、 <em>HanpenBlog</em>、2021年10月30日、閲覧日 2024年3月10日、 <a href="https://hanpenblog.com/16964">https://hanpenblog.com/16964</a>
</div>
<div id="ref-AnkerJapan2023" class="csl-entry">
アンカー・ジャパン株式会社 (2023a) 「<span>Anker史上最高峰の充電器シリーズ「Anker Prime」を発表。超高出力USB急速充電器やモバイルバッテリー等8製品を展開開始</span>」、 2023年8月2日、閲覧日 2024年3月10日、 <a href="https://www.ankerjapan.com/blogs/news/426">https://www.ankerjapan.com/blogs/news/426</a>
</div>
<div id="ref-USBTypeC2" class="csl-entry">
SpecWerkz &amp; Brad Saunders (2023)<em><a href="https://www.usb.org/document-library/usb-type-cr-cable-and-connector-specification-release-23"><span class="nocase">USB Type-C® Cable and Connector Specification Release 2.3</span></a></em>, USB Implementers Forum
</div>
<div id="ref-Anker250W" class="csl-entry">
アンカー・ジャパン株式会社 (2024) 「<span>Anker Prime Power Bank (27650mAh, 250W)</span>」、 <em>Anker Japan</em>、2024年、閲覧日 2024年3月10日、 <a href="https://www.ankerjapan.com/products/a1340?variant=43742910611617">https://www.ankerjapan.com/products/a1340?variant=43742910611617</a>
</div>
<div id="ref-PCWatch" class="csl-entry">
山田祥平 (2019) 「<span>とにもかくにもType-C、Galaxy Note 10+が示す急速充電の方向性</span>」、 <em><span>PC watch</span></em>、2019年11月9日、閲覧日 2024年4月12日、 <a href="https://pc.watch.impress.co.jp/docs/column/config/1217555.html">https://pc.watch.impress.co.jp/docs/column/config/1217555.html</a>
</div>
<div id="ref-AnkerMagazine" class="csl-entry">
アンカー・ジャパン株式会社 (2022a) 「<span>スマホの充電は正しくできてる？みんなが気になるバッテリーの疑問10選)</span>」、 <em><span>ANKER MAGAZINE</span></em>、2022年9月5日、閲覧日 2024年4月12日、 <a href="https://www.ankerjapan.com/blogs/magazine/tips-of-battery">https://www.ankerjapan.com/blogs/magazine/tips-of-battery</a>
</div>
<div id="ref-Anker737" class="csl-entry">
アンカー・ジャパン株式会社 (2022b) 「<span>Anker 737 Power Bank (PowerCore 24000)</span>」、 <em>Anker Japan</em>、2022年、閲覧日 2024年4月12日、 <a href="https://www.ankerjapan.com/products/a1289">https://www.ankerjapan.com/products/a1289</a>
</div>
<div id="ref-Anker200W" class="csl-entry">
アンカー・ジャパン株式会社 (2023b) 「<span>Anker Prime Power Bank (20000mAh, 200W)</span>」、 <em>Anker Japan</em>、2023年、閲覧日 2024年4月12日、 <a href="https://www.ankerjapan.com/products/a1336">https://www.ankerjapan.com/products/a1336</a>
</div>
<div id="ref-Teardown" class="csl-entry">
ChargerLAB (2022)“<span class="nocase">Teardown of Anker 140W PD3.1 Power Bank (737 Power Bank)</span>”, <em><span>YouTube</span></em>, September 12, 2022 Accessed April 13, 2024 <a href="https://youtu.be/NO0P5BO5gTQ?si=KUTZLb9nosgNtZMB&amp;t=176">https://youtu.be/NO0P5BO5gTQ?si=KUTZLb9nosgNtZMB&amp;t=176</a>
</div>
</div></section></div> ]]></description>
  <category>レビュー</category>
  <category>モバイルバッテリー</category>
  <category>Anker</category>
  <category>おすすめ記事</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Anker_Prime_Power_Bank_250W.html</guid>
  <pubDate>Sun, 14 Apr 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/Anker250W.png" medium="image" type="image/png" height="81" width="144"/>
</item>
<item>
  <title>【ご報告】フォトコン優秀賞受賞のお知らせ</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/Refresh/win-a-priize.html</link>
  <description><![CDATA[ 




<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
これはリフレッシュ記事です
</div>
</div>
<div class="callout-body-container callout-body">
<p>この記事は、はてなブログ時代(旧Pottal-Portal)の記事を読みやすく整えたものです。<br> 大きな加筆修正は行っていません。<br> オリジナルの記事は以下を御覧ください。<br></p>
</div>
</div>
<hr>
<section id="asus東京カメラ部-zenfoneで捉えるその一瞬-フォトコンテスト優秀賞を受賞しました" class="level2">
<h2 class="anchored" data-anchor-id="asus東京カメラ部-zenfoneで捉えるその一瞬-フォトコンテスト優秀賞を受賞しました">『ASUS×東京カメラ部　ZenFoneで捉える、その一瞬 フォトコンテスト』優秀賞を受賞しました</h2>
<p>私事ですが、表題の通りASUS及び東京カメラ部主催のフォトコンテスト、『ASUS×東京カメラ部　ZenFoneで捉える、その一瞬 フォトコンテスト』にて、『ZenFoneで特別なアングル部門 優秀賞』をいただきました。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
／<br>ASUS × 東京カメラ部<a href="https://twitter.com/hashtag/ZenFone%E3%81%A7%E6%8D%89%E3%81%88%E3%82%8B%E3%81%9D%E3%81%AE%E4%B8%80%E7%9E%AC?src=hash&amp;ref_src=twsrc%5Etfw">#ZenFoneで捉えるその一瞬</a><br>フォトコンテスト<br>＼<br><br>入賞作品が選出されましたのでご報告させていただきます。<br><br>この度は本コンテストにご参加いただき誠にありがとうございました。<br><br>入賞作品については下記URLよりご確認ください。<a href="https://t.co/ndKtn5yDIn">https://t.co/ndKtn5yDIn</a>
</p>
— ASUS JAPAN (<span class="citation" data-cites="ASUSJapan">@ASUSJapan</span>) <a href="https://twitter.com/ASUSJapan/status/1384039085891747843?ref_src=twsrc%5Etfw">April 19, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>嬉しいです。<br>
賞金の5万円は同じASUS製品であるRT-AX89XというハイエンドWi-Fi6ルーターになりました。</p>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
2月最後（のはず）の <a href="https://twitter.com/hashtag/%E3%81%AF%E3%81%81%E3%80%9C%E3%81%BE%E3%81%9F%E8%B2%B7%E3%81%A3%E3%81%A1%E3%82%83%E3%81%A3%E3%81%9F?src=hash&amp;ref_src=twsrc%5Etfw">#はぁ〜また買っちゃった</a> は <a href="https://twitter.com/hashtag/ASUS?src=hash&amp;ref_src=twsrc%5Etfw">#ASUS</a> の変態ルーター <a href="https://twitter.com/hashtag/RTAX89X?src=hash&amp;ref_src=twsrc%5Etfw">#RTAX89X</a> です！ <br>見てください！！アンテナいっぱい！隣にある同じくASUS（ROG）の変態ルーター <a href="https://twitter.com/hashtag/GTAX11000?src=hash&amp;ref_src=twsrc%5Etfw">#GTAX11000</a> と合わせてアンテナが16本！<br>もうゼーレの方々もびっくり！オンライン円卓会議も余裕です！<a href="https://twitter.com/hashtag/MyNewGear?src=hash&amp;ref_src=twsrc%5Etfw">#MyNewGear</a>… <a href="https://t.co/26NCVgxgn2">pic.twitter.com/26NCVgxgn2</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">@Pottal_MDS</span>) <a href="https://twitter.com/Pottal_MDS/status/1360482680463187972?ref_src=twsrc%5Etfw">February 13, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>RT-AX89Xについてはいつかレビューを書きます。</p>
<p>撮影に使ったスマートフォンはZenFone6 Edition 30という、ASUS 30周年を記念した全世界限定3000台のみ出荷された特別なZenFone6です。</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20210423/20210423191745.jpg" class="img-fluid figure-img"></p>
<figcaption>ZenFone6 Edition 30</figcaption>
</figure>
</div>
<p>まあ、別にカメラ性能は普通のZenFone6と変わらないのですが、このASUS30周年を祝う特別なモデルで受賞出来たのは感慨深いものがあります。<br>
あ、ZenFone6 Edition30についてもいつかレビューを書きたいですね。<br>
なんか、書いてはいるものの公開に至ってないガジェットが多すぎて、その上復学したので忙しくなってしまい全くブログが更新出来そうにないです。</p>
<section id="作品について" class="level5">
<h5 class="anchored" data-anchor-id="作品について">作品について</h5>
<blockquote class="twitter-tweet blockquote">
<p lang="ja" dir="ltr">
朝露までくっきりと。<br>そう、<a href="https://twitter.com/hashtag/ZenFone6?src=hash&amp;ref_src=twsrc%5Etfw">#ZenFone6</a> ならね。<a href="https://twitter.com/hashtag/ZenFone%E3%81%A7%E6%8D%89%E3%81%88%E3%82%8B%E3%81%9D%E3%81%AE%E4%B8%80%E7%9E%AC?src=hash&amp;ref_src=twsrc%5Etfw">#ZenFoneで捉えるその一瞬</a> <a href="https://twitter.com/hashtag/ZenFone%E3%81%A7%E7%89%B9%E5%88%A5%E3%81%AA%E3%82%A2%E3%83%B3%E3%82%B0%E3%83%AB?src=hash&amp;ref_src=twsrc%5Etfw">#ZenFoneで特別なアングル</a> <a href="https://t.co/OhbkKNYAzN">pic.twitter.com/OhbkKNYAzN</a>
</p>
— ポッタル (<span class="citation" data-cites="Pottal_MDS">@Pottal_MDS</span>) <a href="https://twitter.com/Pottal_MDS/status/1327440532742651906?ref_src=twsrc%5Etfw">November 14, 2020</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>上記の通り撮影機材はZenFone6 Edition30です。<br>
撮影場所は千葉県某所で、加工はTwitterのフィルター機能と自動補正くらいです。撮影モードもオートモードで、工夫した点と言えばピントとアングルくらいです。<br>
ちなみに、この写真は認知症の祖父が徘徊したまま帰って来ず、(その後、無事に帰ってきましたが、要介護4認定になりました。)眠れぬ夜を照らした朝焼けと、それを受けて輝く朝露を眩しく思い撮ったという写真で、正直、この作品は賑やかしのためというかASUSの企画だしいっちょ盛り上げてやろうくらいの気持ちで投稿したもので、本命は別にあったのですが…<br>
何が審査員の方々の心に刺さったのかは分かりませんが、数撃ってみるものですね。何は兎も角、素直に嬉しいです。</p>
<p>数撃った作品たちはこちらになります。</p>
<p><a href="https://twitter.com/search?q=from%3APottal_MDS%20%23ZenFone%E3%81%A7%E6%8D%89%E3%81%88%E3%82%8B%E3%81%9D%E3%81%AE%E4%B8%80%E7%9E%AC&amp;src=saved_search_click">twitter.com</a></p>
</section>
<section id="余談" class="level5">
<h5 class="anchored" data-anchor-id="余談">余談</h5>
<p><a href="https://asus.blog.jp/archives/1078771800.html">同じ部門でZenBlogさんも優秀賞を受賞されています。</a>Pottal-Portalを始めたのはZenBlogさんがきっかけなので、隣に並べて嬉しいです。</p>


</section>
</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> Back to top</a> ]]></description>
  <category>Refresh</category>
  <category>お知らせ</category>
  <guid>https://pottal-portal.com/PtPr3/posts/Refresh/win-a-priize.html</guid>
  <pubDate>Wed, 10 Apr 2024 15:00:00 GMT</pubDate>
  <media:content url="https://cdn-ak.f.st-hatena.com/images/fotolife/m/ma2motty/20210423/20210423190714.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>全世界限定3000台 ZenFone6 Edition30 2024年長期レビュー</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/ZenFone6.html</link>
  <description><![CDATA[ 




<div class="callout callout-style-simple callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
本サイトは広告やアフィリエイトプログラムにより収益を得ています
</div>
</div>
<div class="callout-body-container callout-body">

</div>
</div>
<p><a href="../post_images/Zen6_DSC_8973-4.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC_8973-4.png" class="img-fluid"></a></p>
<section id="要旨" class="level2">
<h2 class="anchored" data-anchor-id="要旨">要旨</h2>
<p>ASUSが2019年5月に発表した「ZenFone6」はまさしくASUSを象徴するスマートフォンとなりました。そんなZenFone6の更に限定品である「ZenFone6 Edition30」を2024年の今、敢えてレビューしていきます。</p>
<p>ZenFone6が発表された2019年はASUSの創立30周年となる節目の年であり、機を同じくしてASUSのスマートフォン部門は従来の「薄利多売」「様々なバリエーションモデルでニッチな需要に対応」という方針から<a href="http://blogofmobile.com/article/110786?utm_source=pocket_mylist">ハイエンドに特化する方針</a>へと改めました<span class="citation" data-cites="paopao">(TAMURA 2018)</span>。ZenFone6に搭載された180°回転するFlipカメラは、まさしくこれまでの方向性から一転、ハイエンドへの注力を示す象徴といえるでしょう。レーザーAFを搭載した「Laser」シリーズ、大容量バッテリーを搭載した「Max」シリーズ、自撮りに特化した「Selfie」シリーズ、ハイエンドモデルである「Deluxe（Pro/Z）」等、様々なユーザーにささるラインナップを提供してきたZenFoneシリーズのほぼすべての要素<sup>1</sup>がこのZenFone6には詰め込まれています。まさしくこれまでのZenFoneと、そしてこれからのZenFoneを体現するASUS渾身のプロダクトが、このZenFone6なのです。</p>
<aside id="footnotes" class="footnotes footnotes-end-of-section">
<hr>
<ol>
<li id="fn1"><p>ZenFone6にない要素は、望遠カメラに力を入れた「Zoom」シリーズくらいでしょう。シリーズとしては続かず1代限りであった超廉価モデルの「ZenFone Go」、更にワンセグ機能を搭載した「ZenFone Go TV」というのもありましたが↩︎</p></li>
</ol>
</aside>
</section>
<section id="背景" class="level2">
<h2 class="anchored" data-anchor-id="背景">背景</h2>
<p>ZenFone6 Edtion30は、ASUSの創立30周年を記念し、全世界で合計3000台のみ発売された限定モデルであり、発売から5年が経とうとしているスマートフォンです。</p>
<p>そんなスマートフォンを今更レビューするのは、これが私にとって大切な一台だからです。言ってしまえば、単なる私のこだわりですが、だからこそ、リニューアルしたPottal-Portal 3.0 のトップバッターは、愛するASUSの、しかも特別なモデルであるZenFone6 Edition30しかあるまいと思いレビューをすることにしました。 世にも珍しいカメラが180°フリップするこのスマートフォンですが、2019年のZenFone6から始まりZenfone8 Flip(2021年)で終わってしまったモデルであり、しかも今回レビューするのは全世界で3000台のみの限定モデルということで、おそらく誰にも需要のない記事とはなってしまいますが、私が書きたいから書く、そんな最初からこだわりの詰まった記事を最後までお楽しみいただければ幸いです。</p>
</section>
<section id="whats-this" class="level2">
<h2 class="anchored" data-anchor-id="whats-this">What’s this?</h2>
<ul>
<li>メインカメラが180°フリップするZenFone6の「ASUS 30周年記念」特別モデル</li>
</ul>
<section id="スペック" class="level3">
<h3 class="anchored" data-anchor-id="スペック">スペック</h3>
<iframe src="https://docs.google.com/spreadsheets/d/e/2PACX-1vSX8UmI0a9j00jcLfnIkAy9Q61mZqzes5yKYlkv2FVw59NI2-jW9myuNUI3F1-DyVvprT0S6d3tar8r/pubhtml?gid=0&amp;single=true&amp;widget=true&amp;headers=false" width="100%" height="950">
</iframe>
<p>通常のスマホレビューであれば、カタログスペックを確認した後に、ベンチマークテストを連続で実行し性能を評価したり, オーディオ・ディスプレイについてレビューをしたり, バッテリー持ちや充電速度について検証したりしますが、2019年のスマホであり、しかも全世界に3000台しかない限定スマホに対してこれらを行う意義が見いだせないため、今回はレビューしません。</p>
</section>
</section>
<section id="フォトレビュー" class="level2">
<h2 class="anchored" data-anchor-id="フォトレビュー">フォトレビュー</h2>
<p>お蔵入りしていた当時の写真を引っ張り出した他、新たに撮り直すなどしました。</p>
<section id="略式開封の儀" class="level3">
<h3 class="anchored" data-anchor-id="略式開封の儀">略式開封の儀</h3>
<div id="fig-Zen6_Box" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_Box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0168.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-2" title="図&nbsp;1: 外装"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0168.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0169.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-3" title="図&nbsp;1: 外装"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0169.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_Box-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;1: 外装
</figcaption>
</figure>
</div>
<div id="fig-Zen6_Box2" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_Box2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC_8660.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-4" title="図&nbsp;2: 開封"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC_8660.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0170.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-5" title="図&nbsp;2: 開封"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0170.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0171.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-6" title="図&nbsp;2: 開封"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0171.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0172.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-7" title="図&nbsp;2: 開封"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0172.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_Box2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;2: 開封
</figcaption>
</figure>
</div>
<div id="fig-Zen6_Card" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_Card-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0173.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-8" title="図&nbsp;3: 謎のカード"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0173.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0174.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-9" title="図&nbsp;3: 謎のカード"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0174.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_Card-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;3: 謎のカード
</figcaption>
</figure>
</div>
<div id="fig-Zen6_others" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_others-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC0175.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-10" title="図&nbsp;4: 付属品など"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0175.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_DSC_8674.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-11" title="図&nbsp;4: 付属品など"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC_8674.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_others-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;4: 付属品など
</figcaption>
</figure>
</div>
<section id="背面" class="level4">
<h4 class="anchored" data-anchor-id="背面">背面</h4>
<div id="fig-Zen6_back" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_DSC0182.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-12" title="図&nbsp;5: 背面には指紋センサーを搭載"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0182.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_back-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;5: 背面には指紋センサーを搭載
</figcaption>
</figure>
</div>
</section>
<section id="前面" class="level4">
<h4 class="anchored" data-anchor-id="前面">前面</h4>
<div id="fig-Zen6_front" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_DSC0177.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-13" title="図&nbsp;6: 保護ガラスを取り付け済みなのはご容赦願いたい"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0177.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_front-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;6: 保護ガラスを取り付け済みなのはご容赦願いたい
</figcaption>
</figure>
</div>
</section>
<section id="側面" class="level4">
<h4 class="anchored" data-anchor-id="側面">側面</h4>
<div id="fig-Zen6_side" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_side-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_DSC0184.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-14" title="左側面 SIMスロットのみ"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0184.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左側面<br>SIMスロットのみ</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_DSC0189.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-15" title="右側面 スマートキー、音量ボタン、電源ボタン"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0189.jpg" class="img-fluid figure-img"></a></p>
<figcaption>右側面<br>スマートキー、音量ボタン、電源ボタン</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_DSC0186.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-16" title="上部"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0186.jpg" class="img-fluid figure-img"></a></p>
<figcaption>上部</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_DSC0192.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-17" title="底部 スピーカー、TypeC端子、3.5mmオーディオジャック"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0192.jpg" class="img-fluid figure-img"></a></p>
<figcaption>底部<br>スピーカー、TypeC端子、3.5mmオーディオジャック</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_side-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;7: 側面
</figcaption>
</figure>
</div>
</section>
</section>
</section>
<section id="項目別レビュー" class="level2">
<h2 class="anchored" data-anchor-id="項目別レビュー">項目別レビュー</h2>
<p>ZenFone6 Edition30の良かったところやイマイチなところをざっくりと紹介したのち、筆者の語りたい項目を深掘りしていきます。</p>
<section id="年視点でみたzenfone6の良いところ" class="level3">
<h3 class="anchored" data-anchor-id="年視点でみたzenfone6の良いところ">2024年視点でみたZenFone6の良いところ</h3>
<ul>
<li>◎: ノッチ・パンチホールなしの美しい全画面デザイン</li>
<li>◎: 自在なアングルをもたらすフリップカメラ</li>
<li>◯: 自撮りもメインカメラと同等の画質で撮影可能</li>
<li>◯: 大容量バッテリーかつ長年使えるバッテリーケア機能</li>
<li>◯: 3.5mm オーディオジャック搭載</li>
<li>◯: 迷いにくいレーザーAF</li>
</ul>
<section id="sec-good-1" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-1">◎: ノッチ・パンチホールなしの美しい全画面デザイン</h5>
<p>2024年現在、スマートフォンのディスプレイにはパンチホールやダイナミックアイランド、ノッチと形態や位置こそ様々なものの邪魔なインカメラが鎮座し、画面が欠けてしまうことが当たり前となってしまいました。せっかくカメラの画質が向上し、ディスプレイも色鮮やかになったというのに、綺麗な写真や動画に”穴”を開けてしまうのは、画竜点睛を欠くのではないかと思ってしまいます。 (何かを褒めるために、何かを貶めるのは好きではありませんが)ZenFone6は他のスマホとは違い、インカメラという概念が存在せず、ディスプレイが全画面なため非常に美しい外見です。</p>
<p>とは言え、Appleのように全ベゼル幅が均等というわけではないので、まだ高みを目指せる(妥協のあった)完成度だと思います。 ディスプレイ全体に関しては、別の項でレビューをするため、ここではあくまでデザインに関してのみの言及に留めますが、ディスプレイの角が丸く、しかも本体のアール(丸み)とあっていないのも気に食わないです。せっかくの全画面なのだから、ディスプレイをフルに楽しみたいと思うのは私だけでしょうか。</p>
<p>柔軟性のある有機ELではなく液晶ディスプレイを採用しているので、仕方がないと納得はできますが、残念であることには変わりありません。</p>
<p>四の五の言いましたが、それでも全画面ディスプレイであることの良さは揺るがないため、二重丸をつけました◎</p>
</section>
<section id="sec-good-2" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-2">◎: 自在なアングルをもたらすフリップカメラ</h5>
<p>ミラーレスカメラの世界では、バリアングルやチルト式というモニターを自在に動かせる機構が定番となっています。ファインダーの代わりにモニターに被写体を映してカメラを自在なアングルに構えられるため、大胆な構図をとれることが人気の要因のようです。 ZenFone6も(モニターではなく)カメラ機構を180°フリップさせられることから、それと似たようなことを行えます。</p>
<div id="fig-Zen6_flip_video" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_flip_video-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-video"><video id="video_shortcode_videojs_video1" class="video-js vjs-default-skin vjs-fluid" controls="" preload="auto" data-setup="{}" title=""><source src="../post_images/Zen6_20240401-2243-35.8709165.mp4"></video></div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_flip_video-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;8: ZenFone6のフリップカメラ動作イメージ<br><span class="citation" data-cites="ASUSJAPAN_Zen6">(ASUS 2019)</span>より筆者撮影及び引用
</figcaption>
</figure>
</div>
<p>例えば、猫ちゃんと同じ目線の写真をスマホで撮影する場合、普通のスマホであればスマホを地面近くに(しかも垂直に)構え、厳しい体勢でシャッターボタンを押さなければなりませんが、ZenFone6であれば持ちやすい体勢でスマホを構え、カメラをフリップさせることでらくらく撮影が行えます(図&nbsp;9)。</p>
<div id="fig-Zen6_flip_cam" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_flip_cam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_Flip.png" class="lightbox" data-gallery="quarto-lightbox-gallery-18" title="[@ASUSJAPAN_Zen6]より筆者引用・加工"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Flip.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="ASUSJAPAN_Zen6">(ASUS 2019)</span>より筆者引用・加工</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_flip_cam-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;9: ZenFone6のフリップカメラであれば、楽な姿勢で自在なアングルがとれる
</figcaption>
</figure>
</div>
<div id="fig-cats" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-cats-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_cat.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-19" title="図&nbsp;10: ZenFone6のフリップカメラであれば猫の撮影も思いのまま"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_cat.jpg" class="img-fluid figure-img"></a></p>
</div>
<div class="quarto-layout-cell" style="flex-basis: 50.0%;justify-content: center;">
<p><a href="../post_images/Zen6_cat2.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-20" title="図&nbsp;10: ZenFone6のフリップカメラであれば猫の撮影も思いのまま"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_cat2.jpg" class="img-fluid figure-img"></a></p>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-cats-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;10: ZenFone6のフリップカメラであれば猫の撮影も思いのまま
</figcaption>
</figure>
</div>
</section>
<section id="sec-good-3" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-3">◯: 自撮りもメインカメラと同等の画質で撮影可能</h5>
<p>筆者は自撮りをしませんが、ZenFone6はメインカメラが180°フリップするという仕組みのため、メインカメラ(いわゆる外カメ)と同等の画質でディスプレイを見ながらの自撮りが行えます。</p>
<div id="fig-cats" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-cats-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_Selfie.png" class="lightbox" data-gallery="quarto-lightbox-gallery-21" title="[@ASUSJAPAN_Zen6]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Selfie.png" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="ASUSJAPAN_Zen6">(ASUS 2019)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-cats-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;11: ZenFone6であればメインカメラと同等の画質で自撮りが可能
</figcaption>
</figure>
</div>
<p>(自撮りをするシーンでフォーカスに迷うことがあるかは不明ですが)メインカメラ同等のフォーカスが使えることや、夜間の乏しい光源でも綺麗に撮影できることが謳われており<span class="citation" data-cites="ASUSJAPAN_Zen6">(ASUS 2019)</span>、実際、筆者が試した限りでは最も綺麗に自撮りが撮れるスマートフォンでした。</p>
<p>「でした」とある通り、今では折りたたみスマホを用いて、メインカメラとサブディスプレイを用いた自撮りが(おそらく)最も綺麗に撮れる自撮りだと思うので、自撮り最強スマホとしての役割は他機種に譲ることになりました。</p>
</section>
<section id="sec-good-4" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-4">◯: 大容量バッテリーかつ長年使えるバッテリーケア機能</h5>
<p>ZenFone6は5000mAhの大容量バッテリーを搭載し、なおかつ低速充電や80%(あるいは90%)までの充電制限機能、充電スケジュール機能といったいわゆるいたわり充電機能を備えているため、バッテリーサイクルを長く保つことができ、製品寿命を長くすることが可能です。 もともと、バッテリー容量が大きいためバッテリーが劣化しても比較的影響は軽微に抑えられる機種ではありますが、バッテリー劣化を抑える上記の機能により、発売から5年が経とうとしていますが、今でも普通に使うことが出来ます。</p>
<p>バッテリーより先にOS更新やセキュリティーアップデートの方が先に期限を迎えてしまいましたが、2回のOSアップデートを経てAndroid11まで適用できたため、普段使いで困ることはないでしょう(実際、OSが原因の足切りを経験したことはまだありません)。</p>
</section>
<section id="sec-good-5" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-5">◯: 3.5mm オーディオジャック搭載</h5>
<p>ケーブルが煩わしいためBluetoothヘッドホン・イヤフォンに乗り換えて久しいですが、それでもやはり3.5mmオーディオジャックはあると嬉しいです。 また、ZenFone6は有線イヤフォンをアンテナにしてFMラジオを受信できるため、いざという時に安心です。もっとも、受信できる周波数帯は87.5~108.0MHzまでなので、筆者の聞きたい局(NHK-FM; 82.5MHz)は聞けないのですが。</p>
</section>
<section id="sec-good-6" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-6">◯: 迷いにくいレーザーAF</h5>
<p>一昔前のスマートフォンでは、レーザー光を用いたレーザーAFが一般的でした。しかし、近年ではパッシブAF――特にイメージセンサー側での像面位相差AFやDual PDの台頭もあり、専用の機構を必要とするレーザーAFは逆風に曝されています。また、同じアクティブAFの世界でも、より広いカバーエリアを持つToFセンサー<span class="citation" data-cites="Koyama2020Xperia Tanaka2020Xperia">(小山 2020, 田中 2020)</span>に取って代わられてしまい、本機種が出た2019年においてレーザーAFは風前の灯火といった状況にありました。</p>
<div id="fig-ToF" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-ToF-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell" style="flex-basis: 100.0%;justify-content: flex-start;">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/ToF.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-22" title="[@Koyama2020Xperia;@Tanaka2020Xperia]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/ToF.jpg" class="img-fluid figure-img"></a></p>
<figcaption><span class="citation" data-cites="Koyama2020Xperia Tanaka2020Xperia">(小山 2020, 田中 2020)</span>より筆者引用</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-ToF-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;12: レーザーAFに対するToFの優位性
</figcaption>
</figure>
</div>
<p>余力があれば後日、検証動画を追記という形でアップロードしますが、ZenFone6のAF性能は良好です。</p>
<p>ガラス越しに撮影する, 指でランドルト環(視力検査のような閉じてない輪っか)を作りその間を覗かせるといった意地悪をしない限り、レーザーAFは迷うことを知りません。 ちなみに、前者はガラスでレーザーが反射されてしまい正しく測位が出来ず、後者はレーザーが指で作った輪の間を通過してしまい後景にピントが合ってしまいます。</p>
</section>
<section id="sec-good-7" class="level4">
<h4 class="anchored" data-anchor-id="sec-good-7">ZenFone6 Edition30ならではの良いところ</h4>
<ul>
<li>◎: “Zen”を象徴するスピン加工と美しく象られたASUS30周年ロゴ</li>
<li>◯: 今でも通用するRAM12GB, ストレージ512GB構成</li>
</ul>
<section id="sec-good-8" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-8">◎: “Zen”を象徴するスピン加工と美しく象られたASUS30周年ロゴ</h5>
<p>一昔前のASUS製品、特にZenを冠するモデルには必ず、Zen(禅)を象徴するスピン加工(サーキュラー仕上げ)が施されていました<span class="citation" data-cites="ASUS_Zen">(シンシア 2014)</span>。 ZenBook3やZenFone3, ZenWatch3のような全面にそれを押し出したモデルだけでなく、例えばZenFone2のようにワンポイントであしらったものや、ZenFoneARのように半ばイースターエッグのように目を凝らして探さないと分からないものまで様々でしたが製品のどこかしらには禅の精神が宿っていました。 ところが、通常モデルのZenFone6(そしてそれ以降のモデル)には、どこに目を凝らしてもそれがないのです。その傾向はZenBookにも見られるのですが<sup>2</sup>、本筋から外れてしまうのでとりあえず割愛するとして、通常モデルのZenFone6には見られないZenの象徴が、ASUS30周年を記念したZenFone6 Edition30には見られてとても嬉しいというだけの話です。</p>
<p>また、ASUS30周年を記念して作られたロゴマークも特徴的です(図&nbsp;13)。このロゴマークは「↑」矢印, 「人」, 「♡」をモチーフに、技術革新・デジタルライフによる向上, すべては人から始まるという思いやり, 喜んでもらう・使ってもらうという喜びを込めてデザインされたものです<span class="citation" data-cites="ASUS_Store ASUS_Design">(ASUS JAPAN 2019, Jenny 2019)</span>。</p>
<div id="fig-Zen30" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen30-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://drh.img.digitalriver.com/DRHM/Storefront/Site/asusjp/pb/multimedia/news/201908/logo_30th.png" class="lightbox" data-gallery="quarto-lightbox-gallery-23" title="ASUS創立30周年記念ロゴ"><img src="https://drh.img.digitalriver.com/DRHM/Storefront/Site/asusjp/pb/multimedia/news/201908/logo_30th.png" class="img-fluid figure-img"></a></p>
<figcaption>ASUS創立30周年記念ロゴ</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="https://drh.img.digitalriver.com/DRHM/Storefront/Site/asusjp/pb/multimedia/news/201908/meaning_30th.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-24" title="30周年記念ロゴに込められた意味"><img src="https://drh.img.digitalriver.com/DRHM/Storefront/Site/asusjp/pb/multimedia/news/201908/meaning_30th.jpg" class="img-fluid figure-img"></a></p>
<figcaption>30周年記念ロゴに込められた意味</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen30-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;13: <span class="citation" data-cites="ASUS_Store">(ASUS JAPAN 2019)</span>より筆者引用
</figcaption>
</figure>
</div>
<div id="fig-Zen30_Video" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen30_Video-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-video ratio ratio-16x9"><iframe data-external="1" src="https://player.vimeo.com/video/343161864" frameborder="0" title="" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen=""></iframe></div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen30_Video-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;14: ASUS 30 Year Monogram Concept<br><span class="citation" data-cites="ASUS30_Video">(ASUS Design Center 2019a)</span>より筆者引用
</figcaption>
</figure>
</div>
<p>現在では、ASUS30周年記念ロゴではなく、“A” monogram(Aモノグラム)としてZenfone10(図&nbsp;15 (b))や新しいZenbook(図&nbsp;15 (a))に採用されるようになりました<span class="citation" data-cites="ZenBlog ASUSMono">(藤沢 2022, ASUS Design Center 2019b)</span>。</p>
<div id="fig-A-mono" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-A-mono-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-A-mono" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Zenbook" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-Zenbook-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zenbook.png" class="lightbox" data-gallery="fig-A-mono" title="図&nbsp;15&nbsp;(a): Zenbook14 [@ASUSJAPAN_Zenbook]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Zenbook.png" class="img-fluid figure-img" data-ref-parent="fig-A-mono"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-Zenbook-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(a) Zenbook14<br><span class="citation" data-cites="ASUSJAPAN_Zenbook">(ASUS 2024)</span>より筆者引用
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-A-mono" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-Zenfone10" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-Zenfone10-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zenfone10.png" class="lightbox" data-gallery="fig-A-mono" title="図&nbsp;15&nbsp;(b): Zenfone10 [@ASUSJAPAN_Zenfone10]より筆者引用"><img src="https://pottal-portal.com/PtPr3/post_images/Zenfone10.png" class="img-fluid figure-img" data-ref-parent="fig-A-mono"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-Zenfone10-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
(b) Zenfone10<br><span class="citation" data-cites="ASUSJAPAN_Zenfone10">(ASUS 2023)</span>より筆者引用
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-A-mono-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;15: Aモノグラムを採用した新しいZenシリーズ
</figcaption>
</figure>
</div>
<aside id="footnotes-2" class="footnotes footnotes-end-of-section">
<hr>
<ol start="2">
<li id="fn2"><p>例外はZenBook Duoくらいでしょうか↩︎</p></li>
</ol>
</aside>
</section>
<section id="sec-good-9" class="level5">
<h5 class="anchored" data-anchor-id="sec-good-9">◯: 今でも通用するRAM12GB, ストレージ512GB構成</h5>
<p>ZenFone6の通常版は、6GB/128GB, 8GB/256GBというラインナップでしたが、限定モデルであるZenFone6 Edition30は12GB/512GB構成(RAM/ストレージ)です。</p>
<p>SoCには2019年当時のハイエンドチップであるQualcomm® Snapdragon™ 855を搭載しているため、2024年現在でも十分快適に動作します。 流石に3Dゲームなどを最高設定でプレイするのは厳しいですが、設定を落とせば普通に動作するため、体感としてはミドル~ミドルハイといったところでしょうか。 ブラウジングなども(リフレッシュレートが60Hzなことに目をつぶれば)快適に行えますし、ノッチ・パンチホールがないことで動画の視聴も快適です。</p>
</section>
</section>
</section>
<section id="zenfone6のイマイチなところ" class="level3">
<h3 class="anchored" data-anchor-id="zenfone6のイマイチなところ">ZenFone6のイマイチなところ</h3>
<ul>
<li>△: 机に置いた状態で生体認証によるロック解除できない</li>
<li>△: デリケートなフリップカメラ</li>
<li>△: 防水・おサイフケータイ非対応</li>
<li>✗: USB2.0 &amp; 映像出力不可</li>
</ul>
<section id="sec-bad-1" class="level5">
<h5 class="anchored" data-anchor-id="sec-bad-1">△: 机に置いた状態で生体認証によるロック解除できない</h5>
<p>生体認証は指紋認証及び顔認証に対応していますが、指紋センサーは背面にあり顔認証も(インカメラを搭載しないフリップカメラという都合上)カメラをフリップさせる必要があるため、机に置いたままではカメラをフリップ出来ずに使えません。 机に置いたままロックを解除するにはパスコードやパターン入力をする必要があります。</p>
<p>これの悲しいところは、ZenFone6に来た通知を確かめる際にプライベートな内容の通知は詳細が表示されないため、いちいち机に置いたスマホを手にとって通知をアンロックする必要があるという点になります。もちろん、通知設定を変更しプライベートな内容であってもロック解除を求めないようにすれば済むのですが、普通のスマホなら机に置いたままスマホをタップしてカメラを見つめるだけで詳細が分かるのに、ZenFone6ではできないというのは運用でカバーする必要があるという点でデメリットであると言っていいでしょう。</p>
</section>
<section id="sec-bad-2" class="level5">
<h5 class="anchored" data-anchor-id="sec-bad-2">△: デリケートなフリップカメラ</h5>
<p>ZenFone6はカメラを180°フリップ(回転)させるという機構(図&nbsp;17)のため、普通のスマホに比べてカメラはデリケートなことは事実です。 もちろん、ASUSもそれは承知しているため、いくつもの安全機構を設けて故障を防いでいます。 例えば、フリップカメラを使用時に落下した場合、そのままでは飛び出たカメラに大きなダメージを受けてしまいますが、ZenFone6は落下を検知すると自動でカメラを元の位置に戻し、ダメージを最小限に抑える仕組みが備わっています(図&nbsp;16)。</p>
<div id="fig-Zen6_freefall" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_freefall-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-video"><video id="video_shortcode_videojs_video2" class="video-js vjs-default-skin vjs-fluid" controls="" preload="auto" data-setup="{}" title=""><source src="../post_images/Zen6_freefall.mp4"></video></div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_freefall-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;16: ZenFone6のカメラ保護機能<br>「『A部ツアー 2019』 sponsored by ひかりＴＶショッピング」にて筆者撮影
</figcaption>
</figure>
</div>
<div id="fig-Zen6_FlipCamera_teardown" class="quarto-layout-panel">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_FlipCamera_teardown-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Zen6_FlipCamera_teardown" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-FlipCamera_Motor1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-FlipCamera_Motor1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Left_DSC_9809.NEF.jpg" class="lightbox" data-gallery="fig-Zen6_FlipCamera_teardown" title="図&nbsp;17&nbsp;(a): "><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Left_DSC_9809.NEF.jpg" id="fig-FlipCamera_Motor1" class="img-fluid figure-img" data-ref-parent="fig-Zen6_FlipCamera_teardown"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-FlipCamera_Motor1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Zen6_FlipCamera_teardown" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-FlipCamera_Motor2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-FlipCamera_Motor2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Right_DSC_9808.NEF.jpg" class="lightbox" data-gallery="fig-Zen6_FlipCamera_teardown" title="図&nbsp;17&nbsp;(b): "><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Right_DSC_9808.NEF.jpg" id="fig-FlipCamera_Motor2" class="img-fluid figure-img" data-ref-parent="fig-Zen6_FlipCamera_teardown"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-FlipCamera_Motor2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Zen6_FlipCamera_teardown" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-FlipCamera_Motor3" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-FlipCamera_Motor3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Left_DSC_9815.NEF.jpg" class="lightbox" data-gallery="fig-Zen6_FlipCamera_teardown" title="図&nbsp;17&nbsp;(c): "><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Left_DSC_9815.NEF.jpg" id="fig-FlipCamera_Motor3" class="img-fluid figure-img" data-ref-parent="fig-Zen6_FlipCamera_teardown"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-FlipCamera_Motor3-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
</figcaption>
</figure>
</div>
</div>
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Zen6_FlipCamera_teardown" style="flex-basis: 50.0%;justify-content: flex-start;">
<div id="fig-FlipCamera_Motor4" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-FlipCamera_Motor4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Right_DSC_9817.NEF.jpg" class="lightbox" data-gallery="fig-Zen6_FlipCamera_teardown" title="図&nbsp;17&nbsp;(d): "><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Right_DSC_9817.NEF.jpg" id="fig-FlipCamera_Motor4" class="img-fluid figure-img" data-ref-parent="fig-Zen6_FlipCamera_teardown"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-FlipCamera_Motor4-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
</figcaption>
</figure>
</div>
</div>
</div>
<div class="quarto-layout-row">
<div class="quarto-layout-cell-subref quarto-layout-cell" data-ref-parent="fig-Zen6_FlipCamera_teardown" style="flex-basis: 100.0%;justify-content: flex-start;">
<div id="fig-teardown" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-subfloat-fig figure">
<div aria-describedby="fig-teardown-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Flipcam_DSC_0525.NEF.jpg" class="lightbox" data-gallery="fig-Zen6_FlipCamera_teardown" title="図&nbsp;17&nbsp;(e): "><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Flipcam_DSC_0525.NEF.jpg" id="fig-teardown" class="img-fluid figure-img" data-ref-parent="fig-Zen6_FlipCamera_teardown"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-subfloat-caption quarto-subfloat-fig" id="fig-teardown-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
</figcaption>
</figure>
</div>
</div>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_FlipCamera_teardown-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;17: ZenFone6のフリップカメラ機構の詳細<br>「『WISER TOGETHER～30 Years Together～』 スマートフォン・ノートPC 新製品発表会」にて筆者撮影
</figcaption>
</figure>
</div>
</section>
<section id="sec-bad-3" class="level5">
<h5 class="anchored" data-anchor-id="sec-bad-3">△: 防水・おサイフケータイ非対応</h5>
<p>今でこそ、ASUSのZenfoneシリーズは防水・おサイフケータイに対応していますが<sup>3</sup>、当時のASUSは初代ROG Phone以外防水性能を持ったスマートフォンを作っていませんでしたし<sup>4</sup>、フリップカメラという可動域ができる仕様上、防水性能をもたせることはとても難しいでしょう。また、凹字型の限界までコンパクトに設計された基板(図&nbsp;17 (e))に日本向けのハードウェアローカライズをする余裕があるとは思えません。もちろん、小型端末であってもおサイフケータイに対応しているスマートフォンはいくらでもあります。例えばZenfone8以降のZenfoneシリーズは小型ですし、Unihertz Jelly 2やRakuten Miniなど3インチクラスの超小型端末でもおサイフケータイ対応の例はあります(図&nbsp;18)。 しかし、おサイフケータイへの対応はただNFCアンテナをFeliCa対応のものに載せ替えればいいというものではないため、NFC搭載のスマートフォンと同じ感覚で対応できるものではなく、おサイフケータイ専用の設計で作るか、あるいはFeliCaモジュール等を追加できる余裕をもたせた基板設計が必要になるはずです。</p>
<div id="fig-Zen6_wallet" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_wallet-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_DSC0161.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-32" title="左上から順に Rakuten mini, ZenFone6, Jelly2"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC0161.jpg" class="img-fluid figure-img"></a></p>
<figcaption>左上から順に Rakuten mini, ZenFone6, Jelly2</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_wallet-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;18: おサイフケータイ搭載のコンパクトスマホとの比較
</figcaption>
</figure>
</div>
<p>ZenFone6は従来のような豊富なラインナップで薄利多売をする方針から一転、ハイエンドに特化するという方針<span class="citation" data-cites="paopao">(TAMURA 2018)</span>を受けて作られた最初のスマートフォンですので、そのようなハードウェアローカライズをする専用ラインを設けることが出来なかったのでしょう。</p>
<p>そのような背景を理解しているため、防水・おサイフケータイ非対応に不満を言うつもりはありませんが、仕方のないこととは言え、デメリットであることには違いありませんので△とさせていただきました。</p>
<aside id="footnotes-3" class="footnotes footnotes-end-of-section">
<hr>
<ol start="3">
<li id="fn3"><p>Zenfone8以降のZenfoneシリーズ(Zenfone8, Zenfone9, Zenfone10)↩︎</p></li>
<li id="fn4"><p>実は初代ROG PhoneはIPX4の防水性能を持っています。何故かなかったことにされていますが、当時のスペックシートにもIPX4とあります<span class="citation" data-cites="ASUSJAPAN_ROGPhone_ZS600KL">(ASUS 2018)</span>。↩︎</p></li>
</ol>
</aside>
</section>
<section id="sec-bad-4" class="level5">
<h5 class="anchored" data-anchor-id="sec-bad-4">✗: USB2.0 &amp; 映像出力不可</h5>
<p>ZenFone6 Edition30は512GBの大容量ストレージを備えているので写真や動画をたくさん収めることができます。 しかし、撮った写真をバックアップする際にネックになるのが、USB2.0という点です。もちろん、今はクラウドバックアップという手もありますが、筆者としてはUSBを繋いでサクッとHDDなりSSDなりにバックアップしておきたいです。そうなるとこのUSB2.0という仕様がネックになります。 まあ、ZenFone6はMicroSDカードに対応しているため、写真を最初からMicroSDカード保存にしておくことでもっと手軽にバックアップは撮れるので許しますが… (MicroSDカードの転送速度も大したことはありませんが、スマートフォンをUSB接続でパソコンに繋ぐ時の不安定さやその間ロクに使えない不便さに比べたら全然マシです)</p>
<p>また、PCに転送せずとも、例えばテレビなどの大きなディスプレイに繋いで写真を大きな画面で確認したい, 楽しみたいという時にネックになるのが、映像出力(Alt Mode)に対応していないため、USBハブなどに繋いで手軽に映像出力できないのもイマイチです。</p>
</section>
</section>
<section id="カメラについて" class="level3">
<h3 class="anchored" data-anchor-id="カメラについて">カメラについて</h3>
<p>ZenFone6はメインカメラの他に超広角撮影用のセカンドカメラを搭載したデュアルカメラ構成です。メイン(広角)+望遠という選択肢も普通のスマホであればありですが、フリップカメラとして自撮りをすることを考えると、自撮りで望遠を使うことはなくとも、超広角という広い画角を使って複数人で撮ったり、景色をダイナミックに収められるため、メイン(広角)+超広角という構成の方が理にかなっています<sup>5</sup>。</p>
<p>メインカメラには、4800万画素のSony IMX586イメージセンサー(<img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7B2%7D%E3%82%A4%E3%83%B3%E3%83%81">)を搭載し、レンズはF値1.79。 超広角カメラには、1300万画素のイメージセンサーに、125°をカバーする超広角レンズを採用、F値は2.4となっています。 また、AF機構としてレーザーAFを採用し、メインカメラの2x1 OCL PDAFシステムと合わせて正確で高速なフォーカシングを可能にしています。</p>
<p>メインカメラのレンズがF1.79と筆者の好みよりやや暗めなのは残念ですが、被写界深度が深くボケにくいというメリットもあります。様々なアングルで前景、中景、後景を意識せず1つのまとまった絵として仕上げられるのは魅力かもしれません。特にスマホでテーブルフォト(飯テロ写真)を撮る場合、被写界深度が浅いと料理の一部にだけピントが合ってしまい、意図した距離で撮影できないことがあります。もちろん、最近のスマホは2倍デジタルズームくらいには余裕で耐える解像度がありますので、離れて撮影しボケを抑えクロップするというのもありですが、簡便に飯テロ写真を撮りたい際には、大口径レンズというのは少々考えものです。 また、ボケを際立たせたい際には、ポートレートモードで擬似的に被写界深度を狭めて立体感のある写真を撮ることもできます(F0.95~22までシミュレート可能)。</p>
<section id="作例" class="level4">
<h4 class="anchored" data-anchor-id="作例">作例</h4>
<p>ZenFone6 Edition30で筆者が撮影した作例です。一部写真のGPS情報を削除した以外は撮って出しです。</p>
<div id="fig-Zen6_photo_sky" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_sky-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201007_120552.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-33" title="図&nbsp;19: 好条件で撮影したため金属の質感がリアル"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201007_120552.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_sky-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;19: 好条件で撮影したため金属の質感がリアル
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_over_HDR" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_over_HDR-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201007_163503.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-34" title="図&nbsp;20: HDRが効きすぎてやや嘘っぽく感じる"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201007_163503.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_over_HDR-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;20: HDRが効きすぎてやや嘘っぽく感じる
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_water" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_water-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201008_150053.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-35" title="図&nbsp;21: マニュアル撮影 ISO 200, \frac{1}{320}秒"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201008_150053.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_water-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;21: マニュアル撮影 ISO 200, <img src="https://latex.codecogs.com/png.latex?%5Cfrac%7B1%7D%7B320%7D%E7%A7%92">
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_Flare" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_Flare-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201020_162331.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-36" title="図&nbsp;22: フレアが綺麗だったので撮影 木々の隙間から見える空の白飛びやレンズ端の質感低下が気になる"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201020_162331.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_Flare-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;22: フレアが綺麗だったので撮影 木々の隙間から見える空の白飛びやレンズ端の質感低下が気になる
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_fav" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_fav-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201021_061727.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-37" title="図&nbsp;23: 前ボケや色合いを含めて気に入っている1枚"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201021_061727.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_fav-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;23: 前ボケや色合いを含めて気に入っている1枚
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_win_a_prize" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_win_a_prize-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201021_061936.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-38" title="図&nbsp;24: 朝露にフォーカスを合わせた1枚。これにTwitterでフィルターをかけたものが受賞した"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201021_061936.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_win_a_prize-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;24: 朝露にフォーカスを合わせた1枚。これにTwitterでフィルターをかけたものが<a href="https://www.pottal-portal.com/PtPr3/posts/Refresh/win-a-priize">受賞した</a>
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_food" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_food-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20201229_135635.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-39" title="図&nbsp;25: 我ながら美味しそうに撮れた牡蠣🦪"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20201229_135635.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_food-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;25: 我ながら美味しそうに撮れた牡蠣🦪
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_wing" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_wing-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_P_20200814_200703.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-40" title="図&nbsp;26: エスカレーターが羽のように見えたので撮った写真"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20200814_200703.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_wing-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;26: エスカレーターが羽のように見えたので撮った写真
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_wide1" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_wide1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_P_20200814_200816.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-41" title="超広角カメラで撮影"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_P_20200814_200816.jpg" class="img-fluid figure-img"></a></p>
<figcaption>超広角カメラで撮影</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_wide1-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;27: 超広角側で暗環境は、画質の低下が顕著
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_wide2" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_wide2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/Zen6_wide_P_20200804_125628.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-42" title="超広角カメラで撮影"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_wide_P_20200804_125628.jpg" class="img-fluid figure-img"></a></p>
<figcaption>超広角カメラで撮影</figcaption>
</figure>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_wide2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;28: 超広角でダイナミックに撮影。イマイチな質感にもハッタリが効いた例
</figcaption>
</figure>
</div>
<div id="fig-Zen6_photo_Panorama" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-Zen6_photo_Panorama-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<a href="../post_images/Zen6_Panorama_yzzmzy.jpg" class="lightbox" data-gallery="quarto-lightbox-gallery-43" title="図&nbsp;29: ZenFone6のフリップカメラを使えば、渋谷駅の「明日の神話」も1枚に収められる(この写真のみトリミング)"><img src="https://pottal-portal.com/PtPr3/post_images/Zen6_Panorama_yzzmzy.jpg" class="img-fluid figure-img"></a>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-Zen6_photo_Panorama-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
図&nbsp;29: ZenFone6のフリップカメラを使えば、渋谷駅の「明日の神話」も1枚に収められる(この写真のみトリミング)
</figcaption>
</figure>
</div>
<p>その他、筆者がZenFone6で撮影した写真について気になる方はTwitterを御覧ください。</p>
<p><a href="https://twitter.com/search?q=from%3APottal_MDS%20%23ZenFone%E3%81%A7%E7%89%B9%E5%88%A5%E3%81%AA%E3%82%A2%E3%83%B3%E3%82%B0%E3%83%AB&amp;src=typed_query&amp;f=top">🔎 from:Pottal_MDS #ZenFoneで特別なアングル</a></p>
<aside id="footnotes-4" class="footnotes footnotes-end-of-section">
<hr>
<ol start="5">
<li id="fn5"><p>フリップカメラという物理的に回転する機構を持つ関係上、カメラユニットのスペースにも物理的制約が生まれるため、トリプルカメラにする余裕はなく、またカメラが増えればその分重くなりフリップするための機構も強力にする必要があるため、ZenFone7シリーズでそれを実現した時には驚かされました。しかもZenFone7Proはメインと望遠に光学式手ぶれ補正を搭載するという力の入れようです。↩︎</p></li>
</ol>
</aside>
</section>
</section>
<section id="使い勝手について筆者の使い道について" class="level3">
<h3 class="anchored" data-anchor-id="使い勝手について筆者の使い道について">使い勝手について(筆者の使い道について)</h3>
<p>フリップカメラが特徴のハイエンドスマホであるZenFone6ですが、その中でもプレミアムモデルということで12GB RAM/512GB ストレージを搭載しており、2024年現在でも普通に使えるといった印象です。むしろ、尖ったカメラ機能の方が時代の速度についていけず、メインとして外に持ち出すカメラ専用機というより普段使いのサブスマホとしての利用の方が適しています。</p>
<p>もちろん、スマートフォンにハイエンドなスペックを求めない方も大勢いるでしょう。ミドルレンジで十分という方であれば2024年であってもZenFone6 Edition30はミドルハイクラスの体験を提供できます。ディスプレイが60Hzなのがミドルハイとしては厳しいかもしれませんが、それ以外は不満なく使えるはずです。 しかし、通常モデルのZenFone6ならともかく世界に3000台しかないこの機種をわざわざサブスマホとして買う人はどこにもいないでしょうから、サブスマホとしての使い勝手についてレビューすることに意義があるか極めて怪しいところであります。余談ですが、型落ちとなったハイエンドスマホを中古で安く購入して、ミドルレンジな価格でメインスマホ, あるいはサブスマホとして使うのであれば、ZenFone6よりも(ASUSスマホであれば)ROG Phoneシリーズの方が向いています。</p>
<p>スマホカメラの進歩はまさしく日進月歩であり、流石に2019年のスマートフォンでは最新機種には叶いません。ZenFone6が持つフリップカメラ――メインカメラがそのままインカメラになる――という強みを活かして自撮り番長として戦うことは可能だと思いますが、筆者が自撮りをしないので断言は出来ませんし、自撮りガチ勢は最新のiPhoneか、折りたたみスマホのメインカメラを活用していることでしょう。(折りたたみスマホであれば、メインカメラのそばにサブディスプレイが付いているため、映りを確認しながらメインカメラで撮影が可能です。)</p>
<p>もちろん、ZenFone6は自撮り以外にも、自由なアングルで撮影ができるという強みがあるのですが、2019年当時ならともかく2024年にわざわざ5年前のスマホを持ち出して、新たな視点を求めるかと言われると、筆者はノーです。それに5年も使っていると、このスマホで撮れる画角が頭に入っているので、ディスプレイを注視せずとも、このアングルから写せば何が出てくるかというのが分かってしまい、結果としてフリップカメラを動かすのではなくスマホを動かして撮ってしまいます。</p>
<p>また、筆者の持つモデルは全世界限定3000台という特別なものであるため、おいそれと外で使えません。そのため、今は野外に持ち出さず、家で大切にデスクトップPCのWebカメラとして活用しています。 充電を80%までに制限できること、スマホホルダーで固定した後もフリップカメラで微調整が可能なことがその理由です。</p>
<p>その他、考えられる用途としてはYouTube専用機でしょうか。発色とコントラストに優れた有機ELではないため、Netflixなどで映画を楽しむといった映像美を求める用途にはやや物足りませんが、YouTubeで動画を垂れ流すのであれば十分ですし、明るさの面では液晶の方が有利です。</p>
<p>スピーカーは2つ付いていますが、ROG Phoneシリーズや最新のXperia 1/5シリーズと違い、デュアルフロントスピーカーではないため、(横持ちにした際)左右のスピーカーからバランス良く音を楽しむことは出来ません。そのため、映画のように音響にこだわった作品を視聴するのには向きませんが、YouTubeで何となく動画を流すという用途では気になりません。</p>
</section>
</section>
<section id="まとめ" class="level2">
<h2 class="anchored" data-anchor-id="まとめ">まとめ</h2>
<p>ZenFone6 Edition30は発売から5年が経とうとしても色褪せない最高のスマートフォンである――と言いたいのが本音です。今は後から無理なく写真の補正を行うことも難しくありませんし、生成AIの台頭により、画面に収まらなかった絵を生成し拡張することさえできる時代ですが、アングルというのは、そう簡単に補正を行うことはできません。そういった意味では、自由なアングルで手軽に撮影ができるZenFone6のフリップカメラは最新機種にはない強みを持っています。しかし、いつも凝ったアングルで写真を撮るわけではありません。カメラ専門スマホの中でもアングルにこだわりたい時だけZenFone6を持ち出すというのは想定として厳しいでしょう。また、アングルというのは「気付く」か「気付かない」かです。スマートフォンはカメラに比べれば小さいため、アングルの調整はしやすいので、他のスマホでは撮れない――言い換えれば、ZenFone6でしか撮れないアングルというのはありません。やはり5年という歳月は大きく、特に昨今のハイエンド機種はカメラにかなり力を入れていますから、こうして条件を揃えてしまうとZenFone6は色褪せてしまいます。</p>
<p>しかし、第一線で戦えなくても、使えないわけではありません。サブスマホとしてのセカンドライフは十分におくれます。もちろん、サブスマホとしてわざわざ買い足すのは本末転倒ですが、第一線から退かせて使うという意味では問題がなく、むしろお釣りが出るくらいであるということは、ZenFone6ユーザーなら十分に理解していることでしょう。バッテリーケア機能で劣化の少ない5000mAhのバッテリー、MicroSDカードと2つのnanoSIMをさせるトリプルスロット仕様、5年前のハイエンドSoC、明るい液晶、どれをとってもサブスマホとしては十分過ぎます。 問題は、ZenFone6ユーザーならそれを分かっているのでこの文章を届ける対象がいないことですが、もともと虚空に向かって熱弁を振るっているようなブログなので…まあいつものことです。それに、世界にたった3000台しかないZenFone6 Edition30のレビューですから、今更な話です。だとすれば、筆者にできることはただ一つ。</p>
<p>ZenFone6 Edition30は色褪せてなお美しい、そう惚気けることだけでしょう。</p>



</section>

<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> トップに戻る</a><div id="quarto-appendix" class="default"><section class="quarto-appendix-contents" id="quarto-bibliography"><h2 class="anchored quarto-appendix-heading">参考文献</h2><div id="refs" class="references csl-bib-body hanging-indent" data-entry-spacing="0" data-line-spacing="2">
<div id="ref-paopao" class="csl-entry">
kazuteru TAMURA (2018) 「<span>ASUS、スマホ事業の戦略転換を発表</span>」、 <em><span>blog of mobile</span></em>、2018年、閲覧日 2024年3月2日、 <a href="http://blogofmobile.com/article/110786?utm_source=pocket_mylist">http://blogofmobile.com/article/110786?utm_source=pocket_mylist</a>
</div>
<div id="ref-ASUSJAPAN_Zen6" class="csl-entry">
ASUS (2019) 「<span>ZenFone6 視点を変えろ。世界は変わる。</span>」、 <em><span>ASUS JAPAN</span></em>、2019年、閲覧日 2024年4月2日、 <a href="https://www.asus.com/jp/mobile-handhelds/phones/zenfone/zenfone-6/">https://www.asus.com/jp/mobile-handhelds/phones/zenfone/zenfone-6/</a>
</div>
<div id="ref-Koyama2020Xperia" class="csl-entry">
小山安博 (2020) 「<span>Xperia 1 IIのカメラ技術をひもとく - 新機能Photography Proで「α」並みの本格撮影も</span>」、 <em>マイナビニュース</em>、2020年4月29日、閲覧日 2024年4月3日、 <a href="https://news.mynavi.jp/article/20200429-1025884/3">https://news.mynavi.jp/article/20200429-1025884/3</a>
</div>
<div id="ref-Tanaka2020Xperia" class="csl-entry">
田中巧 (2020) 「<span>デジタル一眼カメラ並みの機能性を実現。ソニー「Xperia 1 II」のカメラ機能の詳細が明らかに</span>」、 <em>価格.comマガジン</em>、2020年4月29日、閲覧日 2024年4月3日、 <a href="https://kakakumag.com/pc-smartphone/?id=15365">https://kakakumag.com/pc-smartphone/?id=15365</a>
</div>
<div id="ref-ASUS_Zen" class="csl-entry">
シンシア (2014) 「<span>【ASUS JAPANシンシアの「華華(ふぁふぁ)通信」】Zenな出会い ～ASUS会長サイン入りZenFone 5をプレゼント</span>」、 <em>PC Watch</em>、2014年11月7日、閲覧日 2024年4月4日、 <a href="https://pc.watch.impress.co.jp/docs/column/cynthia/674839.html">https://pc.watch.impress.co.jp/docs/column/cynthia/674839.html</a>
</div>
<div id="ref-ASUS_Store" class="csl-entry">
ASUS JAPAN (2019) 「<span>ASUSの設立30周年を記念した13.3型ノートPCの「ASUS ZenBook Edition 30」とSIMフリースマートフォンの「ZenFone 6 Edition 30」を発表</span>」、 2019年8月20日、閲覧日 2024年4月4日、 <a href="https://jp.store.asus.com/store/asusjp/html/pbPage.news_20190820_30th/">https://jp.store.asus.com/store/asusjp/html/pbPage.news_20190820_30th/</a>
</div>
<div id="ref-ASUS_Design" class="csl-entry">
Chu Jenny (2019) 「華碩三十週年紀念筆電」、 2019年7月18日、閲覧日 2024年4月4日、 <a href="https://asusdesign.com/tw/2019/07/18/10286/">https://asusdesign.com/tw/2019/07/18/10286/</a>
</div>
<div id="ref-ASUS30_Video" class="csl-entry">

</div>
<div id="ref-ZenBlog" class="csl-entry">
藤沢航 (2022) 「<span>ASUSの新ロゴ「Aモノグラム」に込められた意味とは</span>」、 <em><span>ASUS好きのZenBlog（ゼンブログ）</span></em>、2022年9月5日、閲覧日 2024年4月4日、 <a href="https://jp.store.asus.com/store/asusjp/html/pbPage.news_20190820_30th/">https://jp.store.asus.com/store/asusjp/html/pbPage.news_20190820_30th/</a>
</div>
<div id="ref-ASUSMono" class="csl-entry">
ASUS Design Center (2019b)“ASUS Monogram”, <em>Behance</em>, 7月 11, 2019 Accessed 2024年4月月4日<a href="https://www.behance.net/gallery/81838501/ASUS-Monogram">https://www.behance.net/gallery/81838501/ASUS-Monogram</a>
</div>
<div id="ref-ASUSJAPAN_Zenbook" class="csl-entry">
ASUS (2024) 「<span>ASUS Zenbook 14 OLED (UX3405)</span>」、 <em><span>ASUS JAPAN</span></em>、2024年、閲覧日 2024年4月4日、 <a href="https://www.asus.com/jp/laptops/for-home/zenbook/asus-zenbook-14-oled-ux3405/">https://www.asus.com/jp/laptops/for-home/zenbook/asus-zenbook-14-oled-ux3405/</a>
</div>
<div id="ref-ASUSJAPAN_Zenfone10" class="csl-entry">
ASUS (2023) 「<span>Zenfone10</span>」、 <em><span>ASUS JAPAN</span></em>、2023年、閲覧日 2024年4月4日、 <a href="https://www.asus.com/jp/mobile-handhelds/phones/zenfone/zenfone-10/">https://www.asus.com/jp/mobile-handhelds/phones/zenfone/zenfone-10/</a>
</div>
<div id="ref-ASUSJAPAN_ROGPhone_ZS600KL" class="csl-entry">
ASUS (2018) 「<span>ASUS Zenbook 14 OLED (UX3405)</span>」、 <em><span>ASUS Store</span></em>、2018年、閲覧日 2024年4月6日、 <a href="https://jp.store.asus.com/store/asusjp/ja_JP/pd/productID.5250166100/ROG-Phone-ZS600KL">https://jp.store.asus.com/store/asusjp/ja_JP/pd/productID.5250166100/ROG-Phone-ZS600KL</a>
</div>
</div></section></div> ]]></description>
  <category>レビュー</category>
  <category>スマートフォン</category>
  <category>ASUS</category>
  <category>おすすめ記事</category>
  <guid>https://pottal-portal.com/PtPr3/posts/ZenFone6.html</guid>
  <pubDate>Wed, 10 Apr 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/Zen6_DSC_8973-4.png" medium="image" type="image/png" height="96" width="144"/>
</item>
<item>
  <title>Pottal-Portal 3.0 にアップデートしました</title>
  <dc:creator>Pottal </dc:creator>
  <link>https://pottal-portal.com/PtPr3/posts/PtPr3_Start.html</link>
  <description><![CDATA[ 




<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><a href="../post_images/cover_Lite.png" class="lightbox" data-gallery="quarto-lightbox-gallery-1"><img src="https://pottal-portal.com/PtPr3/post_images/cover_Lite.png" class="img-fluid quarto-figure quarto-figure-center figure-img" width="300"></a></p>
</figure>
</div>
<section id="pottal-portal2.0はpottal-portal-3.0-へアップデートしました" class="level2">
<h2 class="anchored" data-anchor-id="pottal-portal2.0はpottal-portal-3.0-へアップデートしました">Pottal-Portal2.0はPottal-Portal 3.0 へアップデートしました</h2>
<p>2022年4月から「WordPress」で運用しておりました「Pottal-Portal2.0」ですが、この度「Quarto」へと移行し、2024年4月1日より「Pottal-Portal 3.0」として運用させていただきます。</p>
<p>「旧Pottal-Portal」及び「Pottal-Portal2.0」の記事に関しては、必要に応じて順次最適化を行うつもりですが、それまでの間は、一部レイアウトが崩れた状態となってしまうことをご了承下さい。</p>
<section id="pottal-portal-3.0-のアップデート内容" class="level3">
<h3 class="anchored" data-anchor-id="pottal-portal-3.0-のアップデート内容">Pottal-Portal 3.0 のアップデート内容</h3>
<ul>
<li>名称が「Pottal-Portal2.0」から「Pottal-Portal 3.0」になりました
<ul>
<li>ドメインに変更はございません</li>
<li>旧サイトの記事のURLにも変更はございません</li>
<li>名称変更に伴い、サイトロゴ等にも若干の変更がございます</li>
</ul></li>
<li>WordPressから、Quartoへと移行しました
<ul>
<li>Markdownベースで記事を書けるようになったため、更新頻度の向上が見込まれます</li>
<li>Quartoの機能により図表や脚注<sup>1</sup>などにマウスホバーするとインライン表示できるようになりました</li>
</ul></li>
</ul>
</section>
</section>
<section id="アップデート理由について" class="level2">
<h2 class="anchored" data-anchor-id="アップデート理由について">アップデート理由について</h2>
<p>WordPressでの作業が苦痛だったこと、そして図表や目次の表示に難があり、特に長い記事になるとその傾向が顕著になることから、WordPressからの脱却をしたかったのが主な原因です。 また、名前もPottal-Portal 3.0 へと一新することで、一度リセットし、更新頻度の低かったPottal-Portal2.0からの心機一転を図りたかったというのも理由の1つです。</p>
</section>
<section id="quartoとは" class="level2">
<h2 class="anchored" data-anchor-id="quartoとは">Quartoとは</h2>
<p>QuartoはRStudio によって開発されたオープンソースの科学・技術出版システムです。 詳しくは、<a href="https://quarto.org/">公式ドキュメント</a>を御覧ください。</p>
</section>
<section id="今後の抱負について" class="level2">
<h2 class="anchored" data-anchor-id="今後の抱負について">今後の抱負について</h2>
<p>最低でも月に1回は更新したいです。</p>


</section>


<a onclick="window.scrollTo(0, 0); return false;" id="quarto-back-to-top"><i class="bi bi-arrow-up"></i> トップに戻る</a><div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">脚注</h2>

<ol>
<li id="fn1"><p>脚注の例↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>お知らせ</category>
  <guid>https://pottal-portal.com/PtPr3/posts/PtPr3_Start.html</guid>
  <pubDate>Sun, 31 Mar 2024 15:00:00 GMT</pubDate>
  <media:content url="https://pottal-portal.com/PtPr3/post_images/PrPr3_start.png" medium="image" type="image/png" height="75" width="144"/>
</item>
</channel>
</rss>
