本日は、全内容を東京画廊の山本豊津代表に銀座東京画廊で公開説明した以外に6年間にわたり機密事項として封印してきた『音楽の楽譜を絵画に変換する物理的法則』を、封印を解いてついに公開しました。
公開理由は以下の通りです。
- 物理などの新理論や発見は特許を取れない。
- 6年間で、10枚以上のこの法則を利用した大画面のパステル画を制作しストックできたこと。
- ただ発見しましたでは、皆様に多くの場合結局信用してもらえなかったこと。
以上の理由により、今回、そのエビデンスを法則の全内容とともに公開いたしました!
この法則が真実かどうかは?以下のプログラムと、色んな音楽家、ミュージシャンの発言から確かめてください!
聴覚の芸術である「音楽」を、視覚の芸術である「絵画」へと変換することはできないのか?
その問いに対する芸術史上初の『できる』という解答がこの法則です。
今回私は、この理論を確認するためのPython言語プログラム作って実行し、見事に理論通りの結果が描画され、この法則の正しさが実証されました。
それでは、その法則の全貌を公開します!
楽譜を絵画にする4つの法則
① 音階は「光のスペクトル(虹色)」に一致する
ドレミファソラシドの7音階は、光の波長(色)と完全に連動しています。
ド(C / ハ)= 赤
レ(D / ニ)= オレンジ
ミ(E / ホ)= 黄色
ファ(F / ヘ)= 黄緑
ソ(G / ト)= 緑
ラ(A / イ)= 青
シ(B / ロ)= 紫
色は上に行くにしたがって高周波になるので、1オクターブごとに明るくなっていくと考えていいでしょう!
② 音楽の主調音は色彩の主調色になる。画面を覆う主調色

