是否可以控制matplotlib标记方向?

时间:2014-04-28 15:49:38

标签: python matplotlib matplotlib-basemap

我想知道我是否有三角标记,是否可以控制其方向?我有一系列的facets及其相应的顶点,我想绘制它们的底图。我知道使用Mayavi和tvtk.PolyData时它是直接的脚本。但由于我处理的是地图而不是3D对象,所以事情有点复杂。

ps:对于我使用底图工具的地图。

感谢您的帮助。

5 个答案:

答案 0 :(得分:25)

您可以使用关键字参数marker创建custom polygons并向其传递3个数字(number of sides, style, rotation)的元组。

要创建三角形,您可以使用(3, 0, rotation),示例如下所示。

import matplotlib.pyplot as plt

x = [1,2,3]
for i in x:
    plt.plot(i, i, marker=(3, 0, i*90), markersize=20, linestyle='None')

plt.xlim([0,4])
plt.ylim([0,4])

plt.show()

Plot

答案 1 :(得分:4)

查看matplotlib.markers模块。特别感兴趣的是,您可以使用具有指定角度的任意多边形:

marker = (3, 0, 45)  # triangle rotated by 45 degrees.

答案 2 :(得分:4)

我只是想添加一种方法来旋转其他 非常规多边形标记样式 。下面我通过修改标记样式类的transform属性来旋转“细菱形”和“加”和“vline”。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

for m in ['d', '+', '|']:

    for i in range(5):
        a1, a2  = np.random.random(2)
        angle = np.random.choice([180, 45, 90, 35])

        # make a markerstyle class instance and modify its transform prop
        t = mpl.markers.MarkerStyle(marker=m)
        t._transform = t.get_transform().rotate_deg(angle)
        plt.scatter((a1), (a2), marker=t, s=100)

enter image description here

答案 3 :(得分:0)

我认为有一个更好更全面的答案as for Matplotlib 3.3.3 :

有一个选项 "verts" 用于指定标记,它具有 (x,y) 元组列表的形式,这些是路径的顶点。这允许您绘制几乎任何形状的标记,填充与否,打开或关闭等。据我测试,其他标记选项(见下文)仍然适用。

例如

   plt.plot(x,y,
       marker=[(0,-24),(-10,-20),(10,-16),(-10,12),(10,8),(0,-4),(0,0)],
       markersize=42, color='w', linestyle='None',
       markeredgecolor='k', markeredgewidth= 2.)

将创建一个弹簧形状的标记。大小会自动映射到单位正方形,您的点 (0,0) 将放置在 x,y 处。 从这里开始,制作一个函数来旋转给定角度整个坐标列表应该是一项微不足道的任务。

custom, spring-shaped, marker

答案 4 :(得分:0)

自定义 matplotlib.path.Path(不规则三角形)的解决方案

如果您寻找一个标记符号,在该符号中您可以明显地从 [0, 2pi) 降低方向,您就可以构造一个 marker from a path。 由于路径由绘图例程自动缩放(例如最外层的点接触框 -1 <= x, y <= 1),您需要额外的点大小缩放。

enter image description here

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt



def gen_arrow_head_marker(rot):
    """generate a marker to plot with matplotlib scatter, plot, ...

    https://matplotlib.org/stable/api/markers_api.html#module-matplotlib.markers

    rot=0: positive x direction
    Parameters
    ----------
    rot : float
        rotation in degree
        0 is positive x direction

    Returns
    -------
    arrow_head_marker : Path
        use this path for marker argument of plt.scatter
    scale : float
        multiply a argument of plt.scatter with this factor got get markers
        with the same size independent of their rotation.
        Paths are autoscaled to a box of size -1 <= x, y <= 1 by plt.scatter
    """
    arr = np.array([[.1, .3], [.1, -.3], [1, 0]])  # arrow shape
    angle = rot / 180 * np.pi
    rot_mat = np.array([
        [np.cos(angle), np.sin(angle)],
        [-np.sin(angle), np.cos(angle)]
        ])
    arr = np.matmul(arr, rot_mat)  # rotates the arrow

    # scale
    x0 = np.amin(arr[:, 0])
    x1 = np.amax(arr[:, 0])
    y0 = np.amin(arr[:, 1])
    y1 = np.amax(arr[:, 1])
    scale = np.amax(np.abs([x0, x1, y0, y1]))

    arrow_head_marker = mpl.path.Path(arr)
    return arrow_head_marker, scale

fig, ax = plt.subplots()
for rot in [0, 15, 30, 45, 60, 90, 110, 180, 210, 315, 360]:

    marker, scale = gen_arrow_head_marker(rot)
    markersize = 25
    ax.scatter(rot, 0, marker=marker, s=(markersize*scale)**2)

ax.set_xlabel('Rotation in degree')

plt.show()