matplotlib で点を結ぶ曲線を描く 質問する

matplotlib で点を結ぶ曲線を描く 質問する

そこで、点を結合する曲線をプロットしようとしています。使用しているコードは次のとおりです:-

def hanging_line(point1, point2):
    a = (point2[1] - point1[1])/(np.cosh(point2[0]) - np.cosh(point1[0]))
    b = point1[1] - a*np.cosh(point1[0])
    x = np.linspace(point1[0], point2[0], 100)
    y = a*np.cosh(x) + b

    return (x,y)

n_teams = 4
n_weeks = 4

fig, ax = plt.subplots(figsize=(6,6))

t = np.array([
    [1, 2, 4, 3],
    [4, 3, 3, 2],
    [3, 4, 1, 4],
    [2, 1, 2, 1]
])

fig.patch.set_facecolor('#1b1b1b')

for nw in range(n_weeks):
    ax.scatter([nw] * n_weeks, t[:, nw], marker='o', color='#4F535C', s=100, zorder=2)
    
ax.axis('off')
    
for team in t:
    x1, x2 = 0, 1
    
    for rank in range(0, len(team) - 1):
        y1 = n_weeks - team[rank] + 1
        y2 = n_weeks - team[rank + 1] + 1
        x, y = hanging_line([x1, y1], [x2, y2])
        ax.plot(x, y, color='#4F535C', zorder=1)
        x1 += 1
        x2 += 1

コードは次の出力を生成します:-ここに画像の説明を入力してください

しかし、曲線はこんな感じにしたいと思っています。ここに画像の説明を入力してください

必要な結果を得るには、コードにどのような変更を加える必要がありますか?

ベストアンサー1

ここでは、ベジェ曲線

このシーケンスは、[...., i-indent, i, i + 0.8, ...]各整数位置とその前後のスペースに制御点を配置しますi。以下のプロットではindent=0.8、;が使用され、曲線が交差するindent=0直線が作成されますindent>1。他のバリエーションでは、曲線が多かれ少なかれ「角張った」ものになります。

import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
import numpy as np

n_teams = 4
n_weeks = 4
t = np.array([[1, 2, 4, 3],
              [4, 3, 3, 2],
              [3, 4, 1, 4],
              [2, 1, 2, 1]])
fig, ax = plt.subplots(figsize=(10, 4), facecolor='#1b1b1b')
ax.set_facecolor('#1b1b1b')

indent = 0.8
for tj in t:
    ax.scatter(np.arange(len(tj)), tj, marker='o', color='#4F535C', s=100, zorder=3)
    # create bezier curves
    verts = [(i + d, tij) for i, tij in enumerate(tj) for d in (-indent, 0, indent)][1:-1]
    codes = [Path.MOVETO] + [Path.CURVE4] * (len(verts) - 1)
    path = Path(verts, codes)
    patch = patches.PathPatch(path, facecolor='none', lw=2, edgecolor='#4F535C')
    ax.add_patch(patch)
ax.set_xticks([])
ax.set_yticks([])
ax.autoscale() # sets the xlim and ylim for the added patches
plt.show()

結果のプロット

色付きバージョンは次のようになります。

colors = ['crimson', 'skyblue', 'lime', 'gold']
for tj, color in zip(t, colors):
    ax.scatter(np.arange(len(tj)), tj, marker='o', color=color, s=100, zorder=3)
    verts = [(i + d, tij) for i, tij in enumerate(tj) for d in (-indent, 0, indent)][1:-1]
    codes = [Path.MOVETO] + [Path.CURVE4] * (len(verts) - 1)
    path = Path(verts, codes)
    patch = patches.PathPatch(path, facecolor='none', lw=2, edgecolor=color)
    ax.add_patch(patch)

カラー版

次のプロットは、 の異なる値を比較しますindent

インデントの比較

おすすめ記事