調性音楽とは、最初の音がドで始まって、ドで終わるならハ長調。
ミで始まるならニ長調となります。
ドとミの間の音から始まるのはニ短調となります。
ドレミといった長音は『明るい音』として聴こえますし、長音の間にあるピアノでいえば黒鍵にあたる単音は暗い音に聴こえます。
この主調音は、だから、局全体の調子、雰囲気を決めますね。明るい感じの曲か、暗い感じの曲か?
つまり、曲全体を支配している。
絵画では、この各音に当たる色彩が画面全体を支配する色となります。
だから、ハ長調を絵画に翻訳すると下の梅原龍三郎の『櫻島 赤』のように赤が画面の支配色となる。
一方逆に、『桜島 青』は、そうロ長調になります。
こう考えないと、音楽がなぜ、ハ長調やイ短調などの曲調によって、全体の雰囲気が決まるのがの説明もつかないですよね。
私のこの理論は、絵画の主調色の役割もばっちり説明していますよね?
非調性音楽は、シェーンベルグの12音階セリー音楽から始まっています。そうすると、短調は、以下の和音描画のプログラムを実施してもらえれば分かりますが、
赤と朱色、青と紫の『中間のくすんだ色』となります。
つまり純粋な色ではない。濁った中間色になると考えていい。
こうすると、悲しい、たそがれた絵になりますね。
ワシリーカンディンスキー夫妻とシェーンベルグ夫妻が部屋で語らい中に、妻のニーナが「ピカソの作品(夢(赤い椅子に眠る女) 写真などは、12音階音楽を絵画で実現したものだ!」という逸話は至言で、この作品には画面を支配する基調色がないからです。
④ 音の高さと絵画との関係
メロディは、キャンバス上の「時間(X軸)」と「高さ(Y軸)」として配置されます。
◆時間(音の長さ):
1拍(四分音符)を1つの「正方形(□)」とします。例えば3拍伸ばす音なら、正方形を横に3つ並べて表示します。次の音符の正方形へは、線で結んでつながりを表現します。
◆高さ(音程):
縦のY軸は建物の階層のようになります。1階がド、2階がレ、3階がミ…と上がり、7音階で1つのトーテムポールのような高さになります。
◆音には色=音色と高さがあります。
音の高さは、ご存じのように高くなるにしたがって周波数が高くなります。
例えはトランペットで考えると、カンディンスキーが『芸術における精神的なるもの』などの著書で指摘したように、トランペットの音は、視た感じそのものの黄色や黄金のような金属音に聴こえますね?
これに音の高さがある。
とするなら、絵画に翻訳する場合は、画面の下ほど暗く、つまり色としても低周波、上に行くほど白く高周波になっていく。
なんと、これって自然と同じですね?天と地の関係になっている。
この音色と高さの絵画への置き換え法則を見抜けないと、色は青に向かっていくほど高周波になるが、高さも明るい方が高周波になる。では絵画に翻訳するのにどう当てはめればいいの?と分からなくなりここで挫折してしまいますね?
この法則によるプログラム。
この法則を以下のようにプログラムにしました。
まず、坂本龍一の『ラストエンペラー』を描画したら・・・・私の想定通り、紫禁城、桂林の風景、イメージが描画されました。
これは何を意味するのか?作曲家はただ音だけを脳裏に浮かべて作曲するのではない。 ある具体的な風景や情景、を思う浮かべて曲を作るのです。
だからこそ、松本隆などの作詞家は曲から連想されるそのイメージにピッタリ一致する詩を被せることができるのです。
もう一度いいます。
『歌謡曲などの調性音楽は抽象芸術ではない!』
『音楽は全て抽象画のような抽象芸術というのは誤りである!』
あるクラッシック楽団の楽団員の人は私のこの意見に「自分もだか楽団員などクラッシック演奏家は皆薄々はっきりとそのようだと理解していた!」と言いました。
あなたもそう思いませんか?
つまり、大衆音楽などの調性音楽は『具象画』なのです!
今まで、抽象画家は『全ての音楽は抽象芸術だ!』と思い込んでそれを前提に『感覚と印象』で点・線・面、色・絵肌を置いていきました。
つまり、世の抽象画家のほとんどは『抽象印象派』『抽象感覚派』と呼べるでしょう。
点、線、面と色を何となく、キャンバスに置いていく。
しかし、そこにはカンディンスキーに口癖だった『必然性』がない。
必然性の代わりに『なんとなく』なのです。
だから当然、抽象画家の多くは、作詞の詩のような具体物の説明性がどうしようもなく失われていて、欠けていることに凄く苦しんだはずです。
具体的な物や風景、花、木々、人物やそれらの際立つ個性を『全然、説明し表現できない』わけですね?
これは、非常に苦しい経験です。だって、言いたいこと。伝えたいことを鑑賞者に十分に伝えられないわけだから。
しかし、調性音楽、つまり普段耳にするポップミュージックや歌謡曲、バッハなどのクラッシック音楽が『ハ長調』『イ短調』といった主調音から始まる音楽であり、それが具象画であると分かった時、このどうしようもない表現の不自由の原因と対策が見えてきます。
こうなると、そうです。多くの抽象画家の『音楽は抽象である』という思い込みや『絵画と音楽はまったく共通の周波数などの法則が、物理的に医学生理学的に違うから絶対統合できない』というステレオタイプの思い込みが間違いとなり、自分の作品の基盤となる表現理論・手法が極めて貧しく、おおざっぱで乏しくぼやけていることがはっきりします。
これは美術史上の常識をちゃぶ台返しでひっくり返す、コペルニクス的な革新=発見ではないでしょうか?
そこで、今回は、この理論の証明となるこの理論通りに描画するPythonプログラムを作りました。
それがこちらです。
今、イノベーションとは「それまで異質でまったく別のものと考えられてきたものに、共通する法則を見抜いて結合したもの」という定石通り、美術史上、音楽史上初めて絵画と音楽は結合し互いに翻訳可能となったのです。
サンプルプログラム
こちらのプログラムをIDLEの画面にコピペして実行してください。
実行結果はこのページのヘッダーと同じになります。
①IDLEのインストールはこちらです。
②IDLEの起動
◆Windowsの場合、画面最下段の検索窓に『IDLE』と打ってEnterキーを押してください。

◆MACの場合は先のIDLEのインストールページをご覧ください。
②プログラムの実行方法
Pythonに標準で付いている開発環境「IDLE」を起動します。
画面上のメニューから「File」→「New File」をクリックし、新しい真っ白なウィンドウを開きます。
開いたウィンドウに、上記のプログラム(コード)をすべてコピーして貼り付けます。
メニューから「File」→「Save」をクリックし、好きな名前(例:doremi.py など)をつけてパソコンに保存します。
メニューから「Run」→「Run Module」(またはキーボードの F5キー)を押します。
しばらく待つと新しいウィンドウが開き、理論に基づいた「ドレミの歌」の視覚化グラフが描画されます!ぜひお手元で、音楽が絵画に変わる瞬間を体験してみてください。
◆坂本龍一:ラストエンペラー メインテーマの楽譜を絵画に翻訳
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import colors
# ---------------------------------------------------------
# 1. 音楽データの定義(坂本龍一:ラストエンペラー メインテーマ)
# ---------------------------------------------------------
melody = [
# 【Aメロ】
(5, 1, 3), (6, 1, 1), (0, 2, 2), (1, 2, 2), (2, 2, 4),
(0, 2, 2), (5, 1, 2), (4, 1, 2), (5, 1, 4),
# 【Bメロ】
(5, 1, 2), (0, 2, 2), (1, 2, 2), (2, 2, 2), (4, 2, 2),
(2, 2, 4), (1, 2, 2), (0, 2, 2), (5, 1, 6),
]
# ---------------------------------------------------------
# 2. 法則に基づく色の定義
# ---------------------------------------------------------
base_colors = {
0: '#FF0000', 1: '#FFA500', 2: '#FFFF00', 3: '#9ACD32',
4: '#008000', 5: '#0000FF', 6: '#800080'
}
bg_colors = {
0: '#FF76C2', 1: '#FFA376', 2: '#FFE276', 3: '#C2FF76',
4: '#76FFC2', 5: '#76C2FF', 6: '#C276FF' # 「ラ」主調の青系背景
}
def get_color(pitch_class, octave):
"""オクターブが上がると色を明るくする関数"""
base_rgb = colors.to_rgb(base_colors[pitch_class])
if octave <= 1:
return base_rgb
else:
factor = 1.0 - (0.5 ** (octave - 1))
return [c + (1.0 - c) * factor for c in base_rgb]
# ---------------------------------------------------------
# 3. 描画キャンバスと背景色の設定
# ---------------------------------------------------------
fig, ax = plt.subplots(figsize=(16, 8))
# 最初の音(ラ)に基づき、青系の背景に設定
first_pitch = melody[0][0]
ax.set_facecolor(bg_colors[first_pitch])
current_x = 0
square_corners = [] # 全ての正方形の左下と右下の座標を記録するリスト
# ---------------------------------------------------------
# 4. 白大理石の基壇(漢白玉の台座)
# ---------------------------------------------------------
ax.add_patch(patches.Rectangle((0, 0), 100, 0.4, facecolor='#E0E0E0', edgecolor='#CCCCCC', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.4), 100, 0.3, facecolor='#ECECEC', edgecolor='#DDDDDD', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.7), 100, 0.3, facecolor='#F5F5F5', edgecolor='#EEEEEE', zorder=1))
# ---------------------------------------------------------
# 5. 音符(正方形)の配置
# ---------------------------------------------------------
for note in melody:
pitch_class, octave, duration = note
y = pitch_class + 1 + (octave - 1) * 7
note_color = get_color(pitch_class, octave)
# 指定された長さ分、正方形を並べる
for i in range(duration):
sq_x = current_x + i + 0.05
sq_y = y - 0.45
# この正方形の左下(bl)と右下(br)の座標を記録
bl = (sq_x, sq_y)
br = (sq_x + 0.9, sq_y)
square_corners.append({'bl': bl, 'br': br})
rect = patches.Rectangle((sq_x, sq_y), 0.9, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
current_x += duration
# ---------------------------------------------------------
# 6. 前の□の右下から、次の□の左下へ線を繋ぐ
# ---------------------------------------------------------
for i in range(len(square_corners) - 1):
prev_br_x, prev_br_y = square_corners[i]['br'] # 前の□の右下
next_bl_x, next_bl_y = square_corners[i+1]['bl'] # 次の□の左下
# 薄い黒色(グレー)でシンプルに結ぶ
ax.plot([prev_br_x, next_bl_x], [prev_br_y, next_bl_y], color='#555555', linewidth=1.5, zorder=3)
# ---------------------------------------------------------
# 7. 見た目の調整と出力
# ---------------------------------------------------------
ax.set_xlim(0, current_x)
ax.set_ylim(0, 15)
ax.set_yticks(range(1, 15))
yticklabels = ['1F: C(ド)', '2F: D(レ)', '3F: E(ミ)', '4F: F(ファ)', '5F: G(ソ)', '6F: A(ラ)', '7F: B(シ)',
'8F: C(ド高)', '9F: D(レ高)', '10F: E(ミ高)', '11F: F(ファ高)', '12F: G(ソ高)', '13F: A(ラ高)', '14F: B(シ高)']
ax.set_yticklabels(yticklabels)
ax.set_xlabel("Time (Beats)")
ax.set_title("The Last Emperor - Music Art")
plt.grid(True, which='both', axis='y', linestyle='--', alpha=0.5, color='white', zorder=1)
plt.tight_layout()
plt.show()
大瀧詠一 カナリヤ諸島にて 主メロディ部
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import colors
# ---------------------------------------------------------
# 1. 音楽データの定義(大瀧詠一:カナリア諸島にて)
# ---------------------------------------------------------
melody = [
# 【イントロ】
(2, 1, 2), (1, 1, 2), (0, 1, 2), (1, 1, 2), (2, 1, 4),
(4, 1, 2), (3, 1, 2), (2, 1, 2), (3, 1, 2), (4, 1, 4),
(5, 1, 2), (4, 1, 2), (3, 1, 2), (2, 1, 2), (1, 1, 4),
(0, 1, 4),
# 【Aメロ】♪薄く切ったオレンジを アイスティーに浮かべて
(2, 1, 1), (2, 1, 1), (2, 1, 2),
(2, 1, 1), (3, 1, 1), (4, 1, 2),
(5, 1, 1), (4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 4),
(1, 1, 1), (1, 1, 1), (1, 1, 2),
(1, 1, 1), (2, 1, 1), (3, 1, 2),
(4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 1), (0, 1, 4),
# 【Aメロ続き】♪海辺のバルコニーで 空の色を眺める
(2, 1, 1), (2, 1, 1), (2, 1, 2),
(2, 1, 1), (3, 1, 1), (4, 1, 2),
(5, 1, 1), (4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 4),
(1, 1, 1), (1, 1, 1), (1, 1, 2),
(1, 1, 1), (2, 1, 1), (3, 1, 2),
(4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 1), (0, 1, 8),
]
# ---------------------------------------------------------
# 2. 法則に基づく色の定義 【スペクトル反転バージョン】
# ---------------------------------------------------------
base_colors = {
0: '#800080', # ド (C): 紫(←元は赤)
1: '#0000FF', # レ (D): 青(←元はオレンジ)
2: '#008000', # ミ (E): 緑(←元は黄色)
3: '#9ACD32', # ファ (F): 黄緑(中心なのでそのまま)
4: '#FFFF00', # ソ (G): 黄色(←元は緑)
5: '#FFA500', # ラ (A): オレンジ(←元は青)
6: '#FF0000' # シ (B): 赤(←元は紫)
}
bg_colors = {
0: '#C276FF', # ド (C): 紫系
1: '#76C2FF', # レ (D): 青系
2: '#76FFC2', # ミ (E): 緑系 (今回の主調色・ペパーミントグリーン)
3: '#C2FF76', # ファ (F): 黄緑系
4: '#FFE276', # ソ (G): 黄色系
5: '#FFA376', # ラ (A): オレンジ系
6: '#FF76C2' # シ (B): 赤系
}
def get_color(pitch_class, octave):
"""オクターブが上がると色を明るくする関数"""
base_rgb = colors.to_rgb(base_colors[pitch_class])
if octave <= 1:
return base_rgb
else:
factor = 1.0 - (0.5 ** (octave - 1))
return [c + (1.0 - c) * factor for c in base_rgb]
# ---------------------------------------------------------
# 3. 描画キャンバスと背景色の設定
# ---------------------------------------------------------
fig, ax = plt.subplots(figsize=(20, 8))
# 最初の音(ミ)に基づき、背景色が自動で「緑系(#76FFC2)」に設定されます
first_pitch = melody[0][0]
ax.set_facecolor(bg_colors[first_pitch])
current_x = 0
square_corners = []
# ---------------------------------------------------------
# 4. 白いテラスの基壇
# ---------------------------------------------------------
ax.add_patch(patches.Rectangle((0, 0), 150, 0.4, facecolor='#E0E0E0', edgecolor='#CCCCCC', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.4), 150, 0.3, facecolor='#ECECEC', edgecolor='#DDDDDD', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.7), 150, 0.3, facecolor='#F5F5F5', edgecolor='#EEEEEE', zorder=1))
# ---------------------------------------------------------
# 5. 音符(正方形)の配置
# ---------------------------------------------------------
for note in melody:
pitch_class, octave, duration = note
y = pitch_class + 1 + (octave - 1) * 7
note_color = get_color(pitch_class, octave)
for i in range(duration):
sq_x = current_x + i + 0.05
sq_y = y - 0.45
bl = (sq_x, sq_y)
br = (sq_x + 0.9, sq_y)
square_corners.append({'bl': bl, 'br': br})
rect = patches.Rectangle((sq_x, sq_y), 0.9, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
current_x += duration
# ---------------------------------------------------------
# 6. 前の□の右下から、次の□の左下へ線を繋ぐ
# ---------------------------------------------------------
for i in range(len(square_corners) - 1):
prev_br_x, prev_br_y = square_corners[i]['br']
next_bl_x, next_bl_y = square_corners[i+1]['bl']
# 薄い黒色(グレー)でシンプルに結ぶ
ax.plot([prev_br_x, next_bl_x], [prev_br_y, next_bl_y], color='#555555', linewidth=1.5, zorder=3)
# ---------------------------------------------------------
# 7. 見た目の調整と出力
# ---------------------------------------------------------
ax.set_xlim(0, current_x)
ax.set_ylim(0, 10)
ax.set_yticks(range(1, 10))
yticklabels = ['1F: C(ド=紫)', '2F: D(レ=青)', '3F: E(ミ=緑)', '4F: F(ファ=黄緑)', '5F: G(ソ=黄)', '6F: A(ラ=橙)', '7F: B(シ=赤)',
'8F: C(高)', '9F: D(高)']
ax.set_yticklabels(yticklabels)
ax.set_xlabel("Time (Beats)")
ax.set_title("Eiichi Ohtaki - A Canary Island (Reversed Spectrum Art)")
plt.grid(True, which='both', axis='y', linestyle='--', alpha=0.5, color='white', zorder=1)
plt.tight_layout()
plt.show()
カナリヤ諸島にて 冒頭 イントロ部分
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import colors
# ---------------------------------------------------------
# 1. 音楽データの定義(大瀧詠一:カナリア諸島にて)
# ---------------------------------------------------------
melody = [
# 【イントロ】
(2, 1, 2), (1, 1, 2), (0, 1, 2), (1, 1, 2), (2, 1, 4),
(4, 1, 2), (3, 1, 2), (2, 1, 2), (3, 1, 2), (4, 1, 4),
(5, 1, 2), (4, 1, 2), (3, 1, 2), (2, 1, 2), (1, 1, 4),
(0, 1, 4),
# 【Aメロ】♪薄く切ったオレンジを アイスティーに浮かべて
(2, 1, 1), (2, 1, 1), (2, 1, 2),
(2, 1, 1), (3, 1, 1), (4, 1, 2),
(5, 1, 1), (4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 4),
(1, 1, 1), (1, 1, 1), (1, 1, 2),
(1, 1, 1), (2, 1, 1), (3, 1, 2),
(4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 1), (0, 1, 4),
# 【Aメロ続き】♪海辺のバルコニーで 空の色を眺める
(2, 1, 1), (2, 1, 1), (2, 1, 2),
(2, 1, 1), (3, 1, 1), (4, 1, 2),
(5, 1, 1), (4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 4),
(1, 1, 1), (1, 1, 1), (1, 1, 2),
(1, 1, 1), (2, 1, 1), (3, 1, 2),
(4, 1, 1), (3, 1, 1), (2, 1, 1), (1, 1, 1), (0, 1, 8),
]
# ---------------------------------------------------------
# 2. 法則に基づく色の定義 【スペクトル反転バージョン】
# ---------------------------------------------------------
base_colors = {
0: '#800080', # ド (C): 紫(←元は赤)
1: '#0000FF', # レ (D): 青(←元はオレンジ)
2: '#008000', # ミ (E): 緑(←元は黄色)
3: '#9ACD32', # ファ (F): 黄緑(中心なのでそのまま)
4: '#FFFF00', # ソ (G): 黄色(←元は緑)
5: '#FFA500', # ラ (A): オレンジ(←元は青)
6: '#FF0000' # シ (B): 赤(←元は紫)
}
bg_colors = {
0: '#C276FF', # ド (C): 紫系
1: '#76C2FF', # レ (D): 青系
2: '#76FFC2', # ミ (E): 緑系 (今回の主調色・ペパーミントグリーン)
3: '#C2FF76', # ファ (F): 黄緑系
4: '#FFE276', # ソ (G): 黄色系
5: '#FFA376', # ラ (A): オレンジ系
6: '#FF76C2' # シ (B): 赤系
}
def get_color(pitch_class, octave):
"""オクターブが上がると色を明るくする関数"""
base_rgb = colors.to_rgb(base_colors[pitch_class])
if octave <= 1:
return base_rgb
else:
factor = 1.0 - (0.5 ** (octave - 1))
return [c + (1.0 - c) * factor for c in base_rgb]
# ---------------------------------------------------------
# 3. 描画キャンバスと背景色の設定
# ---------------------------------------------------------
fig, ax = plt.subplots(figsize=(20, 8))
# 最初の音(ミ)に基づき、背景色が自動で「緑系(#76FFC2)」に設定されます
first_pitch = melody[0][0]
ax.set_facecolor(bg_colors[first_pitch])
current_x = 0
square_corners = []
# ---------------------------------------------------------
# 4. 白いテラスの基壇
# ---------------------------------------------------------
ax.add_patch(patches.Rectangle((0, 0), 150, 0.4, facecolor='#E0E0E0', edgecolor='#CCCCCC', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.4), 150, 0.3, facecolor='#ECECEC', edgecolor='#DDDDDD', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.7), 150, 0.3, facecolor='#F5F5F5', edgecolor='#EEEEEE', zorder=1))
# ---------------------------------------------------------
# 5. 音符(正方形)の配置
# ---------------------------------------------------------
for note in melody:
pitch_class, octave, duration = note
y = pitch_class + 1 + (octave - 1) * 7
note_color = get_color(pitch_class, octave)
for i in range(duration):
sq_x = current_x + i + 0.05
sq_y = y - 0.45
bl = (sq_x, sq_y)
br = (sq_x + 0.9, sq_y)
square_corners.append({'bl': bl, 'br': br})
rect = patches.Rectangle((sq_x, sq_y), 0.9, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
current_x += duration
# ---------------------------------------------------------
# 6. 前の□の右下から、次の□の左下へ線を繋ぐ
# ---------------------------------------------------------
for i in range(len(square_corners) - 1):
prev_br_x, prev_br_y = square_corners[i]['br']
next_bl_x, next_bl_y = square_corners[i+1]['bl']
# 薄い黒色(グレー)でシンプルに結ぶ
ax.plot([prev_br_x, next_bl_x], [prev_br_y, next_bl_y], color='#555555', linewidth=1.5, zorder=3)
# ---------------------------------------------------------
# 7. 見た目の調整と出力
# ---------------------------------------------------------
ax.set_xlim(0, current_x)
ax.set_ylim(0, 10)
ax.set_yticks(range(1, 10))
yticklabels = ['1F: C(ド=紫)', '2F: D(レ=青)', '3F: E(ミ=緑)', '4F: F(ファ=黄緑)', '5F: G(ソ=黄)', '6F: A(ラ=橙)', '7F: B(シ=赤)',
'8F: C(高)', '9F: D(高)']
ax.set_yticklabels(yticklabels)
ax.set_xlabel("Time (Beats)")
ax.set_title("Eiichi Ohtaki - A Canary Island (Reversed Spectrum Art)")
plt.grid(True, which='both', axis='y', linestyle='--', alpha=0.5, color='white', zorder=1)
plt.tight_layout()
plt.show()
クラッシック音楽の主要なコード・和音の描画
◆まず「Cメジャー」という世界=音階
Cメジャーの音階は、皆さんご存じの
**ド・レ・ミ・ファ・ソ・ラ・シ・ド**
です。
この7つの音を使って、3つの音を重ねると基本的な三和音ができます。
たとえば、
**ド・ミ・ソ**
を同時に鳴らすと「C」という和音になります。
このCは、Cメジャーという音楽の「中心」です。
音楽がどこかへ旅をしても、最後にCへ戻ってくると、 「帰ってきた」という感じがします。
これが**主和音(Ⅰ)**です。
これがクラッシック音楽の代表的な和音です。
| 和声記号 | 和音 | 構成音 | 基本的な役割 |
|---|---|---|---|
| Ⅰ | C | ド・ミ・ソ | 安定・中心 |
| Ⅱ | Dm | レ・ファ・ラ | 次へ進む準備 |
| Ⅳ | F | ファ・ラ・ド | 中心から離れる |
| Ⅴ | G | ソ・シ・レ | Cへ戻りたくなる |
| Ⅴ7 | G7 | ソ・シ・レ・ファ | 強い緊張 |
| Ⅶ° | Bdim | シ・レ・ファ | 非常に不安定 |
それではクラッシック音楽の代表的な和音・コードを描画するプログラムです。
実行結果はこちらです。

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import colors
# ---------------------------------------------------------
# 1. クラシック音楽(Cメジャー調)の代表的な機能和音の定義
# 形式: (和声記号と機能, コード名, 構成音)
# ---------------------------------------------------------
classic_chords = [
("Ⅰ\n(Tonic)", "C", [(0, 1), (2, 1), (4, 1)]), # 主和音:安定
("Ⅳ\n(Subdominant)", "F", [(3, 1), (5, 1), (0, 2)]), # 下属和音:少し動く
("Ⅴ\n(Dominant)", "G", [(4, 1), (6, 1), (1, 2)]), # 属和音:緊張
("Ⅴ7\n(Dominant 7th)", "G7", [(4, 1), (6, 1), (1, 2), (3, 2)]), # 属七の和音:強い緊張
("Ⅱ\n(Supertonic)", "Dm", [(1, 1), (3, 1), (5, 1)]), # Ⅱ度の和音(Ⅳの代理)
("Ⅶ°\n(Diminished)", "Bdim", [(6, 1), (1, 2), (3, 2)]), # 減三和音:不安定
]
# カデンツ(和音の進行)のデモンストレーション用(Ⅴ7 -> Ⅰ)
cadence = [
("Ⅴ7 (Tension)", "G7", [(4, 1), (6, 1), (1, 2), (3, 2)]),
("Ⅰ (Resolution)", "C", [(0, 1), (2, 1), (4, 1)])
]
# ---------------------------------------------------------
# 2. 法則に基づく色の定義
# ---------------------------------------------------------
base_colors = {
0: '#FF0000', # C (ド): 赤
1: '#FFA500', # D (レ): オレンジ
2: '#FFFF00', # E (ミ): 黄
3: '#9ACD32', # F (ファ): 黄緑
4: '#008000', # G (ソ): 緑
5: '#0000FF', # A (ラ): 青
6: '#800080', # B (シ): 紫
}
def get_color(pitch_class, octave):
"""オクターブが上がると色を明るくする関数"""
base_hex = base_colors.get(pitch_class, '#888888')
base_rgb = colors.to_rgb(base_hex)
if octave <= 1:
return base_rgb
else:
factor = 1.0 - (0.5 ** (octave - 1))
return [c + (1.0 - c) * factor for c in base_rgb]
# ---------------------------------------------------------
# 3. 描画キャンバスの設定
# ---------------------------------------------------------
fig, ax = plt.subplots(figsize=(20, 8))
ax.set_facecolor('#76C2FF') # 基本の青系背景
current_x = 0
# 白いテラスの基壇
ax.add_patch(patches.Rectangle((0, 0), 120, 0.4, facecolor='#E0E0E0', edgecolor='#CCCCCC', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.4), 120, 0.3, facecolor='#ECECEC', edgecolor='#DDDDDD', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.7), 120, 0.3, facecolor='#F5F5F5', edgecolor='#EEEEEE', zorder=1))
# ---------------------------------------------------------
# 4. 代表的な6つの和音を描画
# ---------------------------------------------------------
# タイトルテキスト
ax.text(0.5, 13.5, "[ Classical Functional Harmony: The 6 Core Chords ]", fontsize=14, fontweight='bold', color='white', zorder=5)
for function_name, chord_name, notes in classic_chords:
sq_x = current_x + 0.5
for pitch_class, octave in notes:
y = pitch_class + 1 + (octave - 1) * 7
sq_y = y - 0.45
note_color = get_color(pitch_class, octave)
rect = patches.Rectangle((sq_x, sq_y), 1.2, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
# コード名(上)と機能名(下)
ax.text(sq_x + 0.6, -1.0, function_name, ha='center', va='top', fontsize=10, fontweight='bold', color='#333333', zorder=5)
ax.text(sq_x + 0.6, 0.2, chord_name, ha='center', va='center', fontsize=12, fontweight='bold', color='#550000', zorder=5)
current_x += 2.5
# ---------------------------------------------------------
# 5. カデンツ(Ⅴ7 -> Ⅰ の解決)を描画
# ---------------------------------------------------------
current_x += 1.0 # 少し間を開ける
ax.plot([current_x, current_x], [0, 15], color='white', linestyle='--', linewidth=2, zorder=2) # 区切り線
current_x += 1.0
ax.text(current_x, 13.5, "[ The Ultimate Resolution: Dominant 7th to Tonic ]", fontsize=14, fontweight='bold', color='white', zorder=5)
for function_name, chord_name, notes in cadence:
sq_x = current_x + 0.5
for pitch_class, octave in notes:
y = pitch_class + 1 + (octave - 1) * 7
sq_y = y - 0.45
note_color = get_color(pitch_class, octave)
rect = patches.Rectangle((sq_x, sq_y), 1.5, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.5, zorder=4)
ax.add_patch(rect)
ax.text(sq_x + 0.75, -1.0, function_name, ha='center', va='top', fontsize=11, fontweight='bold', color='#333333', zorder=5)
ax.text(sq_x + 0.75, 0.2, chord_name, ha='center', va='center', fontsize=14, fontweight='bold', color='#550000', zorder=5)
current_x += 3.0
# ---------------------------------------------------------
# 6. 見た目の調整と出力
# ---------------------------------------------------------
ax.set_xlim(0, current_x)
ax.set_ylim(-2.5, 15) # 下部のテキスト用にy軸を少し下へ広げる
ax.set_yticks(range(1, 15))
yticklabels = ['1F: C(ド)', '2F: D(レ)', '3F: E(ミ)', '4F: F(ファ)', '5F: G(ソ)', '6F: A(ラ)', '7F: B(シ)',
'8F: C(ド高)', '9F: D(レ高)', '10F: E(ミ高)', '11F: F(ファ高)', '12F: G(ソ高)', '13F: A(ラ高)', '14F: B(シ高)']
ax.set_yticklabels(yticklabels)
ax.set_xlabel("Time / Structure")
ax.set_title("Visualizing Functional Harmony: The Inevitability of Structure")
plt.grid(True, which='both', axis='y', linestyle='--', alpha=0.5, color='white', zorder=1)
plt.tight_layout()
plt.show()
代表的な和音のプログラムだが、短調の和音も描出
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib import colors
# ---------------------------------------------------------
# 1. 和音ペアの定義を拡張(幅を1拍=1個のブロックにコンパクト化)
# 形式: (長調の名前, 長調の構成音, 短調の名前, 短調の構成音)
# ---------------------------------------------------------
chord_pairs = [
("C", [(0, 1), (2, 1), (4, 1)], "C#m", [(0.5, 1), (2, 1), (5, 1)]),
("Db", [(0.5, 1), (2.5, 1), (4.5, 1)], "Dm", [(1, 1), (3, 1), (5, 1)]),
("D", [(1, 1), (3, 1), (5, 1)], "D#m", [(1.5, 1), (3, 1), (5.5, 1)]),
("Eb", [(1.5, 1), (3.5, 1), (5.5, 1)], "Em", [(2, 1), (4, 1), (6, 1)]),
("E", [(2, 1), (4, 1), (6, 1)], "Fm", [(3, 1), (5, 1), (0, 2)]),
("F", [(3, 1), (5, 1), (0, 2)], "F#m", [(3.5, 1), (5.5, 1), (0.5, 2)]),
("F#", [(3.5, 1), (5.5, 1), (0.5, 2)], "Gm", [(4, 1), (6, 1), (1, 2)]),
("G", [(4, 1), (6, 1), (1, 2)], "G#m", [(4.5, 1), (6.5, 1), (1.5, 2)]),
("Ab", [(4.5, 1), (6.5, 1), (1.5, 2)], "Am", [(5, 1), (0, 2), (2, 2)]),
("A", [(5, 1), (0, 2), (2, 2)], "A#m", [(5.5, 1), (0.5, 2), (2.5, 2)]),
]
# ---------------------------------------------------------
# 2. 法則に基づく色の定義(短調は赤〜オレンジの中間でくすんだ暗い色)
# ---------------------------------------------------------
base_colors = {
0: '#FF0000', # C (ド): 赤
0.5: '#C45500', # C# / Db: 赤とオレンジの中間でくすんだ暗い色
1: '#FFA500', # D (レ): オレンジ
1.5: '#B87A00', # D# / Eb: オレンジ寄りのくすんだ暗い色
2: '#FFFF00', # E (ミ): 黄
2.5: '#D1D100', # E# / F: 黄のくすみ
3: '#9ACD32', # F (ファ): 黄緑
3.5: '#7A9A28', # F# / Gb: くすんだ黄緑
4: '#008000', # G (ソ): 緑
4.5: '#006633', # G# / Ab: くすんだ緑
5: '#0000FF', # A (ラ): 青
5.5: '#0000B3', # A# / Bb: くすんだ青
6: '#800080', # B (シ): 紫
6.5: '#5E005E' # B# / C: くすんだ紫
}
bg_colors = {
0: '#FF76C2', 1: '#FFA376', 2: '#FFE276', 3: '#C2FF76',
4: '#76FFC2', 5: '#76C2FF', 6: '#C276FF'
}
def get_color(pitch_class, octave):
"""オクターブが上がると色を明るくする関数"""
base_hex = base_colors.get(pitch_class, '#888888')
base_rgb = colors.to_rgb(base_hex)
if octave <= 1:
return base_rgb
else:
factor = 1.0 - (0.5 ** (octave - 1))
return [c + (1.0 - c) * factor for c in base_rgb]
# ---------------------------------------------------------
# 3. 描画キャンバスの設定(和音が増えたため横幅を拡大)
# ---------------------------------------------------------
fig, ax = plt.subplots(figsize=(22, 8))
ax.set_facecolor('#76C2FF') # 基本の青系背景
current_x = 0
# 白いテラスの基壇
ax.add_patch(patches.Rectangle((0, 0), 120, 0.4, facecolor='#E0E0E0', edgecolor='#CCCCCC', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.4), 120, 0.3, facecolor='#ECECEC', edgecolor='#DDDDDD', zorder=1))
ax.add_patch(patches.Rectangle((0, 0.7), 120, 0.3, facecolor='#F5F5F5', edgecolor='#EEEEEE', zorder=1))
# ---------------------------------------------------------
# 4. 1個(1拍分)の長調と短調のペアを連続配置
# ---------------------------------------------------------
for major_name, major_notes, minor_name, minor_notes in chord_pairs:
# --- 【長調(1個のみ)】 ---
sq_x = current_x + 0.05
for pitch_class, octave in major_notes:
y = pitch_class + 1 + (octave - 1) * 7
sq_y = y - 0.45
note_color = get_color(pitch_class, octave)
rect = patches.Rectangle((sq_x, sq_y), 0.9, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
# 長調のコード名
ax.text(current_x + 0.5, 0.2, major_name, ha='center', va='center',
fontsize=10, fontweight='bold', color='#333333', zorder=5)
current_x += 1.2 # 次の短調までのスペース
# --- 【半音ずれた短調(1個のみ)】 ---
sq_x = current_x + 0.05
for pitch_class, octave in minor_notes:
y = pitch_class + 1 + (octave - 1) * 7
sq_y = y - 0.45
note_color = get_color(pitch_class, octave)
rect = patches.Rectangle((sq_x, sq_y), 0.9, 0.9,
facecolor=note_color, edgecolor='black', linewidth=1.2, zorder=4)
ax.add_patch(rect)
# 短調のコード名
ax.text(current_x + 0.5, 0.2, minor_name, ha='center', va='center',
fontsize=10, fontweight='bold', color='#550000', zorder=5)
current_x += 2.0 # 次のペアのセットまでの大きめのスペース
# ---------------------------------------------------------
# 5. 見た目の調整と出力
# ---------------------------------------------------------
ax.set_xlim(0, current_x)
ax.set_ylim(0, 15)
ax.set_yticks(range(1, 15))
yticklabels = ['1F: C(ド)', '2F: D(レ)', '3F: E(ミ)', '4F: F(ファ)', '5F: G(ソ)', '6F: A(ラ)', '7F: B(シ)',
'8F: C(ド高)', '9F: D(レ高)', '10F: E(ミ高)', '11F: F(ファ高)', '12F: G(ソ高)', '13F: A(ラ高)', '14F: B(シ高)']
ax.set_yticklabels(yticklabels)
ax.set_xlabel("Chord Variations (Major vs Shifted Minor)")
ax.set_title("Expanded Spectral Translation: 10 Major & Minor Chord Pairs")
plt.grid(True, which='both', axis='y', linestyle='--', alpha=0.5, color='white', zorder=1)
plt.tight_layout()
plt.show()




