是否可以用纯色填充圆图并在matplotlib中保存为svg?

Is it possible to fill in a circular graph with a solid colour and save it as svg in matplotlib?

我写了一些代码,从 matplotlib 中的图形创建随机补丁。基本上它的工作原理是,您使用圆的参数方程从从圆中获取的节点创建一个图形,然后沿着 (0,0) 的向量随机移动节点到圆周上的节点。这样一来,您就可以确保在绘制圆圈后避免线条相互交叉。最后,您只需将第一个 (x,y) 坐标附加到坐标列表中即可闭合圆圈。

我接下来要做的是找到一种方法,用纯色填充圆形图形,这样我就可以创建一个“图章”,可以用来在 canvas 上制作随机补丁希望不会产生交叉边缘。我想用它来制作 svg 格式的程序风险图,因为其中很多都是使用 jpeg 使用光栅图像格式上传的,边缘很糟糕。

我很确定我的节点信息应该足以实现这一点,但我不知道如何实现它。有人可以帮忙吗?

import numpy as np
import matplotlib.pyplot as plt



def node_circle(r=0.5,res=100):
    # Create arrays (x and y coordinates) for the nodes on the circumference of a circle. Use parametric equation.
    # x = r cos(t)    y = r sin(t)

    t = np.linspace(0,2*np.pi,res)
    x = r*np.cos(t)
    y = r*np.sin(t)

    return t,x,y



def sgn(x,x_shift=-0.5,y_shift=1):

    # A shifted sign function to use as a switching function 
    # in order to avoid shifts lower than -0.5 which is 
    # the radius of the circle.

    return -0.5*(np.abs(x -x_shift)/(x -x_shift)) +y_shift



def displacer(x,y,low=-0.5,high=0.5,maxrad=0.5):

    # Displaces the node points of the circle

    shift = 0
    shift_increment = 0

    for i in range(len(x)):
        shift_increment = np.random.uniform(low,high)
        shift += shift_increment*sgn(maxrad)

        x[i] += x[i]*shift
        y[i] += y[i]*shift

    x = np.append(x,x[0])
    y = np.append(y,y[0])

    return x,y


def plot():

    # Actually visualises everything

    fig, ax = plt.subplots(figsize=(4,4))

    # np.random.seed(1)

    ax.axis('off')

    t,x,y = node_circle(res=100)

    a = 0

    x,y = displacer(x,y,low=-0.15,high=0.15)

    ax.plot(x,y,'r-')
    # ax.scatter(x,y,)

    plt.show()

plot()

明白了:答案是使用matplotlib.Patches.Polygon

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon



def node_circle(r=0.5,res=100):
    # Create arrays (x and y coordinates) for the nodes on the circumference of a circle. Use parametric equation.
    # x = r cos(t)    y = r sin(t)

    t = np.linspace(0,2*np.pi,res)
    x = r*np.cos(t)
    y = r*np.sin(t)

    return x,y



def sgn(x,x_shift=-0.5,y_shift=1):

    # A shifted sign function to use as a switching function 
    # in order to avoid shifts lower than -0.5 which is 
    # the radius of the circle.

    return -0.5*(np.abs(x -x_shift)/(x -x_shift)) +y_shift



def displacer(x,y,low=-0.5,high=0.5,maxrad=0.5):

    # Displaces the node points of the circle

    shift = 0
    shift_increment = 0

    for i in range(len(x)):
        shift_increment = np.random.uniform(low,high)
        shift += shift_increment*sgn(maxrad)

        x[i] += x[i]*shift
        y[i] += y[i]*shift

    x = np.append(x,x[0])
    y = np.append(y,y[0])

    return x,y




def patch_distributor(M,N,res,grid='square'):
    
    # Distribute Patches based on a specified pattern/grid.
    
    if grid == 'square':
        data = np.zeros(shape=(M,N,2,res+1))

        for i in range(M):
            for j in range(N):
                x,y = displacer(*node_circle(res=res),low=-0.2,high=0.2)
                data[i,j,0,:] = x
                data[i,j,1,:] = y
        
        return data



def plot(res):

    # Actually visualises everything

    fig, ax = plt.subplots(figsize=(4,4))

    # np.random.seed(1)

    ax.axis('off')

    # x,y = node_circle(res=res)
    # x,y = displacer(x,y,low=-0.15,high=0.15)
    # xy = np.zeros((len(x),2))
    # xy[:,0] = x
    # xy[:,1] = y

    patch_data = patch_distributor(10,10,res)

    for i in range(patch_data.shape[0]):
        for j in range(patch_data.shape[1]):
            x,y = patch_data[i,j]
            x += i*0.5
            y += j*0.5
            xy = np.zeros((len(x),2))
            xy[:,0] = x
            xy[:,1] = y

            patch = Polygon(xy,fc='w',ec='k',lw=2,zorder=np.random.randint(2),antialiased=False)
            ax.add_patch(patch)

    ax.autoscale_view()

    # ax.plot(x,y,'r-')
    # ax.scatter(x,y,)

    plt.savefig('lol.png')

plot(res=40)

# Displace circle along the line of (0,0) -> (cos(t),sin(t))
# Make the previous step influence the next to avoid jaggedness
# limit displacement level to an acceptable amount
# Random displaced cubic grid as placing points for stamps.