Skip to content

Instantly share code, notes, and snippets.

@ddejohn
Created October 16, 2021 21:04
Show Gist options
  • Save ddejohn/fa67039541bdb7e387c403fe32a65eb9 to your computer and use it in GitHub Desktop.
Save ddejohn/fa67039541bdb7e387c403fe32a65eb9 to your computer and use it in GitHub Desktop.
Reproducible duration issue
import random
import itertools
from typing import Tuple
import numpy as np
import plotly.graph_objects as go
import gif
def random_rectangle():
x0, x1 = random.choice(GRID)
y0, y1 = random.choice(GRID)
return Rectangle(x0, x1, y0, y1)
class Color:
def __init__(self, r, g, b):
rgb = {"r": r, "g": g, "b": b}
highlight = {**rgb}
main_color = max(rgb, key=lambda k: rgb[k])
highlight[main_color] = min(255, highlight[main_color] + 25)
self.fillcolor = "rgb({r}, {g}, {b})".format(**rgb)
self.linecolor = "rgb({r}, {g}, {b})".format(**highlight)
def as_dict(self):
return dict(fillcolor=self.fillcolor, line_color=self.linecolor)
class Rectangle:
def __init__(self, x0, x1, y0, y1) -> None:
self.x0, self.x1 = sorted((x0, x1))
self.y0, self.y1 = sorted((y0, y1))
self.x = (self.x0, self.x1)
self.y = (self.y0, self.y1)
def as_dict(self):
return dict(x0=self.x0, x1=self.x1, y0=self.y0, y1=self.y1)
def __repr__(self):
return ", ".join(f"{k}: {v}" for k, v in self.as_dict().items())
def area(self):
return (self.x1 - self.x0) * (self.y1 - self.y0)
def intersect(self, other: "Rectangle"):
a, b = self, other
x_arrangements = {(a.x0, b.x0, a.x1, b.x1): (b.x0, a.x1),
(b.x0, a.x0, b.x1, a.x1): (a.x0, b.x1),
(a.x0, b.x0, b.x1, a.x1): (b.x0, b.x1),
(b.x0, a.x0, a.x1, b.x1): (a.x0, a.x1)}
y_arrangements = {(a.y0, b.y0, a.y1, b.y1): (b.y0, a.y1),
(b.y0, a.y0, b.y1, a.y1): (a.y0, b.y1),
(a.y0, b.y0, b.y1, a.y1): (b.y0, b.y1),
(b.y0, a.y0, a.y1, b.y1): (a.y0, a.y1)}
overlap_x = x_arrangements.get(tuple(sorted((*a.x, *b.x))))
overlap_y = y_arrangements.get(tuple(sorted((*a.y, *b.y))))
if not (overlap_x and overlap_y):
raise ValueError("These two rectangles do not overlap")
return Rectangle(*overlap_x, *overlap_y)
COLOR_LIST = [Color(127, 60, 141),
Color(17, 165, 121),
Color(57, 105, 172),
Color(242, 183, 1),
Color(231, 63, 116),
Color(128, 186, 90),
Color(230, 131, 16),
Color(0, 134, 149),
Color(207, 28, 144),
Color(249, 123, 114)]
COLORS = itertools.cycle(COLOR_LIST)
GRID = list(itertools.permutations(range(-4, 5), r=2))
@gif.frame
def make_rect_frame(shapes, fig):
fig.update_layout(shapes=shapes)
return fig
def make_rect(*, x0, x1, y0, y1, fillcolor, line_color):
refs = dict(xref="x", yref="y")
line = dict(type="line", **refs, line_width=3, line_color=line_color)
rect = dict(type="rect", **refs, x0=x0, x1=x1, y0=y0, y1=y1, fillcolor=fillcolor, opacity=0.25)
N = dict(x0=x0, x1=x1, y0=y1, y1=y1)
S = dict(x0=x0, x1=x1, y0=y0, y1=y0)
E = dict(x0=x1, x1=x1, y0=y0, y1=y1)
W = dict(x0=x0, x1=x0, y0=y0, y1=y1)
outline = [{**line, **coords} for coords in (N, S, E, W)]
return [rect, *outline]
def sliding_rectangle_animation(a, b_rects, a_color, b_color, trace_color):
x_vals = []
y_vals = []
frames = []
a_rect = make_rect(**a.as_dict(), **a_color)
for b in b_rects:
fig = rect_fig()
x_vals.append(b.x1)
try:
y_vals.append(a.intersect(b).area())
except ValueError:
y_vals.append(0)
b_rect = make_rect(**b.as_dict(), **b_color)
fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode="lines", line_width=3, line_color=trace_color))
frames.append(make_rect_frame(a_rect + b_rect, fig))
gif.save(frames, "sliding_rects.gif")
def rect_fig():
fig = go.Figure()
fig.update_xaxes(range=(-2, 3), visible=False, zeroline=False)
fig.update_yaxes(range=(-0.25, 1.25), visible=False, zeroline=False) #, scaleanchor="x", scaleratio=1)
fig.update_layout(height=300,
width=1000,
margin_t=0,
margin_b=0,
margin_l=0,
margin_r=0,
paper_bgcolor="#696969",
plot_bgcolor="#696969",
showlegend=False)
return fig
fixed_rect = Rectangle(-0.5, 0.5, 0, 1)
x_coords = np.arange(-3, 3, 0.01)
sliding_rects = [Rectangle(x, x + 1, 0, 1) for x in x_coords]
a_color, b_color, trace_color = random.sample(COLOR_LIST, 3)
a_color = a_color.as_dict()
b_color = b_color.as_dict()
trace_color = trace_color.fillcolor
sliding_rectangle_animation(fixed_rect, sliding_rects, a_color, b_color, trace_color)
@ddejohn
Copy link
Author

ddejohn commented Oct 16, 2021

gif.save() call on line 118

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment