在matplotlib中绘制曲线连接点

2024-04-29

所以我试图绘制曲线来连接点,这是我正在使用的代码:-

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

The code is producing the following output:- enter image description here

But I want the curved lines to look somewhat like this: enter image description here

我应该在代码中进行哪些更改才能获得所需的结果?


这是一种使用的方法贝塞尔曲线 https://matplotlib.org/3.1.0/gallery/shapes_and_collections/quad_bezier.html.

序列[...., 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:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在matplotlib中绘制曲线连接点 的相关文章

随机推荐