用matplotlib用自定义填充填充多边形 [英] Fill polygon with custom hatch with matplotlib

查看:125
本文介绍了用matplotlib用自定义填充填充多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用线阴影填充一堆多边形.这些线必须相对于x轴具有特定角度.我发现matplotlib已经支持一些填充类,并且可以定义一个自定义类(例如

I want to fill a bunch of polygons with line hatch. The lines must have a specific angle with respect to x-axis. I found that matplotlib already suppots some hatch classes and one can define a custom class (like How to fill a polygon with a custom hatch in matplotlib?). I tried to generate a custom hatch but when I append it to the list of hatches the init function doesn't know the angle. I tried with the following class:

class AngularHatch(HatchPatternBase):
    def __init__(self, hatch, density, angle):
        self.num_lines = int((hatch.count('{'))*density*3)
        self.num_vertices = self.num_lines * 2
        self.R = np.array([[np.cos(angle), -np.sin(angle)],
                       [np.sin(angle), np.cos(angle)]])

    def set_vertices_and_codes(self, vertices, codes):
        steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False,
                                  retstep=True)
        steps += stepsize / 2.
        vertices[0::2, 0] = 0
        vertices[0::2, 1] = steps
        vertices[1::2, 0] = 1
        vertices[1::2, 1] = steps
        for i, v in enumerate(vertices):
            vertices[i] = self.R.dot(v)
    codes[0::2] = Path.MOVETO
    codes[1::2] = Path.LINETO

然后,将此类添加到可用于孵化的可用类的列表中.但是,由于代码是从Horizo​​ntalHatch源代码中修改的,因此不会生成正确的行

Then I add this class to the list of available classes for hatching. However this will not generate the correct lines since the code is modified from the HorizontalHatch source code here and I think this generates lines in the unit square. Moreover I need to generate this patch for a specific angle for each polygon I want to render. ¿Any ideas on how to give the correct angle to this class per polygon?

推荐答案

以下内容无法解决此问题.它只是解决了部分问题,并说明了该方法在何时失败.我目前深信使用matplotlib不可能以任意角度进行阴影填充,因为单位晶胞的大小是固定的.

为克服设置角度的问题,可以定义一种自定义格式以从中获取角度信息.例如. "{angle}{factor}",这样"{45}{2}"会产生45°角和2的密度因子的影线.

To overcome the problem of setting the angle, one may define a custom format from which to take the angle information. E.g. "{angle}{factor}", such that "{45}{2}" would produce a hatching with an angle of 45° and a density factor of 2.

然后,我不完全了解计算顶点的尝试.要复制内置舱口的行为,可以直接旋转它们.

I then do not completely understand the attempt of calculating the vertices. To replicate the behaviour of the hatches which are built-in, one may rotate them directly.

问题在于,这种线阴影仅适用于45°的角度.这是因为单位单元边缘的线对齐不正确.请参阅以下内容:

The problem is that this way the line hatches work only for angles of 45°. This is because the lines at the edges of the unit cell do not align well. See the following:

import numpy as np
import matplotlib.hatch
import matplotlib.path
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Rectangle

class AngularHatch(matplotlib.hatch.HatchPatternBase):
    def __init__(self, hatch, density):
        self.num_lines=0
        self.num_vertices=0
        if hatch[0] == "{":
            h = hatch.strip("{}").split("}{")
            angle = np.deg2rad(float(h[0])-45)
            d = float(h[1])
            self.num_lines = int(density*d)
            self.num_vertices = (self.num_lines + 1) * 2
            self.R = np.array([[np.cos(angle), -np.sin(angle)],
                                [np.sin(angle), np.cos(angle)]])

    def set_vertices_and_codes(self, vertices, codes):

        steps = np.linspace(-0.5, 0.5, self.num_lines + 1, True)

        vertices[0::2, 0] = 0.0 + steps
        vertices[0::2, 1] = 0.0 - steps
        vertices[1::2, 0] = 1.0 + steps
        vertices[1::2, 1] = 1.0 - steps
        codes[0::2] = matplotlib.path.Path.MOVETO
        codes[1::2] = matplotlib.path.Path.LINETO
        vertices[:,:] = np.dot((vertices-0.5),self.R)+0.5



matplotlib.hatch._hatch_types.append(AngularHatch)

fig = plt.figure()
ax = fig.add_subplot(111)

ellipse = ax.add_patch(Rectangle((0.1, 0.1), 0.4, 0.8, fill=False))
ellipse.set_hatch('{45}{1}')
ellipse.set_color('red')
ellipse = ax.add_patch(Rectangle((0.55, 0.1), 0.4, 0.8, fill=False))
ellipse.set_hatch('{22}{1}')
ellipse.set_color('blue')
plt.show()

这篇关于用matplotlib用自定义填充填充多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