Python matplotlibでグラフを作る-5（Pythonプログラムをスタンドアロンの実行可能ファイルにする）

#####実行した環境
Ubuntu Stdio 18.04LTS
Python 3.6.5

Pythonのプログラムを実行ファイルに出来るらしいので、やってみました。
最初にBaseMapの地図をやってみましたが、ModuleNotFoundError: No module named 'mpl_toolkits'がでて出来ませんでした。
cartopyで作成した地図もエラーがでました。すべてのスクリプトが実行ファイルに変換できることでもないようです。

グラフは出来るか確認したら出来ました。

2020/07/16
以前使用していた古いPCにUbuntuStdio 20.04LTSをインストールしファイルをコピーして実行させるとちゃんと動作しました。
--onefile　（１つのファイル）にしているせいか、pythonで動作させるより遅かったですが、Pythonを使用していない人にも配布できますね。一番下にショートカットを作成する方法も追記しました。ダブルクリックで実行できます。

###インストール(Ubuntu Stdio 18.04LTSの場合)

```shell-session
$ pip3 search pyinstaller
PyInstaller (3.3.1)           - PyInstaller bundles a Python application and all its dependencies into a single package.

$ pip3 install PyInstaller
```

これで、pyinstallerは/home/ty/.local/binにインストールされていました。(Ubuntu Stdio 18.04LTSの場合)

Python matplotlibでグラフを作る-4（選挙の投票率）
https://qiita.com/ty21ky/items/f150875dab1b2d503647
で作成したプログラムでやってみました。

```python:投票率.py
#!/usr/bin/python3
# coding: UTF-8

import matplotlib.pyplot as plt
import csv

filename_before = '前回投票率.csv'
filename = '投票率.csv'

#前回のデータと今回の期日前投票の票数等
votes_before = []

with open(filename_before) as f_before:
    reader_before = csv.reader(f_before)

    next(reader_before)

    for row_before in reader_before:
        #votes_before.append(float(row_before[0]))
        votes_before.append(row_before[0])

#今回の投票数
votes = []

with open(filename) as f:
    reader = csv.reader(f)

    next(reader)

    for row in reader:
        votes.append(float(row[0]))  #何時の投票数

start_hour = 8
end_hour = 20
end_hour1 = len(votes) + 7
vote_hours = range(start_hour, end_hour + 1)
vote_hours1 = range(start_hour, end_hour1 + 1)  #当日用
hour_range = [start_hour, end_hour]
rate_range = [0, 100]
hour_tics = range(start_hour, end_hour + 1)
rate_tics = range(0, 100 + 5, 5)

# 前回選挙  Last Election
l_e_label = votes_before[5]  # 凡例（日本語を指定するとエラー）
l_e_n_v_t = float(votes_before[6])  # (%) 前回の期日前投票率
l_e_votes = [
    float(votes_before[7]),      #  8時の投票率
    float(votes_before[8]),      #  9時の投票率
    float(votes_before[9]),      # 10時の投票率
    float(votes_before[10]),      # 11時の投票率
    float(votes_before[11]),     # 12時の投票率
    float(votes_before[12]),     # 13時の投票率
    float(votes_before[13]),     # 14時の投票率
    float(votes_before[14]),     # 15時の投票率
    float(votes_before[15]),     # 16時の投票率
    float(votes_before[16]),     # 17時の投票率
    float(votes_before[17]),     # 18時の投票率
    float(votes_before[18]),     # 19時の投票率
    float(votes_before[19]),  # 最終投票率
]

# 今回選挙
t_t_label = votes_before[0]  # 凡例（日本語を指定するとエラー）
election_name = votes_before[1]  # 選挙名称
election_date = votes_before[2]  # 選挙日付
number_of_voters = float(votes_before[3])  # この選挙時における選挙人名簿登録者数
number_of_votes_before_due_date = float(votes_before[4])  # 期日前投票数

# 各時間の投票率

voter_turnout = [vote / number_of_voters * 100 for vote in votes]

# novbdd_voter_turnout 期日前投票率
n_v_t = number_of_votes_before_due_date / number_of_voters * 100

# print(n_v_t)

font = {'family': 'IPAGothic'}  # 日本語Fontを指定

plt.xlim(hour_range)
plt.ylim(rate_range)

plt.xlabel('（時）', **font)
plt.ylabel('投票率(%)', **font)

plt.xticks(hour_tics)
plt.yticks(rate_tics)
plt.grid(color='gray', linestyle='--')

# 当日合計投票率
plt.plot(vote_hours1, [v + n_v_t for v in voter_turnout],
         linewidth=5, color='red', label=t_t_label)
# 前回の合計投票率
plt.plot(vote_hours, [v + l_e_n_v_t for v in l_e_votes],
         linestyle='--', linewidth=5, color='gray', label=l_e_label)
# 当日投票率
plt.plot(vote_hours1, voter_turnout,
         color='red', label=t_t_label)
# 前回の当日投票率
plt.plot(vote_hours, l_e_votes,
         linestyle='--', color='gray', label=l_e_label)
# 期日前投票率
plt.plot(hour_range, [n_v_t, n_v_t],
         color='red', label=t_t_label)
# 前回の期日前投票率
plt.plot(hour_range, [l_e_n_v_t, l_e_n_v_t],
         linestyle='--', color='gray', label=l_e_label)
# グラフの凡例
plt.legend(loc='upper left')
plt.title('{}  {}  投票率'.format(election_date, election_name), **font)
# 凡例でfontを指定するとエラーになるためtextで表示
plt.text(10.5, 90, '合計投票率', color="black", fontsize=20, **font)
plt.text(10.5, 78, '当日投票率', color="black", fontsize=20, **font)
plt.text(10.5, 66, '期日前投票率', color="black", fontsize=20, **font)

#plt.savefig('投票率.png')  #pngで保存
plt.show()
```
投票率.csv

```shell-session
投票数
0
38736.4992
77472.9984
120359.8368
146722.176533333
173084.516266667
199446.856
244255.147733333
289063.439466667
333871.7312
378680.022933333
423488.314666667
468296.6064
```
前回投票率.csv

```shell-session
投票率
2018
滋賀県知事選挙
6月24日
1152872
129243
2014
8.98887913113647
0
5.29
9.46
14.41
17.92
21.43
24.94
27.76
30.58
33.305
36.03
39.47
50.15
```
私の環境の場合(pyinstallerがインストールされているフォルダにパスが通っていないので、フルパスを指定しています。)

```shell-session
$ /home/ty/.local/bin/pyinstaller --onefile 投票率.py
```
--onefileオプションをつけると、ファイルが１つになり便利ですが、遅くなると何処かに書いていました。

を実行すると、__pycache__フォルダ、buildフォルダ、distフォルダ、投票率.specファイルが作成されました。

このdistフォルダの中に、投票率と言う実行ファイルが出来ていました。

```shell-session
$ ./dist/投票率
```
を実行するとちゃんとグラフが表示されました。

Windows,Macは参考になるサイトが沢山ありましたが、Ubuntuは、あっても大分前のverだったりしてあまり参考になりませんでした。

### 作成された実行ファイルのショートカットを作成してダブルクリックで実行できるようにする

参考
https://qiita.com/ty21ky/items/c2357b6cf24fda49280e

１．作成された実行ファイルに実行権限を与えます。

```shell-session
chmod +x 「ファイル名」
```

2.ICONを作成するか、ダウンロードするか、ルートで検索すれば沢山存在します。
32x32ピクセルの.pngを作成する。

３．ショートカットを作成する。

```shell-session
[Desktop Entry]
Name=ショートカットに表示される名称（ファイル名は表示されません）
Comment=アプリの説明
Exec=/home/○○/・・・・/application（実行ファイル名-フルPathにしておくと、何処にでも移動出来る）
Icon=/home/○○/・・・・/application.png
Terminal=false      //ターミナルを起動する必要がある場合はtrueにする。計算結果等はすぐに閉じてしまうので処理が必要
Type=Application
```

４．ショートカットに実行権限を与えなくとも、ダブルクリックと聞いてくる。
完了

参考
https://github.com/pyinstaller/pyinstaller/wiki
ここに、Manual・サポートされるパッケージ等があります。