🍞

Processingの自由課題をノープランで締め切り1時間半前から作る

2024/12/09に公開

なんと、あと1時間半で、Processingの大学の自由課題の締め切りとなってしまいました。

本当はこの日までにProcessingを完全に理解した状態になる予定だったのですが、まだ20%くらいしか理解できた気がしません。しかし締め切りは締め切りなので、これから1時間半で質の低い作品を作り、なんとか出すしかないという状況です。(ちなみに正午締め切りなのに起きるのが遅かったので、こんなに追い込まれてしまいました...)

がんばります(泣)

まずは以下のサイトで使用データをきめるところからです。

https://ourworldindata.org/data

10分経過

見ていて気になったデータを適当に箇条書きでメモしていきます。

  • 過去1000年の京都の桜の満開日のデータ。気候変動の影響で満開日が早まっているようです。これに関しては、サイト内のグラフがすでに完璧に近い気がするので、どのようにアレンジするかが難しそうです

https://ourworldindata.org/grapher/date-of-the-peak-cherry-tree-blossom-in-kyoto?time=earliest..1368

  • 世界の国々の幸福度のデータです。自分は普段ゼミで幸福度についてアンケートデータなどを使って調べているので、普通に普段やってることと近くて興味があります。余裕があったら(ないのですが)国の経済状況などのほかのデータと組み合わせてみたいです

https://ourworldindata.org/grapher/happiness-cantril-ladder?tab=chart

  • 世界の国々の1人あたりカロリー供給量のデータです。円の大きさで図示するかわりにパンの大きさで図示したりしてみたい

https://ourworldindata.org/grapher/daily-per-capita-caloric-supply?tab=table

めっちゃ迷ってしまうので、次の10分で使うデータまで決めたいです

20分経過

  • 世界の国々の、政府の社会関係予算?の構成比です。日本の予算の構成が世界の国々と比べてどのような特徴があるかということは結構気になります。予算の特徴ごとに色分けしたりしてみたい

https://ourworldindata.org/grapher/social-expenditure-as-percentage-of-gdp?tab=table

いろいろ悩みますが、とりあえず一番安パイな気がする1人あたりカロリー供給量のデータを使おうと思います。

https://ourworldindata.org/grapher/daily-per-capita-caloric-supply?tab=table

地図上に、1人あたりカロリー供給量に応じて大きさが異なる円をプロットする、という、テキストにのっていた人口密度のプロットのやり方とほぼ同じコードで出来そうなコードだけ一旦作って、本当に間に合わなくてヤバいとなったらそれをそのまま出そうと思います。

30分経過

CSVファイルをダウンロードして中を見ると、このように国と年のペアごとに入っていました。今回は2021年のデータだけ欲しいです。

いかにも急いでやった、やっつけ仕事的なPythonコードで、2021年の世界の国々の行だけ取り出しました。(よく考えると、これするだけなら全然Excelで出来たかも)

with open("daily-per-capita-caloric-supply.csv", encoding="utf-8") as f:
    data1 = f.read().split("\n")

header_row = data1[0]

result = header_row + "\n"

for row in data1[1:]:
    items = row.split(",")
    country_code = items[1]
    year = items[2]
    if year == "2021" and country_code != "":
        print(items)
        result += ",".join(items) + "\n"

result = result.rstrip("\n")

with open("calory-data-2021.csv", encoding="utf-8", mode="w") as f:
    f.write(result)

2021年だけになりました。

よく考えると国ごとの緯度経度のデータもどこかから入手しなきゃじゃん!と気づいたので(テキストにあった人口密度の図示するやつは世界の国々じゃなくて世界の都市だった)、ちょっと探してみます

40分経過

おっ使えそうじゃーんと思ったネット上のCSVデータが、国コードの付け方が、カロリーのデータと異なっていて、そんなぁ...となってます。
https://developers.google.com/public-data/docs/canonical/countries_csv

どうやら国コードも2文字のコードや3文字のコードなどいくつか種類があるらしいです。

https://www.asahi-net.or.jp/~ax2s-kmtn/ref/iso3166-1.html

カロリーのデータと同じ3文字の国コードの規格の、国ごとの緯度経度データも、なんとか見つけることができました。これとカロリーのデータを対応させていきます。

https://gist.github.com/tadast/8827699

50分経過

ひたすらカロリーのデータと緯度経度のデータを対応させるための作業をPythonでしています。かたくなにread_csv()を使わずread()で読み込んでいるせいでクソコード化が進んでいます。

with open("daily-per-capita-caloric-supply.csv", encoding="utf-8") as f:
    data_calory = f.read().split("\n")[1:]

with open("countries_codes_and_coordinates.csv", encoding="utf-8") as f:
    data_coordinates = f.read().split("\n")[1:]

latitude_dict = {}
longitude_dict = {}

for row in data_coordinates:
    items = row.split('"')
    items2 = []
    for item in items:
        if item.strip() not in [",",""]:
            items2.append(item) 
    latitude_dict[items2[2]] = items2[-2]
    longitude_dict[items2[2]] = items2[-1]

result =  "ido,keido,calory\n"

for row in data_calory:
    items = row.split(",")
    country_name = items[0]
    country_code = items[1]
    year = items[2]

    if year == "2021" and country_code not in ["","OWID_WRL"]:

        print(latitude_dict[country_code], longitude_dict[country_code])

        result += f"{latitude_dict[country_code]},{longitude_dict[country_code]},{items[3]}\n"

result = result.rstrip("\n")

with open("calory-ido-keido.csv", encoding="utf-8", mode="w") as f:
    f.write(result)

なんとかこんな感じでできました。本日まだProcessingを一度も起動していないので、大急ぎで起動します

1時間経過

現状のこのような感じです。CSVファイルをエクスプローラーからポチポチ追加したりするのに無駄にてこずってしまい、あまり進んでいないです。がんばります。

PImage 世界地図の画像 = loadImage("world.png");
size(1080, 540);
image(世界地図の画像, 0, 0);

Table= loadTable("calory-ido-keido.csv", "header");
int 行数 =.getRowCount();

println(行数);

1時間40分経過

現在の進捗です。

ううーーーーっ
うわーーーーーっ

(すべて自業自得でしかないですが...)

最終的なコードは以下です。

PImage 世界地図の画像 = loadImage("world.png");

PImage 大きいパン = loadImage("big_v2.png");
PImage ふつうのパン = loadImage("normal.png");
PImage 小さいパン = loadImage("small.png");

size(1080, 540);
image(世界地図の画像, 0, 0);

Table= loadTable("calory-ido-keido.csv", "header");
int 行数 =.getRowCount();

for (int i=0;i<行数;i++){
  float 緯度 =.getRow(i).getFloat("ido");
  float 経度 =.getRow(i).getFloat("keido");
  float カロリー供給量 =.getRow(i).getFloat("calory");
  
  float x = map(経度, -180, 180, 0, 1080);
  float y = map(緯度, -90, 90, 540, 0);
  
  if (カロリー供給量 > 3200){
    image(大きいパン, x, y, 30, 30);
  } else if (カロリー供給量 > 2500){
    image(ふつうのパン, x, y, 30, 30);
  } else {
    image(小さいパン, x, y, 30, 30);
  } 
}

実行結果はこんな感じです。

供給カロリー3段階でパンの画像を変更しています。

割と何でも許される授業なんじゃないかと思ってこれで出してるんですが、普通に遅れたからとかじゃなく内容がしょぼすぎて落とされたらどうしよう(汗)

結論

Processingの自由課題をノープランで締め切り1時間半前から作るのは、無理

最後までお読みいただきありがとうございました。

Discussion