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

问题描述 投票:0回答:5

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

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

python matplotlib matplotlib-basemap
5个回答
48
投票

您可以使用关键字参数marker创建

自定义多边形
并向其传递一个由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


16
投票

我只是想添加一种方法来旋转其他非规则多边形标记样式。下面我通过修改标记样式类的变换属性旋转了“细菱形”和“plus”和“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)


6
投票

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

如果您寻找一个标记符号,您可以在其中明显地从 [0, 2pi) 下降方向,您可以从路径构造一个标记。 由于路径由绘图例程自动缩放(使得最外点接触框 -1 <= x, y <= 1), you need additional point size scaling.

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], [.1, .3]]) # 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])) codes = [mpl.path.Path.MOVETO, mpl.path.Path.LINETO,mpl.path.Path.LINETO, mpl.path.Path.CLOSEPOLY] arrow_head_marker = mpl.path.Path(arr, codes) 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()
    

5
投票
看看

matplotlib.markers 模块:

(numsides, 0, angle)

 -
具有 
numsides
 边的正多边形,旋转 
angle

(numsides, 1, angle)
 -
具有 
numsides
 边的星形符号,旋转 
angle

(numsides, 2, angle)
 -
具有 
numsides
 边的星号,旋转 
angle

例如,您可以使用具有指定角度的任意多边形:

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

2
投票
我认为有一个更好、更全面的答案

对于 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 处。
从这里开始,创建一个函数来旋转整个坐标列表的给定角度应该是一个简单的任务。

© www.soinside.com 2019 - 2024. All rights reserved.