8

我正在使用matplotlib.patheffects虚线绘制路径。我的目标是将每条路径精确地划分为沿路径均匀分布的 N 段。由于需要以像素长度而不是数据坐标来指定破折号,因此我正在使用ax.transData.transform_point(),并且我在大多数情况下都可以使用,但是在需要按比例缩小图形的情况下,破折号无法适当缩放.

这是一个演示问题的代码示例:

import sys
import matplotlib.pyplot as plt
import matplotlib.patheffects as PathEffects
from matplotlib.patches import PathPatch
from matplotlib.path import Path
import numpy as np

MIN=1 if len(sys.argv) <= 1 else int(sys.argv[1])
MAX=MIN if len(sys.argv) <=2  else int(sys.argv[2])
SCALE=4 if len(sys.argv) <=3  else int(sys.argv[3])
COUNT=MAX-MIN+1

fig = plt.figure(1, figsize=(COUNT*SCALE,SCALE))

for i in range(MIN, MAX+1):
    ax = plt.subplot(1, COUNT, i-MIN+1)
    ax.set_xlim(0, i)
    ax.set_ylim(0, i)
    path = Path([(0,0), (0,i) ,(i,i)], [Path.MOVETO, Path.CURVE3, Path.CURVE3])
    pp = PathPatch(path, fill=False)

    def path_length(path):
        QI_SAMPLES=1000
        v = path.vertices
        v = [ax.transData.transform_point(p) for p in v ]
        if len(v) > 2:
            v = [ quad_interpolate( i/(1.0 * QI_SAMPLES), v[0], v[1], v[2])
                  for i in range(0, QI_SAMPLES)]
        dv = np.diff(v, axis=0)
        return np.sum(np.sqrt(np.sum(dv**2, axis=-1)))

    def quad_interpolate(i, A, B, C):
        (ax, ay) = A
        (bx, by) = B
        (cx, cy) = C
        ii = 1.-i
        i2 = i*i
        ii2 = ii*ii
        rx = ax*ii2 + 2*bx*ii*i + cx*i2
        ry = ay*ii2 + 2*by*ii*i + cy*i2
        return (rx, ry)

    ax.add_patch(pp)

    length = path_length(path)
    dash_length = length/(2*i)
    space_length = length/(2*i)
    offset=-(space_length/2)

    pe = [PathEffects.withStroke(linewidth=3,
                                 dashes=[offset, (dash_length, space_length)],
                                 foreground="b")]
    pp.set_path_effects(pe)

plt.show()

命令行参数是(最小段)(最大段)(子图比例)。您可能必须使用不同的命令行参数运行它才能触发问题,具体取决于您的显示大小——在我的系统上,使用“1 8 3”运行显示如下:

好情节

在运行“1 8 4”时显示:

糟糕的情节

如您所见,第二个情节不太正确——第八个子情节只有七个破折号,其他情节也有点偏离。

我怎样才能做到这一点,以便将破折号长度可靠地转换为基础轴的坐标空间,而不管比例如何?或者是否有其他方法可以沿着不依赖于以像素长度指定它们的路径获取虚线?

更新: 这是绘制直线而不是曲线的样子。好的:

好情节2

坏的:

糟糕的情节2

正如评论中所指出的,看起来即使是“好”的地块也略有偏差,因为子地块不是很方正。但是ax.transData.transform_point转型不应该解决这个问题吗?

4

0 回答 0