这是一种使用的方法贝塞尔曲线 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
: