Skip to content

Instantly share code, notes, and snippets.

@michaelfm1211
Last active November 23, 2022 03:35
Show Gist options
  • Save michaelfm1211/9ec0fdb5aefda514f43846d3fbb94d24 to your computer and use it in GitHub Desktop.
Save michaelfm1211/9ec0fdb5aefda514f43846d3fbb94d24 to your computer and use it in GitHub Desktop.
highly experimental and useless graphing program
from PIL import Image
from math import ceil
# these variables are not used everywhere and some parts just assume that they are both (100, 100).
# change at your own risk.
scale = (100, 100)
res = (100, 100)
# Graphs the function `expr` by plugging in every x-value on the graph and plotting the result. If
# `fillIn` is True, then the function will try to connect the dots. `expr` has the signature
# (x: float) -> float and can only be used for functions in the form y=
def graph_yeq(pixels, fillIn, expr, color):
last = None
for i in range(res[0]):
try:
y = expr(i-50)
if type(y) == complex or y > 50 or y < -50:
raise IndexError
pixels[i, 50-y] = (*color, 255)
if last is None:
last = y
if fillIn and 1 < y-last:
for j in range(ceil(y-last)):
pixels[i, 50-y+j] = (*color, 255)
elif fillIn and 1 < last-y:
for j in range(ceil(last-y)):
pixels[i-1, 50-last+j] = (*color, 255)
last = y
except IndexError:
# x-value is on the graph, but y-value isn't
pass
except ZeroDivisionError:
# x-value is not in the domain of expr()
pass
# Graphs the function `expr` by plugging in every point on the graph. This is less efficient than graph_yeq,
# but it handle stuff than can't be put into the form y=, such as circles. `expr` has the signature
# (x: float, y: float) -> (float, float). If the difference between the two elements of the returned tuple
# is less than `thres`, then the point passed to `expr` will be plotted. If `thres` is 0, then this means
# they are exactly equal, but if None is passed then a default value will be used to attempt to connect the
# lines.
def graph_eq(pixels, thres, expr, color):
if thres is None:
thres = scale[0]/res[0]
for i in range(res[0]):
for j in range(res[1]):
try:
tst = expr(i-50, 50-j)
if abs(tst[1] - tst[0]) <= thres:
pixels[i, j] = (*color, 255)
except ZeroDivisionError:
# x-value is not in the domain of expr()
pass
img = Image.new('RGBA', res, color='white')
pixels = img.load()
# axes
graph_eq(pixels, 0, lambda x, _: (x, 0), (0, 0, 0))
graph_eq(pixels, 0, lambda _, y: (y, 0), (0, 0, 0))
graph_yeq(pixels, True, lambda x: -2*x, (255, 0, 0))
graph_yeq(pixels, True, lambda x: 4*x**0.5, (0, 0, 255))
img.save('graph.png')
img.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment