Code Interpreterでどのような症例報告用パワーポイントスライドが作成できるようになったのか?
0. はじめに
AIを用いたプレゼン用スライドの作成方法はバラエティに富んでいます。キーワードを提示しAIに全て作成してもらう方法やこちら側がある程度原案を用意し, AIに体裁を整えてもらう方法などあります。症例報告などある程度「型」が決まった発表はAIにスタイルを整えてもらうのには好都合です。
現在のChatGPTでは考察を作ることは難しく, それ以外の検査項目や患者情報などの単なる情報を要約する能力は優れています。プレゼンの原案をこちらで用意すれば, アウトラインレベルの設定するなどでの手法でパワーポイントに出力することができます。
今回のバージョンアップ (Code Interpreter) (2023/7) ではファイルアップロード機能やGPT上でPythonが使用できるようになりました。ChatGPT内でPython codeの作成, 実行, 評価を自動でしてくれるようになりました。Pythonによってプログラミングの知識がなくても「機能性を持った」スライドの作成や「複雑な」グラフなど「簡単に」作成できるようになりました。
今回, ファイルアップロード機能などによってどのような恩恵があったか検証したいと思います。
1. Code Interpreter
1.1 Code Interpreterの導入
ChatGPT plusに加入している必要があります。ChatGPT 左下のSettingsから

Beta features の Code Interpreterを有効にします。

GPT4→Code Interpreter Betaにチェックを入れます。

チャット欄の Send a message の左にある⊕ボタンを押せば ファイルのアップロードができます。
1.2 個人情報保護の注意点
一応, ChatGPTにはprivate modeがありますが。情報漏洩の危険性は否めないです。患者情報をOpen AIに流出させてしまう危険があるのでprivate modeは必須と考えます。今回の検証ではCode Interpreterでどこまで自動化が便利になるのかという技術的な側面からの検証です。用いるデータは架空の患者データで, AIと共著した架空論文, 架空電子カルテを用います。


これらの患者情報を元に最終的にhigh qualityなパワポスライドが作成可能かどうか検証します。
1.3 致命的なバグ (一度で返してくれない問題)
2023/7 リリース時より存在している深刻なバグです。こちらが作成依頼したら「現環境では出来ません」と返答する問題があります。その場合, 根気強く何度も「やって下さい」とお願いしたら「しぶしぶ」やってくれますが…
Code Interpreterにパワポ作成を依頼したら「出来ない」と言われる問題。原因はpython-pptxライブラリが最初からインストールされていることを「認識」していないことらしいです。対策としては① 同じchat欄を使用 ② 前回作成したcode全体を読み込ませる。くらいでしょうか。 pic.twitter.com/7bGRRTJETn
— プチpony (@pony_pon471) July 14, 2023
2. 方法

究極的には患者の「乱雑なカルテ情報」から学会で発表できる位の高品質な「症例報告」パワポプレゼンスライドができることが理想です。しかしながら現時点のAIの能力では課題点が山積みです。入力情報が少ない (=プロンプトが少ない) ほど作成が早くて簡単ですが出来上がるスライドの品質は低いです。 逆に入力情報が多ければ (プロンプトが多い), 高品質なスライドができますが作成時間がかかります。
① 簡易プロンプト (最小限のプロンプト)
とにかく簡単にプレゼンスライドを作成。患者カルテ テキストファイルから「症例報告のスライドを作ってください」のようにプロンプトします。さすがに1行ではGPT側も困ると思いますので, 何枚でとか, 診断, 治療について考察してくださいなど最低限のルールを提示します。
② 少し詳細なプロンプト
ある程度こちら側でカルテ原文を整えて原案を作成します。症例報告の「型」にする方法はいくつかあると思いますが, 今回は以下の方法↓で「病歴要約の形」に一旦変形してそのままパワポスライドに変換します。現時点で考察など高度な文章を作成することは不可能のため手動で補完する必要はあります。
③ 詳細プロンプト
②をさらに詳細に掘り下げてパワーポイントに出力する前に原案を作成します。プロンプトの作成に手間がかかること, codeを処理する時間がかかるため作成難度は高いですがハイクオリティなものができ, 一度作成しておくと再利用など利便性は高いと思われます。
3. 作成
では実際に作成し検証していきます。
3.1 簡易プロンプト
まずはカルテ原文を読み込ませます。

これだけで症例報告を作ることは難しいと思いますので 先ほど創作したネコミウイルス感染症の総説 (Review article) のワードファイルを学習してもらいます。

それでは実際に作ってもらいます。
python-pptxライブラリを使用してPythonコードを実行し、カルテ原文から7枚のPowerPoint
プレゼンテーションを作成してください。
スライドの構成は以下の通りです。
S1: title 病院奇譚 猫の主治医
S2: 主訴 現病歴
S3: 患者背景 既往歴、家族歴、生活アレルギー歴など
S4:入院時現症
S5:入院時検査所見
S6:入院後経過と考察
S7:総合考察 ネコミウイルス感染症のウイルス学、診断、治療などについてまとめてください。出来たパワーポイントスライドです.。

いろいろ突っ込みどころがあります。カルテをそのまま貼り付けただけのものが出来上がりました…そらそうですよね…
3.2 少し詳細なプロンプト
前述の方法±手動+気合でカルテ原文を「病歴要約の形」に変換します。検査値など文字がうまく並べ替えられ, 表などそのまま流用できます。

準備した病歴要約のワードファイルを左の⊕ボタンからアップロードして準備します。このワードファイルからプレゼン用パワーポイントを作るように頼みます。

python-pptxライブラリを使用してPythonコードを実行し、abstractから7枚のPowerPoint
プレゼンテーションを作成してください。フォントサイズは26で。
S1からS6はabstractをそのまま引用してください。S7総合考察はabstractやこれまで提示した
reviewなどでそちらがまとめてください。
スライドの構成は以下の通りです。
S1: title 病院奇譚 猫の主治医 確定診断名
S2: 【主訴】【現病歴】
S3: 【既往歴】【社会生活歴】【家族歴】
S4:【入院時現症】
S5:【検査所見】
S6:【入院後経過と考察】
S7:総合考察 ネコミウイルス感染症のウイルス学、診断、治療などについてまとめてください
2-3分待ちます エラーが出たら何回か自動でやり直しをしてくれますのでしばらく待ちます。

※ 現在何かしらのバグ?でテキストボックス内に文字が収納されないバグが存在しています。ChatGPTに何回か聞いたり調べてみましたが原因は良くわかりません。テキストボックスを手動でリサイズしたら収まってくれますが。全テキストボックスのサイズをこちらで再調整する必要があります。

出来上がったパワーポイントファイルの完成度はまずまずです。
手打ちで自作するより圧倒的に早くできます。しかし, これをそのまま発表スライドに使うのは心もとないです。
3. 詳細プロンプト
3.1 準備: スライドの型 (構成) の分類
スライドの構成を種類ごとに分類したいと思います。症例報告で作成するは個人的に以下の⑥種類に大別できると考えます。

① 文字列
基本的な型, 文字をひたすら並べるだけです。タイトル, 【主訴】【現病歴】【既往歴】【生活歴】【入院時現症】などがこれにあたります。これまで紹介した手法ではこのtypeのスライドしか作成できません。基本的なスライドの体裁, 構成はこちらを参考させていただきました。
② 検査所見
血液検査などの各種検査項目をスライドに少ない枚数 (1, 2枚) に収めます。I. 文字列としてひたすら並べる方法や, II. 表にする方法があります。
I. 文字列は短時間で作成できますが, 見栄えの観点から学会発表ではII. 表を用いる人の方が多いように思えます。

③ 入院後経過表
症例報告のスライド作りで最も骨の折れる作業ではないでしょうか。以下のサイトに経過表の「sample」や作り方が紹介されていますので当方も良く利用します。
症例ごとに経過表の構成が大きく変わります。さらに現時点のChatGPTでは直接powerpointやexcelのグラフに変換することは困難です。そのためAIで自動化, 高率化することは難しく, 今のところpowerpointで手動で作る方が早いと思われます。今回, sampleを作ってみましたので今後sampleをもとに他の症例でも応用できたらと考えています。
④ 表
他の研究との比較表などがこれにあたります。もともとChatGPTは表を作成する機能がありますので, Code Interpreterの恩恵はそれほどないかもしれません。

⑤ 文字列特殊型
①の派生です。箇条書き+それの引用文献など
⑥ その他
写真や自作の図など
3.2 作成
デザインは当方の趣味で背景を「紺色」, 基本的な文字を「白」で作ってみます。
3.2.1 文字列
文字だけのシンプルな構成のスライドを作ってみます。
背景色, テキストボックスの位置とサイズ, 文字の設定 (フォントサイズ, 色) を具体的に指示します。まずは1枚目 titleだけのスライドです。
python-pptxライブラリを使用してPythonコードを実行し、PowerPointプレゼンテーションを作成してください。
背景色 R0G0B70
空白は自動で改行しないでください。
S1:テキストボックス1: 高さ1.5 inch 幅9 inch左から0.8inch, 上から1.2inch “病院奇譚 猫の主治医” フォント 44 ボールド 黄色
テキストボックス2: 高さ1.5 inch 幅9 inch左から0.8inch, 上から3.4inch “動物病院 内科” フォント36 ボールド 白
テキストボックス3: 高さ1.5 inch 幅9 inch左から0.8inch, 上から5.5inch サイズ縦1.5inch 12inch “筆頭者のCOI表示 演題発表に関し、開示すべきCOI関係にある企業等はありません。” フォント 28 ボールド R200G255B255
1枚のスライドを作成するのに1-2分かかります…

パワーポイントをダウンロードします。出来上がったスライドのテキストボックスの文字がはみ出てるのを手動で直します。

show workをクリックすると実際に作成されたpython codeが表示されます

Copy codeをクリックするとコピーできるので次回から再利用可能となります。

下↓は今回作成したスライド1枚分のコードです。
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
# Create a blank presentation
presentation = Presentation()
# Define slide layout as blank
slide_layout = presentation.slide_layouts[6]
# Add a slide with the blank layout
slide = presentation.slides.add_slide(slide_layout)
# Define the background color
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 70) # R0G0B70
# Define the parameters for the text boxes
text_boxes = [
{
"height": 1.5, "width": 9, "left": 0.8, "top": 1.2,
"text": "病院奇譚 猫の主治医", "font_size": 44, "bold": True, "color": (255, 255, 0)
}, # Yellow
{
"height": 1.5, "width": 9, "left": 0.8, "top": 3.4,
"text": "動物病院 内科", "font_size": 36, "bold": True, "color": (255, 255, 255)
}, # White
{
"height": 1.5, "width": 12, "left": 0.8, "top": 5.5,
"text": "筆頭者のCOI表示 演題発表に関し、開示すべきCOI関係にある企業等はありません。",
"font_size": 28, "bold": True, "color": (200, 255, 255)
}, # R200G255B255
]
# Add the text boxes to the slide
for tb in text_boxes:
text_box = slide.shapes.add_textbox(
Inches(tb["left"]), Inches(tb["top"]), Inches(tb["width"]), Inches(tb["height"])
)
frame = text_box.text_frame
frame.word_wrap = False
frame.auto_size = True
frame.text = tb["text"]
para = frame.paragraphs[0]
para.alignment = PP_ALIGN.LEFT
run = para.runs[0]
run.font.size = Pt(tb["font_size"])
run.font.bold = tb["bold"]
run.font.color.rgb = RGBColor(*tb["color"])
# Save the presentation
presentation_file = "/mnt/data/my_presentation.pptx"
presentation.save(presentation_file)
1枚のスライドでこれだけの量です…
同様に他のスライドも作成します。

1枚のスライド文のcodeを作成するのにかかる時間はβのためか大体1-2分です。理想は数枚文のスライドを依頼してPCを放置して出来上がるのを待つといったところですが, 同時に2枚分以上の作成を依頼した場合, エラーの出現率が異常に上がる印象です。 そのため, 1枚ずつ作成が現実的ですが, それでは実用性が実用性があまりありません。時期バージョンに期待です。
3.2.2 検査結果 (表)
下準備:予め表に使う検査値を抽出して並び替えておきます。
患者情報から
検査所見を抜き出して以下の形式で文字列を作成してください。
該当する項目がなければ● で置き換えてください。
表1: TP ● g/dL, CK ● U/L, LDH ● IU/L, AST ● IU/L, ALT ● IU/L, ALP ● IU/L, γGTP ● IU/L, T-Bil ● mg/dL, BUN ● mg/dL, Cre ● mg/dL, Na ● mEq/L, K ● mEq/L, CRP ● mg/dL, Glu ● mg/dL
表2:WBC ● /uL, Lymp ●%, Mono ●%, Neut ●%, Eosino ●%, Hb ● g/dL, PLT ● x 10^4/uL, PT-INR ●, APTT ● sec
このあたりの単純作業はGPT 3.5で十分です。

準備した検査値を使って, 表を作成を指示します。さらに, 基準値も提示し, 高値はピンク色, 低値は青色になるように設定します。

パワーポイントスライドです ↓。(色を自動で変えるという) 機能性を持ち併せています。

ほぼ理想の表ができました。高値 (AST, CRP) はピンク色, 低値 ( K) は青色に自動で変換されました。PLTは設定があまく低値 (青) ですが…
3.2.3 入院後経過表
これまではAIを用いた複雑なグラフ作成は困難でした。今回のバージョンアップ (Code Interpreter) でPython +matplotlibが直接GPT上で実行可能となりかなり簡単に作成することが可能となりました。
今回は良く見かける, 横軸に入院後日数 (day), 縦軸に2軸 検査値 (ここではCRP, EBC), さらにその上に使用薬剤 (ステロイド) を1枚にまとめたものを作図してみます。型となるコード (python code) さえきっちりしていればプロンプトは雑でOKです。

背景が紺色なので透明グラフを高解像度のSVG形式で作成してパワポスライドに貼り付けました。

この表も手入力で自作するよりも圧倒的に早く作成が可能です。
長くなってしまいましたので ④ 表 ⑤ 文字列特殊型 ⑥ その他は後編で解説したいと思います。
4. パワーポイントファイル, コードを再利用して作成する方法
AIを用いたファイル全般に言えることですが, 初回はプロンプトを考えたり, コードのエラーを修正したりと大変ですが一度作ってしまえば次回から簡単に似たようなファイルを量産することが可能です。

パワーポイントファイル (ppt), パイソンコード (code) のどちらを流用するかは一長一短あります。
4.1 パワーポイントファイル (pptx) を流用して作成
【主訴】【現病歴】から【検査所見】が含まれたパワーポイントファイル (01-05.ppt) をアップロードして作成してみます。

出来上がったパワポスライドです。

文字に関しては問題なく再現できていますが, フォントや色, 表など形式は不十分です。

アップロードしたpptファイルについてGPTが認識でき再現できること, できないことについて質問してみました。
認識出来る事
構造:
・スライドの枚数
・スライドのレイアウト
・テキストボックスの数
・スライドボックスのテキスト内容
出来ない事
詳細なレイアウト
・テキストボックスの位置
・背景色や画像
・特定のテキストスタイル
そこまで複雑なスライド作成を目的としていないのではこれでこの完成度で十分かもしれませんが…
4.2 パイソンコード (python code) を流用して作成
Chat欄にpython codeと必要な箇所の患者情報をコピペして作成します。

今回はスライド1枚タイトルを別の症例で作ってみます。

スライドの構成は同じで文字だけが変わりました。
繰り返しになりますが, 枚数が多いとエラーが起きる頻度が高くなりますので一枚ずつ作ります。
次は検査値の表です。別の患者 (架空) のデータを渡します。

Python codeを引用する場合は雑なプロンプトでもGPT側が考えてよさげなスライドを作成してくれます。

瞬時に作成できました。手打ちで作成するより圧倒的に短時間で作成できそうです。(好中球の基準値を設定していないため好中球NEが白のままですが…)
python codeを流用する手法はいずれもスライドの種類でもpptを流用するよりも再現性が高いことが利点です。
5. まとめ
現時点での大きな問題点として
・テキストボックスはみ出しバグ
・コード作成の時間が長い コード自体が長い
・そもそも作ってくれないことが多い (何度もお願いする羽目になる)
が挙げられますが
sample codeを再利用することで時短が可能になります。
また, 上の問題点はリリースされたばかりのバグだと思いますので気長にまちましょう。
6. サンプルコード
6.1 文字列

python code
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import MSO_ANCHOR, MSO_AUTO_SIZE
# Create a new presentation
prs = Presentation()
# Define slide layout
slide_layout = prs.slide_layouts[6] # title slide
slide = prs.slides.add_slide(slide_layout)
# Set slide background color
background = slide.background
fill = background.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0, 0, 70)
# Create textbox 1
left = Inches(4)
top = Inches(0.4)
width = Inches(1.8)
height = Inches(1.4)
txBox1 = slide.shapes.add_textbox(left, top, width, height)
tf1 = txBox1.text_frame
tf1.word_wrap = False
p = tf1.add_paragraph()
p.text = "症例"
run = p.runs[0]
run.font.size = Pt(44)
run.font.bold = True
run.font.color.rgb = RGBColor(255, 255, 0) # yellow
# Create textbox 2
left = Inches(0.4)
top = Inches(1.7)
width = Inches(9)
height = Inches(5)
txBox2 = slide.shapes.add_textbox(left, top, width, height)
tf2 = txBox2.text_frame
tf2.word_wrap = False
# Add each paragraph separately to control color
p = tf2.add_paragraph()
run = p.add_run()
run.text = "【主訴】"
run.font.size = Pt(26)
run.font.color.rgb = RGBColor(255, 255, 0) # yellow
run = p.add_run()
run.text = "発熱、全身倦怠感"
run.font.size = Pt(26)
run.font.color.rgb = RGBColor(255, 255, 255) # white
p = tf2.add_paragraph()
run = p.add_run()
run.text = "【現病歴】"
run.font.size = Pt(26)
run.font.color.rgb = RGBColor(255, 255, 0) # yellow
p = tf2.add_paragraph()
run = p.add_run()
run.text = "2023年8月10日、突然の発熱と倦怠感、咽頭痛と呼吸苦を感じ、解熱鎮痛薬を内服したものの症状は改善しなかった。前医へ相談し、肺炎が疑われ、レントゲン検査を受け、肺に異常陰影が指摘された。血液検査で白血球数上昇が指摘され、キャッツ総合病院へ緊急紹介された。8月12日、キャッツ総合病院への入院となった。"
run.font.size = Pt(26)
run.font.color.rgb = RGBColor(255, 255, 255) # white
# Save presentation
prs.save("medical_case_revised.pptx")
6.2 検査値 (表)

プロンプト
① 検査値を整えるプロンプト
患者情報から
検査所見を抜き出して以下の形式で文字列を作成してください。該当する項目がなければ● で置き換えてください。
表1: TP ● g/dL, CK ● U/L, LDH ● IU/L, AST ● IU/L, ALT ● IU/L, ALP ● IU/L, γGTP ● IU/L, T-Bil ● mg/dL, BUN ● mg/dL, Cre ● mg/dL, Na ● mEq/L, K ● mEq/L, CRP ● mg/dL, Glu ● mg/dL
表2:WBC ● /uL, Lymp ●%, Mono ●%, Neut ●%, Eosino ●%, Hb ● g/dL, PLT ● x 10^4/uL, PT-INR ●, APTT ● sec
② パワポスライドを作るプロンプト
S5: python-pptxライブラリを使用してPythonコードを実行し、PowerPointプレゼンテーションを作成してください。
背景色 R0G10B40
テキストボックス: 高さ0.5inch 幅4inch 左 3inch 縦0.2inch ”【主要な検査所見】 "フォント28 黄色
・以下の検査値で表を作成してください。
各検査項目で基準値を参照して高値, 正常値, 低値を判定してください。
色の設定:高値はホットピンク, 低値はシアン, 正常値は白 同じ行の検査項目, 数値, 単位は同じ色で統一。例えばTPが高値ならTPと同じ行の数字とg/dLはいずれもホットピンク。色を設定する前に各セルにテキストが存在することを確認し存在しなければ設定不要。
表の罫線は不要(背景と同様に透明) 背景はなし 文字はフォント18 白色。表をスライドに貼り付けてください。
表1(14行3列:1列目検査項目 例TP, 2列目 数値 例 7.3, 3列目単位 例 g/dL)。
表のサイズ:高さ6inch 幅4.3inch 位置:左 0.4inch 縦1.4inch
:TP 7.3 g/dL, CK 100 U/L, LDH 220 IU/L, AST 80 IU/L, ALT 45 IU/L, ALP ● IU/L, γGTP 45 IU/L, T-Bil 0.8 mg/dL, BUN 15 mg/dL, Cre 1 mg/dL, Na 140 mEq/L, K 3.3 mEq/L, CRP 2.5 mg/dL, Glu 85 mg/dL
表2 (12行3列)
WBC 7500 /uL, Lymp ●%, Mono ●%, Neut ●%, Eosino ●%, Hb 8.4 g/dL, PLT 300 x 10^4/uL, PT-INR ●, APTT ● sec
高さ3.5inch 幅4.3inch 左 5.2inch 縦1.4inch
基準値: AST 7-56, ALT 7-56, LDH 140-280, ChE 8300-18700, γGTP 10-60, CK 38-174, TP 6.4-8.3, T-Bil 0.1-1.2, BUN 7-20, Cre 0.74-1.35, UA 3.4-7.0, Na 135-145, K 3.5-5.1, Cl 96-106, Glu 70-110, WBC 4500-11000, HGB 13.5-17.5, HCT 38.8-50.0, MCV 80-96, PLT 150000-450000, CRP 0.0-1.0
python code
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
# Update table data
table_data1 = [
["TP", "7.3", "g/dL"],
["CK", "100", "U/L"],
["LDH", "220", "IU/L"],
["AST", "80", "IU/L"],
["ALT", "45", "IU/L"],
["ALP", "●", "IU/L"],
["γGTP", "45", "IU/L"],
["T-Bil", "0.8", "mg/dL"],
["BUN", "15", "mg/dL"],
["Cre", "1", "mg/dL"],
["Na", "140", "mEq/L"],
["K", "3.3", "mEq/L"],
["CRP", "2.5", "mg/dL"],
["Glu", "85", "mg/dL"],
]
table_data2 = [
["WBC", "7500", "/uL"],
["Lymp", "●", "%"],
["Mono", "●", "%"],
["Neut", "●", "%"],
["Eosino", "●", "%"],
["Hb", "8.4", "g/dL"],
["PLT", "300", "x 10^4/uL"],
["PT-INR", "●", ""],
["APTT", "●", "sec"],
]
# Define the reference values
reference_values = {
"AST": [7, 56],
"ALT": [7, 56],
"LDH": [140, 280],
"ChE": [8300, 18700],
"γGTP": [10, 60],
"CK": [38, 174],
"TP": [6.4, 8.3],
"T-Bil": [0.1, 1.2],
"BUN": [7, 20],
"Cre": [0.74, 1.35],
"UA": [3.4, 7.0],
"Na": [135, 145],
"K": [3.5, 5.1],
"Cl": [96, 106],
"Glu": [70, 110],
"WBC": [4500, 11000],
"HGB": [13.5, 17.5],
"HCT": [38.8, 50.0],
"MCV": [80, 96],
"PLT": [150000, 450000],
"CRP": [0.0, 1.0]
}
# Create a new presentation
prs = Presentation()
# Set slide background color
slide_layout = prs.slide_layouts[6] # select an empty layout
slide = prs.slides.add_slide(slide_layout)
slide.background.fill.solid()
slide.background.fill.fore_color.rgb = RGBColor(0, 0, 70)
# Add a textbox
left = Inches(3)
top = Inches(0.2)
width = Inches(4)
height = Inches(0.5)
txBox = slide.shapes.add_textbox(left, top, width, height)
tf = txBox.text_frame
p = tf.add_paragraph()
p.text = "【主要な検査所見】"
p.font.size = Pt(28)
p.font.color.rgb = RGBColor(255, 255, 0) # Yellow
# Function to create table
def create_table(table_data, left, top, width, height):
# Define table size
rows, cols = len(table_data), len(table_data[0])
# Add table to slide
table = slide.shapes.add_table(rows, cols, left, top, width, height).table
# Set font for table
font_size = 18
color_white = RGBColor(255, 255, 255)
color_hotpink = RGBColor(255, 105, 180)
color_cyan = RGBColor(0, 255, 255)
# Set table cell properties
for r in range(rows):
for c in range(cols):
cell = table.cell(r, c)
cell.text = table_data[r][c]
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.size = Pt(font_size)
cell.fill.background()
# Set color based on reference values
for r in range(rows):
if table_data[r][0] in reference_values and not table_data[r][1].startswith("●"):
low, high = reference_values[table_data[r][0]]
try:
value = float(table_data[r][1])
if value > high:
for c in range(cols):
cell = table.cell(r, c)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = color_hotpink
elif value < low:
for c in range(cols):
cell = table.cell(r, c)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = color_cyan
else:
for c in range(cols):
cell = table.cell(r, c)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = color_white
except ValueError:
for c in range(cols):
cell = table.cell(r, c)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = color_white
else:
for c in range(cols):
cell = table.cell(r, c)
for paragraph in cell.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = color_white
# Create two tables
create_table(table_data1, Inches(0.4), Inches(1.4), Inches(4.3), Inches(6))
create_table(table_data2, Inches(5.2), Inches(1.4), Inches(4.3), Inches(3.5))
# Save presentation
prs.save("/mnt/data/medical_test_results.pptx")
5.3 経過表グラフ

