乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

プログラミング

今回は最適化問題を解くことが出来る
OR-Toolsについてです。

解説動画はこちら




OR-Toolsとは


Googleが開発している、組合せ最適化のためのライブラリ

様々な最適化問題を解くためのソルバーが充実していて
C++実装だが、Pythonなどいろいろな言語で使えます。


解ける最適化問題

次のような最適化問題を解くことができます。


1.配送ルート最適化
巡回セールスマン問題 : 1台の車両で最短経路を回る
配送計画問題 : 複数台の車両で分担して配送する

2.スケジューリングと制約プログラミング
決められた制約を全て満たしつつ、最適なスケジュールを組む
従業員のシフト作成
工場のライン計画

3.線形計画・整数計画(LP, MIP)
目的関数を最大化、または最小化する問題を数式で解く手法
生産計画 : 在庫と予算の範囲内で利益の最大化
リソース配分 : 予算内での広告効果最大化の割り当て

4.詰込み・割当問題
ナップサック問題 : 容量制限のあるバッグに価値が最大になるよう詰める
ビンピッキング問題 : サイズの異なる荷物を出来るだけ少ないトラックに詰める

5.ネットワークフロー
最大流問題 : パイプラインで一度に流せる最大量を求める
最小費用問題 : 指定量の輸送で、コストが最も安くなるルートと量の特定


インストール

Google Colab でも無いみたいなので、入れる必要あります。
pip install ortools


OR-Toolsの基本的な使い方

1.ライブラリの読み込み

解く問題に応じて、対応するライブラリを読み込みします
# CP-SATソルバー(制約プログラミング/MIP)
from ortools.sat.python import cp_model

# 線形計画法ソルバー(LP)
from ortools.linear_solver import pywraplp

# 配送計画(Routing)
from ortools.constraint_solver import pywrapcp, routing_enums_pb2

2. 最適化モデル構築

次に最適化モデルを作ります。
基本の「4ステップ」があります。

STEP 1: モデルのインスタンス作成
まず、問題を定義するための「箱」を作ります。

from ortools.sat.python import cp_model

model = cp_model.CpModel()


STEP 2: 変数の作成
「何を求めたいか」を変数として定義します。

整数変数: model.NewIntVar(下限, 上限, '変数名')
ブール変数: model.NewBoolVar('変数名')


STEP 3: 制約条件の追加
model.Add(...) を使って、守らなければならないルールを記述します。

等式・不等式: model.Add(x + y <= 10)
論理制約: 「Aの時だけBを適用する」といった
条件付き制約(OnlyEnforceIf)も可能


STEP 4: 目的関数の設定と実行
「何を最大化(または最小化)したいか」を決め
ソルバーを起動します。

# 最小化の場合
model.Minimize(目的の式)

# ソルバーの起動
solver = cp_model.CpSolver()
result = solver.Solve(model)

ここまでのコードを作れば
最適化問題が解ける様になっていると思います。


問題を解いてみる

簡単なつるかめ算をやって
あっているかを確認してみましょう。


問題1:
「つる」と「かめ」が合計で10匹、足の合計は28本です
それぞれ何匹ずついるでしょうか?

コードはこんな感じになります。
from ortools.sat.python import cp_model

def solve_tsurukame():
    # モデルの作成
    model = cp_model.CpModel()

    # 変数の定義 (0匹以上10匹以下)
    tsuru = model.NewIntVar(0, 10, 'tsuru')
    kame = model.NewIntVar(0, 10, 'kame')

    # 制約1: 合計が10匹
    model.Add(tsuru + kame == 10)

    # 制約2: 足の合計が28本
    model.Add(2 * tsuru + 4 * kame == 28)

    # ソルバーの準備と実行
    solver = cp_model.CpSolver()
    result = solver.Solve(model)

    if result == cp_model.OPTIMAL:
        print(f'つる: {solver.Value(tsuru)} 羽')
        print(f'かめ: {solver.Value(kame)} 匹')

solve_tsurukame()
つる: 6 羽
かめ: 4 匹


問題2:
50円切手と80円切手が計20枚、合計で1240円になるとき
それぞれ何枚ずつあるでしょうか?

from ortools.sat.python import cp_model

def solve_stamps():
    model = cp_model.CpModel()

    # 変数の定義 (0枚以上20枚以下)
    s50 = model.NewIntVar(0, 20, '50yen')
    s80 = model.NewIntVar(0, 20, '80yen')

    # 制約1: 合計20枚
    model.Add(s50 + s80 == 20)

    # 制約2: 合計金額が1240円
    model.Add(50 * s50 + 80 * s80 == 1240)

    solver = cp_model.CpSolver()
    result = solver.Solve(model)

    if result == cp_model.OPTIMAL:
        print(f'50円切手: {solver.Value(s50)} 枚')
        print(f'80円切手: {solver.Value(s80)} 枚')

solve_stamps()
50円切手: 12 枚
80円切手: 8 枚



問題3:

動画内ではすこし難しめの
入試問題なんかもやっています。

是非みてみてください。



まとめ


OR-Toolsは最適化問題を解くのに、かなり有効なライブラリです。

実社会の巨大な課題にも応用可能で
「Amazonのような配送ルート作成」や
「学校の複雑な時間割作成」など
他にもいろいろな最適化に応用できるものがあります。

だだし、使いこなすにはちょっとした
数学の知識が必要かもしれません。

使いこなせるとかなり問題を解ける幅が広がるので
実社会の問題解決にかなり有利かもしれません。

是非使ってみてください
それでは。



 

今回はPythonからRustを呼び出して
超高速化する方法についてです。

解説動画はこちら




Pythonは書きやすくて便利だけど
他の言語に比べるとどうしても遅い。


そんな時はRustの高速なネイティブコードを
Pythonから呼び出して計算速度を上げられます。


Python-Rust連携の方法

maturin

Rustで書かれたコードをPythonのパッケージ(wheel形式)
としてビルド・公開するためのビルドツールです。

これを使ってPythonとRustを連携させます。

主な手順は以下です。
1.Rust と maturin をインストール
2.Rust拡張用のプロジェクトを作る
3.Rustコードを作る
4.Cargo.toml を修正する
5.Python用拡張としてビルドする

早速手順を見ていきましょう。

なおGoogle ColabでのRust-Python連携方法になります。
自前のPCだとかだと、少し手順は変わってきます。

1.Rust と maturin をインストール

まず初めはColab内に必要なものをインストールします
# Rust をインストール
!curl https://sh.rustup.rs -sSf | sh -s -- -y -q
import os
os.environ["PATH"] = f"{os.environ['HOME']}/.cargo/bin:" + os.environ["PATH"]
!rustc --version
!cargo --version
!pip install -U maturin
!maturin --version

2. Rust拡張用のプロジェクトを作る
デフォルトのディレクトリはcontentになっているので
その中にプロジェクトを作り移動します。
!maturin init fastcalc
%cd /content/fastcalc

UIのフォルダマークからディレクトリが
作成されていると思います。


3. Rustコードを作る

すでにあるコードを上書きする形で
コードを書き換えます。
ここでは簡単な計算を行うコードを指定して
関数を作っています。

%%writefile src/lib.rs
use pyo3::prelude::*;

#[pyfunction]
fn sum_squares(n: u64) -> u64 {
    let mut s = 0;
    for i in 0..n {
        s += i * i;
    }
    s
}

#[pymodule]
fn fastcalc(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_squares, m)?)?;
    Ok(())
}

4. Cargo.toml を修正

設定用のファイルも上書きします。

%%writefile Cargo.toml
[package]
name = "fastcalc"
version = "0.1.0"
edition = "2021"

[lib]
name = "fastcalc"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.21", features = ["extension-module"] }

5. Python用拡張としてビルド

RustコードをPythonライブラリとしてビルドします。

# Python環境から Rust を見えるように PATH を追加
!export PATH="$HOME/.cargo/bin:$PATH"

# wheel を作る
!maturin build --release

# wheel を pip install
!pip install target/wheels/*.whl

6.Pythonから Rust 関数を呼ぶ

1-5までが出来ていたら
ライブラリを呼び出して、Rustの関数が実行できます。

import fastcalc
fastcalc.sum_squares(100_000_000)

7.Python版と速度比較

これで速度比較が出せると思います。

import time

def sum_squares_py(n):
    s = 0
    for i in range(n):
        s += i * i
    return s

N = 100_000_000

t0 = time.time()
sum_squares_py(N)
t1 = time.time()
python_time = t1 - t0

t2 = time.time()
fastcalc.sum_squares(N)
t3 = time.time()

rust_time = t3 - t2
print("Python: {:.8f} sec".format(python_time))
print("Rust  : {:.8f} sec".format(rust_time))
print("Rust vs Python : {:.10f}".format(python_time / rust_time))

どれくらいの速度差になるかは
是非動画の方を見てみてください。

動画内ではもう一つの
シミュレーションも行っていますので
参考になると思います。



まとめ

maturinを使ったRustコードのPython拡張を作って実行できるようにすると
実行速度が高速な関数を呼び出せるようになります。


Pythonの簡単さはそのままに、重い計算はRustに任せる
これが Python × Rust 連携の最強パターンです。


最近はPolarsなどの大量データ処理や
深層学習モデルの構築や推論なども
Rust製ライブラリが増えてきています。

無いものは自分で作れると
自作の処理の時短になって
めちゃくちゃ捗ります。

今日はここまでです
それでは。

今回はGeoPandasとFoliumによる
地理データの取り扱い方です。


解説動画はこちら


 
Pythonで地理データを取り扱う方法


今回は地理データを取り扱う方法として
2つのライブラリをご紹介します。


GeoPandas

Pandasライブラリに
空間(Geometry)を実現したライブラリ

Pandasの DataFrame を拡張
各行に 1つのジオメトリ(形状) を持つ
GIS(地理情報システム)向けの演算が可能
静的なplotが行える


Folium

Leaflet.js を
Python から操作する描画用ライブラリ

出力は HTML
OpenStreemMapをタイルレイヤとして表示できる
Jupyter / Web / 静的ファイルで使える
インタラクティブな描画が行える

ということでこの2つを用いて
地理データを描画していきましょう。



GeoPandasを用いた地理描画

最初はGeoPandasを用いた描画です
Google colabで実行できるコードになっていますが
Google colabでは日本語が取り扱えないので
別途ライブラリが必要です。


ライブラリのインストール

日本語を使用するため
japanize-matplotlib
をインストールしておきます。
pip install japanize-matplotlib


架空のデータを読み込んで描画する


まず初めは、何もない状態から
架空のデータを使っていきます。

pandasに読み込んだ後
GeoPandasに緯度経度として読み込みします。
# -----------------
# 1. データの準備 (架空のオープンデータ)
# -----------------

# (A) 地理データ: 都道府県庁所在地のポイントデータ (GeoJSONを想定)
# 緯度・経度と都道府県名が含まれるGeoDataFrameを作成
data_geo = {
    'city': ['Sapporo', 'Sendai', 'Tokyo', 'Nagoya', 'Osaka', 'Fukuoka'],
    'prefecture': ['北海道', '宮城', '東京', '愛知', '大阪', '福岡'],
    'latitude': [43.06, 38.27, 35.69, 35.18, 34.69, 33.59],
    'longitude': [141.35, 140.87, 139.69, 136.91, 135.50, 130.40]
}
df_geo = pd.DataFrame(data_geo)

# GeoDataFrameに変換
# 'geometry'カラムを作成し、緯度・経度からポイント(点)の地理情報を持たせる
gdf_city = gpd.GeoDataFrame(
    df_geo,
    geometry=gpd.points_from_xy(df_geo.longitude, df_geo.latitude),
    crs="EPSG:4326"
)
print("GeoDataFrameの確認:\n", gdf_city.head())
GeoDataFrameの確認:
       city prefecture  latitude  longitude              geometry
0  Sapporo        北海道     43.06     141.35  POINT (141.35 43.06)
1   Sendai         宮城     38.27     140.87  POINT (140.87 38.27)
2    Tokyo         東京     35.69     139.69  POINT (139.69 35.69)
3   Nagoya         愛知     35.18     136.91  POINT (136.91 35.18)
4    Osaka         大阪     34.69     135.50   POINT (135.5 34.69)


データに少し加工を加え、情報を足します。
# (B) 属性データ: 都道府県ごとの人口データ
# 都道府県ごとの人口属性データフレーム
data_attr = {
    'prefecture': ['北海道', '宮城', '東京', '愛知', '大阪', '福岡'],
    'population_mil': [5.2, 2.3, 14.0, 7.5, 8.8, 5.1], # 単位: 百万人
    'density_class': ['Low', 'Mid', 'High', 'High', 'High', 'Mid']
}
df_attr = pd.DataFrame(data_attr)

# -----------------
# 2. データの結合 (Merge)
# -----------------
# 'prefecture'カラムをキーにしてGeoDataFrameと属性データを結合
gdf_merged = gdf_city.merge(df_attr, on='prefecture')
print("\n結合後のGeoDataFrameの確認:\n", gdf_merged[['prefecture', 'population_mil', 'geometry']].head())
結合後のGeoDataFrameの確認:
   prefecture  population_mil              geometry
0        北海道             5.2  POINT (141.35 43.06)
1         宮城             2.3  POINT (140.87 38.27)
2         東京            14.0  POINT (139.69 35.69)
3         愛知             7.5  POINT (136.91 35.18)
4         大阪             8.8   POINT (135.5 34.69)


次のコードで簡易なプロットを行えます。
# 結合したデータを基にGeoPandasで簡易プロット
gdf_merged.plot(column='population_mil', legend=True, figsize=(5, 5),
                markersize=gdf_merged['population_mil'] * 10)
plt.title("GeoPandasによる簡易プロット (人口規模)")
plt.show()
スクリーンショット 2025-12-13 17.24.29

緯度経度だけを用いて描画していますが
これだけだと、あまり意味がない描画ですね

これをFoliumで描画しなおします。
# Foliumの描画準備 (日本の中心付近にマップを初期化)
map_center = [35.68, 139.69] # 東京の緯度・経度
m = folium.Map(location=map_center, zoom_start=5)

# -----------------
# 1. シンプルなマーカー表示 (庁所在地)
# -----------------
for idx, row in gdf_merged.iterrows():
    # ポップアップに表示する情報をHTMLで作成
    html = f"""
        

{row['prefecture']}庁所在地

人口: {row['population_mil']}百万人

密度区分: {row['density_class']}

""" iframe = folium.IFrame(html) popup = folium.Popup(iframe, min_width=200, max_width=300) # Markerを追加 folium.Marker( location=[row.latitude, row.longitude], popup=popup, icon=folium.Icon(color='blue', icon='info-sign') ).add_to(m) # ----------------- # 2. ヒートマップの追加 (人口密度に応じて色を濃く) # ----------------- from folium.plugins import HeatMap # HeatMapに必要なデータ形式: [[緯度, 経度, 強度], ...] # 強度として人口(百万)を使用 heat_data = [[row.latitude, row.longitude, row.population_mil] for idx, row in gdf_merged.iterrows()] HeatMap(heat_data).add_to(m) # ----------------- # 3. GeoPandasとFoliumを組み合わせた応用描画 # Foliumでは、CircleMarkerを使って、データを視覚的に表現できます。 def get_color(density): if density == 'High': return 'red' elif density == 'Mid': return 'orange' else: return 'green' for idx, row in gdf_merged.iterrows(): folium.CircleMarker( location=[row.latitude, row.longitude], radius=row['population_mil'] * 1.5, # 人口規模に応じて円の大きさを変更 color=get_color(row['density_class']), fill=True, fill_color=get_color(row['density_class']), fill_opacity=0.7, tooltip=f"{row['prefecture']}: {row['population_mil']}M" ).add_to(m) # マップをHTMLファイルとして保存 m.save("interactive_map.html") print("\nFoliumマップオブジェクトを作成しました。")

Foliumでは作った地図を
静的なHTMLとして保存ができます。

Google Colabでは
デフォルトのフォルダに
HTMLファイルが出力されると思います。

変数 m を実行すると
中身を描画することもできます。

スクリーンショット 2025-12-13 17.21.28

こんな感じで、架空のデータですが
地図上に描画できました。

Foliumはインタラクティブに操作できるので
色々遊べます。



500キロメートル圏内を描画する


GeoPandasで緯度経度から少し計算して
描画用のデータを作ることができます。

まずは距離を測るためのCRSというデータへ変換します。
# -----------------
# 1. CRSの変換 (距離計算のため)
# -----------------
# 緯度・経度 (4326) からメートル単位のCRS (3857) へ変換
gdf_projected = gdf_merged.to_crs("EPSG:3857")
print("\nCRS変換後のGeoDataFrame (EPSG:3857):\n", gdf_projected.head())
       city prefecture  latitude  longitude                          geometry  \
0  Sapporo        北海道     43.06     141.35  POINT (15735010.024 5321108.922)   
1   Sendai         宮城     38.27     140.87  POINT (15681576.668 4617638.286)   
2    Tokyo         東京     35.69     139.69  POINT (15550219.669 4258049.263)   
3   Nagoya         愛知     35.18     136.91  POINT (15240751.485 4188369.409)   
4    Osaka         大阪     34.69     135.50  POINT (15083791.002 4121832.777) 



これで計算する用意ができたので
Foliumにデータを加えます。
# -----------------
# 2. バッファリング (空間分析)
# -----------------
# 東京、大阪、名古屋の庁所在地から「500km圏内」のバッファを作成
# 単位はメートルなので 500 * 1000 = 500,000メートル
buffer_distance = 500 * 1000

# GeoPandasのbuffer()メソッドでバッファを作成
# わかりやすさのため、東京の行(index=2)のみを抽出
tokyo_buffer = gdf_projected.iloc[[2]].buffer(buffer_distance)

# バッファを元のCRS (4326) に戻し、Foliumで表示できるようにする
tokyo_buffer_wgs84 = tokyo_buffer.to_crs("EPSG:4326")

# -----------------
# 3. Foliumでの分析結果の可視化
# -----------------

# 新しいFoliumマップを作成
m_analysis = folium.Map(location=map_center, zoom_start=5)

# バッファリング結果 (Polygon) をFoliumに描画
folium.GeoJson(
    tokyo_buffer_wgs84.__geo_interface__, # GeoPandasオブジェクトをGeoJSON互換の形式に変換
    name='500km Buffer from Tokyo',
    style_function=lambda x: {
        'fillColor': 'purple',
        'color': 'purple',
        'weight': 2,
        'fillOpacity': 0.3
    }
).add_to(m_analysis)

# マーカーとヒートマップも再表示 (任意)
for idx, row in gdf_merged.iterrows():
    folium.Marker(
        location=[row.latitude, row.longitude],
        popup=f"{row['prefecture']} - {row['population_mil']}M"
    ).add_to(m_analysis)

# マップにレイヤー切り替え機能を追加して見やすくする
folium.LayerControl().add_to(m_analysis)
m_analysis.save("analysis_map.html")

今度は m_analysis という変数の中身を見てみると
スクリーンショット 2025-12-13 17.22.35

こんな感じで東京から500キロメートル圏内を
塗ることができました。



CSVファイルを読み込みして描画する


今度は架空ではなく
実際のデータで描画してみましょう。

地震のデータがあるので
これを用います。

地震データの取得先
https://www.data.jma.go.jp/eqdb/data/shindo/

このサイトから検索して
CSVファイルにして
Google Colabのファイル置き場に配置します。

CSVを読み込みします。
import pandas as pd
import folium
from folium.plugins import MarkerCluster
from io import StringIO
import re

# ----------------------------------------------------
# 1. データ準備
# ----------------------------------------------------
csv_data = """地震の発生日,地震の発生時刻,震央地名,緯度,経度,深さ,M,最大震度
2025/12/10,23:52:24.1,青森県東方沖,40°50.1′N,142°45.3′E,36 km,6.0,震度4
2025/12/09,18:09:45.9,青森県東方沖,41°16.0′N,142°25.1′E,47 km,5.3,震度3
2025/12/09,06:52:42.7,青森県東方沖,40°56.6′N,143°18.0′E,15 km,6.6,震度4
2025/12/09,03:56:29.5,青森県東方沖,40°57.0′N,143°07.6′E,19 km,6.1,震度3
2025/12/08,23:33:39.2,青森県東方沖,40°53.0′N,142°35.2′E,42 km,5.9,震度3
2025/12/08,23:15:10.1,青森県東方沖,40°58.0′N,142°17.2′E,54 km,7.5,震度6強
2025/12/05,12:11:24.1,熊本県阿蘇地方,32°58.5′N,131°06.8′E,4 km,3.3,震度3
"""
# df = pd.read_csv(StringIO(csv_data))
df = pd.read_csv('地震リスト.csv')
df.head(3)<
地震の発生日 地震の発生時刻 震央地名 緯度 経度 深さ 最大震度
0 2025/12/10 23:52:24.1 青森県東方沖 40°50.1′N 142°45.3′E 36 km 6.0 震度4
1 2025/12/09 18:09:45.9 青森県東方沖 41°16.0′N 142°25.1′E 47 km 5.3 震度3
2 2025/12/09 06:52:42.7 青森県東方沖 40°56.6′N 143°18.0′E 15 km 6.6 震度4


緯度経度などのデータが
そのままでは使えないので加工します。

def convert_dms_to_decimal(dms_str):
    """ '40°50.1′N' のような文字列を十進数形式に変換する関数 """
    match = re.match(r"(\d+)°(\d+\.?\d*)′([NSEW])", dms_str)
    if not match:
        return None
    
    degrees = float(match.group(1))
    minutes = float(match.group(2))
    direction = match.group(3)
    decimal = degrees + minutes / 60
    
    # 南緯(S)と西経(W)はマイナスにする
    if direction in ('S', 'W'):
        decimal *= -1  
    return decimal

# 緯度と経度を数値に変換
df['緯度_dec'] = df['緯度'].apply(convert_dms_to_decimal)
df['経度_dec'] = df['経度'].apply(convert_dms_to_decimal)

# 震度を強度順に数値化するための辞書
shindo_mapping = {
    '震度1': 10,
    '震度2': 20,
    '震度3': 30,
    '震度4': 40,
    '震度5弱': 51,
    '震度5強': 55,
    '震度6弱': 61,
    '震度6強': 65,
    '震度7': 70,
}

# 震度を数値に変換
df['shindo_value'] = df['最大震度'].map(shindo_mapping)

def get_shindo_color(shindo):
    # 震度値 (30, 40, ..., 70) を利用
    if shindo >= 65:  # 震度6強, 震度7
        return 'darkred'
    elif shindo >= 55: # 震度5強, 震度6弱
        return 'red'
    elif shindo >= 51: # 震度5弱
        return 'orange'
    elif shindo >= 40: # 震度4
        return 'lightred'
    elif shindo >= 30: # 震度3
        return 'green'
    else:
        return 'gray' # その他

描画を行います。
# ----------------------------------------------------
# 1. Folium マップの作成
# ----------------------------------------------------
# 日本の中心付近を初期位置とする
map_center = [df['緯度_dec'].mean(), df['経度_dec'].mean()]
m = folium.Map(location=map_center, zoom_start=5)

# ----------------------------------------------------
# 2. 震度ごとに FeatureGroup (レイヤー) を作成
# ----------------------------------------------------

# 震度レベルごとの FeatureGroup を格納する辞書
shindo_layers = {}

# 震度マッピングのキー(例: '震度7', '震度6強')を降順でソート
sorted_shindo_levels = sorted(shindo_mapping.keys(), key=lambda x: shindo_mapping[x], reverse=True)

for shindo_level in sorted_shindo_levels:
    # レイヤー名を設定 (LayerControlに表示される名前)
    layer_name = f"最大震度: {shindo_level}"
    # FeatureGroupを作成し、マップに追加
    fg = folium.FeatureGroup(name=layer_name, show=True).add_to(m)
    shindo_layers[shindo_level] = fg

# ----------------------------------------------------
# 3. データの反復処理と適切なレイヤーへのマーカー追加
# ----------------------------------------------------
for idx, row in df.iterrows():
    datetime_full = f"{row['地震の発生日']} {row['地震の発生時刻'][:8]}"
    
    # ポップアップ情報
    popup_html = f"""
        **最大震度: {row['最大震度']}**
発生日時: {datetime_full}
震央地名: {row['震央地名']}
深さ: {row['深さ']}
マグニチュード(M): {row['M']}
""" marker_color = get_shindo_color(row['shindo_value']) current_shindo_level = row['最大震度'] # 該当する震度の FeatureGroup を取得 target_fg = shindo_layers.get(current_shindo_level) if target_fg is not None: # マーカーを対応する FeatureGroup に追加 folium.Marker( location=[row['緯度_dec'], row['経度_dec']], popup=popup_html, icon=folium.Icon(color=marker_color, icon='flash', prefix='fa') ).add_to(target_fg) # ---------------------------------------------------- # 4. LayerControl (表示切り替えボックス) を追加 # ---------------------------------------------------- folium.LayerControl(collapsed=False).add_to(m) # ---------------------------------------------------- # 5. マップの保存と表示 # ---------------------------------------------------- m.save("earthquake_layer_control_map.html") print("震度別表示切り替え機能付きFoliumマップの作成が完了しました。")

変数 m を表示してみると
スクリーンショット 2025-12-13 17.21.43


震度ごとに表示を切り替えすることができます。





まとめ

GeoPandasで計算して、Foliumで描画すると
以下のような分析が簡単に行えます。

商圏分析
人口ヒートマップ
配送ルート可視化
不動産マップ
災害・危険区域表示

これらの分析を行う際に
このライブラリの組み合わせは
非常に捗ります。

かなり便利なので
使ってみると面白いと思います
それでは。


AI計算資源の覇権はどっちになるのか
NVIDIA GPU vs Google TPU
という内容で動画を作りました。

解説動画はこちら

 
個人的にはGemini Pro 3 が
恐ろしく役立っているので
TPU勢力拡大の構図は見えました。


今回はGoogleの新しいAIエージェント搭載エディター
Antigravity のご紹介です


解説動画はこちら




Google Antigravityとは

Google が 2025-11-18に発表した
エージェントファーストの開発プラットフォーム(IDE)
VS-CODEがベース



主な特徴

VS-CODEと同様のインターフェースで
エージェントファースト開発体験

エディタ・ターミナル・ブラウザを横断して
タスクを自律的に遂行できる



マネージャービューとエディタビュー

「マネージャービュー」では
複数ワークスペース・複数エージェントを一元管理し
各エージェントの進行状況や成果物を俯瞰できる

「エディタビュー」では
従来のコード編集画面に近い操作感の中で
エージェントとの対話や修正も行える



インストール方法

以下のサイトよりダウンロード
ダウンロード先


対象OS
MacOS
Windows
Linux

MacOSは
ダウンロード後に
imgファイルを開いてドラッグ



利用方法

ソフトウェアを開くのみ

初回起動時
Agent利用方法は選択式
「Agent-assisted development」 を選択

Agent利用はGoogleアカウントが必要
未作成の人は要作成
アカウントある人はログインが必要



日本語化の方法

1
左側メニューのExtensionから
Japanese Language Pack for Visual Studio Code
を探してインストールする

インストールが失敗して手動でインストールする場合は
MS-CEINTL.vscode-language-pack-ja-x.xxx.x.vsix
を手動ダウンロードしてから

Extensionメニューの ... マークから
Install From VSIX を選択してファイルを選択してインストールする


2
Shift + Command + P でメニューを開き
Configure Display Language を選択
対応言語から ja を選択して再起動する



その他設定

ブラウザーのChrome 拡張機能である
Antigravity Browser Extension 
をインストールしておくと便利(Chrome用)
(ブラウザー実行時にAntigravityが起動する)

回答を日本語にしてもらう

Agentパネル右上の「…」から
「Customizations → Rules → +Global」で
「日本語で回答してください」と設定



使い方

Editorモード
初期使用はこのモード
VS-CODEと同様のインターフェースでコードを編集する

利用できるエージェント
gemini 3 pro(High)
gemini 3 pro(Low)
Claude Sonnet 4.5
Claude Sonnet 4.5 (Thinking)
GPT-OSS 120B(Midium)


利用モード
Planning : 複雑タスク向け
FAST : シンプルタスク向け



エージェントの利用料金

現在は無料のパブリックプレビュー版のため料金なし
ただし、利用制限はあり
(クォータは5時間ごとにリフレッシュされるが)



Agent Managerモード

「⌘E」で「Agent Manager」に切り替えできる
今回は利用方法は割愛



早速作ってみる

gemini pro で回答してもらいました

数独ゲームを作ってみるプロンプト

数独ゲームを実行することのできる
sudoku.htmlを作成して下さい

以下の仕様にてJavascriptで数独ゲームを作成してください

# 仕様
画面中央に 9x9 マスの数独版を表示し
初期配置は30マス分を表示する
入力用の数字選択用の入力ボックスを数独版の下に配置する
入力ボックスは1~9の数字と、消去用のボタンを配置する
入力ボックスの数字を選択した状態で
数独版のマスをクリックすることで
数独版の該当マスに
入力した数字を表示する
数独版の該当マスをクリックすることで
数独版の該当マスの数字を消去する
全てのマスを埋めることで数独ゲームを完了する
数独ゲームを完了したら
数独版の下に数独を完了したことを表示する

リスキーダイスを作ってみるプロンプト

以下の仕様にてJavascriptでサイコロゲームを作成してください
risky_dice.htmlを作成して下さい

# 仕様
画面中央に 正20面体 のサイコロを表示する
サイコロの1面だけが「大凶」、残りの19面が「大吉」と文字列を表示させる
サイコロの下に「サイコロを降る」ボタンを配置して
クリックしたらサイコロを降ることができる
サイコロを降ったらサイコロの面の文字列を表示する
「大凶」の場合はゲームオーバーのポップアップを表示する



まとめ

まだプレビュー版のため
エージェント利用枠などが低く
お試し利用しかできていないですね

ただgemini pro を無料でも
IDEで使用できるのは大きいです

エージェントモードの詳しい使い方などが
分かり次第、また解説していきたいと思います。






このページのトップヘ