我想知道如何在间隔(-1,1)中使用python中的PIL绘制任何函数。我已经开始使用函数y = x**2
,到目前为止我有这个:
from PIL import Image
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def parabola(x):
return (-1) * (x ** 2)
def draw_function(function, size=200):
im = Image.new("RGB", (size, size))
for x in range(size):
for y in range(size):
if function(x)< function(y):
im.putpixel((x,y), BLACK)
else:
im.putpixel((x,y), WHITE)
im.show()
draw_function(parabola)
但我得到的只是:
我想得到:
你能告诉我问题出在哪里吗?
好吧,我不认为你正确地解决了这个问题。首先,考虑一下像素为黑色的条件意味着:
function(x) < function(y)
这并没有真正定义抛物线下面的区域。这样做的条件是
function(x) < y
另外,想想你的绘图区域是什么。这是[0, 200) x [0, 200)
。此外,在PIL
中,x
坐标在图像中向下增加,因此您的抛物线将是可见的(如果有的话)颠倒。
这是对您的代码的一点修改:
from PIL import Image
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def parabola(x):
return (-1) * ((x - 100) ** 2) + 150
def draw_function(function, size=200):
im = Image.new("RGB", (size, size))
for x in range(size):
for y in range(size):
if function(x) < y:
im.putpixel((x,y), BLACK)
else:
im.putpixel((x,y), WHITE)
im.show()
draw_function(parabola)
您需要确保x
和y
值,以便它们代表0
到size-1
范围内的坐标,以便使用它们在Image
上绘制。这是在下面的代码中完成的,首先找到函数将为该范围内的x
值返回的最小值和最大值。然后它使用它们来翻译(移动)并缩放它们,使它们都落入所需的范围。要使曲线下方的区域为填充,您需要绘制垂直线,而不是单个像素。为此,我使用ImageDraw.Draw.line()
而不是im.putpixel()
。图像背景也在WHITE
调用中初始化为Image.new()
。
另请注意,所生成的图像将从大多数教科书中显示的图像上下颠倒,因为原点是左上角,y轴从那里到左下角。大多数插图的起源都在左下角。如果你愿意,你也可以解决这个问题。
from PIL import Image, ImageDraw
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
def parabola(x):
return (-1) * (x ** 2)
def draw_function(function, size=200):
min_y, max_y = 0, 0
for x in range(size):
val = function(x)
if val < min_y:
min_y = val
if val > max_y:
max_y = val
delta = max_y - min_y
im = Image.new("RGB", (size, size), WHITE)
draw = ImageDraw.Draw(im)
for x in range(size):
y = int(((function(x)-min_y) / delta) * (size-1))
draw.line([(x, 0), (x, y)], BLACK)
im.show()
draw_function(parabola)
结果: