matplotlib-円グラフの作成メモ
の編集
https://erion1107-pukiwiki.erion1107.net/?matplotlib-%E5%86%86%E3%82%B0%E3%83%A9%E3%83%95%E3%81%AE%E4%BD%9C%E6%88%90%E3%83%A1%E3%83%A2
[
トップ
] [
編集
|
差分
|
バックアップ
|
添付
|
リロード
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
-- 雛形とするページ --
kiji-template
2018年度学習計画メモ
20180217-01-オフラインインストール発表用メモ
Ansible構成例
AWS認定ソリューションアーキテクト・アソシエーション認定テスト対策
bashコーディング規約
BracketName
CentOS7で自宅サーバー作成勉強用リスト
CentOS 7とSamba4で自宅用Active Directory Domain Controller (AD DC)を構築する① インストール編
CloudflareとLet’s EncryptでWebサイトをHTTPS化
COBOLプログラミング入門
conoHaAPIまとめ
Docker-Command一覧
DockerCommandCheatSheet
Docker_Cmd_List
ERION1107-mywiki
erion1107-mywiki
ERION1107自分用のwiki
ESXiインストールについて
FontPage
FormattingRules
FPGAのアーキテクチャとソフトエラー起因の可用性低下
FrontPage
F#EntryForWeb
F#入門
Help
IaC for Ansible with Windows OS
Install_Redmine3.4_with_CentOS7.3
InterWiki
InterWikiName
InterWikiSandBox
Java-Struts2導入について
JavaSwingコンポーネント
Java入門
Java入門2
Linux 標準教科書に出てくるコマンドリスト
matplotlib-円グラフの作成メモ
MBSAについて
MenuBar
Non-BlockingIOを使ってみよう-Java編
PHP
PowerShell入門
PukiWiki
PukiWiki/1.4
PukiWiki/1.4/Manual
PukiWiki/1.4/Manual/Plugin
PukiWiki/1.4/Manual/Plugin/A-D
PukiWiki/1.4/Manual/Plugin/E-G
PukiWiki/1.4/Manual/Plugin/H-K
PukiWiki/1.4/Manual/Plugin/L-N
PukiWiki/1.4/Manual/Plugin/O-R
PukiWiki/1.4/Manual/Plugin/S-U
PukiWiki/1.4/Manual/Plugin/V-Z
pukiwiki記法の書き方入門
python-code-memo
re-view入門
RecentDeleted
SandBox
SoftEther VPN for Linuxについて
SoftEtherVPNについて
Spring解体新書メモ
SQL_Entry
StudyCentOSForWebSiteBuild
Tips作業メモ
UML
UNIXコマンド
Using_Prism.Unity_with_WPF
Vagrant入門
VivlioStyleで行こう!
VPNのススメ
WikiEngines
WikiName
WikiWikiWeb
WindowsPhone開発のためのPrism+ReactiveProperty基本
WindowsとLinuxのオフラインインストールについて調べてみた
WindowsとLinuxのオフラインインストールについて調べてみた 2
wireshark
WSL(Windows Subsystem for Linux)の基本Memo
yaml-sample
YAMLを覚えよう
YukiWiki
ZABBIX
■Redmine On Docker
お仕事用メモ
はじめてのアプリ発注
アプリ開発後に行う動作テストについて
カタン戦術論
デザインパターン23種
プレゼン発表のコツ
レンタルサーバーに独自SSL「Let's Encrypt」導入(Windows10編)
個人アプリ開発のメモ
勉強会発表用メモ
自分用のpukiwiki
記憶術メモ
[[matplotlib-円グラフの作成メモ]] * 目次 [#ac924d71] #contents * 円グラフの作成 [#wb931522] https://github.com/jgm/pandoc/releases/download/3.1.11/pandoc-3.1.11-windows-x86_64.zip # プロキシ情報の設定 $proxyUri = "http://PROXY_SERVER:PORT" $proxyCred = Get-Credential -UserName "USERNAME" -Message "Enter your proxy credentials" # ダウンロード Invoke-WebRequest -Uri "URL" -Proxy $proxyUri -ProxyCredential $proxyCred -OutFile "output_file.zip" ** 目的 [#e23b4c43] 機械学習やビッグデータの解析では,大量にある多次元データを様々な側面から見る必要がある.ここでは,matplotlibを用いた円グラフの作成方法を学ぶ. ** 説明 [#c977589f] *** 円グラフの描画 [#fd9df9c5] まずは簡単な円グラフを描画してみよう. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count]) plt.show() if __name__ == '__main__': main() 6行目から8行目で,280名の学生のある科目のテストの点数からなる配列を作っている.10行目で90点以上の点数をとった学生数を,11行目で80点以上90点未満の点数をとった学生数を求めている.以下同様に,12行目から15行目までで,各範囲の点数をとった学生数を求めている.19行目のように,axオブジェクトのpieメソッドを,円グラフとして表したい数からなるリストを引数として呼び出すと,円グラフを作成することができる. *** 凡例・タイトルの表示 [#oce74bd0] 円グラフに凡例とタイトルを指定するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count]) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 10行目で凡例として表示する文字列からなるリストを作成し,21行目のように,axオブジェクトのlegendメソッドを,作成したリストを引数として呼び出すと,円グラフに凡例をつけることができる.また,タイトルの指定の仕方はこれまでと同様である. *** 開始位置と描画方向の指定 [#i9d54ccb] 上の実行結果からわかるように,この円グラフは3時の位置から開始し,半時計回りに描画されている.これを12時の位置から開始し,時計回りに描画するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], startangle=90, counterclock=False) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数startangleに90度と指定すると,デフォルトの開始位置から半時計回り(デフォルトの描画方向)に90度の位置から描画を開始できる.また,キーワード引数counterclockにFalseを指定すると,時計回りに描画することができる. *** ラベルの指定 [#g22c97dd] 凡例としてではなく,円グラフの周囲にラベルを表示するには,pieメソッドのキーワード引数labelsを使用すればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], labels=labels, startangle=90, counterclock=False) ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() *** 各データの割合をパーセント表示 [#n9514cee] 各データの割合をパーセント表示することができる. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], autopct='%.1f%%', startangle=90, counterclock=False) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数autopctに’%.1f%%’と指定すると,小数点以下1桁までの浮動小数点数として各データの割合をパーセント表示することができる.記述のルールはf文字列のフォーマット指定と同じである. この例では,パーセント表示の一部が重複してしまっている.表示位置を変更するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数pctdistanceに数値を指定することで,パーセント表示の位置を変更できる.0が円の中心を1が円周を表しており,20行目のように1.1と指定することで,円の少し外側に表示位置を変更している. *** 各領域の色の指定 [#ua39c0aa] 円グラフの各領域の色を指定するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] colors = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], colors=colors, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 11行目で各領域の色を表す文字列からなるリストを作成し,21行目のpieメソッドのキーワード引数colorsで色のリストを指定している. *** 各領域の輝度の指定 [#p3f82918] 円グラフをグレースケールとして作成したい場合には,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] brightness = ['0.15', '0.3', '0.45', '0.6', '0.75', '0.9'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], colors=brightness, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 11行目で各領域の輝度を表す文字列からなるリストを作成している.0が最も暗く,1が最も明るい画素を表している.21行目のように,pieメソッドのキーワード引数colorsで輝度のリストを指定することで,グレースケールの円グラフを作成できる. *** 各領域の境界線の指定 [#cc5b21b5] 円グラフの各領域の境界線を表示するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] brightness = ['0.15', '0.3', '0.45', '0.6', '0.75', '0.9'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], wedgeprops={'linewidth': 1, 'edgecolor': 'black'}, colors=brightness, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 21行目のように,pieメソッドのキーワード引数wedgepropsに辞書として境界線の太さと色を指定することができる.辞書のキーlinewidthが線の太さを,キーedgecolorが線の色を表している. ** 参考サイト [#z020ca2b] http://makotomurakami.com/blog/2020/04/03/4614/ ** python-pptx画像書き込み [#j96ce18b] import plotly.graph_objs as go import plotly.io as pio from pptx import Presentation from pptx.util import Inches from io import BytesIO # サンプルのplotlyグラフを作成 fig = go.Figure(data=[go.Scatter(x=[1, 2, 3], y=[4, 1, 2])]) #fig.update_layout(title='グラフのタイトル', legend_font_family='メイリオ') fig.update_layout(title='グラフのタイトル', legend_font_family='MSゴシック') # plotlyグラフを画像に変換 img_bytes = pio.to_image(fig, format='png') # BytesIOを使用して画像データをバッファに保持 img_buffer = BytesIO(img_bytes) # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # 画像をスライドに追加 #left = Inches(1) #top = Inches(2) #width = Inches(5) #height = Inches(4) #pic = slide.shapes.add_picture(img_buffer, left, top, width, height) pic = slide.shapes.add_picture(img_buffer, Inches(1), Inches(2), Inches(7), Inches(5)) # プレゼンテーションを保存 prs.save("example_with_plotly.pptx") # バッファを閉じる img_buffer.close() ** その1 [#f18e555b] import matplotlib.pyplot as plt from pptx import Presentation from pptx.util import Inches from io import BytesIO # サンプルのMatplotlibグラフを作成 plt.plot([1, 2, 3], [4, 1, 2]) plt.xlabel("X軸") plt.ylabel("Y軸") plt.title("Matplotlibグラフ") # グラフを画像に変換 img_buffer = BytesIO() plt.savefig(img_buffer, format='png') img_buffer.seek(0) plt.close() # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # 画像をスライドに追加 left = Inches(1) top = Inches(2) width = Inches(5) height = Inches(4) pic = slide.shapes.add_picture(img_buffer, left, top, width, height) # プレゼンテーションを保存 prs.save("example_with_matplotlib.pptx") # バッファを閉じる img_buffer.close() ** その2 [#df58f18d] import plotly.graph_objs as go from pptx import Presentation from pptx.util import Inches from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT # サンプルのplotly表データを作成 data = [ go.Table( header=dict(values=['列1', '列2']), cells=dict(values=[[1, 2, 3], [4, 5, 6]]) ) ] # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # テーブルをスライドに追加 left = Inches(1) top = Inches(2) width = Inches(5) height = Inches(2) table = slide.shapes.add_table(rows=3, cols=3, left=left, top=top, width=width, height=height) #table.fill.solid() #table.fill.fore_color.rgb = (255, 255, 255) # ヘッダーを追加 for col, header_text in enumerate(data[0]['header']['values']): cell = table.table.cell(0, col) cell.text = header_text cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER # データ行を追加 for row, row_data in enumerate(data[0]['cells']['values']): for col, cell_value in enumerate(row_data): cell = table.table.cell(row + 1, col) cell.text = str(cell_value) cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER # プレゼンテーションを保存 prs.save("example_with_plotly_table.pptx") ** その3 [#n6fbb03b] from pptx import Presentation from pptx.util import Inches from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT from pptx.dml.color import RGBColor # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空白スライド # 表を作成 rows = 3 cols = 3 left = Inches(1) top = Inches(2) width = Inches(6) height = Inches(2) table = slide.shapes.add_table(rows, cols, left, top, width, height).table # セル結合 table.cell(0, 0).merge(table.cell(1, 0)) # セルにテキストを挿入 cell = table.cell(0, 0) cell.text = '値はありませんでした。' # セルのスタイルを設定 cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER cell.text_frame.font.size = Inches(0.2) cell.fill.solid() cell.fill.fore_color.rgb = RGBColor(217, 217, 217) # グレーのセル色 # プレゼンテーションを保存 prs.save('table_example.pptx') ** その4 [#o4d7710e] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空白スライド # 表データを準備 data = [ ['Value 1', 'Value 2', 'Value 3'], ['', '', ''], ['', '', ''], ['Value 4', 'Value 5', 'Value 6'] ] # 表を作成 rows = len(data) cols = len(data[0]) left = Inches(1) top = Inches(2) width = Inches(6) height = Inches(2) table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 表データをセルに挿入 for row in range(rows): for col in range(cols): cell = table.cell(row, col) cell.text = data[row][col] # 空行を見つけてセル結合 for row in range(1, rows): is_empty_row = all(cell.text == '' for cell in table.row_cells(row)) if is_empty_row: for cell in table.row_cells(row): cell._tc.set_attribute('rowSpan', '2') table.cell(row + 1, 0).text = '値はありませんでした。' for col in range(1, cols): table.cell(row + 1, col).text = '' table.cell(row + 1, col)._tc.set_attribute('vMerge', '1') # プレゼンテーションを保存 prs.save('merged_table.pptx') ** その5 [#w62f1da0] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空のスライド # 表を作成 rows = 3 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(2), Inches(8), Inches(4)).table # 表のヘッダーを設定 for i in range(cols): cell = table.cell(0, i) cell.text = f'Header {i+1}' # 新しい行を追加 new_row = table.add_row().cells new_row[0].text = 'New' new_row[1].text = 'Row' new_row[2].text = 'Added' # プレゼンテーションを保存 prs.save('table_example.pptx') ** その6 [#a3d119aa] from pptx import Presentation from pptx.util import Inches def add_row_to_table_if_not_exists(table, row_index): while len(table.rows) <= row_index: table.add_row() # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空のスライド # 表を作成 rows = 3 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(2), Inches(8), Inches(4)).table # 表のヘッダーを設定 for i in range(cols): cell = table.cell(0, i) cell.text = f'Header {i+1}' # 行が存在しない場合に新しい行を追加 target_row_index = 4 # 追加したい行のインデックス add_row_to_table_if_not_exists(table, target_row_index) target_row = table.rows[target_row_index].cells target_row[0].text = 'New' target_row[1].text = 'Row' target_row[2].text = 'Added' # プレゼンテーションを保存 prs.save('table_with_dynamic_row.pptx') ** その7 [#q59a0240] もちろんです。PythonでJSONファイルを読み込み、その情報を使ってPython-pptxでスライドを制御するプログラムの例を以下に示します。 JSONファイル (data.json): json { "slides": [ { "title": "Slide 1", "content": [ "Point 1", "Point 2", "Point 3" ] }, { "title": "Slide 2", "content": [ "Item A", "Item B", "Item C" ] } ] } Pythonプログラム: python import json from pptx import Presentation from pptx.util import Inches # JSONファイルを読み込む with open('data.json', 'r') as json_file: data = json.load(json_file) # 新しいプレゼンテーションを作成 prs = Presentation() # JSONデータからスライドを作成 for slide_data in data['slides']: slide = prs.slides.add_slide(prs.slide_layouts[1]) # タイトルとコンテンツのスライド title = slide.shapes.title title.text = slide_data['title'] left = Inches(1) top = Inches(2) width = Inches(8) height = Inches(4) content_box = slide.shapes.add_textbox(left, top, width, height) content_frame = content_box.text_frame for point in slide_data['content']: p = content_frame.add_paragraph() p.text = point # プレゼンテーションを保存 prs.save('output_presentation.pptx') このコードは、JSONファイルからスライドのタイトルとコンテンツ情報を取得し、Python-pptxを使用してプレゼンテーションを生成する例です。JSONファイルを編集して必要な情報を追加または変更し、スライドの構造や内容をカスタマイズできます。 ** その8 [#j9c97800] from pptx import Presentation from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas def convert_pptx_to_pdf(input_pptx, output_pdf): prs = Presentation(input_pptx) pdf_canvas = canvas.Canvas(output_pdf, pagesize=letter) for slide in prs.slides: pdf_canvas.showPage() pdf_canvas.drawString(100, 100, slide.name) # スライド名を追加できます pdf_canvas.drawImage("slide.png", 0, 0, width=letter[0], height=letter[1]) # スライドを画像として追加します pdf_canvas.save() if __name__ == "__main__": input_pptx = "input.pptx" # 変換したいPowerPointファイルのパス output_pdf = "output.pdf" # 保存するPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その9 [#m52c42a2] from pptx import Presentation from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas def convert_pptx_to_pdf(input_pptx, output_pdf): # PowerPointファイルを開く presentation = Presentation(input_pptx) # PDFファイルを作成 pdf_canvas = canvas.Canvas(output_pdf, pagesize=letter) # 各スライドをPDFに描画 for slide in presentation.slides: pdf_canvas.showPage() pdf_canvas.drawImage(slide.get_image(), 0, 0, width=letter[0], height=letter[1]) # PDFファイルをクローズ pdf_canvas.save() if __name__ == "__main__": input_pptx_file = "input.pptx" # PowerPointファイルのパス output_pdf_file = "output.pdf" # 出力PDFファイルのパス convert_pptx_to_pdf(input_pptx_file, output_pdf_file) ** その10 [#fb3d302b] import plotly.graph_objects as go # サンプルデータ(データは適宜置き換えてください) categories = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"] values = [30, 25, 20, 15, 10, 5, 4, 3, 2, 1, 1] total_values = sum(values) # トップ10のデータとそれ以下のデータに分割 top_10_categories = categories[:10] top_10_values = values[:10] remaining_categories = categories[10:] remaining_values = values[10:] # トップ10のデータに対する円グラフを作成 fig = go.Figure() fig.add_trace( go.Pie( labels=top_10_categories, values=top_10_values, textinfo="label+percent", title="Top 10 Categories", ) ) # トップ10以外のデータの合計値を計算 remaining_value = sum(remaining_values) # トップ10以外のデータの割合を表示しない if remaining_value > 0: fig.add_trace( go.Pie( labels=["Others"], values=[remaining_value], textinfo="none", title="", ) ) # グラフを表示 fig.show() ** その11 [#d8040899] import plotly.express as px # サンプルデータ(データは適宜置き換えてください) data = [ {"Category": "A", "Value": 30}, {"Category": "B", "Value": 25}, {"Category": "C", "Value": 20}, {"Category": "D", "Value": 15}, {"Category": "E", "Value": 10}, {"Category": "F", "Value": 5}, {"Category": "G", "Value": 4}, {"Category": "H", "Value": 3}, {"Category": "I", "Value": 2}, {"Category": "J", "Value": 1}, {"Category": "K", "Value": 1}, # ここにさらにデータを追加 ] # データを降順にソート data.sort(key=lambda x: x["Value"], reverse=True) # トップ10のデータとそれ以下のデータに分割 top_10_data = data[:10] remaining_data = data[10:] # トップ10のデータに対する円グラフを作成 fig = px.pie(top_10_data, values="Value", names="Category", title="Top 10 Categories") # トップ10以外のデータの合計値を計算 remaining_value = sum(item["Value"] for item in remaining_data) # トップ10以外のデータの割合を表示しない if remaining_value > 0: fig.add_trace( px.pie( [{"Category": "Others", "Value": remaining_value}], values="Value", names="Category", title="", ).data[0] ) # グラフを表示 fig.show() ** その12 [#a13a1298] import plotly.graph_objects as go # サンプルデータ(データは適宜置き換えてください) categories = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"] values = [30, 25, 20, 15, 10, 5, 4, 3, 2, 1, 1] # データを降順にソート sorted_data = sorted(zip(categories, values), key=lambda x: x[1], reverse=True) # トップ10のラベルと値を取得 top_10_labels, top_10_values = zip(*sorted_data[:10]) # トップ10のデータに対する円グラフを作成 fig = go.Figure(data=[go.Pie(labels=top_10_labels, values=top_10_values, textinfo="percent+label")]) # グラフを表示 fig.show() ** その13 [#h094c839] from pptx import Presentation from pptx.util import Inches # プレゼンテーションを作成 prs = Presentation("template.pptx") # テンプレートファイルを指定 # プレースホルダー名とJSONデータをマッピング data = [ {"PlaceholderName": "Title", "Text": "Title 1"}, {"PlaceholderName": "Content", "Text": "Content 1"}, # 他のデータ行も追加 ] # ページに収まる行数を計算 lines_per_page = 10 # 例: 1ページに10行 # スライドを追加し、プレースホルダーにデータを挿入 current_slide = None for item in data: if current_slide is None: current_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 新しいスライドを作成 current_slide.shapes[item["PlaceholderName"]].text = item["Text"] if len(current_slide.shapes[item["PlaceholderName"]].text_frame.paragraphs) >= lines_per_page: current_slide = None # ページが変わる場合、新しいスライドを作成 # PowerPointファイルを保存 prs.save("output.pptx") ** その14 [#ua21fd13] from pptx import Presentation # プレゼンテーションを作成 prs = Presentation() # テンプレートファイルを読み込む(.pptxファイル) template = Presentation("your_template.pptx") # スライドマスターの名前を指定 slide_master_name = "Your Slide Master Name" # 指定した名前のスライドマスターを探す selected_slide_master = None for slide_master in template.slide_master: if slide_master.name == slide_master_name: selected_slide_master = slide_master break if selected_slide_master: # 新しいスライドを作成し、指定したスライドマスターを適用 slide = prs.slides.add_slide(selected_slide_master) else: print(f"Slide Master '{slide_master_name}' not found in the template.") # プレゼンテーションを保存 prs.save("output.pptx") ** その15 [#sbd50787] from pptx import Presentation from pptx.util import Pt import json # プレゼンテーションを作成 prs = Presentation() # テンプレートファイルを読み込む(.pptxファイル) template = Presentation("your_template.pptx") # JSONデータを読み込む with open("your_data.json", "r") as json_file: data = json.load(json_file) # 1ページに表示できる最大行数 max_lines_per_page = 10 # スライドマスターを指定 slide_master = template.slide_master[0] # ページ数を計算 total_pages = len(data) // max_lines_per_page + 1 for page_number in range(total_pages): # 新しいスライドを作成し、スライドマスターを適用 slide = prs.slides.add_slide(slide_master) # プレースホルダー1とプレースホルダー2を取得 placeholder1 = slide.placeholders[0] placeholder2 = slide.placeholders[1] # JSONデータから現在のページに挿入するデータを取得 start_index = page_number * max_lines_per_page end_index = start_index + max_lines_per_page page_data = data[start_index:end_index] # プレースホルダー1にデータを挿入 text_frame1 = placeholder1.text_frame for line in page_data: p = text_frame1.add_paragraph() p.text = line["placeholder1_data"] p.space_before = Pt(14) # 適切なスペースを設定 # プレースホルダー2にデータを挿入 text_frame2 = placeholder2.text_frame for line in page_data: p = text_frame2.add_paragraph() p.text = line["placeholder2_data"] p.space_before = Pt(14) # 適切なスペースを設定 # プレゼンテーションを保存 prs.save("output.pptx") ** その16 [#y11c2db7] import plotly.graph_objects as go # サンプルデータを作成 labels = ["Category A", "Category B", "Category C", "Category D", "Category E"] values = [20, 30, 10, 15, 25] # 凡例名が長い場合、途中で切る max_legend_length = 10 # ここで凡例名の最大長を設定します shortened_labels = [label[:max_legend_length] + "..." if len(label) > max_legend_length else label for label in labels] fig = go.Figure(data=[go.Pie(labels=shortened_labels, values=values)]) fig.update_traces(textinfo="percent+label") # グラフを表示 fig.show() sudo mkdir -p /usr/share/fonts/mplus sudo wget https://osdn.net/frs/redir.php?m=jaist&f=%2Fmix-mplus-ipa%2F70053%2Fmplus-TESTFLIGHT-063a.tar.xz -O mplus-fonts.tar.xz sudo tar xvf mplus-fonts.tar.xz -C /usr/share/fonts/mplus from pptx import Presentation from pptx.util import Inches def create_presentation_with_meiryo(): # Create a presentation prs = Presentation() # Add a slide slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5 is a blank slide layout # Add a title and content slide layout title_slide_layout = prs.slide_layouts[0] slide = prs.slides.add_slide(title_slide_layout) title = slide.shapes.title title.text = "Sample Presentation" content_slide_layout = prs.slide_layouts[1] slide = prs.slides.add_slide(content_slide_layout) shapes = slide.shapes body_shape = shapes.placeholders[1] tf = body_shape.text_frame # Add text to the content slide p = tf.add_paragraph() p.text = "Hello, Meiryo!" p.space_after = Inches(0.1) # Save the presentation to a file prs.save('/tmp/meiryo_presentation.pptx') create_presentation_with_meiryo() ** その17 [#m7f52d5a] def estimate_text_box_size( txt, font, # ImageFont max_width: Union[int, None] = None, line_spacing: int = 4 ): """ Example of use: right_margin = left_margin = Length(Cm(0.25)).pt * pt_per_pixel top_margin = bottom_margin = Length(Cm(0.13)).pt * pt_per_pixel width, height = estimate_text_box_size( txt, font, max_width=shape_width - (right_margin + left_margin), ) print("Computed in pixels (w, h)") print((width + right_margin + left_margin, height + top_margin + bottom_margin)) :param txt: :param font: :param max_width: :param line_spacing: :return: """ from PIL import ImageDraw, Image image = Image.new(size=(400, 300), mode='RGB') draw = ImageDraw.Draw(image) emu_per_inch = 914400 px_per_inch = 72.0 pt_per_pixel = 0.75 fontsize_pt = 12 # font = ImageFont.truetype("arial.ttf", int(fontsize_pt / pt_per_pixel)) import textwrap, math if max_width is not None: actual_txt = [] for line in txt.split("\n"): _, _, width, h = font.getbbox(line) split_at = len(line) // math.ceil(width / max_width) actual_txt = actual_txt + textwrap.wrap(line, width=split_at) new_lines = len(actual_txt) actual_txt = "\n".join( actual_txt ) else: actual_txt = txt new_lines = 0 left, top, right, bottom = draw.multiline_textbbox( (0, 0), actual_txt, font=font, spacing=line_spacing ) ascent, descent = font.getmetrics() return right - left, bottom # + descent * new_lines ** その18 [#bce41366] from pptx import Presentation from pptx.util import Inches import polars as pl # 新しいプレゼンテーションを作成 prs = Presentation() # サンプルデータを生成 data = { 'Column 1': list(range(1, 13)), 'Column 2': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'] } # Polarsデータフレームを作成 df = pl.DataFrame(data) # 2列12行のテーブルを作成 table = df.to_pptx() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルをスライドに挿入 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) table.plots[0].set_size(left, top, width, height) slide.shapes.add_picture(io.BytesIO(table.to_image()), left, top, width, height) # プレゼンテーションを保存 prs.save('table_example.pptx') ** その19 [#u55bdf22] from pptx import Presentation from pptx.util import Inches import polars as pl # 新しいプレゼンテーションを作成 prs = Presentation() # サンプルデータを生成 data = { '対象月': ['2023-01', '2023-02', '2023-03', '2023-04'], '件数': [100, 150, 120, 200] } # Polarsデータフレームを作成 df = pl.DataFrame(data) # テーブルを作成 table = df.to_pptx() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルをスライドに挿入 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) table.plots[0].set_size(left, top, width, height) slide.shapes.add_picture(io.BytesIO(table.to_image()), left, top, width, height) # プレゼンテーションを保存 prs.save('table_example.pptx') ** その20 [#n556b94b] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルの行数と列数を指定 rows = 5 cols = 2 # テーブルの位置とサイズを指定 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) # テーブルをスライドに挿入 table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 列の幅を設定 table.columns[0].width = Inches(3) table.columns[1].width = Inches(3) # テーブルにヘッダーを追加 table.cell(0, 0).text = '対象月' table.cell(0, 1).text = '件数' # データを追加 data = [ ['2023-01', '100'], ['2023-02', '150'], ['2023-03', '120'], ['2023-04', '200'], ] for row_index, row_data in enumerate(data): for col_index, cell_data in enumerate(row_data): table.cell(row_index + 1, col_index).text = cell_data # プレゼンテーションを保存 prs.save('table_example.pptx') ** その21 [#a1b41d35] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation('your_presentation.pptx') # 既存のPowerPointファイルを読み込む # スライドのインデックス slide_index = 0 # スライドのインデックス(0から始まる) # コンテンツプレースホルダーのインデックス content_placeholder_index = 0 # コンテンツプレースホルダーのインデックス(0から始まる) # 図のプレースホルダーのインデックス image_placeholder_index = 1 # 図のプレースホルダーのインデックス(0から始まる) # スライドを取得 slide = prs.slides[slide_index] # コンテンツプレースホルダーを取得 content_placeholder = slide.placeholders[content_placeholder_index] # コンテンツプレースホルダーの位置と大きさを取得 left = content_placeholder.left top = content_placeholder.top width = content_placeholder.width height = content_placeholder.height # 図のプレースホルダーに変更 content_placeholder.placeholder_format.idx = image_placeholder_index # 図のプレースホルダーに位置と大きさを設定 image_placeholder = slide.placeholders[image_placeholder_index] image_placeholder.left = left image_placeholder.top = top image_placeholder.width = width image_placeholder.height = height # プレゼンテーションを保存 prs.save('updated_presentation.pptx') ** その22 [#ta285ac6] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドにテーブルを追加する関数 def add_table_to_slide(slide, rows): left = Inches(1) # テーブルの位置を調整 top = Inches(1) width = Inches(8) height = Inches(5) table = slide.shapes.add_table(rows, 2, left, top, width, height).table # テーブルのデザインやセルの内容を設定 for row in range(rows): for col in range(2): cell = table.cell(row, col) cell.text = f'Row {row}, Col {col}' # 仮のデータを作成 data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # データをスライドに追加 for i in range(0, len(data), 10): slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5はタイトルとコンテンツ add_table_to_slide(slide, min(10, len(data) - i)) # プレゼンテーションを保存 prs.save('output.pptx') ** その23 [#c819a594] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加する関数 def add_new_slide(prs): slide_layout = prs.slide_layouts[5] # 5は新しいページのスライドレイアウトに対応します slide = prs.slides.add_slide(slide_layout) return slide # サンプルの長い文字列 long_text = "Your long text goes here. This is just a sample to demonstrate a long string in the table cell." # 新しいスライドを追加し、テキストをセルに追加する関数 def add_text_to_slide(slide, text): table = slide.shapes.add_table(rows=1, cols=1, left=Inches(0.5), top=Inches(1), width=Inches(8), height=Inches(1)).table cell = table.cell(0, 0) cell.text = text # 文字列をチャンクに分割し、指定の文字数でテーブルセルに追加 chunk_size = 50 # テキストを分割するサイズ text_chunks = [long_text[i:i + chunk_size] for i in range(0, len(long_text), chunk_size)] current_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 最初のスライドを追加 for chunk in text_chunks: if len(current_slide.shapes) == 0: add_text_to_slide(current_slide, chunk) else: if len(current_slide.shapes[0].text_frame.text) + len(chunk) > chunk_size: current_slide = add_new_slide(prs) add_text_to_slide(current_slide, chunk) else: current_slide.shapes[0].text_frame.text += chunk # プレゼンテーションを保存 prs.save('output_presentation.pptx') ** その24 [#i052114a] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを作成 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 適切なレイアウトを選択 # 10行のサンプルデータ(仮のデータ) sample_data = [ ['A1', 'B1', 'C1'], ['A2', 'B2', 'C2'], ['A3', 'B3', 'C3'], # ... 他の行データを含める ... ] # テーブルを作成 rows = 4 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table # テーブルにデータを挿入 row_index = 0 for row in sample_data: if row_index >= rows: # テーブルの行数を超えたら新しいスライドにテーブルを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table row_index = 0 for col_index, cell_value in enumerate(row): table.cell(row_index, col_index).text = cell_value row_index += 1 # プレゼンテーションを保存 prs.save('output_presentation.pptx') ** その25 [#zb5d7725] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide_layout = prs.slide_layouts[5] # 5は新しいページのスライドレイアウトに対応します slide = prs.slides.add_slide(slide_layout) # 表を追加する関数 def add_table_to_slide(slide): left = Inches(1) top = Inches(1.5) width = Inches(8) height = Inches(1.5) rows = 5 # 表の行数 cols = 3 # 表の列数 table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 表の見た目を調整(任意) table.columns[0].width = Inches(2) table.columns[1].width = Inches(3) table.columns[2].width = Inches(3) return table # 表にレコードを追加する関数 def add_record_to_table(table, data): row_count = len(table.rows) for row_index, record in enumerate(data): if row_count <= row_index: table.add_row().cells for col_index, value in enumerate(record): table.cell(row_index, col_index).text = value # サンプルのレコードデータ new_records = [ ["Name 4", "Description 4", "Value 4"], ["Name 5", "Description 5", "Value 5"], ["Name 6", "Description 6", "Value 6"] ] # 最初のレコードを表に追加 table = add_table_to_slide(slide) initial_records = [ ["Name 1", "Description 1", "Value 1"], ["Name 2", "Description 2", "Value 2"], ["Name 3", "Description 3", "Value 3"] ] add_record_to_table(table, initial_records) # 後から新しいレコードを表に追加 add_record_to_table(table, new_records) # プレゼンテーションを保存 prs.save('table_presentation.pptx') ** その26 [#vd733bbf] from pptx import Presentation from pptx.util import Pt from pptx.enum.text import MSO_ANCHOR, MSO_UNDERLINE from pptx.dml.color import RGBColor def underline_specific_text(paragraph, target_text): for run in paragraph.runs: if target_text in run.text: # 特定の文字が含まれるRunに下線を引く run.font.underline = True run.font.underline = MSO_UNDERLINE.DASH_LINE def main(): # 新しいプレゼンテーションを作成 presentation = Presentation() # スライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[0]) # テキストボックスを追加 textbox = slide.shapes.add_textbox(left=Pt(100), top=Pt(100), width=Pt(500), height=Pt(200)) text_frame = textbox.text_frame # テキストを追加 p = text_frame.add_paragraph() p.text = "This is an example text. Only 'example' should be underlined." #テキストの一部の色を赤色に変える pg = text_frame.paragraphs[0] run = pg.add_run() run.text = "Anaconda" run.font.color.rgb = RGBColor(255, 0, 0) #テキストの一部を青色に変える run = pg.add_run() run.text = " and Miniconda" run.font.color.rgb = RGBColor(0, 0, 255) run.font.underline = True run.font.underline = MSO_UNDERLINE.DOTTED_LINE run = pg.add_run() run.text = "Anaconda2" run.font.color.rgb = RGBColor(255, 0, 0) # 特定の文字だけに下線を引く # underline_specific_text(p, "example") """ #白紙のスライドを追加 slide_layout_6 = ppt.slide_layouts[6] slide_6 = ppt.slides.add_slide(slide_layout_6) shapes = slide_6.shapes shape = shapes.add_textbox(Cm(1), Cm(1), Cm(5), Cm(5)) text_frame = shape.text_frame #テキストの一部の色を赤色に変える pg = text_frame.paragraphs[0] run = pg.add_run() run.text = "Anaconda" run.font.color.rgb = RGBColor(255, 0, 0) #テキストの一部を青色に変える run = pg.add_run() run.text = " and Miniconda" run.font.color.rgb = RGBColor(0, 0, 255) """ # プレゼンテーションを保存 presentation.save("underlined_text.pptx") if __name__ == "__main__": main() ** その27 [#k5db21e6] def convert_dates(date_list): converted_dates = [] for idx, date_str in enumerate(date_list): # 日付文字列をyyyymmdd形式からdatetimeオブジェクトに変換 date_object = datetime.strptime(date_str, "%Y%m%d") # 初日の場合はyyyymmdd形式で追加、それ以外はdd形式で追加 if idx == 0: converted_dates.append(date_object.strftime("%Y%m%d")) else: converted_dates.append(date_object.strftime("%d")) return converted_dates ** その28 [#s3a18a68] from pptx import Presentation from pptx.util import Inches def prs_to_pixels(prs, emu_value): """ Convert EMUs (English Metric Units) to pixels based on the presentation settings. Parameters: - prs: Presentation object. - emu_value: Value in EMUs. Returns: - pixel_value: Value in pixels. """ emus_per_inch = 914400 inches_per_pixel = 1 / prs.slide_width # Assuming the width of the slide as the reference pixel_value = emu_value / emus_per_inch / inches_per_pixel return round(pixel_value) def get_placeholder_size(prs, slide_master, placeholder_idx): """ Get the width and height of a placeholder on the slide master in pixels. Parameters: - prs: Presentation object. - slide_master: The slide master object. - placeholder_idx: The index of the placeholder on the slide master. Returns: - width_pixels: Width of the placeholder in pixels. - height_pixels: Height of the placeholder in pixels. """ placeholder = slide_master.placeholders[placeholder_idx] width_emu, height_emu = placeholder.width, placeholder.height width_pixels = prs_to_pixels(prs, width_emu) height_pixels = prs_to_pixels(prs, height_emu) return width_pixels, height_pixels # PowerPointプレゼンテーションの読み込み presentation = Presentation('your_presentation.pptx') # スライドマスターの取得 (例: 最初のスライドマスター) slide_master = presentation.slide_master # プレースホルダーのインデックス (例: 0はタイトル、1はサブタイトル) placeholder_idx = 0 # プレースホルダーのwidthとheightをピクセルで取得 width_pixels, height_pixels = get_placeholder_size(presentation, slide_master, placeholder_idx) # 結果の表示 print(f"Width: {width_pixels} pixels") print(f"Height: {height_pixels} pixels") ** その29 [#c229d5bd] import plotly.graph_objects as go # データの作成 labels = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E', 'Category F', 'Category G', 'Category H', 'Category I', 'Category J'] values = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] # 円グラフの作成 fig = go.Figure(data=[go.Pie(labels=labels, values=values)]) # レイアウトの設定 fig.update_layout( title='Pie Chart', legend=dict( orientation='h', # 凡例の方向を水平に設定 x=0.5, # x軸の中央に配置 y=1.15, # y軸の位置を調整 xanchor='center', # x軸のアンカーポイントを中央に設定 yanchor='top', # y軸のアンカーポイントを上端に設定 traceorder='normal', # 凡例の並び順を指定 borderwidth=1, # 凡例の境界線の太さを指定 bordercolor='Black' # 凡例の境界線の色を指定 ) ) # グラフの表示 fig.show() ** その30 [#pb00d386] from pptx import Presentation from pptx.util import Inches def create_table_on_slide(prs, slide, data): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=len(data[0]), left=Inches(1), top=Inches(1), width=Inches(8)).table # 表にデータを挿入 for row_num, row_data in enumerate(data): for col_num, cell_value in enumerate(row_data): table.cell(row_num, col_num).text = str(cell_value) # 表が入りきらない場合は新しいスライドを作成して続きの表を作成 if table.rows[0].height > slide.shapes.height: new_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 新しい空のスライドを作成(indexは適切なものを選択) create_table_on_slide(prs, new_slide, data) # プレゼンテーションの作成 presentation = Presentation() # データ(2次元リスト)の例 table_data = [ ["Header 1", "Header 2", "Header 3"], ["Data 1-1", "Data 1-2", "Data 1-3"], ["Data 2-1", "Data 2-2", "Data 2-3"], # ... 続きのデータ ] # 最初のスライドに表を作成 first_slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # indexは適切なものを選択 create_table_on_slide(presentation, first_slide, table_data) # プレゼンテーションを保存 presentation.save("output.pptx") **その31 [#xe80cdfe] from pptx import Presentation from pptx.util import Inches, Pt def create_table_on_slide(prs, slide, data): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=len(data[0]), left=Inches(1), top=Inches(1), width=Inches(8)).table # 表にデータを挿入 for row_num, row_data in enumerate(data): for col_num, cell_value in enumerate(row_data): table.cell(row_num, col_num).text = str(cell_value) return table def add_rows_to_table(table, num_rows): # 指定された数の行を表に追加 for _ in range(num_rows): table.add_row() # プレゼンテーションの作成 presentation = Presentation() # データ(2次元リスト)の例 table_data = [ ["Header 1", "Header 2", "Header 3"], ["Data 1-1", "Data 1-2", "Data 1-3"], ["Data 2-1", "Data 2-2", "Data 2-3"], # ... 続きのデータ ] # 最初のスライドに表を作成 first_slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # indexは適切なものを選択 table = create_table_on_slide(presentation, first_slide, table_data) # 3行追加した後の座標を取得 add_rows_to_table(table, 3) table_x = table.left table_y = table.top print(f"Table coordinates after adding 3 rows: ({table_x}, {table_y})") # 4行追加した後の座標を取得 add_rows_to_table(table, 4) table_x = table.left table_y = table.top print(f"Table coordinates after adding 4 rows: ({table_x}, {table_y})") # プレゼンテーションを保存 presentation.save("output.pptx") ** その32 [#xa061721] from pptx import Presentation # プレゼンテーションの作成 presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表の追加 table = slide.shapes.add_table(rows=1, cols=3, left=100, top=100, width=Inches(4)).table # 追加した表のインデックス(idx)を取得 tables_on_slide = slide.shapes._spTree table_idx = list(tables_on_slide).index(table._element) print(f"Index of the added table: {table_idx}") # プレゼンテーションを保存 presentation.save("output.pptx") ** その33 [#v2b3fda0] from pptx import Presentation from pptx.util import Inches def add_table_to_slide(slide): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=3, left=Inches(1), top=Inches(1), width=Inches(4)).table # 表のヘッダーを設定 table.cell(0, 0).text = "Header 1" table.cell(0, 1).text = "Header 2" table.cell(0, 2).text = "Header 3" return table def add_record_to_table(table, data): # 新しいレコード(行)を表に追加 table.add_row() # レコードにデータを挿入 for col_num, cell_value in enumerate(data): table.cell(table.rows[-1].index, col_num).text = str(cell_value) # PowerPointファイルを読み込み presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表をスライドに追加 added_table = add_table_to_slide(slide) # レコードを表に追加 record_data = ["Data 1", "Data 2", "Data 3"] add_record_to_table(added_table, record_data) # プレゼンテーションを保存 presentation.save("output.pptx") ** その34 [#e8417f90] from pptx import Presentation from pptx.util import Inches, Pt import json def create_table(slide, data): rows, cols = len(data) + 1, len(data[0]) table = slide.shapes.add_table(rows=rows, cols=cols, left=Inches(1), top=Inches(1), width=Inches(8), height=Inches(4)).table # Set column widths for col, width in enumerate([Inches(2)] * cols): table.columns[col].width = width # Populate header row for col, header in enumerate(data[0]): cell = table.cell(0, col) cell.text = header cell.text_frame.paragraphs[0].font.bold = True # Populate data rows for row, row_data in enumerate(data[1:], start=1): for col, value in enumerate(row_data): cell = table.cell(row, col) cell.text = value cell.text_frame.word_wrap = True def create_slides_from_json(template_path, json_path, output_path): with open(json_path, 'r') as json_file: json_data = json.load(json_file) prs = Presentation(template_path) for data in json_data: slide = prs.slides.add_slide(prs.slide_layouts[0]) # Assuming the first layout is suitable create_table(slide, data) prs.save(output_path) # 使用例 template_file = 'your_template.pptx' json_data_file = 'your_data.json' output_file = 'output.pptx' create_slides_from_json(template_file, json_data_file, output_file) ** その35 [#pf2735df] from pptx import Presentation from pptx.util import Inches, Pt def get_textbox_height(textbox): paragraphs = textbox.text_frame.paragraphs total_height = 0 for paragraph in paragraphs: for run in paragraph.runs: total_height += run.font.size.pt return total_height def main(): # プレゼンテーションファイルのパスを指定 presentation_path = 'your_presentation.pptx' # プレゼンテーションを読み込む presentation = Presentation(presentation_path) # 例として1つ目のスライドの1つ目のテキストボックスを取得 first_slide = presentation.slides[0] first_textbox = first_slide.shapes[0] # テキストボックスの高さを取得 textbox_height = get_textbox_height(first_textbox) print(f'Textbox Height: {textbox_height} pt') if __name__ == "__main__": main() ** その36 [#lfdf7146] from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.enum.text import MSO_ANCHOR, PP_ALIGN def create_table_with_condition(slide, data): rows, cols = 3, 4 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table # データのセットアップ for row in range(rows): for col in range(cols): cell = table.cell(row, col) cell.text = data[row][col] cell.text_frame.text = data[row][col] cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 最終行が条件に合致する場合、セルを結合して指定のテキストを置き換える if data[-1] == ['合計', '-', '0', '-']: last_row_cell = table.cell(rows-1, 0) last_row_cell.merge(table.cell(rows-1, cols-1)) last_row_cell.text_frame.clear() last_row_cell.text_frame.text = '対象データはありませんでした' last_row_cell.text_frame.paragraphs[0].font.size = Pt(14) last_row_cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 最終行のセル以外の文字をクリア # for col in range(cols-1): # table.cell(rows-1, col).text_frame.clear() # プレゼンテーションの作成 presentation = Presentation() slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # Blank Slide # 3行4列の表データ data = [ ['A1', 'B1', 'C1', 'D1'], ['A2', 'B2', 'C2', 'D2'], ['合計', '-', '0', '-'] ] # 条件に合わせて表を作成 create_table_with_condition(slide, data) # プレゼンテーションの保存 presentation.save('output-023-03.pptx') ** その37 [#d0de4fd6] import polars as pl def detect_rows_with_only_specified_value(df, specified_value): # 指定した文字列以外が存在するかどうかを判定する条件式を構築 condition = ~df.drop(["index"]).apply(lambda series: series.nunique() > 1, in_place=True) # 検知された条件に合致する行のインデックスを取得 detected_indexes = df.filter(condition)["index"].to_list() return detected_indexes # データの作成 data = { 'A': ['apple', 'orange', 'apple'], 'B': ['banana', 'banana', 'banana'], 'C': ['cherry', 'cherry', 'cherry'], 'D': ['date', 'date', 'date'] } df = pl.DataFrame(data) # 検知する文字列を指定 specified_value = 'date' # プログラムを実行して指定した文字列が行内にしか存在しない行を検知 detected_indexes = detect_rows_with_only_specified_value(df, specified_value) # 検知された行のインデックスを表示 print(f"Rows with only '{specified_value}': {detected_indexes}") ** その38 [#s65f52cc] import json from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.dml.color import RGBColor def create_table(slide, title, data): title_shape = slide.shapes.title title_shape.text = title # 表の位置とサイズ left = Inches(1) top = title_shape.top + title_shape.height + Inches(0.5) width = Inches(8) height = Inches(4) # 表を作成 table = slide.shapes.add_table(rows=len(data) + 1, cols=len(data[0]), left=left, top=top, width=width, height=height).table # 表のスタイル設定 table.style = "Table Grid" # タイトル行のフォント設定 title_row = table.rows[0] for cell in title_row.cells: cell.text_frame.text = cell.text_frame.text.title() cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].font.bold = True cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) # データ行のフォント設定と折り返し for i, row in enumerate(data): data_row = table.rows[i + 1] for j, value in enumerate(row): cell = data_row.cells[j] cell.text_frame.text = str(value) cell.text_frame.paragraphs[0].font.size = Pt(12) cell.text_frame.word_wrap = True def create_presentation(json_file): # PowerPointファイルを生成 presentation = Presentation() # JSONファイルからデータを読み込む with open(json_file, 'r') as f: json_data = json.load(f) for i, data in enumerate(json_data): # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # タイトルとデータから表を作成 create_table(slide, f"Table {i + 1}", data) # PowerPointファイルを保存 presentation.save("output.pptx") # JSONファイルから表を作成してPowerPointファイルに保存 create_presentation("table_data.json") ** その39 [#kcd687dd] import json from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.dml.color import RGBColor def create_table(slide, title, headers): title_shape = slide.shapes.title title_shape.text = title # 表の位置とサイズ left = Inches(1) top = title_shape.top + title_shape.height + Inches(0.5) width = Inches(8) height = Inches(4) # 表を作成 table = slide.shapes.add_table(rows=2, cols=len(headers), left=left, top=top, width=width, height=height).table # 表のスタイル設定 table.style = "Table Grid" # タイトル行のフォント設定 title_row = table.rows[0] for j, header in enumerate(headers): cell = title_row.cells[j] cell.text_frame.text = header cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].font.bold = True cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) def add_row_to_table(table, data): # 表に新しい行を追加 row_cells = table.add_row().cells # データ行のフォント設定と折り返し for j, value in enumerate(data): cell = row_cells[j] cell.text_frame.text = str(value) cell.text_frame.paragraphs[0].font.size = Pt(12) cell.text_frame.word_wrap = True def create_presentation(json_file): # PowerPointファイルを生成 presentation = Presentation() # JSONファイルからデータを読み込む with open(json_file, 'r') as f: json_data = json.load(f) for i, data in enumerate(json_data): # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # タイトル行とデータ行1行だけの表を作成 create_table(slide, f"Table {i + 1}", data.keys()) # JSONデータのレコードを読み込んで表に行を追加 add_row_to_table(slide.shapes[0].table, data.values()) # PowerPointファイルを保存 presentation.save("output.pptx") # JSONファイルから表を作成してPowerPointファイルに保存 create_presentation("table_data.json") ** その40 [#m1c0c6ea] [ {"Name": "Alice", "Age": 25}, {"Name": "Bob", "Age": 30}, {"Name": "Charlie", "Age": 22}, {"Name": "David", "Age": 35}, {"Name": "Eva", "Age": 28}, {"Name": "Frank", "Age": 31}, {"Name": "Grace", "Age": 24}, {"Name": "Hank", "Age": 29}, {"Name": "Ivy", "Age": 33}, {"Name": "Jack", "Age": 26}, {"Name": "Kate", "Age": 32}, {"Name": "Leo", "Age": 27}, {"Name": "Mia", "Age": 30}, {"Name": "Nate", "Age": 23}, {"Name": "Olivia", "Age": 34}, {"Name": "Paul", "Age": 31}, {"Name": "Quinn", "Age": 25}, {"Name": "Ryan", "Age": 28}, {"Name": "Sara", "Age": 29}, {"Name": "Tom", "Age": 36} ] ** その41 [#y4f61d3e] from copy import deepcopy from pptx import slide from pptx.table import Table, _Row, _Column, _Cell def add_row(slide: slide, top_point: int, left_point: int, table: Table) -> Table: new_row = deepcopy(table._tbl.tr_lst[-1]) # duplicating last row of the table as a new row to be added cell_margin_top = 0 cell_margin_bottom = 0 for tc in new_row.tc_lst: cell = _Cell(tc, new_row.tc_lst) cell.text = '' # defaulting cell contents to empty text cell_margin_top = cell.text_frame.margin_top cell_margin_bottom = cell.text_frame.margin_bottom table._tbl.append(new_row) # for shape in slide.shapes: if shape.top == top_point and shape.left == left_point: print('追加したレコード分、表の高さを更新します') #shape.height = shape.height + cell_margin_top + cell_margin_bottom # return table.rows[-1] return table def remove_row(table: Table, row_to_delete: _Row) -> None: table._tbl.remove(row_to_delete._tr) ** その42 [#zed425e9] import collections.abc from pptx import Presentation from pptx.util import Inches import table_add # # レコード追加した後に追加したレコード分の高さ情報を更新する # cell_height = cell.text_frame.margin_top + cell.text_frame.margin_bottom # table def check_table_size(slide): left_point = 100 top_point = 200 for shape in slide.shapes: print(shape.name) if shape.top == top_point and shape.left == left_point: print('追加したオブジェクトの位置: ' + str(shape.shape_id)) print('座標: ' + str(shape.top) + ':' + str(shape.left) + ':' + str(shape.height) + ':' + str(shape.width)) def add_table_to_slide(slide): left_point = 100 top_point = 200 # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=3, left=left_point, top=top_point, width=Inches(4), height=Inches(1)).table # 表のヘッダーを設定 table.cell(0, 0).text = "Header 1" table.cell(0, 1).text = "Header 2" table.cell(0, 2).text = "Header 3" return table def add_record_to_table(slide, top_point, left_point, table, data, cnt): # 新しいレコード(行)を表に追加 table = table_add.add_row(slide, top_point, left_point, table) # レコードにデータを挿入 for col_num, cell_value in enumerate(data): table.cell(cnt, col_num).text = str(cell_value) # PowerPointファイルを読み込み presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表をスライドに追加 added_table = add_table_to_slide(slide) left_point = 100 # レコードを追加したタイミングでオブジェクトの高さを更新する top_point = 200 # レコードを表に追加 record_data = ["Data 1", "Data 2", "Data 3"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 1) check_table_size(slide) record_data = ["Data 4", "Data 5", "Data 6"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 2) check_table_size(slide) record_data = ["Data 7", "Data 8", "Data 9"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 3) check_table_size(slide) # プレゼンテーションを保存 presentation.save("output.pptx") ** その43 [#n0f60db5] from pptx import Presentation from pptx.util import Inches def get_table_height(table): # Tableが属するshapeオブジェクトの高さを取得 height = table._element.get_or_add_txBody().bodyPr.get('anchor').split(',')[3] return int(height) # PowerPointファイルを生成 presentation = Presentation() # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 表を追加 table = slide.shapes.add_table(rows=3, cols=3, left=Inches(1), top=Inches(1), width=Inches(4), height=Inches(2)).table # 表の高さを取得 table_height = get_table_height(table) # 結果の表示 print(f"Table Height: {table_height} pt") # PowerPointファイルを保存 presentation.save("output.pptx") ** その44 [#w986b0db] import uno from com.sun.star.beans import PropertyValue def set_custom_formatting(sheet): # 2つ目のスライドを取得 slide = sheet.getSlides().getByIndex(1) # インデックスは0から始まるので、2つ目のスライドはインデックス1 # 2番目のスライドのプレースホルダー番号2を取得 placeholder = slide.getShapes().getByIndex(1) # インデックスは0から始まるので、2つ目のプレースホルダーはインデックス1 # タブ文字に1点鎖線を設定 placeholder.getPropertyValue("LineDash") # 1点鎖線の定義 placeholder.setPropertyValue("LineDash", (100,)) # 1点鎖線に設定 # 右側のルーラーに12を設定 sheet.setPropertyValue("RightMargin", 12) def convert_pptx_to_pdf(input_path, output_path): local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local_context) context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context) # ファイルを開く doc = desktop.loadComponentFromURL(f"file://{input_path}", "_blank", 0, ()) # 特定のシートに対してカスタムフォーマットを適用 set_custom_formatting(doc.getSheets().getByIndex(0)) # PDFに変換 pdf_export_props = ( PropertyValue("FilterName", 0, "writer_pdf_Export", 0), PropertyValue("Overwrite", 0, True, 0) ) output_url = f"file://{output_path}" doc.storeToURL(output_url, pdf_export_props) # ドキュメントを閉じる doc.close(True) if __name__ == "__main__": input_pptx_path = "/path/to/your_presentation.pptx" output_pdf_path = "/path/to/output.pdf" convert_pptx_to_pdf(input_pptx_path, output_pdf_path) ** その45 [#pccb485f] import os def convert_pptx_to_pdf(input_pptx, output_pdf): os.system(f'PowerShell -Command "& {{ Start-Process powerpnt -ArgumentList \\"{os.path.abspath(input_pptx)}\\", /pt \\"{os.path.abspath(output_pdf)}\\" -Wait }}"') # 使用例 input_pptx = 'C:\\path\\to\\your\\presentation.pptx' # 入力のPowerPointファイルのパス output_pdf = 'C:\\path\\to\\your\\output.pdf' # 出力のPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その46 [#t634e87f] import os def convert_pptx_to_pdf(input_pptx, output_pdf): os.system(f'PowerShell -Command "& {{ Start-Process powerpnt -ArgumentList \\"{os.path.abspath(input_pptx)}\\", /pt \\"Microsoft Print to PDF\\", \\"{os.path.abspath(output_pdf)}\\" -Wait }}"') # 使用例 input_pptx = 'C:\\path\\to\\your\\presentation.pptx' # 入力のPowerPointファイルのパス output_pdf = 'C:\\path\\to\\your\\output.pdf' # 出力のPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その47 [#uf222b5d] # PowerPointのCOMオブジェクトを作成 $powerPoint = New-Object -ComObject PowerPoint.Application # 変換元のフォルダと変換先のフォルダを指定 $inputFolder = "C:\Path\To\Input\Folder" $outputFolder = "C:\Path\To\Output\Folder" # 変換元フォルダ内の.pptxファイルを検索 $pptxFiles = Get-ChildItem -Path $inputFolder -Filter *.pptx foreach ($pptxFile in $pptxFiles) { # PowerPointファイルを開く $presentation = $powerPoint.Presentations.Open($pptxFile.FullName) # PDFに変換して保存 $pdfFileName = [System.IO.Path]::ChangeExtension($pptxFile.Name, "pdf") $pdfFilePath = Join-Path -Path $outputFolder -ChildPath $pdfFileName $presentation.ExportAsFixedFormat($pdfFilePath, 32) # 32はPDF形式 # PowerPointを閉じる $presentation.Close() } # PowerPointのCOMオブジェクトを解放 $powerPoint.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($powerPoint) | Out-Null ** その48 [#d1c17e9a] import logging import logging.config import yaml def setup_logging(config_file='logging_config.yaml'): with open(config_file, 'rt') as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) def main(): # ログ設定を読み込む setup_logging() # ロガーを取得 logger = logging.getLogger(__name__) # ログメッセージの出力 logger.debug("This is a debug message") logger.info("This is an info message") logger.warning("This is a warning message") logger.error("This is an error message") logger.critical("This is a critical message") if __name__ == "__main__": main() ** その49 [#g83dc600] logging_config.yaml version: 1 formatters: simple: format: "%(asctime)s - %(levelname)s - %(message)s" handlers: console: class: logging.StreamHandler level: INFO formatter: simple file: class: logging.FileHandler filename: example.log level: DEBUG formatter: simple loggers: my_logger: level: DEBUG handlers: [console, file] propagate: no root: level: INFO handlers: [console] ** その50 [#qb4493f3] # ログ設定のバージョン version: 1 # フォーマッターの定義 formatters: simple: format: "%(asctime)s - %(levelname)s - %(message)s" # ハンドラーの定義 handlers: # コンソールにログを出力するハンドラー console: class: logging.StreamHandler level: INFO formatter: simple # ファイルにログを出力するハンドラー file: class: logging.FileHandler filename: example.log level: DEBUG formatter: simple # ロガーの定義 loggers: # 特定のロガー (ここでは my_logger) の設定 my_logger: level: DEBUG handlers: [console, file] propagate: no # ルートロガー (すべてのロガーに適用される設定) root: level: INFO # ルートロガーのログレベル handlers: [console] # ルートロガーに適用されるハンドラー ** その51 [#h13cbc4e] AWS EC2でwindowsサーバー+Office環境を構築したい。非機能要件書いて。性能要件や費用も月年単位で分かるように。 ChatGPT 以下に、AWS EC2上でWindowsサーバーおよびOffice環境を構築する際の非機能要件、性能要件、および費用に関する要件を示します。これらは一般的な要件であり、具体的なプロジェクトやニーズに応じて調整する必要があります。 非機能要件: セキュリティ: インスタンスへのアクセスはセキュアな方法で行い、最小限の必要なポートのみを公開する。 WindowsサーバーおよびOffice製品のライセンスは正規のものを使用し、セキュリティパッチやアップデートは適切に適用する。 可用性と信頼性: EC2インスタンスはマルチアベイラビリティーゾーン(Multi-AZ)に展開し、冗長性を確保する。 バックアップおよびリカバリ戦略を確立し、データの保護と復旧を行う。 パフォーマンス: インスタンスタイプは、適切なCPU、メモリ、およびストレージリソースを持つものを選定する。 ディスクI/Oおよびネットワークスループットの要件に対応するため、適切なEBSボリュームおよびネットワークの帯域幅を確保する。 拡張性: 将来的な需要に備えて、必要に応じてリソースを拡張できるアーキテクチャを確立する。 性能要件: CPUおよびメモリ: インスタンスは、Officeアプリケーションおよび関連サービスの要件に応じたCPUおよびメモリを搭載する。 ディスクI/O: ディスクI/OはOffice製品の正常な動作に必要な速度を確保する。 ネットワーク帯域幅: インターネット接続およびVPC内の通信において、必要なネットワーク帯域幅を確保する。 費用要件: EC2インスタンスの料金: EC2インスタンスの選定において、性能要件および予算に合致するインスタンスタイプを選択する。 ストレージ料金: 使用するEBSボリュームのサイズおよび性能に応じたストレージ料金を考慮する。 ネットワーク料金: インターネット接続およびデータ転送に伴うネットワーク料金を評価し、予算に合わせて適切な設定を行う。 Windowsライセンス料金: Windows ServerおよびOffice製品の正規のライセンスを購入し、ライセンスに関連する料金を考慮する。 これらの要件に基づいて、AWSのコスト計算ツールや料金ページを活用して、月や年単位での予算を立てることが重要です。また、適切な予備費用(リザーブドインスタンスなど)を検討することも良いプラクティスです。 ** その52 [#v6fb7411] import concurrent.futures def your_function(arg): # ここに並列化したい処理を記述 # この関数は複数のスレッドで同時に実行されます result = arg * 2 return result def main(): # 並列処理のためのスレッド数を指定 num_threads = 4 # ThreadPoolExecutorを作成 with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: # 並列処理したいデータをリストで準備 data_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # mapメソッドを使用して並列処理を実行 results = list(executor.map(your_function, data_list)) # 結果の表示 print(results) if __name__ == "__main__": main() ** その54 [#d7b6c619] import boto3 from concurrent.futures import ThreadPoolExecutor, as_completed def process_message(message): # ここにメッセージを処理する具体的なロジックを記述 print(f"Processing message: {message['Body']}") def receive_messages(queue_url, max_messages=10, num_threads=2): # AWSの認証情報やリージョンを設定 aws_access_key = 'YOUR_ACCESS_KEY' aws_secret_key = 'YOUR_SECRET_KEY' aws_region = 'YOUR_REGION' # SQSクライアントの作成 sqs = boto3.client('sqs', region_name=aws_region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) # メッセージをまとめて取得 response = sqs.receive_message( QueueUrl=queue_url, MaxNumberOfMessages=max_messages, AttributeNames=[ 'All' ], MessageAttributeNames=[ 'All' ], VisibilityTimeout=0, WaitTimeSeconds=0 ) # メッセージが取得できたかどうかを確認 messages = response.get('Messages', []) if messages: with ThreadPoolExecutor(max_workers=num_threads) as executor: # submitメソッドを使用して各メッセージを非同期に処理 futures = [executor.submit(process_message, message) for message in messages] # すべてのFutureが完了するまで待機 for future in as_completed(futures): try: future.result() except Exception as e: print(f"Error processing message: {e}") # 取得したメッセージを削除 for message in messages: sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=message['ReceiptHandle']) else: print("No messages available in the queue.") # SQSのURLを指定してメッセージを取得(最大10件、スレッド数2) queue_url = 'YOUR_SQS_QUEUE_URL' receive_messages(queue_url, max_messages=10, num_threads=2) ** その55 [#qca2d650] import boto3 from botocore.exceptions import NoCredentialsError # AWSの認証情報 aws_access_key = 'YOUR_ACCESS_KEY' aws_secret_key = 'YOUR_SECRET_KEY' aws_region = 'YOUR_REGION' aws_sqs_queue_url = 'YOUR_SQS_QUEUE_URL' aws_s3_bucket = 'YOUR_S3_BUCKET' aws_s3_key = 'YOUR_S3_KEY' # MFAの情報 mfa_device_arn = 'YOUR_MFA_DEVICE_ARN' mfa_code = 'YOUR_MFA_CODE' # プロキシの設定 proxy_host = 'YOUR_PROXY_HOST' proxy_port = 'YOUR_PROXY_PORT' proxies = { 'http': f'http://{proxy_host}:{proxy_port}', 'https': f'http://{proxy_host}:{proxy_port}', } def get_temporary_credentials(): # STSクライアントの作成 sts = boto3.client('sts', region_name=aws_region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) # MFAの情報を含めて一時的な認証情報を取得 response = sts.get_session_token( DurationSeconds=3600, # 任意の有効期間 SerialNumber=mfa_device_arn, TokenCode=mfa_code ) return response['Credentials'] try: # MFAを含めた一時的な認証情報を取得 temporary_credentials = get_temporary_credentials() # SQSクライアントの作成 sqs = boto3.client('sqs', region_name=aws_region, aws_access_key_id=temporary_credentials['AccessKeyId'], aws_secret_access_key=temporary_credentials['SecretAccessKey'], aws_session_token=temporary_credentials['SessionToken'], proxies=proxies) # SQSからメッセージを取得 response = sqs.receive_message( QueueUrl=aws_sqs_queue_url, MaxNumberOfMessages=10, AttributeNames=['All'], MessageAttributeNames=['All'], VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) if messages: for message in messages: print(f"Received message from SQS: {message['Body']}") # SQSのメッセージを削除 receipt_handle = message['ReceiptHandle'] sqs.delete_message(QueueUrl=aws_sqs_queue_url, ReceiptHandle=receipt_handle) # S3クライアントの作成 s3 = boto3.client('s3', region_name=aws_region, aws_access_key_id=temporary_credentials['AccessKeyId'], aws_secret_access_key=temporary_credentials['SecretAccessKey'], aws_session_token=temporary_credentials['SessionToken'], proxies=proxies) # S3からファイルをダウンロード s3.download_file(aws_s3_bucket, aws_s3_key, 'downloaded_file.txt') print("File downloaded from S3.") else: print("No messages available in the SQS queue.") except NoCredentialsError: print("Credentials not available") except Exception as e: print(f"An error occurred: {e}") ** その56 [#i1921020] import boto3 from botocore.exceptions import NoCredentialsError # AWSの認証情報 aws_access_key_id = 'YOUR_ACCESS_KEY_ID' aws_secret_access_key = 'YOUR_SECRET_ACCESS_KEY' aws_session_token = 'YOUR_SESSION_TOKEN' # MFA認証が必要な場合 # プロキシ設定 (必要に応じて) proxies = { 'http': 'http://proxy.example.com:8888', 'https': 'http://proxy.example.com:8888', } # MFAデバイス情報 mfa_serial = 'arn:aws:iam::ACCOUNT_ID:mfa/USERNAME' mfa_token_code = '123456' # 実際のMFAデバイスから取得したコード # S3とSQSクライアントの作成 s3_client = boto3.client('s3', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, proxies=proxies) sqs_client = boto3.client('sqs', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, proxies=proxies) # MFAデバイスのトークンを取得 mfa_token = boto3.client('sts', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key).get_session_token( SerialNumber=mfa_serial, TokenCode=mfa_token_code )['Credentials']['SessionToken'] # SQSからメッセージを取得 queue_url = 'YOUR_SQS_QUEUE_URL' try: response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MaxNumberOfMessages=1, MessageAttributeNames=['All'], VisibilityTimeout=0, WaitTimeSeconds=0 ) # メッセージがある場合、処理を行う if 'Messages' in response: message = response['Messages'][0] print(f"Received message: {message['Body']}") # ここでメッセージの処理を行う # メッセージを削除する receipt_handle = message['ReceiptHandle'] sqs_client.delete_message( QueueUrl=queue_url, ReceiptHandle=receipt_handle ) else: print("No messages in the queue") except NoCredentialsError: print('Credentials not available') except Exception as e: print(f"Error: {str(e)}") ** その57 [#c66441f1] import boto3 from botocore.exceptions import NoCredentialsError def get_mfa_session_token(profile_name, mfa_device_arn, mfa_code): sts_client = boto3.client('sts') response = sts_client.get_session_token( DurationSeconds=3600, SerialNumber=mfa_device_arn, TokenCode=mfa_code ) session_credentials = response['Credentials'] session = boto3.Session( aws_access_key_id=session_credentials['AccessKeyId'], aws_secret_access_key=session_credentials['SecretAccessKey'], aws_session_token=session_credentials['SessionToken'] ) return session def receive_messages_with_mfa(queue_url, mfa_session): sqs_client = mfa_session.client('sqs') try: response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MessageAttributeNames=['All'], MaxNumberOfMessages=10, VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) for message in messages: print(f"Received message: {message['Body']}") except NoCredentialsError: print("Credentials not available") if __name__ == "__main__": # AWSのプロファイル名 aws_profile = 'your_profile' # MFAデバイスARN mfa_device_arn = 'arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device' # MFAコード mfa_code = input("Enter MFA code: ") # SQSキューのURL sqs_queue_url = 'https://sqs.your-region.amazonaws.com/your-account-id/your-queue-name' # MFAセッションを取得 mfa_session = get_mfa_session_token(aws_profile, mfa_device_arn, mfa_code) # SQSからメッセージを受信 receive_messages_with_mfa(sqs_queue_url, mfa_session) ** その58 [#ufea8ede] import boto3 from botocore.exceptions import NoCredentialsError def get_mfa_session_token(profile_name, mfa_device_arn, mfa_code): sts_client = boto3.client('sts') response = sts_client.get_session_token( DurationSeconds=3600, SerialNumber=mfa_device_arn, TokenCode=mfa_code ) session_credentials = response['Credentials'] session = boto3.Session( aws_access_key_id=session_credentials['AccessKeyId'], aws_secret_access_key=session_credentials['SecretAccessKey'], aws_session_token=session_credentials['SessionToken'] ) return session def receive_messages_with_mfa(queue_url, mfa_session): sqs_client = mfa_session.client('sqs') s3_client = mfa_session.client('s3') try: # SQSからメッセージを受信 response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MessageAttributeNames=['All'], MaxNumberOfMessages=10, VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) # メッセージがある場合、S3にファイルを格納 for message in messages: s3_client.put_object( Bucket='your-s3-bucket', Key=f'my-folder/{message["MessageId"]}.txt', Body=message['Body'] ) print(f"Stored message in S3: {message['MessageId']}") except NoCredentialsError: print("Credentials not available") except Exception as e: print(f"Error: {e}") if __name__ == "__main__": # AWSのプロファイル名 aws_profile = 'your_profile' # MFAデバイスARN mfa_device_arn = 'arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device' # MFAコード mfa_code = input("Enter MFA code: ") # SQSキューのURL sqs_queue_url = 'https://sqs.your-region.amazonaws.com/your-account-id/your-queue-name' # MFAセッションを取得 mfa_session = get_mfa_session_token(aws_profile, mfa_device_arn, mfa_code) # SQSからメッセージを受信してS3に格納 receive_messages_with_mfa(sqs_queue_url, mfa_session) ** その59 [#d95c4336] import subprocess import platform def run_command(command): process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output, error = process.communicate() return output.decode('utf-8'), error.decode('utf-8'), process.returncode def get_mfa_code(): return input("Enter MFA code: ") def run_script(): mfa_enabled = True # ローカル開発時はTrue、本番環境ではFalseと仮定 if mfa_enabled: mfa_code = get_mfa_code() command = f"aws sts get-session-token --serial-number arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device --token-code {mfa_code}" output, error, return_code = run_command(command) if return_code == 0: # MFA認証が成功した場合、セッショントークン情報を抽出 session_token_info = output.splitlines() aws_access_key_id = session_token_info[2].split(":")[1].strip() aws_secret_access_key = session_token_info[3].split(":")[1].strip() aws_session_token = session_token_info[4].split(":")[1].strip() # 本番環境で使う設定 # ここで本番環境用のAWSクレデンシャル情報を設定する else: print(f"MFA authentication failed: {error}") return else: # 本番環境で使う設定 # ここで本番環境用のAWSクレデンシャル情報を設定する # 本番環境またはMFA認証成功後に行う処理 # ここにAWS SDK for Python (Boto3) を使用して実際の処理を記述する if __name__ == "__main__": run_script() ** その60 [#m300645e] def update_mfa_section(credentials_file, new_access_key_id, new_secret_access_key): with open(credentials_file, 'r') as file: lines = file.readlines() in_mfa_section = False for i, line in enumerate(lines): if line.strip() == '[mfa]': in_mfa_section = True continue # [mfa] セクションは更新せずに次の行に移動 if in_mfa_section and line.startswith('['): break # [mfa] セクションの終わりに到達したらループを終了 if in_mfa_section: if line.startswith("aws_access_key_id"): lines[i] = f"aws_access_key_id = {new_access_key_id}\n" elif line.startswith("aws_secret_access_key"): lines[i] = f"aws_secret_access_key = {new_secret_access_key}\n" with open(credentials_file, 'w') as file: file.writelines(lines) if __name__ == "__main__": credentials_file = "path/to/your/aws/credentials/file" # AWS credentialsファイルのパス new_access_key_id = "your-new-access-key-id" # 新しいアクセスキーID new_secret_access_key = "your-new-secret-access-key" # 新しいシークレットアクセスキー update_mfa_section(credentials_file, new_access_key_id, new_secret_access_key) ** その61 [#l88d683e] def get_changed_values(credentials_file): changed_values = {} with open(credentials_file, 'r') as file: lines = file.readlines() for line in lines: # 更新された行かどうかを確認 if line.startswith("aws_access_key_id"): parts = line.split("=") key = parts[0].strip() value = parts[1].strip() changed_values[key] = value elif line.startswith("aws_secret_access_key"): parts = line.split("=") key = parts[0].strip() value = parts[1].strip() changed_values[key] = value return changed_values if __name__ == "__main__": credentials_file = "path/to/your/aws/credentials/file" # 更新されたAWS credentialsファイルのパス updated_values = get_changed_values(credentials_file) print("Updated values:") print(updated_values) ** その62 [#p8cc680a] import logging from logging.handlers import TimedRotatingFileHandler import os import datetime # ログフォーマットを設定 log_format = '%(asctime)s - %(levelname)s - %(message)s' # ロガーを設定 logger = logging.getLogger() logger.setLevel(logging.DEBUG) # ファイルの日付フォーマットを設定 date_format = '%Y-%m-%d' today_date = datetime.datetime.now().strftime(date_format) # ファイルハンドラを作成 log_file = 'example.log' backup_file = f'example_{today_date}.log' file_handler = TimedRotatingFileHandler(log_file, when='M', interval=1, backupCount=0, encoding='utf-8', atTime=datetime.time(0, 0, 0)) file_handler.suffix = f'_{today_date}' file_handler.setLevel(logging.DEBUG) # ログフォーマットを設定 formatter = logging.Formatter(log_format) file_handler.setFormatter(formatter) # ロガーにハンドラを追加 logger.addHandler(file_handler) # ログメッセージの出力 logger.debug('This is a debug message') logger.info('This is an info message') logger.warning('This is a warning message') logger.error('This is an error message') logger.critical('This is a critical message') # 古いバックアップファイルを削除 try: os.remove(backup_file) except FileNotFoundError: pass ** その63 [#v4e056d8] import logging from logging.handlers import TimedRotatingFileHandler import datetime def setup_logger(log_path): # ロギングの設定 logger = logging.getLogger() logger.setLevel(logging.INFO) # ローテーション設定 handler = TimedRotatingFileHandler(log_path, when="midnight", interval=1, backupCount=12) handler.suffix = "%Y-%m-%d.log" # ファイル名の接尾辞を設定する formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) def main(): log_path = "path/to/your/log/directory/logfile.log" # ログファイルのパスを指定してください setup_logger(log_path) # ログ出力例 logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") if __name__ == "__main__": main() ** その64 [#cd14ddc0] def some_function(): logger = get_logger() logger.info("This is an info message from some_function") def another_function(): logger = get_logger() logger.error("This is an error message from another_function") if __name__ == "__main__": some_function() another_function() import logging import threading class SingletonLogger: _instance = None _lock = threading.Lock() def __new__(cls): if not cls._instance: with cls._lock: if not cls._instance: cls._instance = super(SingletonLogger, cls).__new__(cls) cls._instance._initialize() return cls._instance def _initialize(self): self.logger = logging.getLogger("SingletonLogger") self.logger.setLevel(logging.DEBUG) # Create console handler with a higher log level ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # Create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) # Add the handlers to the logger self.logger.addHandler(ch) def get_logger(self): return self.logger # グローバル関数からシングルトンロガーを取得する関数 def get_logger(): return SingletonLogger().get_logger() ** その65 [#gff1ebff] AWSTemplateFormatVersion: '2010-09-09' Resources: MyLogGroup: Type: 'AWS::Logs::LogGroup' Properties: LogGroupName: !Sub '/aws/workspace/${AWS::StackName}-application-log' RetentionInDays: 7 CloudWatchAgent: Type: 'AWS::SSM::Document' Properties: DocumentType: 'Command' Content: schemaVersion: '2.2' description: 'Install and configure the CloudWatch Agent' mainSteps: - action: 'aws:runPowerShellScript' name: 'configureCloudWatchAgent' inputs: runCommand: - | $config = @" { "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "C:\\path\\to\\application.log", "log_group_name": "/aws/workspace/${AWS::StackName}-application-log", "log_stream_name": "{instance_id}" } ] } } } } "@ $config | Out-File -FilePath "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.json" -Force Start-Service AmazonCloudWatchAgent Write-Host "CloudWatch Agent configured" WorkspaceInstance: Type: 'AWS::WorkSpaces::Workspace' Properties: BundleId: 'wsb-xxxxxx' # 置き換え必要 DirectoryId: 'd-xxxxxx' # 置き換え必要 UserName: 'your-username' # 置き換え必要 RootVolumeEncryptionEnabled: false UserVolumeEncryptionEnabled: false VolumeEncryptionKey: '' WorkspaceProperties: ComputeTypeName: 'STANDARD' RootVolumeSizeGib: 80 UserVolumeSizeGib: 10 RunningMode: 'AUTO_STOP' RunningModeAutoStopTimeoutInMinutes: 60 DependsOn: CloudWatchAgent CloudWatchErrorMetricFilter: Type: 'AWS::Logs::MetricFilter' Properties: LogGroupName: !Ref MyLogGroup FilterPattern: 'ERROR' MetricTransformations: - MetricValue: '1' MetricNamespace: 'MyApp' MetricName: 'ErrorCount' CloudWatchErrorAlarm: Type: 'AWS::CloudWatch::Alarm' Properties: AlarmDescription: 'Alarm if there are any ERROR messages in the application log' Namespace: 'MyApp' MetricName: 'ErrorCount' Statistic: 'Sum' Period: 300 EvaluationPeriods: 1 Threshold: 1 ComparisonOperator: 'GreaterThanOrEqualToThreshold' AlarmActions: - !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:your-sns-topic' # 置き換え必要 ** その66 [#f039360e] 以下に、CloudFormationテンプレートを使用してIAMロールを作成し、そのロールを使用してWorkspacesで生成されたログファイルをCloudWatchに送信する方法を示します。 CloudFormationテンプレート このテンプレートは、必要なIAMロールとポリシーを作成し、CloudWatch Logsエージェントの設定ファイルを出力するためのものです。 AWSTemplateFormatVersion: '2010-09-09' Resources: CloudWatchLogsIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Principal: Service: - 'ec2.amazonaws.com' - 'workspaces.amazonaws.com' Action: - 'sts:AssumeRole' Policies: - PolicyName: 'CloudWatchLogsPolicy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: - 'arn:aws:logs:*:*:*' CloudWatchLogsAgentConfig: Type: 'AWS::SSM::Document' Properties: DocumentType: 'Command' Content: schemaVersion: '2.2' description: 'CloudWatch Logs Agent configuration document' parameters: log_group_name: type: 'String' description: '(Required) CloudWatch Log Group name' log_stream_name: type: 'String' description: '(Required) CloudWatch Log Stream name' log_file_path: type: 'String' description: '(Required) Log file path' mainSteps: - action: 'aws:configureCloudWatchLogs' name: 'configureCloudWatchLogs' inputs: logGroupName: '{{ log_group_name }}' logStreamName: '{{ log_stream_name }}' file: '{{ log_file_path }}' state: 'Enabled' 手順 CloudFormationテンプレートをデプロイ: 上記のテンプレートを cloudformation-template.yaml という名前で保存し、AWS CloudFormationスタックとしてデプロイします。 AWS CLIを使用してスタックを作成する場合: aws cloudformation create-stack --stack-name CloudWatchLogsSetup --template-body file://cloudformation-template.yaml --capabilities CAPABILITY_IAM CloudWatch Logsエージェントの設定: Workspaces上でログファイルをCloudWatch Logsに送信するために、CloudWatch Logsエージェントを設定します。 エージェントの設定ファイルは、上記のテンプレートの一部として SSM Document として作成されます。SSMドキュメントを使用してエージェントを設定します。 以下のようにAWS CLIでSSMドキュメントを実行できます: aws ssm send-command \ --document-name "CloudWatchLogsAgentConfig" \ --targets "Key=instanceIds,Values=your-instance-id" \ --parameters log_group_name="your-log-group",log_stream_name="your-log-stream",log_file_path="C:\path\to\log\file.log" CloudWatch Logsエージェントの設定 インストール: CloudWatch Logsエージェントをインストールします。Windowsの場合、以下のPowerShellコマンドを実行します: powershell -Command "Install-Module -Name AWS.Tools.CloudWatchLogs -Force -AllowClobber" 設定ファイル: 設定ファイルを作成します。以下の例では、Windowsのログファイルパスを指定します。 [general] state_file = C:\ProgramData\Amazon\CloudWatchLogs\state [logstreamname] log_group_name = your-log-group log_stream_name = your-log-stream file = C:\path\to\log\file.log エージェントの開始: エージェントを開始します。Windowsの場合、以下のPowerShellコマンドを実行します: powershell -Command "Start-Service -Name AmazonCloudWatchAgent" この手順に従うことで、Workspaces上のログファイルをCloudWatchに送信するための設定を行うことができます。 ** その67 [#w7a09e31] AWSTemplateFormatVersion: '2010-09-09' Resources: CloudWatchAgentUser: Type: 'AWS::IAM::User' Properties: UserName: 'CloudWatchAgentUser' Policies: - PolicyName: 'CloudWatchAgentAdminPolicy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Action: - 'cloudwatch:PutMetricData' - 'cloudwatch:PutDashboard' - 'cloudwatch:GetDashboard' - 'cloudwatch:GetMetricData' - 'cloudwatch:ListMetrics' - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' ** その68 [#e2488c1d] import plotly.graph_objects as go # データ months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # 各グループのデータセット(データの数は任意) groups = { 'Group A': [20, 14, 23, 17, 12, 30, 10, 28, 21, 19, 25, 15], 'Group B': [12, 18, 29, 14, 22, 19, 9, 16, 18, 21, 17, 20], 'Group C': [9, 12, 15, 20, 14, 13, 22, 15, 13, 16, 11, 17], 'Group D': [5, 8, 9, 11, 8, 7, 9, 11, 10, 9, 8, 10], 'Group E': [10, 15, 8, 12, 14, 11, 12, 9, 11, 8, 9, 10] } # カラーパターンを指定 colors = ['blue', 'orange', 'green', 'red', 'purple'] # グラフ作成 fig = go.Figure() # グループデータを動的に追加する for idx, (group_name, values) in enumerate(groups.items()): fig.add_trace(go.Bar( x=months, y=values, name=group_name, marker_color=colors[idx % len(colors)] # カラーを循環させる )) # グラフレイアウトの設定 fig.update_layout( barmode='stack', # 棒を積み上げるモード title='Monthly Stacked Bar Chart', xaxis_title='Month', yaxis_title='Values', xaxis_tickangle=-45 # X軸のラベルを傾ける ) # グラフを表示 fig.show()
タイムスタンプを変更しない
[[matplotlib-円グラフの作成メモ]] * 目次 [#ac924d71] #contents * 円グラフの作成 [#wb931522] https://github.com/jgm/pandoc/releases/download/3.1.11/pandoc-3.1.11-windows-x86_64.zip # プロキシ情報の設定 $proxyUri = "http://PROXY_SERVER:PORT" $proxyCred = Get-Credential -UserName "USERNAME" -Message "Enter your proxy credentials" # ダウンロード Invoke-WebRequest -Uri "URL" -Proxy $proxyUri -ProxyCredential $proxyCred -OutFile "output_file.zip" ** 目的 [#e23b4c43] 機械学習やビッグデータの解析では,大量にある多次元データを様々な側面から見る必要がある.ここでは,matplotlibを用いた円グラフの作成方法を学ぶ. ** 説明 [#c977589f] *** 円グラフの描画 [#fd9df9c5] まずは簡単な円グラフを描画してみよう. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count]) plt.show() if __name__ == '__main__': main() 6行目から8行目で,280名の学生のある科目のテストの点数からなる配列を作っている.10行目で90点以上の点数をとった学生数を,11行目で80点以上90点未満の点数をとった学生数を求めている.以下同様に,12行目から15行目までで,各範囲の点数をとった学生数を求めている.19行目のように,axオブジェクトのpieメソッドを,円グラフとして表したい数からなるリストを引数として呼び出すと,円グラフを作成することができる. *** 凡例・タイトルの表示 [#oce74bd0] 円グラフに凡例とタイトルを指定するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count]) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 10行目で凡例として表示する文字列からなるリストを作成し,21行目のように,axオブジェクトのlegendメソッドを,作成したリストを引数として呼び出すと,円グラフに凡例をつけることができる.また,タイトルの指定の仕方はこれまでと同様である. *** 開始位置と描画方向の指定 [#i9d54ccb] 上の実行結果からわかるように,この円グラフは3時の位置から開始し,半時計回りに描画されている.これを12時の位置から開始し,時計回りに描画するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], startangle=90, counterclock=False) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数startangleに90度と指定すると,デフォルトの開始位置から半時計回り(デフォルトの描画方向)に90度の位置から描画を開始できる.また,キーワード引数counterclockにFalseを指定すると,時計回りに描画することができる. *** ラベルの指定 [#g22c97dd] 凡例としてではなく,円グラフの周囲にラベルを表示するには,pieメソッドのキーワード引数labelsを使用すればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], labels=labels, startangle=90, counterclock=False) ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() *** 各データの割合をパーセント表示 [#n9514cee] 各データの割合をパーセント表示することができる. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], autopct='%.1f%%', startangle=90, counterclock=False) ax.legend(labels, loc='best') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数autopctに’%.1f%%’と指定すると,小数点以下1桁までの浮動小数点数として各データの割合をパーセント表示することができる.記述のルールはf文字列のフォーマット指定と同じである. この例では,パーセント表示の一部が重複してしまっている.表示位置を変更するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 20行目のように,pieメソッドのキーワード引数pctdistanceに数値を指定することで,パーセント表示の位置を変更できる.0が円の中心を1が円周を表しており,20行目のように1.1と指定することで,円の少し外側に表示位置を変更している. *** 各領域の色の指定 [#ua39c0aa] 円グラフの各領域の色を指定するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] colors = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], colors=colors, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 11行目で各領域の色を表す文字列からなるリストを作成し,21行目のpieメソッドのキーワード引数colorsで色のリストを指定している. *** 各領域の輝度の指定 [#p3f82918] 円グラフをグレースケールとして作成したい場合には,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] brightness = ['0.15', '0.3', '0.45', '0.6', '0.75', '0.9'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], colors=brightness, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 11行目で各領域の輝度を表す文字列からなるリストを作成している.0が最も暗く,1が最も明るい画素を表している.21行目のように,pieメソッドのキーワード引数colorsで輝度のリストを指定することで,グレースケールの円グラフを作成できる. *** 各領域の境界線の指定 [#cc5b21b5] 円グラフの各領域の境界線を表示するには,以下のようにすればよい. from numpy.random import default_rng import matplotlib.pyplot as plt def main(): rg = default_rng(seed=0) students_count = 280 scores = rg.normal(65.9, 10.8, students_count) labels = ['S', 'A', 'B', 'C', 'D', 'E'] brightness = ['0.15', '0.3', '0.45', '0.6', '0.75', '0.9'] s_count = (90 <= scores).sum() a_count = ((80 <= scores) & (scores < 90)).sum() b_count = ((70 <= scores) & (scores < 80)).sum() c_count = ((60 <= scores) & (scores < 70)).sum() d_count = ((50 <= scores) & (scores < 60)).sum() e_count = (scores < 50).sum() fig = plt.figure(figsize=plt.figaspect(1.0)) ax = fig.add_subplot() ax.pie([s_count, a_count, b_count, c_count, d_count, e_count], wedgeprops={'linewidth': 1, 'edgecolor': 'black'}, colors=brightness, autopct='%1.1f%%', pctdistance=1.1, startangle=90, counterclock=False) ax.legend(labels, loc='lower right') ax.set_title('Fig.1: Student grades.') plt.show() if __name__ == '__main__': main() 21行目のように,pieメソッドのキーワード引数wedgepropsに辞書として境界線の太さと色を指定することができる.辞書のキーlinewidthが線の太さを,キーedgecolorが線の色を表している. ** 参考サイト [#z020ca2b] http://makotomurakami.com/blog/2020/04/03/4614/ ** python-pptx画像書き込み [#j96ce18b] import plotly.graph_objs as go import plotly.io as pio from pptx import Presentation from pptx.util import Inches from io import BytesIO # サンプルのplotlyグラフを作成 fig = go.Figure(data=[go.Scatter(x=[1, 2, 3], y=[4, 1, 2])]) #fig.update_layout(title='グラフのタイトル', legend_font_family='メイリオ') fig.update_layout(title='グラフのタイトル', legend_font_family='MSゴシック') # plotlyグラフを画像に変換 img_bytes = pio.to_image(fig, format='png') # BytesIOを使用して画像データをバッファに保持 img_buffer = BytesIO(img_bytes) # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # 画像をスライドに追加 #left = Inches(1) #top = Inches(2) #width = Inches(5) #height = Inches(4) #pic = slide.shapes.add_picture(img_buffer, left, top, width, height) pic = slide.shapes.add_picture(img_buffer, Inches(1), Inches(2), Inches(7), Inches(5)) # プレゼンテーションを保存 prs.save("example_with_plotly.pptx") # バッファを閉じる img_buffer.close() ** その1 [#f18e555b] import matplotlib.pyplot as plt from pptx import Presentation from pptx.util import Inches from io import BytesIO # サンプルのMatplotlibグラフを作成 plt.plot([1, 2, 3], [4, 1, 2]) plt.xlabel("X軸") plt.ylabel("Y軸") plt.title("Matplotlibグラフ") # グラフを画像に変換 img_buffer = BytesIO() plt.savefig(img_buffer, format='png') img_buffer.seek(0) plt.close() # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # 画像をスライドに追加 left = Inches(1) top = Inches(2) width = Inches(5) height = Inches(4) pic = slide.shapes.add_picture(img_buffer, left, top, width, height) # プレゼンテーションを保存 prs.save("example_with_matplotlib.pptx") # バッファを閉じる img_buffer.close() ** その2 [#df58f18d] import plotly.graph_objs as go from pptx import Presentation from pptx.util import Inches from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT # サンプルのplotly表データを作成 data = [ go.Table( header=dict(values=['列1', '列2']), cells=dict(values=[[1, 2, 3], [4, 5, 6]]) ) ] # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5は白紙のスライドレイアウト # テーブルをスライドに追加 left = Inches(1) top = Inches(2) width = Inches(5) height = Inches(2) table = slide.shapes.add_table(rows=3, cols=3, left=left, top=top, width=width, height=height) #table.fill.solid() #table.fill.fore_color.rgb = (255, 255, 255) # ヘッダーを追加 for col, header_text in enumerate(data[0]['header']['values']): cell = table.table.cell(0, col) cell.text = header_text cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER # データ行を追加 for row, row_data in enumerate(data[0]['cells']['values']): for col, cell_value in enumerate(row_data): cell = table.table.cell(row + 1, col) cell.text = str(cell_value) cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER # プレゼンテーションを保存 prs.save("example_with_plotly_table.pptx") ** その3 [#n6fbb03b] from pptx import Presentation from pptx.util import Inches from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT from pptx.dml.color import RGBColor # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空白スライド # 表を作成 rows = 3 cols = 3 left = Inches(1) top = Inches(2) width = Inches(6) height = Inches(2) table = slide.shapes.add_table(rows, cols, left, top, width, height).table # セル結合 table.cell(0, 0).merge(table.cell(1, 0)) # セルにテキストを挿入 cell = table.cell(0, 0) cell.text = '値はありませんでした。' # セルのスタイルを設定 cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER cell.text_frame.font.size = Inches(0.2) cell.fill.solid() cell.fill.fore_color.rgb = RGBColor(217, 217, 217) # グレーのセル色 # プレゼンテーションを保存 prs.save('table_example.pptx') ** その4 [#o4d7710e] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空白スライド # 表データを準備 data = [ ['Value 1', 'Value 2', 'Value 3'], ['', '', ''], ['', '', ''], ['Value 4', 'Value 5', 'Value 6'] ] # 表を作成 rows = len(data) cols = len(data[0]) left = Inches(1) top = Inches(2) width = Inches(6) height = Inches(2) table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 表データをセルに挿入 for row in range(rows): for col in range(cols): cell = table.cell(row, col) cell.text = data[row][col] # 空行を見つけてセル結合 for row in range(1, rows): is_empty_row = all(cell.text == '' for cell in table.row_cells(row)) if is_empty_row: for cell in table.row_cells(row): cell._tc.set_attribute('rowSpan', '2') table.cell(row + 1, 0).text = '値はありませんでした。' for col in range(1, cols): table.cell(row + 1, col).text = '' table.cell(row + 1, col)._tc.set_attribute('vMerge', '1') # プレゼンテーションを保存 prs.save('merged_table.pptx') ** その5 [#w62f1da0] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空のスライド # 表を作成 rows = 3 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(2), Inches(8), Inches(4)).table # 表のヘッダーを設定 for i in range(cols): cell = table.cell(0, i) cell.text = f'Header {i+1}' # 新しい行を追加 new_row = table.add_row().cells new_row[0].text = 'New' new_row[1].text = 'Row' new_row[2].text = 'Added' # プレゼンテーションを保存 prs.save('table_example.pptx') ** その6 [#a3d119aa] from pptx import Presentation from pptx.util import Inches def add_row_to_table_if_not_exists(table, row_index): while len(table.rows) <= row_index: table.add_row() # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 空のスライド # 表を作成 rows = 3 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(2), Inches(8), Inches(4)).table # 表のヘッダーを設定 for i in range(cols): cell = table.cell(0, i) cell.text = f'Header {i+1}' # 行が存在しない場合に新しい行を追加 target_row_index = 4 # 追加したい行のインデックス add_row_to_table_if_not_exists(table, target_row_index) target_row = table.rows[target_row_index].cells target_row[0].text = 'New' target_row[1].text = 'Row' target_row[2].text = 'Added' # プレゼンテーションを保存 prs.save('table_with_dynamic_row.pptx') ** その7 [#q59a0240] もちろんです。PythonでJSONファイルを読み込み、その情報を使ってPython-pptxでスライドを制御するプログラムの例を以下に示します。 JSONファイル (data.json): json { "slides": [ { "title": "Slide 1", "content": [ "Point 1", "Point 2", "Point 3" ] }, { "title": "Slide 2", "content": [ "Item A", "Item B", "Item C" ] } ] } Pythonプログラム: python import json from pptx import Presentation from pptx.util import Inches # JSONファイルを読み込む with open('data.json', 'r') as json_file: data = json.load(json_file) # 新しいプレゼンテーションを作成 prs = Presentation() # JSONデータからスライドを作成 for slide_data in data['slides']: slide = prs.slides.add_slide(prs.slide_layouts[1]) # タイトルとコンテンツのスライド title = slide.shapes.title title.text = slide_data['title'] left = Inches(1) top = Inches(2) width = Inches(8) height = Inches(4) content_box = slide.shapes.add_textbox(left, top, width, height) content_frame = content_box.text_frame for point in slide_data['content']: p = content_frame.add_paragraph() p.text = point # プレゼンテーションを保存 prs.save('output_presentation.pptx') このコードは、JSONファイルからスライドのタイトルとコンテンツ情報を取得し、Python-pptxを使用してプレゼンテーションを生成する例です。JSONファイルを編集して必要な情報を追加または変更し、スライドの構造や内容をカスタマイズできます。 ** その8 [#j9c97800] from pptx import Presentation from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas def convert_pptx_to_pdf(input_pptx, output_pdf): prs = Presentation(input_pptx) pdf_canvas = canvas.Canvas(output_pdf, pagesize=letter) for slide in prs.slides: pdf_canvas.showPage() pdf_canvas.drawString(100, 100, slide.name) # スライド名を追加できます pdf_canvas.drawImage("slide.png", 0, 0, width=letter[0], height=letter[1]) # スライドを画像として追加します pdf_canvas.save() if __name__ == "__main__": input_pptx = "input.pptx" # 変換したいPowerPointファイルのパス output_pdf = "output.pdf" # 保存するPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その9 [#m52c42a2] from pptx import Presentation from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas def convert_pptx_to_pdf(input_pptx, output_pdf): # PowerPointファイルを開く presentation = Presentation(input_pptx) # PDFファイルを作成 pdf_canvas = canvas.Canvas(output_pdf, pagesize=letter) # 各スライドをPDFに描画 for slide in presentation.slides: pdf_canvas.showPage() pdf_canvas.drawImage(slide.get_image(), 0, 0, width=letter[0], height=letter[1]) # PDFファイルをクローズ pdf_canvas.save() if __name__ == "__main__": input_pptx_file = "input.pptx" # PowerPointファイルのパス output_pdf_file = "output.pdf" # 出力PDFファイルのパス convert_pptx_to_pdf(input_pptx_file, output_pdf_file) ** その10 [#fb3d302b] import plotly.graph_objects as go # サンプルデータ(データは適宜置き換えてください) categories = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"] values = [30, 25, 20, 15, 10, 5, 4, 3, 2, 1, 1] total_values = sum(values) # トップ10のデータとそれ以下のデータに分割 top_10_categories = categories[:10] top_10_values = values[:10] remaining_categories = categories[10:] remaining_values = values[10:] # トップ10のデータに対する円グラフを作成 fig = go.Figure() fig.add_trace( go.Pie( labels=top_10_categories, values=top_10_values, textinfo="label+percent", title="Top 10 Categories", ) ) # トップ10以外のデータの合計値を計算 remaining_value = sum(remaining_values) # トップ10以外のデータの割合を表示しない if remaining_value > 0: fig.add_trace( go.Pie( labels=["Others"], values=[remaining_value], textinfo="none", title="", ) ) # グラフを表示 fig.show() ** その11 [#d8040899] import plotly.express as px # サンプルデータ(データは適宜置き換えてください) data = [ {"Category": "A", "Value": 30}, {"Category": "B", "Value": 25}, {"Category": "C", "Value": 20}, {"Category": "D", "Value": 15}, {"Category": "E", "Value": 10}, {"Category": "F", "Value": 5}, {"Category": "G", "Value": 4}, {"Category": "H", "Value": 3}, {"Category": "I", "Value": 2}, {"Category": "J", "Value": 1}, {"Category": "K", "Value": 1}, # ここにさらにデータを追加 ] # データを降順にソート data.sort(key=lambda x: x["Value"], reverse=True) # トップ10のデータとそれ以下のデータに分割 top_10_data = data[:10] remaining_data = data[10:] # トップ10のデータに対する円グラフを作成 fig = px.pie(top_10_data, values="Value", names="Category", title="Top 10 Categories") # トップ10以外のデータの合計値を計算 remaining_value = sum(item["Value"] for item in remaining_data) # トップ10以外のデータの割合を表示しない if remaining_value > 0: fig.add_trace( px.pie( [{"Category": "Others", "Value": remaining_value}], values="Value", names="Category", title="", ).data[0] ) # グラフを表示 fig.show() ** その12 [#a13a1298] import plotly.graph_objects as go # サンプルデータ(データは適宜置き換えてください) categories = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"] values = [30, 25, 20, 15, 10, 5, 4, 3, 2, 1, 1] # データを降順にソート sorted_data = sorted(zip(categories, values), key=lambda x: x[1], reverse=True) # トップ10のラベルと値を取得 top_10_labels, top_10_values = zip(*sorted_data[:10]) # トップ10のデータに対する円グラフを作成 fig = go.Figure(data=[go.Pie(labels=top_10_labels, values=top_10_values, textinfo="percent+label")]) # グラフを表示 fig.show() ** その13 [#h094c839] from pptx import Presentation from pptx.util import Inches # プレゼンテーションを作成 prs = Presentation("template.pptx") # テンプレートファイルを指定 # プレースホルダー名とJSONデータをマッピング data = [ {"PlaceholderName": "Title", "Text": "Title 1"}, {"PlaceholderName": "Content", "Text": "Content 1"}, # 他のデータ行も追加 ] # ページに収まる行数を計算 lines_per_page = 10 # 例: 1ページに10行 # スライドを追加し、プレースホルダーにデータを挿入 current_slide = None for item in data: if current_slide is None: current_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 新しいスライドを作成 current_slide.shapes[item["PlaceholderName"]].text = item["Text"] if len(current_slide.shapes[item["PlaceholderName"]].text_frame.paragraphs) >= lines_per_page: current_slide = None # ページが変わる場合、新しいスライドを作成 # PowerPointファイルを保存 prs.save("output.pptx") ** その14 [#ua21fd13] from pptx import Presentation # プレゼンテーションを作成 prs = Presentation() # テンプレートファイルを読み込む(.pptxファイル) template = Presentation("your_template.pptx") # スライドマスターの名前を指定 slide_master_name = "Your Slide Master Name" # 指定した名前のスライドマスターを探す selected_slide_master = None for slide_master in template.slide_master: if slide_master.name == slide_master_name: selected_slide_master = slide_master break if selected_slide_master: # 新しいスライドを作成し、指定したスライドマスターを適用 slide = prs.slides.add_slide(selected_slide_master) else: print(f"Slide Master '{slide_master_name}' not found in the template.") # プレゼンテーションを保存 prs.save("output.pptx") ** その15 [#sbd50787] from pptx import Presentation from pptx.util import Pt import json # プレゼンテーションを作成 prs = Presentation() # テンプレートファイルを読み込む(.pptxファイル) template = Presentation("your_template.pptx") # JSONデータを読み込む with open("your_data.json", "r") as json_file: data = json.load(json_file) # 1ページに表示できる最大行数 max_lines_per_page = 10 # スライドマスターを指定 slide_master = template.slide_master[0] # ページ数を計算 total_pages = len(data) // max_lines_per_page + 1 for page_number in range(total_pages): # 新しいスライドを作成し、スライドマスターを適用 slide = prs.slides.add_slide(slide_master) # プレースホルダー1とプレースホルダー2を取得 placeholder1 = slide.placeholders[0] placeholder2 = slide.placeholders[1] # JSONデータから現在のページに挿入するデータを取得 start_index = page_number * max_lines_per_page end_index = start_index + max_lines_per_page page_data = data[start_index:end_index] # プレースホルダー1にデータを挿入 text_frame1 = placeholder1.text_frame for line in page_data: p = text_frame1.add_paragraph() p.text = line["placeholder1_data"] p.space_before = Pt(14) # 適切なスペースを設定 # プレースホルダー2にデータを挿入 text_frame2 = placeholder2.text_frame for line in page_data: p = text_frame2.add_paragraph() p.text = line["placeholder2_data"] p.space_before = Pt(14) # 適切なスペースを設定 # プレゼンテーションを保存 prs.save("output.pptx") ** その16 [#y11c2db7] import plotly.graph_objects as go # サンプルデータを作成 labels = ["Category A", "Category B", "Category C", "Category D", "Category E"] values = [20, 30, 10, 15, 25] # 凡例名が長い場合、途中で切る max_legend_length = 10 # ここで凡例名の最大長を設定します shortened_labels = [label[:max_legend_length] + "..." if len(label) > max_legend_length else label for label in labels] fig = go.Figure(data=[go.Pie(labels=shortened_labels, values=values)]) fig.update_traces(textinfo="percent+label") # グラフを表示 fig.show() sudo mkdir -p /usr/share/fonts/mplus sudo wget https://osdn.net/frs/redir.php?m=jaist&f=%2Fmix-mplus-ipa%2F70053%2Fmplus-TESTFLIGHT-063a.tar.xz -O mplus-fonts.tar.xz sudo tar xvf mplus-fonts.tar.xz -C /usr/share/fonts/mplus from pptx import Presentation from pptx.util import Inches def create_presentation_with_meiryo(): # Create a presentation prs = Presentation() # Add a slide slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5 is a blank slide layout # Add a title and content slide layout title_slide_layout = prs.slide_layouts[0] slide = prs.slides.add_slide(title_slide_layout) title = slide.shapes.title title.text = "Sample Presentation" content_slide_layout = prs.slide_layouts[1] slide = prs.slides.add_slide(content_slide_layout) shapes = slide.shapes body_shape = shapes.placeholders[1] tf = body_shape.text_frame # Add text to the content slide p = tf.add_paragraph() p.text = "Hello, Meiryo!" p.space_after = Inches(0.1) # Save the presentation to a file prs.save('/tmp/meiryo_presentation.pptx') create_presentation_with_meiryo() ** その17 [#m7f52d5a] def estimate_text_box_size( txt, font, # ImageFont max_width: Union[int, None] = None, line_spacing: int = 4 ): """ Example of use: right_margin = left_margin = Length(Cm(0.25)).pt * pt_per_pixel top_margin = bottom_margin = Length(Cm(0.13)).pt * pt_per_pixel width, height = estimate_text_box_size( txt, font, max_width=shape_width - (right_margin + left_margin), ) print("Computed in pixels (w, h)") print((width + right_margin + left_margin, height + top_margin + bottom_margin)) :param txt: :param font: :param max_width: :param line_spacing: :return: """ from PIL import ImageDraw, Image image = Image.new(size=(400, 300), mode='RGB') draw = ImageDraw.Draw(image) emu_per_inch = 914400 px_per_inch = 72.0 pt_per_pixel = 0.75 fontsize_pt = 12 # font = ImageFont.truetype("arial.ttf", int(fontsize_pt / pt_per_pixel)) import textwrap, math if max_width is not None: actual_txt = [] for line in txt.split("\n"): _, _, width, h = font.getbbox(line) split_at = len(line) // math.ceil(width / max_width) actual_txt = actual_txt + textwrap.wrap(line, width=split_at) new_lines = len(actual_txt) actual_txt = "\n".join( actual_txt ) else: actual_txt = txt new_lines = 0 left, top, right, bottom = draw.multiline_textbbox( (0, 0), actual_txt, font=font, spacing=line_spacing ) ascent, descent = font.getmetrics() return right - left, bottom # + descent * new_lines ** その18 [#bce41366] from pptx import Presentation from pptx.util import Inches import polars as pl # 新しいプレゼンテーションを作成 prs = Presentation() # サンプルデータを生成 data = { 'Column 1': list(range(1, 13)), 'Column 2': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'] } # Polarsデータフレームを作成 df = pl.DataFrame(data) # 2列12行のテーブルを作成 table = df.to_pptx() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルをスライドに挿入 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) table.plots[0].set_size(left, top, width, height) slide.shapes.add_picture(io.BytesIO(table.to_image()), left, top, width, height) # プレゼンテーションを保存 prs.save('table_example.pptx') ** その19 [#u55bdf22] from pptx import Presentation from pptx.util import Inches import polars as pl # 新しいプレゼンテーションを作成 prs = Presentation() # サンプルデータを生成 data = { '対象月': ['2023-01', '2023-02', '2023-03', '2023-04'], '件数': [100, 150, 120, 200] } # Polarsデータフレームを作成 df = pl.DataFrame(data) # テーブルを作成 table = df.to_pptx() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルをスライドに挿入 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) table.plots[0].set_size(left, top, width, height) slide.shapes.add_picture(io.BytesIO(table.to_image()), left, top, width, height) # プレゼンテーションを保存 prs.save('table_example.pptx') ** その20 [#n556b94b] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドを追加 slide_layout = prs.slide_layouts[5] # ブランクスライド slide = prs.slides.add_slide(slide_layout) # テーブルの行数と列数を指定 rows = 5 cols = 2 # テーブルの位置とサイズを指定 left = Inches(1) top = Inches(1) width = Inches(6) height = Inches(3) # テーブルをスライドに挿入 table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 列の幅を設定 table.columns[0].width = Inches(3) table.columns[1].width = Inches(3) # テーブルにヘッダーを追加 table.cell(0, 0).text = '対象月' table.cell(0, 1).text = '件数' # データを追加 data = [ ['2023-01', '100'], ['2023-02', '150'], ['2023-03', '120'], ['2023-04', '200'], ] for row_index, row_data in enumerate(data): for col_index, cell_data in enumerate(row_data): table.cell(row_index + 1, col_index).text = cell_data # プレゼンテーションを保存 prs.save('table_example.pptx') ** その21 [#a1b41d35] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation('your_presentation.pptx') # 既存のPowerPointファイルを読み込む # スライドのインデックス slide_index = 0 # スライドのインデックス(0から始まる) # コンテンツプレースホルダーのインデックス content_placeholder_index = 0 # コンテンツプレースホルダーのインデックス(0から始まる) # 図のプレースホルダーのインデックス image_placeholder_index = 1 # 図のプレースホルダーのインデックス(0から始まる) # スライドを取得 slide = prs.slides[slide_index] # コンテンツプレースホルダーを取得 content_placeholder = slide.placeholders[content_placeholder_index] # コンテンツプレースホルダーの位置と大きさを取得 left = content_placeholder.left top = content_placeholder.top width = content_placeholder.width height = content_placeholder.height # 図のプレースホルダーに変更 content_placeholder.placeholder_format.idx = image_placeholder_index # 図のプレースホルダーに位置と大きさを設定 image_placeholder = slide.placeholders[image_placeholder_index] image_placeholder.left = left image_placeholder.top = top image_placeholder.width = width image_placeholder.height = height # プレゼンテーションを保存 prs.save('updated_presentation.pptx') ** その22 [#ta285ac6] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # スライドにテーブルを追加する関数 def add_table_to_slide(slide, rows): left = Inches(1) # テーブルの位置を調整 top = Inches(1) width = Inches(8) height = Inches(5) table = slide.shapes.add_table(rows, 2, left, top, width, height).table # テーブルのデザインやセルの内容を設定 for row in range(rows): for col in range(2): cell = table.cell(row, col) cell.text = f'Row {row}, Col {col}' # 仮のデータを作成 data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # データをスライドに追加 for i in range(0, len(data), 10): slide = prs.slides.add_slide(prs.slide_layouts[5]) # 5はタイトルとコンテンツ add_table_to_slide(slide, min(10, len(data) - i)) # プレゼンテーションを保存 prs.save('output.pptx') ** その23 [#c819a594] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加する関数 def add_new_slide(prs): slide_layout = prs.slide_layouts[5] # 5は新しいページのスライドレイアウトに対応します slide = prs.slides.add_slide(slide_layout) return slide # サンプルの長い文字列 long_text = "Your long text goes here. This is just a sample to demonstrate a long string in the table cell." # 新しいスライドを追加し、テキストをセルに追加する関数 def add_text_to_slide(slide, text): table = slide.shapes.add_table(rows=1, cols=1, left=Inches(0.5), top=Inches(1), width=Inches(8), height=Inches(1)).table cell = table.cell(0, 0) cell.text = text # 文字列をチャンクに分割し、指定の文字数でテーブルセルに追加 chunk_size = 50 # テキストを分割するサイズ text_chunks = [long_text[i:i + chunk_size] for i in range(0, len(long_text), chunk_size)] current_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 最初のスライドを追加 for chunk in text_chunks: if len(current_slide.shapes) == 0: add_text_to_slide(current_slide, chunk) else: if len(current_slide.shapes[0].text_frame.text) + len(chunk) > chunk_size: current_slide = add_new_slide(prs) add_text_to_slide(current_slide, chunk) else: current_slide.shapes[0].text_frame.text += chunk # プレゼンテーションを保存 prs.save('output_presentation.pptx') ** その24 [#i052114a] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを作成 slide = prs.slides.add_slide(prs.slide_layouts[5]) # 適切なレイアウトを選択 # 10行のサンプルデータ(仮のデータ) sample_data = [ ['A1', 'B1', 'C1'], ['A2', 'B2', 'C2'], ['A3', 'B3', 'C3'], # ... 他の行データを含める ... ] # テーブルを作成 rows = 4 cols = 3 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table # テーブルにデータを挿入 row_index = 0 for row in sample_data: if row_index >= rows: # テーブルの行数を超えたら新しいスライドにテーブルを追加 slide = prs.slides.add_slide(prs.slide_layouts[5]) table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table row_index = 0 for col_index, cell_value in enumerate(row): table.cell(row_index, col_index).text = cell_value row_index += 1 # プレゼンテーションを保存 prs.save('output_presentation.pptx') ** その25 [#zb5d7725] from pptx import Presentation from pptx.util import Inches # 新しいプレゼンテーションを作成 prs = Presentation() # 新しいスライドを追加 slide_layout = prs.slide_layouts[5] # 5は新しいページのスライドレイアウトに対応します slide = prs.slides.add_slide(slide_layout) # 表を追加する関数 def add_table_to_slide(slide): left = Inches(1) top = Inches(1.5) width = Inches(8) height = Inches(1.5) rows = 5 # 表の行数 cols = 3 # 表の列数 table = slide.shapes.add_table(rows, cols, left, top, width, height).table # 表の見た目を調整(任意) table.columns[0].width = Inches(2) table.columns[1].width = Inches(3) table.columns[2].width = Inches(3) return table # 表にレコードを追加する関数 def add_record_to_table(table, data): row_count = len(table.rows) for row_index, record in enumerate(data): if row_count <= row_index: table.add_row().cells for col_index, value in enumerate(record): table.cell(row_index, col_index).text = value # サンプルのレコードデータ new_records = [ ["Name 4", "Description 4", "Value 4"], ["Name 5", "Description 5", "Value 5"], ["Name 6", "Description 6", "Value 6"] ] # 最初のレコードを表に追加 table = add_table_to_slide(slide) initial_records = [ ["Name 1", "Description 1", "Value 1"], ["Name 2", "Description 2", "Value 2"], ["Name 3", "Description 3", "Value 3"] ] add_record_to_table(table, initial_records) # 後から新しいレコードを表に追加 add_record_to_table(table, new_records) # プレゼンテーションを保存 prs.save('table_presentation.pptx') ** その26 [#vd733bbf] from pptx import Presentation from pptx.util import Pt from pptx.enum.text import MSO_ANCHOR, MSO_UNDERLINE from pptx.dml.color import RGBColor def underline_specific_text(paragraph, target_text): for run in paragraph.runs: if target_text in run.text: # 特定の文字が含まれるRunに下線を引く run.font.underline = True run.font.underline = MSO_UNDERLINE.DASH_LINE def main(): # 新しいプレゼンテーションを作成 presentation = Presentation() # スライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[0]) # テキストボックスを追加 textbox = slide.shapes.add_textbox(left=Pt(100), top=Pt(100), width=Pt(500), height=Pt(200)) text_frame = textbox.text_frame # テキストを追加 p = text_frame.add_paragraph() p.text = "This is an example text. Only 'example' should be underlined." #テキストの一部の色を赤色に変える pg = text_frame.paragraphs[0] run = pg.add_run() run.text = "Anaconda" run.font.color.rgb = RGBColor(255, 0, 0) #テキストの一部を青色に変える run = pg.add_run() run.text = " and Miniconda" run.font.color.rgb = RGBColor(0, 0, 255) run.font.underline = True run.font.underline = MSO_UNDERLINE.DOTTED_LINE run = pg.add_run() run.text = "Anaconda2" run.font.color.rgb = RGBColor(255, 0, 0) # 特定の文字だけに下線を引く # underline_specific_text(p, "example") """ #白紙のスライドを追加 slide_layout_6 = ppt.slide_layouts[6] slide_6 = ppt.slides.add_slide(slide_layout_6) shapes = slide_6.shapes shape = shapes.add_textbox(Cm(1), Cm(1), Cm(5), Cm(5)) text_frame = shape.text_frame #テキストの一部の色を赤色に変える pg = text_frame.paragraphs[0] run = pg.add_run() run.text = "Anaconda" run.font.color.rgb = RGBColor(255, 0, 0) #テキストの一部を青色に変える run = pg.add_run() run.text = " and Miniconda" run.font.color.rgb = RGBColor(0, 0, 255) """ # プレゼンテーションを保存 presentation.save("underlined_text.pptx") if __name__ == "__main__": main() ** その27 [#k5db21e6] def convert_dates(date_list): converted_dates = [] for idx, date_str in enumerate(date_list): # 日付文字列をyyyymmdd形式からdatetimeオブジェクトに変換 date_object = datetime.strptime(date_str, "%Y%m%d") # 初日の場合はyyyymmdd形式で追加、それ以外はdd形式で追加 if idx == 0: converted_dates.append(date_object.strftime("%Y%m%d")) else: converted_dates.append(date_object.strftime("%d")) return converted_dates ** その28 [#s3a18a68] from pptx import Presentation from pptx.util import Inches def prs_to_pixels(prs, emu_value): """ Convert EMUs (English Metric Units) to pixels based on the presentation settings. Parameters: - prs: Presentation object. - emu_value: Value in EMUs. Returns: - pixel_value: Value in pixels. """ emus_per_inch = 914400 inches_per_pixel = 1 / prs.slide_width # Assuming the width of the slide as the reference pixel_value = emu_value / emus_per_inch / inches_per_pixel return round(pixel_value) def get_placeholder_size(prs, slide_master, placeholder_idx): """ Get the width and height of a placeholder on the slide master in pixels. Parameters: - prs: Presentation object. - slide_master: The slide master object. - placeholder_idx: The index of the placeholder on the slide master. Returns: - width_pixels: Width of the placeholder in pixels. - height_pixels: Height of the placeholder in pixels. """ placeholder = slide_master.placeholders[placeholder_idx] width_emu, height_emu = placeholder.width, placeholder.height width_pixels = prs_to_pixels(prs, width_emu) height_pixels = prs_to_pixels(prs, height_emu) return width_pixels, height_pixels # PowerPointプレゼンテーションの読み込み presentation = Presentation('your_presentation.pptx') # スライドマスターの取得 (例: 最初のスライドマスター) slide_master = presentation.slide_master # プレースホルダーのインデックス (例: 0はタイトル、1はサブタイトル) placeholder_idx = 0 # プレースホルダーのwidthとheightをピクセルで取得 width_pixels, height_pixels = get_placeholder_size(presentation, slide_master, placeholder_idx) # 結果の表示 print(f"Width: {width_pixels} pixels") print(f"Height: {height_pixels} pixels") ** その29 [#c229d5bd] import plotly.graph_objects as go # データの作成 labels = ['Category A', 'Category B', 'Category C', 'Category D', 'Category E', 'Category F', 'Category G', 'Category H', 'Category I', 'Category J'] values = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] # 円グラフの作成 fig = go.Figure(data=[go.Pie(labels=labels, values=values)]) # レイアウトの設定 fig.update_layout( title='Pie Chart', legend=dict( orientation='h', # 凡例の方向を水平に設定 x=0.5, # x軸の中央に配置 y=1.15, # y軸の位置を調整 xanchor='center', # x軸のアンカーポイントを中央に設定 yanchor='top', # y軸のアンカーポイントを上端に設定 traceorder='normal', # 凡例の並び順を指定 borderwidth=1, # 凡例の境界線の太さを指定 bordercolor='Black' # 凡例の境界線の色を指定 ) ) # グラフの表示 fig.show() ** その30 [#pb00d386] from pptx import Presentation from pptx.util import Inches def create_table_on_slide(prs, slide, data): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=len(data[0]), left=Inches(1), top=Inches(1), width=Inches(8)).table # 表にデータを挿入 for row_num, row_data in enumerate(data): for col_num, cell_value in enumerate(row_data): table.cell(row_num, col_num).text = str(cell_value) # 表が入りきらない場合は新しいスライドを作成して続きの表を作成 if table.rows[0].height > slide.shapes.height: new_slide = prs.slides.add_slide(prs.slide_layouts[5]) # 新しい空のスライドを作成(indexは適切なものを選択) create_table_on_slide(prs, new_slide, data) # プレゼンテーションの作成 presentation = Presentation() # データ(2次元リスト)の例 table_data = [ ["Header 1", "Header 2", "Header 3"], ["Data 1-1", "Data 1-2", "Data 1-3"], ["Data 2-1", "Data 2-2", "Data 2-3"], # ... 続きのデータ ] # 最初のスライドに表を作成 first_slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # indexは適切なものを選択 create_table_on_slide(presentation, first_slide, table_data) # プレゼンテーションを保存 presentation.save("output.pptx") **その31 [#xe80cdfe] from pptx import Presentation from pptx.util import Inches, Pt def create_table_on_slide(prs, slide, data): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=len(data[0]), left=Inches(1), top=Inches(1), width=Inches(8)).table # 表にデータを挿入 for row_num, row_data in enumerate(data): for col_num, cell_value in enumerate(row_data): table.cell(row_num, col_num).text = str(cell_value) return table def add_rows_to_table(table, num_rows): # 指定された数の行を表に追加 for _ in range(num_rows): table.add_row() # プレゼンテーションの作成 presentation = Presentation() # データ(2次元リスト)の例 table_data = [ ["Header 1", "Header 2", "Header 3"], ["Data 1-1", "Data 1-2", "Data 1-3"], ["Data 2-1", "Data 2-2", "Data 2-3"], # ... 続きのデータ ] # 最初のスライドに表を作成 first_slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # indexは適切なものを選択 table = create_table_on_slide(presentation, first_slide, table_data) # 3行追加した後の座標を取得 add_rows_to_table(table, 3) table_x = table.left table_y = table.top print(f"Table coordinates after adding 3 rows: ({table_x}, {table_y})") # 4行追加した後の座標を取得 add_rows_to_table(table, 4) table_x = table.left table_y = table.top print(f"Table coordinates after adding 4 rows: ({table_x}, {table_y})") # プレゼンテーションを保存 presentation.save("output.pptx") ** その32 [#xa061721] from pptx import Presentation # プレゼンテーションの作成 presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表の追加 table = slide.shapes.add_table(rows=1, cols=3, left=100, top=100, width=Inches(4)).table # 追加した表のインデックス(idx)を取得 tables_on_slide = slide.shapes._spTree table_idx = list(tables_on_slide).index(table._element) print(f"Index of the added table: {table_idx}") # プレゼンテーションを保存 presentation.save("output.pptx") ** その33 [#v2b3fda0] from pptx import Presentation from pptx.util import Inches def add_table_to_slide(slide): # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=3, left=Inches(1), top=Inches(1), width=Inches(4)).table # 表のヘッダーを設定 table.cell(0, 0).text = "Header 1" table.cell(0, 1).text = "Header 2" table.cell(0, 2).text = "Header 3" return table def add_record_to_table(table, data): # 新しいレコード(行)を表に追加 table.add_row() # レコードにデータを挿入 for col_num, cell_value in enumerate(data): table.cell(table.rows[-1].index, col_num).text = str(cell_value) # PowerPointファイルを読み込み presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表をスライドに追加 added_table = add_table_to_slide(slide) # レコードを表に追加 record_data = ["Data 1", "Data 2", "Data 3"] add_record_to_table(added_table, record_data) # プレゼンテーションを保存 presentation.save("output.pptx") ** その34 [#e8417f90] from pptx import Presentation from pptx.util import Inches, Pt import json def create_table(slide, data): rows, cols = len(data) + 1, len(data[0]) table = slide.shapes.add_table(rows=rows, cols=cols, left=Inches(1), top=Inches(1), width=Inches(8), height=Inches(4)).table # Set column widths for col, width in enumerate([Inches(2)] * cols): table.columns[col].width = width # Populate header row for col, header in enumerate(data[0]): cell = table.cell(0, col) cell.text = header cell.text_frame.paragraphs[0].font.bold = True # Populate data rows for row, row_data in enumerate(data[1:], start=1): for col, value in enumerate(row_data): cell = table.cell(row, col) cell.text = value cell.text_frame.word_wrap = True def create_slides_from_json(template_path, json_path, output_path): with open(json_path, 'r') as json_file: json_data = json.load(json_file) prs = Presentation(template_path) for data in json_data: slide = prs.slides.add_slide(prs.slide_layouts[0]) # Assuming the first layout is suitable create_table(slide, data) prs.save(output_path) # 使用例 template_file = 'your_template.pptx' json_data_file = 'your_data.json' output_file = 'output.pptx' create_slides_from_json(template_file, json_data_file, output_file) ** その35 [#pf2735df] from pptx import Presentation from pptx.util import Inches, Pt def get_textbox_height(textbox): paragraphs = textbox.text_frame.paragraphs total_height = 0 for paragraph in paragraphs: for run in paragraph.runs: total_height += run.font.size.pt return total_height def main(): # プレゼンテーションファイルのパスを指定 presentation_path = 'your_presentation.pptx' # プレゼンテーションを読み込む presentation = Presentation(presentation_path) # 例として1つ目のスライドの1つ目のテキストボックスを取得 first_slide = presentation.slides[0] first_textbox = first_slide.shapes[0] # テキストボックスの高さを取得 textbox_height = get_textbox_height(first_textbox) print(f'Textbox Height: {textbox_height} pt') if __name__ == "__main__": main() ** その36 [#lfdf7146] from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.enum.text import MSO_ANCHOR, PP_ALIGN def create_table_with_condition(slide, data): rows, cols = 3, 4 table = slide.shapes.add_table(rows, cols, Inches(1), Inches(1), Inches(6), Inches(3)).table # データのセットアップ for row in range(rows): for col in range(cols): cell = table.cell(row, col) cell.text = data[row][col] cell.text_frame.text = data[row][col] cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 最終行が条件に合致する場合、セルを結合して指定のテキストを置き換える if data[-1] == ['合計', '-', '0', '-']: last_row_cell = table.cell(rows-1, 0) last_row_cell.merge(table.cell(rows-1, cols-1)) last_row_cell.text_frame.clear() last_row_cell.text_frame.text = '対象データはありませんでした' last_row_cell.text_frame.paragraphs[0].font.size = Pt(14) last_row_cell.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 最終行のセル以外の文字をクリア # for col in range(cols-1): # table.cell(rows-1, col).text_frame.clear() # プレゼンテーションの作成 presentation = Presentation() slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # Blank Slide # 3行4列の表データ data = [ ['A1', 'B1', 'C1', 'D1'], ['A2', 'B2', 'C2', 'D2'], ['合計', '-', '0', '-'] ] # 条件に合わせて表を作成 create_table_with_condition(slide, data) # プレゼンテーションの保存 presentation.save('output-023-03.pptx') ** その37 [#d0de4fd6] import polars as pl def detect_rows_with_only_specified_value(df, specified_value): # 指定した文字列以外が存在するかどうかを判定する条件式を構築 condition = ~df.drop(["index"]).apply(lambda series: series.nunique() > 1, in_place=True) # 検知された条件に合致する行のインデックスを取得 detected_indexes = df.filter(condition)["index"].to_list() return detected_indexes # データの作成 data = { 'A': ['apple', 'orange', 'apple'], 'B': ['banana', 'banana', 'banana'], 'C': ['cherry', 'cherry', 'cherry'], 'D': ['date', 'date', 'date'] } df = pl.DataFrame(data) # 検知する文字列を指定 specified_value = 'date' # プログラムを実行して指定した文字列が行内にしか存在しない行を検知 detected_indexes = detect_rows_with_only_specified_value(df, specified_value) # 検知された行のインデックスを表示 print(f"Rows with only '{specified_value}': {detected_indexes}") ** その38 [#s65f52cc] import json from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.dml.color import RGBColor def create_table(slide, title, data): title_shape = slide.shapes.title title_shape.text = title # 表の位置とサイズ left = Inches(1) top = title_shape.top + title_shape.height + Inches(0.5) width = Inches(8) height = Inches(4) # 表を作成 table = slide.shapes.add_table(rows=len(data) + 1, cols=len(data[0]), left=left, top=top, width=width, height=height).table # 表のスタイル設定 table.style = "Table Grid" # タイトル行のフォント設定 title_row = table.rows[0] for cell in title_row.cells: cell.text_frame.text = cell.text_frame.text.title() cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].font.bold = True cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) # データ行のフォント設定と折り返し for i, row in enumerate(data): data_row = table.rows[i + 1] for j, value in enumerate(row): cell = data_row.cells[j] cell.text_frame.text = str(value) cell.text_frame.paragraphs[0].font.size = Pt(12) cell.text_frame.word_wrap = True def create_presentation(json_file): # PowerPointファイルを生成 presentation = Presentation() # JSONファイルからデータを読み込む with open(json_file, 'r') as f: json_data = json.load(f) for i, data in enumerate(json_data): # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # タイトルとデータから表を作成 create_table(slide, f"Table {i + 1}", data) # PowerPointファイルを保存 presentation.save("output.pptx") # JSONファイルから表を作成してPowerPointファイルに保存 create_presentation("table_data.json") ** その39 [#kcd687dd] import json from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN from pptx.dml.color import RGBColor def create_table(slide, title, headers): title_shape = slide.shapes.title title_shape.text = title # 表の位置とサイズ left = Inches(1) top = title_shape.top + title_shape.height + Inches(0.5) width = Inches(8) height = Inches(4) # 表を作成 table = slide.shapes.add_table(rows=2, cols=len(headers), left=left, top=top, width=width, height=height).table # 表のスタイル設定 table.style = "Table Grid" # タイトル行のフォント設定 title_row = table.rows[0] for j, header in enumerate(headers): cell = title_row.cells[j] cell.text_frame.text = header cell.text_frame.paragraphs[0].font.size = Pt(14) cell.text_frame.paragraphs[0].font.bold = True cell.text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) def add_row_to_table(table, data): # 表に新しい行を追加 row_cells = table.add_row().cells # データ行のフォント設定と折り返し for j, value in enumerate(data): cell = row_cells[j] cell.text_frame.text = str(value) cell.text_frame.paragraphs[0].font.size = Pt(12) cell.text_frame.word_wrap = True def create_presentation(json_file): # PowerPointファイルを生成 presentation = Presentation() # JSONファイルからデータを読み込む with open(json_file, 'r') as f: json_data = json.load(f) for i, data in enumerate(json_data): # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # タイトル行とデータ行1行だけの表を作成 create_table(slide, f"Table {i + 1}", data.keys()) # JSONデータのレコードを読み込んで表に行を追加 add_row_to_table(slide.shapes[0].table, data.values()) # PowerPointファイルを保存 presentation.save("output.pptx") # JSONファイルから表を作成してPowerPointファイルに保存 create_presentation("table_data.json") ** その40 [#m1c0c6ea] [ {"Name": "Alice", "Age": 25}, {"Name": "Bob", "Age": 30}, {"Name": "Charlie", "Age": 22}, {"Name": "David", "Age": 35}, {"Name": "Eva", "Age": 28}, {"Name": "Frank", "Age": 31}, {"Name": "Grace", "Age": 24}, {"Name": "Hank", "Age": 29}, {"Name": "Ivy", "Age": 33}, {"Name": "Jack", "Age": 26}, {"Name": "Kate", "Age": 32}, {"Name": "Leo", "Age": 27}, {"Name": "Mia", "Age": 30}, {"Name": "Nate", "Age": 23}, {"Name": "Olivia", "Age": 34}, {"Name": "Paul", "Age": 31}, {"Name": "Quinn", "Age": 25}, {"Name": "Ryan", "Age": 28}, {"Name": "Sara", "Age": 29}, {"Name": "Tom", "Age": 36} ] ** その41 [#y4f61d3e] from copy import deepcopy from pptx import slide from pptx.table import Table, _Row, _Column, _Cell def add_row(slide: slide, top_point: int, left_point: int, table: Table) -> Table: new_row = deepcopy(table._tbl.tr_lst[-1]) # duplicating last row of the table as a new row to be added cell_margin_top = 0 cell_margin_bottom = 0 for tc in new_row.tc_lst: cell = _Cell(tc, new_row.tc_lst) cell.text = '' # defaulting cell contents to empty text cell_margin_top = cell.text_frame.margin_top cell_margin_bottom = cell.text_frame.margin_bottom table._tbl.append(new_row) # for shape in slide.shapes: if shape.top == top_point and shape.left == left_point: print('追加したレコード分、表の高さを更新します') #shape.height = shape.height + cell_margin_top + cell_margin_bottom # return table.rows[-1] return table def remove_row(table: Table, row_to_delete: _Row) -> None: table._tbl.remove(row_to_delete._tr) ** その42 [#zed425e9] import collections.abc from pptx import Presentation from pptx.util import Inches import table_add # # レコード追加した後に追加したレコード分の高さ情報を更新する # cell_height = cell.text_frame.margin_top + cell.text_frame.margin_bottom # table def check_table_size(slide): left_point = 100 top_point = 200 for shape in slide.shapes: print(shape.name) if shape.top == top_point and shape.left == left_point: print('追加したオブジェクトの位置: ' + str(shape.shape_id)) print('座標: ' + str(shape.top) + ':' + str(shape.left) + ':' + str(shape.height) + ':' + str(shape.width)) def add_table_to_slide(slide): left_point = 100 top_point = 200 # スライドに新しい表を作成 table = slide.shapes.add_table(rows=1, cols=3, left=left_point, top=top_point, width=Inches(4), height=Inches(1)).table # 表のヘッダーを設定 table.cell(0, 0).text = "Header 1" table.cell(0, 1).text = "Header 2" table.cell(0, 2).text = "Header 3" return table def add_record_to_table(slide, top_point, left_point, table, data, cnt): # 新しいレコード(行)を表に追加 table = table_add.add_row(slide, top_point, left_point, table) # レコードにデータを挿入 for col_num, cell_value in enumerate(data): table.cell(cnt, col_num).text = str(cell_value) # PowerPointファイルを読み込み presentation = Presentation() # 新しいスライドの追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 適切なスライドレイアウトを選択 # 表をスライドに追加 added_table = add_table_to_slide(slide) left_point = 100 # レコードを追加したタイミングでオブジェクトの高さを更新する top_point = 200 # レコードを表に追加 record_data = ["Data 1", "Data 2", "Data 3"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 1) check_table_size(slide) record_data = ["Data 4", "Data 5", "Data 6"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 2) check_table_size(slide) record_data = ["Data 7", "Data 8", "Data 9"] add_record_to_table(slide, top_point, left_point, added_table, record_data, 3) check_table_size(slide) # プレゼンテーションを保存 presentation.save("output.pptx") ** その43 [#n0f60db5] from pptx import Presentation from pptx.util import Inches def get_table_height(table): # Tableが属するshapeオブジェクトの高さを取得 height = table._element.get_or_add_txBody().bodyPr.get('anchor').split(',')[3] return int(height) # PowerPointファイルを生成 presentation = Presentation() # 新しいスライドを追加 slide = presentation.slides.add_slide(presentation.slide_layouts[5]) # 表を追加 table = slide.shapes.add_table(rows=3, cols=3, left=Inches(1), top=Inches(1), width=Inches(4), height=Inches(2)).table # 表の高さを取得 table_height = get_table_height(table) # 結果の表示 print(f"Table Height: {table_height} pt") # PowerPointファイルを保存 presentation.save("output.pptx") ** その44 [#w986b0db] import uno from com.sun.star.beans import PropertyValue def set_custom_formatting(sheet): # 2つ目のスライドを取得 slide = sheet.getSlides().getByIndex(1) # インデックスは0から始まるので、2つ目のスライドはインデックス1 # 2番目のスライドのプレースホルダー番号2を取得 placeholder = slide.getShapes().getByIndex(1) # インデックスは0から始まるので、2つ目のプレースホルダーはインデックス1 # タブ文字に1点鎖線を設定 placeholder.getPropertyValue("LineDash") # 1点鎖線の定義 placeholder.setPropertyValue("LineDash", (100,)) # 1点鎖線に設定 # 右側のルーラーに12を設定 sheet.setPropertyValue("RightMargin", 12) def convert_pptx_to_pdf(input_path, output_path): local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local_context) context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context) # ファイルを開く doc = desktop.loadComponentFromURL(f"file://{input_path}", "_blank", 0, ()) # 特定のシートに対してカスタムフォーマットを適用 set_custom_formatting(doc.getSheets().getByIndex(0)) # PDFに変換 pdf_export_props = ( PropertyValue("FilterName", 0, "writer_pdf_Export", 0), PropertyValue("Overwrite", 0, True, 0) ) output_url = f"file://{output_path}" doc.storeToURL(output_url, pdf_export_props) # ドキュメントを閉じる doc.close(True) if __name__ == "__main__": input_pptx_path = "/path/to/your_presentation.pptx" output_pdf_path = "/path/to/output.pdf" convert_pptx_to_pdf(input_pptx_path, output_pdf_path) ** その45 [#pccb485f] import os def convert_pptx_to_pdf(input_pptx, output_pdf): os.system(f'PowerShell -Command "& {{ Start-Process powerpnt -ArgumentList \\"{os.path.abspath(input_pptx)}\\", /pt \\"{os.path.abspath(output_pdf)}\\" -Wait }}"') # 使用例 input_pptx = 'C:\\path\\to\\your\\presentation.pptx' # 入力のPowerPointファイルのパス output_pdf = 'C:\\path\\to\\your\\output.pdf' # 出力のPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その46 [#t634e87f] import os def convert_pptx_to_pdf(input_pptx, output_pdf): os.system(f'PowerShell -Command "& {{ Start-Process powerpnt -ArgumentList \\"{os.path.abspath(input_pptx)}\\", /pt \\"Microsoft Print to PDF\\", \\"{os.path.abspath(output_pdf)}\\" -Wait }}"') # 使用例 input_pptx = 'C:\\path\\to\\your\\presentation.pptx' # 入力のPowerPointファイルのパス output_pdf = 'C:\\path\\to\\your\\output.pdf' # 出力のPDFファイルのパス convert_pptx_to_pdf(input_pptx, output_pdf) ** その47 [#uf222b5d] # PowerPointのCOMオブジェクトを作成 $powerPoint = New-Object -ComObject PowerPoint.Application # 変換元のフォルダと変換先のフォルダを指定 $inputFolder = "C:\Path\To\Input\Folder" $outputFolder = "C:\Path\To\Output\Folder" # 変換元フォルダ内の.pptxファイルを検索 $pptxFiles = Get-ChildItem -Path $inputFolder -Filter *.pptx foreach ($pptxFile in $pptxFiles) { # PowerPointファイルを開く $presentation = $powerPoint.Presentations.Open($pptxFile.FullName) # PDFに変換して保存 $pdfFileName = [System.IO.Path]::ChangeExtension($pptxFile.Name, "pdf") $pdfFilePath = Join-Path -Path $outputFolder -ChildPath $pdfFileName $presentation.ExportAsFixedFormat($pdfFilePath, 32) # 32はPDF形式 # PowerPointを閉じる $presentation.Close() } # PowerPointのCOMオブジェクトを解放 $powerPoint.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($powerPoint) | Out-Null ** その48 [#d1c17e9a] import logging import logging.config import yaml def setup_logging(config_file='logging_config.yaml'): with open(config_file, 'rt') as f: config = yaml.safe_load(f.read()) logging.config.dictConfig(config) def main(): # ログ設定を読み込む setup_logging() # ロガーを取得 logger = logging.getLogger(__name__) # ログメッセージの出力 logger.debug("This is a debug message") logger.info("This is an info message") logger.warning("This is a warning message") logger.error("This is an error message") logger.critical("This is a critical message") if __name__ == "__main__": main() ** その49 [#g83dc600] logging_config.yaml version: 1 formatters: simple: format: "%(asctime)s - %(levelname)s - %(message)s" handlers: console: class: logging.StreamHandler level: INFO formatter: simple file: class: logging.FileHandler filename: example.log level: DEBUG formatter: simple loggers: my_logger: level: DEBUG handlers: [console, file] propagate: no root: level: INFO handlers: [console] ** その50 [#qb4493f3] # ログ設定のバージョン version: 1 # フォーマッターの定義 formatters: simple: format: "%(asctime)s - %(levelname)s - %(message)s" # ハンドラーの定義 handlers: # コンソールにログを出力するハンドラー console: class: logging.StreamHandler level: INFO formatter: simple # ファイルにログを出力するハンドラー file: class: logging.FileHandler filename: example.log level: DEBUG formatter: simple # ロガーの定義 loggers: # 特定のロガー (ここでは my_logger) の設定 my_logger: level: DEBUG handlers: [console, file] propagate: no # ルートロガー (すべてのロガーに適用される設定) root: level: INFO # ルートロガーのログレベル handlers: [console] # ルートロガーに適用されるハンドラー ** その51 [#h13cbc4e] AWS EC2でwindowsサーバー+Office環境を構築したい。非機能要件書いて。性能要件や費用も月年単位で分かるように。 ChatGPT 以下に、AWS EC2上でWindowsサーバーおよびOffice環境を構築する際の非機能要件、性能要件、および費用に関する要件を示します。これらは一般的な要件であり、具体的なプロジェクトやニーズに応じて調整する必要があります。 非機能要件: セキュリティ: インスタンスへのアクセスはセキュアな方法で行い、最小限の必要なポートのみを公開する。 WindowsサーバーおよびOffice製品のライセンスは正規のものを使用し、セキュリティパッチやアップデートは適切に適用する。 可用性と信頼性: EC2インスタンスはマルチアベイラビリティーゾーン(Multi-AZ)に展開し、冗長性を確保する。 バックアップおよびリカバリ戦略を確立し、データの保護と復旧を行う。 パフォーマンス: インスタンスタイプは、適切なCPU、メモリ、およびストレージリソースを持つものを選定する。 ディスクI/Oおよびネットワークスループットの要件に対応するため、適切なEBSボリュームおよびネットワークの帯域幅を確保する。 拡張性: 将来的な需要に備えて、必要に応じてリソースを拡張できるアーキテクチャを確立する。 性能要件: CPUおよびメモリ: インスタンスは、Officeアプリケーションおよび関連サービスの要件に応じたCPUおよびメモリを搭載する。 ディスクI/O: ディスクI/OはOffice製品の正常な動作に必要な速度を確保する。 ネットワーク帯域幅: インターネット接続およびVPC内の通信において、必要なネットワーク帯域幅を確保する。 費用要件: EC2インスタンスの料金: EC2インスタンスの選定において、性能要件および予算に合致するインスタンスタイプを選択する。 ストレージ料金: 使用するEBSボリュームのサイズおよび性能に応じたストレージ料金を考慮する。 ネットワーク料金: インターネット接続およびデータ転送に伴うネットワーク料金を評価し、予算に合わせて適切な設定を行う。 Windowsライセンス料金: Windows ServerおよびOffice製品の正規のライセンスを購入し、ライセンスに関連する料金を考慮する。 これらの要件に基づいて、AWSのコスト計算ツールや料金ページを活用して、月や年単位での予算を立てることが重要です。また、適切な予備費用(リザーブドインスタンスなど)を検討することも良いプラクティスです。 ** その52 [#v6fb7411] import concurrent.futures def your_function(arg): # ここに並列化したい処理を記述 # この関数は複数のスレッドで同時に実行されます result = arg * 2 return result def main(): # 並列処理のためのスレッド数を指定 num_threads = 4 # ThreadPoolExecutorを作成 with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: # 並列処理したいデータをリストで準備 data_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # mapメソッドを使用して並列処理を実行 results = list(executor.map(your_function, data_list)) # 結果の表示 print(results) if __name__ == "__main__": main() ** その54 [#d7b6c619] import boto3 from concurrent.futures import ThreadPoolExecutor, as_completed def process_message(message): # ここにメッセージを処理する具体的なロジックを記述 print(f"Processing message: {message['Body']}") def receive_messages(queue_url, max_messages=10, num_threads=2): # AWSの認証情報やリージョンを設定 aws_access_key = 'YOUR_ACCESS_KEY' aws_secret_key = 'YOUR_SECRET_KEY' aws_region = 'YOUR_REGION' # SQSクライアントの作成 sqs = boto3.client('sqs', region_name=aws_region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) # メッセージをまとめて取得 response = sqs.receive_message( QueueUrl=queue_url, MaxNumberOfMessages=max_messages, AttributeNames=[ 'All' ], MessageAttributeNames=[ 'All' ], VisibilityTimeout=0, WaitTimeSeconds=0 ) # メッセージが取得できたかどうかを確認 messages = response.get('Messages', []) if messages: with ThreadPoolExecutor(max_workers=num_threads) as executor: # submitメソッドを使用して各メッセージを非同期に処理 futures = [executor.submit(process_message, message) for message in messages] # すべてのFutureが完了するまで待機 for future in as_completed(futures): try: future.result() except Exception as e: print(f"Error processing message: {e}") # 取得したメッセージを削除 for message in messages: sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=message['ReceiptHandle']) else: print("No messages available in the queue.") # SQSのURLを指定してメッセージを取得(最大10件、スレッド数2) queue_url = 'YOUR_SQS_QUEUE_URL' receive_messages(queue_url, max_messages=10, num_threads=2) ** その55 [#qca2d650] import boto3 from botocore.exceptions import NoCredentialsError # AWSの認証情報 aws_access_key = 'YOUR_ACCESS_KEY' aws_secret_key = 'YOUR_SECRET_KEY' aws_region = 'YOUR_REGION' aws_sqs_queue_url = 'YOUR_SQS_QUEUE_URL' aws_s3_bucket = 'YOUR_S3_BUCKET' aws_s3_key = 'YOUR_S3_KEY' # MFAの情報 mfa_device_arn = 'YOUR_MFA_DEVICE_ARN' mfa_code = 'YOUR_MFA_CODE' # プロキシの設定 proxy_host = 'YOUR_PROXY_HOST' proxy_port = 'YOUR_PROXY_PORT' proxies = { 'http': f'http://{proxy_host}:{proxy_port}', 'https': f'http://{proxy_host}:{proxy_port}', } def get_temporary_credentials(): # STSクライアントの作成 sts = boto3.client('sts', region_name=aws_region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) # MFAの情報を含めて一時的な認証情報を取得 response = sts.get_session_token( DurationSeconds=3600, # 任意の有効期間 SerialNumber=mfa_device_arn, TokenCode=mfa_code ) return response['Credentials'] try: # MFAを含めた一時的な認証情報を取得 temporary_credentials = get_temporary_credentials() # SQSクライアントの作成 sqs = boto3.client('sqs', region_name=aws_region, aws_access_key_id=temporary_credentials['AccessKeyId'], aws_secret_access_key=temporary_credentials['SecretAccessKey'], aws_session_token=temporary_credentials['SessionToken'], proxies=proxies) # SQSからメッセージを取得 response = sqs.receive_message( QueueUrl=aws_sqs_queue_url, MaxNumberOfMessages=10, AttributeNames=['All'], MessageAttributeNames=['All'], VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) if messages: for message in messages: print(f"Received message from SQS: {message['Body']}") # SQSのメッセージを削除 receipt_handle = message['ReceiptHandle'] sqs.delete_message(QueueUrl=aws_sqs_queue_url, ReceiptHandle=receipt_handle) # S3クライアントの作成 s3 = boto3.client('s3', region_name=aws_region, aws_access_key_id=temporary_credentials['AccessKeyId'], aws_secret_access_key=temporary_credentials['SecretAccessKey'], aws_session_token=temporary_credentials['SessionToken'], proxies=proxies) # S3からファイルをダウンロード s3.download_file(aws_s3_bucket, aws_s3_key, 'downloaded_file.txt') print("File downloaded from S3.") else: print("No messages available in the SQS queue.") except NoCredentialsError: print("Credentials not available") except Exception as e: print(f"An error occurred: {e}") ** その56 [#i1921020] import boto3 from botocore.exceptions import NoCredentialsError # AWSの認証情報 aws_access_key_id = 'YOUR_ACCESS_KEY_ID' aws_secret_access_key = 'YOUR_SECRET_ACCESS_KEY' aws_session_token = 'YOUR_SESSION_TOKEN' # MFA認証が必要な場合 # プロキシ設定 (必要に応じて) proxies = { 'http': 'http://proxy.example.com:8888', 'https': 'http://proxy.example.com:8888', } # MFAデバイス情報 mfa_serial = 'arn:aws:iam::ACCOUNT_ID:mfa/USERNAME' mfa_token_code = '123456' # 実際のMFAデバイスから取得したコード # S3とSQSクライアントの作成 s3_client = boto3.client('s3', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, proxies=proxies) sqs_client = boto3.client('sqs', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, aws_session_token=aws_session_token, proxies=proxies) # MFAデバイスのトークンを取得 mfa_token = boto3.client('sts', aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key).get_session_token( SerialNumber=mfa_serial, TokenCode=mfa_token_code )['Credentials']['SessionToken'] # SQSからメッセージを取得 queue_url = 'YOUR_SQS_QUEUE_URL' try: response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MaxNumberOfMessages=1, MessageAttributeNames=['All'], VisibilityTimeout=0, WaitTimeSeconds=0 ) # メッセージがある場合、処理を行う if 'Messages' in response: message = response['Messages'][0] print(f"Received message: {message['Body']}") # ここでメッセージの処理を行う # メッセージを削除する receipt_handle = message['ReceiptHandle'] sqs_client.delete_message( QueueUrl=queue_url, ReceiptHandle=receipt_handle ) else: print("No messages in the queue") except NoCredentialsError: print('Credentials not available') except Exception as e: print(f"Error: {str(e)}") ** その57 [#c66441f1] import boto3 from botocore.exceptions import NoCredentialsError def get_mfa_session_token(profile_name, mfa_device_arn, mfa_code): sts_client = boto3.client('sts') response = sts_client.get_session_token( DurationSeconds=3600, SerialNumber=mfa_device_arn, TokenCode=mfa_code ) session_credentials = response['Credentials'] session = boto3.Session( aws_access_key_id=session_credentials['AccessKeyId'], aws_secret_access_key=session_credentials['SecretAccessKey'], aws_session_token=session_credentials['SessionToken'] ) return session def receive_messages_with_mfa(queue_url, mfa_session): sqs_client = mfa_session.client('sqs') try: response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MessageAttributeNames=['All'], MaxNumberOfMessages=10, VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) for message in messages: print(f"Received message: {message['Body']}") except NoCredentialsError: print("Credentials not available") if __name__ == "__main__": # AWSのプロファイル名 aws_profile = 'your_profile' # MFAデバイスARN mfa_device_arn = 'arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device' # MFAコード mfa_code = input("Enter MFA code: ") # SQSキューのURL sqs_queue_url = 'https://sqs.your-region.amazonaws.com/your-account-id/your-queue-name' # MFAセッションを取得 mfa_session = get_mfa_session_token(aws_profile, mfa_device_arn, mfa_code) # SQSからメッセージを受信 receive_messages_with_mfa(sqs_queue_url, mfa_session) ** その58 [#ufea8ede] import boto3 from botocore.exceptions import NoCredentialsError def get_mfa_session_token(profile_name, mfa_device_arn, mfa_code): sts_client = boto3.client('sts') response = sts_client.get_session_token( DurationSeconds=3600, SerialNumber=mfa_device_arn, TokenCode=mfa_code ) session_credentials = response['Credentials'] session = boto3.Session( aws_access_key_id=session_credentials['AccessKeyId'], aws_secret_access_key=session_credentials['SecretAccessKey'], aws_session_token=session_credentials['SessionToken'] ) return session def receive_messages_with_mfa(queue_url, mfa_session): sqs_client = mfa_session.client('sqs') s3_client = mfa_session.client('s3') try: # SQSからメッセージを受信 response = sqs_client.receive_message( QueueUrl=queue_url, AttributeNames=['All'], MessageAttributeNames=['All'], MaxNumberOfMessages=10, VisibilityTimeout=0, WaitTimeSeconds=0 ) messages = response.get('Messages', []) # メッセージがある場合、S3にファイルを格納 for message in messages: s3_client.put_object( Bucket='your-s3-bucket', Key=f'my-folder/{message["MessageId"]}.txt', Body=message['Body'] ) print(f"Stored message in S3: {message['MessageId']}") except NoCredentialsError: print("Credentials not available") except Exception as e: print(f"Error: {e}") if __name__ == "__main__": # AWSのプロファイル名 aws_profile = 'your_profile' # MFAデバイスARN mfa_device_arn = 'arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device' # MFAコード mfa_code = input("Enter MFA code: ") # SQSキューのURL sqs_queue_url = 'https://sqs.your-region.amazonaws.com/your-account-id/your-queue-name' # MFAセッションを取得 mfa_session = get_mfa_session_token(aws_profile, mfa_device_arn, mfa_code) # SQSからメッセージを受信してS3に格納 receive_messages_with_mfa(sqs_queue_url, mfa_session) ** その59 [#d95c4336] import subprocess import platform def run_command(command): process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output, error = process.communicate() return output.decode('utf-8'), error.decode('utf-8'), process.returncode def get_mfa_code(): return input("Enter MFA code: ") def run_script(): mfa_enabled = True # ローカル開発時はTrue、本番環境ではFalseと仮定 if mfa_enabled: mfa_code = get_mfa_code() command = f"aws sts get-session-token --serial-number arn:aws:iam::account-id-without-hyphens:mfa/your-mfa-device --token-code {mfa_code}" output, error, return_code = run_command(command) if return_code == 0: # MFA認証が成功した場合、セッショントークン情報を抽出 session_token_info = output.splitlines() aws_access_key_id = session_token_info[2].split(":")[1].strip() aws_secret_access_key = session_token_info[3].split(":")[1].strip() aws_session_token = session_token_info[4].split(":")[1].strip() # 本番環境で使う設定 # ここで本番環境用のAWSクレデンシャル情報を設定する else: print(f"MFA authentication failed: {error}") return else: # 本番環境で使う設定 # ここで本番環境用のAWSクレデンシャル情報を設定する # 本番環境またはMFA認証成功後に行う処理 # ここにAWS SDK for Python (Boto3) を使用して実際の処理を記述する if __name__ == "__main__": run_script() ** その60 [#m300645e] def update_mfa_section(credentials_file, new_access_key_id, new_secret_access_key): with open(credentials_file, 'r') as file: lines = file.readlines() in_mfa_section = False for i, line in enumerate(lines): if line.strip() == '[mfa]': in_mfa_section = True continue # [mfa] セクションは更新せずに次の行に移動 if in_mfa_section and line.startswith('['): break # [mfa] セクションの終わりに到達したらループを終了 if in_mfa_section: if line.startswith("aws_access_key_id"): lines[i] = f"aws_access_key_id = {new_access_key_id}\n" elif line.startswith("aws_secret_access_key"): lines[i] = f"aws_secret_access_key = {new_secret_access_key}\n" with open(credentials_file, 'w') as file: file.writelines(lines) if __name__ == "__main__": credentials_file = "path/to/your/aws/credentials/file" # AWS credentialsファイルのパス new_access_key_id = "your-new-access-key-id" # 新しいアクセスキーID new_secret_access_key = "your-new-secret-access-key" # 新しいシークレットアクセスキー update_mfa_section(credentials_file, new_access_key_id, new_secret_access_key) ** その61 [#l88d683e] def get_changed_values(credentials_file): changed_values = {} with open(credentials_file, 'r') as file: lines = file.readlines() for line in lines: # 更新された行かどうかを確認 if line.startswith("aws_access_key_id"): parts = line.split("=") key = parts[0].strip() value = parts[1].strip() changed_values[key] = value elif line.startswith("aws_secret_access_key"): parts = line.split("=") key = parts[0].strip() value = parts[1].strip() changed_values[key] = value return changed_values if __name__ == "__main__": credentials_file = "path/to/your/aws/credentials/file" # 更新されたAWS credentialsファイルのパス updated_values = get_changed_values(credentials_file) print("Updated values:") print(updated_values) ** その62 [#p8cc680a] import logging from logging.handlers import TimedRotatingFileHandler import os import datetime # ログフォーマットを設定 log_format = '%(asctime)s - %(levelname)s - %(message)s' # ロガーを設定 logger = logging.getLogger() logger.setLevel(logging.DEBUG) # ファイルの日付フォーマットを設定 date_format = '%Y-%m-%d' today_date = datetime.datetime.now().strftime(date_format) # ファイルハンドラを作成 log_file = 'example.log' backup_file = f'example_{today_date}.log' file_handler = TimedRotatingFileHandler(log_file, when='M', interval=1, backupCount=0, encoding='utf-8', atTime=datetime.time(0, 0, 0)) file_handler.suffix = f'_{today_date}' file_handler.setLevel(logging.DEBUG) # ログフォーマットを設定 formatter = logging.Formatter(log_format) file_handler.setFormatter(formatter) # ロガーにハンドラを追加 logger.addHandler(file_handler) # ログメッセージの出力 logger.debug('This is a debug message') logger.info('This is an info message') logger.warning('This is a warning message') logger.error('This is an error message') logger.critical('This is a critical message') # 古いバックアップファイルを削除 try: os.remove(backup_file) except FileNotFoundError: pass ** その63 [#v4e056d8] import logging from logging.handlers import TimedRotatingFileHandler import datetime def setup_logger(log_path): # ロギングの設定 logger = logging.getLogger() logger.setLevel(logging.INFO) # ローテーション設定 handler = TimedRotatingFileHandler(log_path, when="midnight", interval=1, backupCount=12) handler.suffix = "%Y-%m-%d.log" # ファイル名の接尾辞を設定する formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) def main(): log_path = "path/to/your/log/directory/logfile.log" # ログファイルのパスを指定してください setup_logger(log_path) # ログ出力例 logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") if __name__ == "__main__": main() ** その64 [#cd14ddc0] def some_function(): logger = get_logger() logger.info("This is an info message from some_function") def another_function(): logger = get_logger() logger.error("This is an error message from another_function") if __name__ == "__main__": some_function() another_function() import logging import threading class SingletonLogger: _instance = None _lock = threading.Lock() def __new__(cls): if not cls._instance: with cls._lock: if not cls._instance: cls._instance = super(SingletonLogger, cls).__new__(cls) cls._instance._initialize() return cls._instance def _initialize(self): self.logger = logging.getLogger("SingletonLogger") self.logger.setLevel(logging.DEBUG) # Create console handler with a higher log level ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # Create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) # Add the handlers to the logger self.logger.addHandler(ch) def get_logger(self): return self.logger # グローバル関数からシングルトンロガーを取得する関数 def get_logger(): return SingletonLogger().get_logger() ** その65 [#gff1ebff] AWSTemplateFormatVersion: '2010-09-09' Resources: MyLogGroup: Type: 'AWS::Logs::LogGroup' Properties: LogGroupName: !Sub '/aws/workspace/${AWS::StackName}-application-log' RetentionInDays: 7 CloudWatchAgent: Type: 'AWS::SSM::Document' Properties: DocumentType: 'Command' Content: schemaVersion: '2.2' description: 'Install and configure the CloudWatch Agent' mainSteps: - action: 'aws:runPowerShellScript' name: 'configureCloudWatchAgent' inputs: runCommand: - | $config = @" { "logs": { "logs_collected": { "files": { "collect_list": [ { "file_path": "C:\\path\\to\\application.log", "log_group_name": "/aws/workspace/${AWS::StackName}-application-log", "log_stream_name": "{instance_id}" } ] } } } } "@ $config | Out-File -FilePath "C:\\ProgramData\\Amazon\\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.json" -Force Start-Service AmazonCloudWatchAgent Write-Host "CloudWatch Agent configured" WorkspaceInstance: Type: 'AWS::WorkSpaces::Workspace' Properties: BundleId: 'wsb-xxxxxx' # 置き換え必要 DirectoryId: 'd-xxxxxx' # 置き換え必要 UserName: 'your-username' # 置き換え必要 RootVolumeEncryptionEnabled: false UserVolumeEncryptionEnabled: false VolumeEncryptionKey: '' WorkspaceProperties: ComputeTypeName: 'STANDARD' RootVolumeSizeGib: 80 UserVolumeSizeGib: 10 RunningMode: 'AUTO_STOP' RunningModeAutoStopTimeoutInMinutes: 60 DependsOn: CloudWatchAgent CloudWatchErrorMetricFilter: Type: 'AWS::Logs::MetricFilter' Properties: LogGroupName: !Ref MyLogGroup FilterPattern: 'ERROR' MetricTransformations: - MetricValue: '1' MetricNamespace: 'MyApp' MetricName: 'ErrorCount' CloudWatchErrorAlarm: Type: 'AWS::CloudWatch::Alarm' Properties: AlarmDescription: 'Alarm if there are any ERROR messages in the application log' Namespace: 'MyApp' MetricName: 'ErrorCount' Statistic: 'Sum' Period: 300 EvaluationPeriods: 1 Threshold: 1 ComparisonOperator: 'GreaterThanOrEqualToThreshold' AlarmActions: - !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:your-sns-topic' # 置き換え必要 ** その66 [#f039360e] 以下に、CloudFormationテンプレートを使用してIAMロールを作成し、そのロールを使用してWorkspacesで生成されたログファイルをCloudWatchに送信する方法を示します。 CloudFormationテンプレート このテンプレートは、必要なIAMロールとポリシーを作成し、CloudWatch Logsエージェントの設定ファイルを出力するためのものです。 AWSTemplateFormatVersion: '2010-09-09' Resources: CloudWatchLogsIAMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Principal: Service: - 'ec2.amazonaws.com' - 'workspaces.amazonaws.com' Action: - 'sts:AssumeRole' Policies: - PolicyName: 'CloudWatchLogsPolicy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: - 'arn:aws:logs:*:*:*' CloudWatchLogsAgentConfig: Type: 'AWS::SSM::Document' Properties: DocumentType: 'Command' Content: schemaVersion: '2.2' description: 'CloudWatch Logs Agent configuration document' parameters: log_group_name: type: 'String' description: '(Required) CloudWatch Log Group name' log_stream_name: type: 'String' description: '(Required) CloudWatch Log Stream name' log_file_path: type: 'String' description: '(Required) Log file path' mainSteps: - action: 'aws:configureCloudWatchLogs' name: 'configureCloudWatchLogs' inputs: logGroupName: '{{ log_group_name }}' logStreamName: '{{ log_stream_name }}' file: '{{ log_file_path }}' state: 'Enabled' 手順 CloudFormationテンプレートをデプロイ: 上記のテンプレートを cloudformation-template.yaml という名前で保存し、AWS CloudFormationスタックとしてデプロイします。 AWS CLIを使用してスタックを作成する場合: aws cloudformation create-stack --stack-name CloudWatchLogsSetup --template-body file://cloudformation-template.yaml --capabilities CAPABILITY_IAM CloudWatch Logsエージェントの設定: Workspaces上でログファイルをCloudWatch Logsに送信するために、CloudWatch Logsエージェントを設定します。 エージェントの設定ファイルは、上記のテンプレートの一部として SSM Document として作成されます。SSMドキュメントを使用してエージェントを設定します。 以下のようにAWS CLIでSSMドキュメントを実行できます: aws ssm send-command \ --document-name "CloudWatchLogsAgentConfig" \ --targets "Key=instanceIds,Values=your-instance-id" \ --parameters log_group_name="your-log-group",log_stream_name="your-log-stream",log_file_path="C:\path\to\log\file.log" CloudWatch Logsエージェントの設定 インストール: CloudWatch Logsエージェントをインストールします。Windowsの場合、以下のPowerShellコマンドを実行します: powershell -Command "Install-Module -Name AWS.Tools.CloudWatchLogs -Force -AllowClobber" 設定ファイル: 設定ファイルを作成します。以下の例では、Windowsのログファイルパスを指定します。 [general] state_file = C:\ProgramData\Amazon\CloudWatchLogs\state [logstreamname] log_group_name = your-log-group log_stream_name = your-log-stream file = C:\path\to\log\file.log エージェントの開始: エージェントを開始します。Windowsの場合、以下のPowerShellコマンドを実行します: powershell -Command "Start-Service -Name AmazonCloudWatchAgent" この手順に従うことで、Workspaces上のログファイルをCloudWatchに送信するための設定を行うことができます。 ** その67 [#w7a09e31] AWSTemplateFormatVersion: '2010-09-09' Resources: CloudWatchAgentUser: Type: 'AWS::IAM::User' Properties: UserName: 'CloudWatchAgentUser' Policies: - PolicyName: 'CloudWatchAgentAdminPolicy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: 'Allow' Action: - 'cloudwatch:PutMetricData' - 'cloudwatch:PutDashboard' - 'cloudwatch:GetDashboard' - 'cloudwatch:GetMetricData' - 'cloudwatch:ListMetrics' - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' ** その68 [#e2488c1d] import plotly.graph_objects as go # データ months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] # 各グループのデータセット(データの数は任意) groups = { 'Group A': [20, 14, 23, 17, 12, 30, 10, 28, 21, 19, 25, 15], 'Group B': [12, 18, 29, 14, 22, 19, 9, 16, 18, 21, 17, 20], 'Group C': [9, 12, 15, 20, 14, 13, 22, 15, 13, 16, 11, 17], 'Group D': [5, 8, 9, 11, 8, 7, 9, 11, 10, 9, 8, 10], 'Group E': [10, 15, 8, 12, 14, 11, 12, 9, 11, 8, 9, 10] } # カラーパターンを指定 colors = ['blue', 'orange', 'green', 'red', 'purple'] # グラフ作成 fig = go.Figure() # グループデータを動的に追加する for idx, (group_name, values) in enumerate(groups.items()): fig.add_trace(go.Bar( x=months, y=values, name=group_name, marker_color=colors[idx % len(colors)] # カラーを循環させる )) # グラフレイアウトの設定 fig.update_layout( barmode='stack', # 棒を積み上げるモード title='Monthly Stacked Bar Chart', xaxis_title='Month', yaxis_title='Values', xaxis_tickangle=-45 # X軸のラベルを傾ける ) # グラフを表示 fig.show()
テキスト整形のルールを表示する