python code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Given data
data_psl = {
'day': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'PSL': [40, 40, 40, 30, 30, 20, 20, 10, 0, 0]
}
data_crp = {
'day': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'CRP': [10.2, 8.0, np.nan, 2.3, np.nan, 1.2, np.nan, 0.2, 0.03, 0.5]
}
data_wbc = {
'day': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'WBC': [10200, 8900, np.nan, 7700, np.nan, 5500, np.nan, 4230, np.nan, 5000]
}
# Create dataframes
df_psl = pd.DataFrame(data_psl)
df_crp = pd.DataFrame(data_crp)
df_wbc = pd.DataFrame(data_wbc)
# Interpolate missing values
df_crp['CRP'] = df_crp['CRP'].interpolate()
df_wbc['WBC'] = df_wbc['WBC'].interpolate()
# Define color settings
psl_color = '#7030A0' # RGB(112, 48, 160)
crp_color = '#FF69B4' # Deep pink
wbc_color = '#00FFFF' # Cyan
title_color = 'yellow'
axis_color = 'white'
# Set the default figure background to transparent
plt.rcParams['figure.facecolor'] = 'none'
# Create a figure with two subplots with different heights
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), gridspec_kw={'height_ratios': [1, 3]})
fig.suptitle('Clinical Course', fontsize=14, fontweight='bold', color=title_color) # Add a title with yellow color
# PSL Bar graph
ax1.bar(df_psl['day'], df_psl['PSL'], color=psl_color, edgecolor=psl_color, align='edge', width=1.0)
ax1.set_ylabel('PSL', color=psl_color)
ax1.tick_params(axis='y', colors=psl_color)
ax1.tick_params(axis='x', bottom=False, labelbottom=False) # Remove x-axis labels
ax1.spines['bottom'].set_visible(False) # Remove x-axis line at y=0
ax1.grid(False) # Remove grid
for spine in ax1.spines.values(): # Change color of all spines to white
spine.set_edgecolor(axis_color)
# CRP Line graph
ax2.plot(df_crp['day'], df_crp['CRP'], color=crp_color, marker='o', markersize=8, markerfacecolor=crp_color)
ax2.set_ylabel('CRP', color=crp_color)
# WBC Line graph
ax2b = ax2.twinx() # Create a second y-axis
ax2b.plot(df_wbc['day'], df_wbc['WBC'], color=wbc_color, marker='s', markersize=8, markerfacecolor=wbc_color) # Change marker to square
ax2b.set_ylabel('WBC', color=wbc_color)
ax2b.tick_params(axis='y', colors=wbc_color)
ax2.set_xlabel('Day', color=axis_color)
ax2.tick_params(axis='y', colors=crp_color)
ax2.tick_params(axis='x', colors=axis_color) # Change color of x-axis ticks to white
ax2.xaxis.set_ticks(np.arange(min(df_crp['day']), max(df_crp['day'])+1, 1)) # Set x-axis ticks
ax2.grid(False) # Remove grid
ax2b.grid(False) # Remove grid
for spine in ax2.spines.values(): # Change color of all spines to white
spine.set_edgecolor(axis_color)
for spine in ax2b.spines.values(): # Change color of all spines to white
spine.set_edgecolor(axis_color)
plt.tight_layout()
# Save the figure as a SVG file
fig.savefig("/path/to/save/clinical_course_graph_specific_psl.svg", format='svg', transparent=True)
plt.show()
