所以,我必须做一些图形/可视化工作,因为我在这个领域有0经验,这已经变成了一场噩梦。
简而言之,我有一系列同心圆(b,c,d),半径为1,2,3,垂直线(e,f)穿过原点(-x - y = 0和-x + y = 0)。以下是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等等(我只是对这类东西有0次经验,所以我决定使用PIL / PILLOW可能不是最聪明的。) / p>
对此事的任何见解都将深表感谢。
答案 0 :(得分:1)
绘制从最大的第一个到最小的扇区序列。连续较小的圆形扇区将绘制在之前的扇形之上,从而为您寻找的区域形状。使用代码调用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')
答案 1 :(得分:0)
好的,所以,在没有睡了差不多2天之后,我找到了一个解决方案,适合现在或将来也遇到这个问题的人。
简而言之,我找到了每个部分内的所有坐标,然后构建了一个位图图像。它并不是特别快,但它确实有效。
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()
此代码生成以下图像:
来自不同图像数组的另一个例子: