Python 绘制和着色圆形截面

Python 绘制和着色圆形截面,python,Python,所以,我必须做一些图形/可视化工作,这是一场噩梦,因为我在这方面没有经验 简言之,我有一系列的同心圆(b,c,d),半径为1,2,3,以及穿过原点(-x-y=0和-x+y=0)的垂直线(e,f)。下面是GeoGebra可视化: 我还有一个12个灰度像素值的数组。该数组中的每个值对应于图像部分要着色的颜色(3个圆圈,每个圆圈有4个部分)。下面是一个示例图像,为了清晰起见,我在其中用粉色着色了一个区域 我已经能够创建可以着色的饼图切片,它适用于圆b中的部分,但不适用于其他两个部分 from PI

所以,我必须做一些图形/可视化工作,这是一场噩梦,因为我在这方面没有经验

简言之,我有一系列的同心圆(b,c,d),半径为1,2,3,以及穿过原点(-x-y=0和-x+y=0)的垂直线(e,f)。下面是GeoGebra可视化:

我还有一个12个灰度像素值的数组。该数组中的每个值对应于图像部分要着色的颜色(3个圆圈,每个圆圈有4个部分)。下面是一个示例图像,为了清晰起见,我在其中用粉色着色了一个区域

我已经能够创建可以着色的饼图切片,它适用于圆b中的部分,但不适用于其他两个部分

from PIL import Image, ImageDraw

x_center = 400 // 2
y_center = 400 //2

img = Image.new('RGBA', (400, 400), 'white')

idraw = ImageDraw.Draw(img)

idraw.pieslice([x_center-100, x_center-100, 
               y_center + 106, y_center + 106], 225, 315, fill='blue')

和和弦很接近,但我需要一个弧形的底部,而不是一条直线

from PIL import Image, ImageDraw

x_center = 400 // 2
y_center = 400 //2

im = Image.new('RGBA', (400, 400), 'white')

draw = ImageDraw.Draw(im)
draw.chord([x_center-100, x_center-100, 
           y_center + 106, y_center + 106], 225, 315, fill='blue')

现在,最终目标是获取最终产品并将其保存为png或jpeg格式。这是因为每幅图像都反映了一个时间片,我想将它们全部涂抹到一个视频中。然而,我100%愿意使用任何最有效的工具,无论是PIL、matplotlib等(我对这类东西没有经验,所以我决定使用PIL/Pizz可能不是最明智的)


对这件事的任何见解都将不胜感激。

好吧,在几乎两天没有睡觉之后,我为现在或将来碰巧也有这个问题的人找到了解决办法

简而言之,我找到了每个部分中的所有坐标,然后构建了一个位图图像。它不是特别快,但它可以工作

import numpy as np
from matplotlib import pyplot as plt


def inside_circle(radius, x_center, y_center):
    """
    Determines all points that fall within a circle

    Returns a set of tuples with each tuple being an x-y coordinate 
    inside the circle

    """

    valid = set()

    for x in xrange(0, 601):
        for y in xrange(0, 601):
            if ((x - x_center)*(x- x_center)) + \
               ((y - y_center)*(y - y_center)) <= radius*radius:
                valid.add((x, y))

    return valid

def above_line(all_points, p1, p2):
    """
    Determines if each point is above the line defined by p1 and p2

    Returns a set of tuples with each tuple being an x-y coordinate 
    above line

    """

    valid = set()

    for point in all_points:
        p = np.array([point])
        is_above = np.cross(p-p1, p2-p1) < 0

        if is_above:
            valid.add(tuple(point))

    return valid

# Find all points in each circle
circle_1 = inside_circle(radius=100, x_center=300, y_center=300)
circle_2 = inside_circle(radius=200, x_center=300, y_center=300)
circle_3 = inside_circle(radius=300, x_center=300, y_center=300)

# Find all points above each line
above_positive = above_line(all_points=circle_3, 
                            p1=np.array([100, 100]), 
                            p2=np.array([300, 300]))  # pos sloped line
above_negative = above_line(all_points=circle_3, 
                            p1=np.array([100, 500]), 
                            p2=np.array([300, 300]))  # neg sloped line

# Find all points in each ring
ring_1 = circle_1
ring_2 = {i for i in circle_2 if i not in circle_1}
ring_3 = {i for i in circle_3 if i not in circle_2}

# Find all points in each wedge
wedge_0 = {i for i in circle_3 if (i in above_negative) and 
          (i in above_positive)}
wedge_1 = {i for i in circle_3 if (i in above_negative) and 
          (i not in above_positive)}
wedge_2 = {i for i in circle_3 if (i not in above_negative) and 
          (i not in above_positive)}
wedge_3 = {i for i in circle_3 if (i not in above_negative) and 
          (i in above_positive)}

# Take colours and convert each value to int (my data is floats, but 
# I have used ints for this example)
image = [255, 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255]

for index, value in enumerate(image):
    image[index] = np.int64(round(abs(value)))

# Build a list where each index holds the coordinates for a particular 
# section [{section 0 cords} ... {section 11 cords}]
wedges = [wedge_0, wedge_1, wedge_2, wedge_3]
rings = [ring_1, ring_2, ring_3]
cords_in_sections = []
section_number = 0

for ring in rings:
    current_index = 0

    while current_index < len(wedges):
        points = {i for i in ring if i in wedges[current_index]}
        cords_in_sections.append(points)

        section_number += 1
        current_index += 1

# Create an 600x600 matrix of white pixels, then change pixel values in 
# each section
pixel_matrix = np.full((600, 600), 255)

# This is ugly, but seem to work better than a {cord: colour} dict 
for row, y in enumerate(pixel_matrix):
    for column, x in enumerate(y):
        if (column, row) in cords_in_sections[0]:
            pixel_matrix[row, column] = image[0]
        elif (column, row) in cords_in_sections[1]:
            pixel_matrix[row, column] = image[1]
        elif (column, row) in cords_in_sections[2]:
            pixel_matrix[row, column] = image[2]
        elif (column, row) in cords_in_sections[3]:
            pixel_matrix[row, column] = image[3]
        elif (column, row) in cords_in_sections[4]:
            pixel_matrix[row, column] = image[4]
        elif (column, row) in cords_in_sections[5]:
            pixel_matrix[row, column] = image[5]
        elif (column, row) in cords_in_sections[6]:
            pixel_matrix[row, column] = image[6]
        elif (column, row) in cords_in_sections[7]:
            pixel_matrix[row, column] = image[7]
        elif (column, row) in cords_in_sections[8]:
            pixel_matrix[row, column] = image[8]
        elif (column, row) in cords_in_sections[9]:
            pixel_matrix[row, column] = image[9]
        elif (column, row) in cords_in_sections[10]:
            pixel_matrix[row, column] = image[10]
        elif (column, row) in cords_in_sections[11]:
            pixel_matrix[row, column] = image[11]

plt.imshow(pixel_matrix, cmap='gray')
plt.axis('off')
plt.show()
将numpy导入为np
从matplotlib导入pyplot作为plt
def内圆(半径、x_中心、y_中心):
"""
确定落在圆内的所有点
返回一组元组,每个元组都是x-y坐标
圈内
"""
valid=set()
对于x范围内的x(0601):
对于X范围内的y(0601):
如果((x-x_中心)*(x-x_中心))+\

((y-y_中心)*(y-y_中心))从最大的第一个扇区到最小的扇区序列。连续较小的圆形扇区将绘制在前面的扇区之上,给出您要查找的区域形状。例如,使用您的代码调用
idraw.pieslice

idraw.pieslice([x_center-100, x_center-100, 
           y_center+100, y_center+100], 225, 315, fill='blue')
idraw.pieslice([x_center-80, x_center-80, 
           y_center+80, y_center+80], 225, 315, fill='red')

假设您希望圆以您命名为
x\u center
y\u center
的坐标为中心,则需要为边界框添加和减去相同的值,而不是使用
[x\u center-100,x\u center-100,y\u center+106,y\u center+106]
我刚刚开始写同样的东西。只要这些区域是不透明的,这就应该像一种魅力。干杯当然你可以画一些东西。。。这是一个比我想出的更好的解决办法。我必须画5000个这样的东西,所以这个解决方案将节省我很多时间。谢谢如果重复绘制相同的图案,则只生成一次图案并重复粘贴会更有意义。生成具有透明度的图案(RGBA)。在RGBA矩形中粘贴要比绘制两个圆楔快。