histogram can be flashed through horizontally and vertically, linearly or at random

This commit is contained in:
Ben Hambrecht
2018-03-23 17:00:12 +01:00
parent 52cabaaaf0
commit 0d20a94c29

View File

@ -108,20 +108,19 @@ class Histogram(VMobject):
class FlashThroughHistogram(Animation): class FlashThroughHistogram(Animation):
CONFIG = { CONFIG = {
"cell_height" : 1.0,
"cell_color" : WHITE, "cell_color" : WHITE,
"cell_opacity" : 0.8, "cell_opacity" : 0.8,
"hist_opacity" : 0.2 "hist_opacity" : 0.2
} }
def __init__(self, mobject, mode = "random", **kwargs): def __init__(self, mobject, direction = "horizontal", mode = "random", **kwargs):
digest_config(self,kwargs) digest_config(self, kwargs)
self.cell_height_scaled = mobject.y_scale * self.cell_height self.cell_height = mobject.y_scale
self.prototype_cell = Rectangle( self.prototype_cell = Rectangle(
width = 1, width = 1,
height = self.cell_height_scaled, height = self.cell_height,
fill_color = self.cell_color, fill_color = self.cell_color,
fill_opacity = self.cell_opacity, fill_opacity = self.cell_opacity,
stroke_width = 0, stroke_width = 0,
@ -131,6 +130,7 @@ class FlashThroughHistogram(Animation):
y_values = mobject.y_values y_values = mobject.y_values
self.mode = mode self.mode = mode
self.direction = direction
self.generate_cell_indices(x_values,y_values) self.generate_cell_indices(x_values,y_values)
Animation.__init__(self,mobject,**kwargs) Animation.__init__(self,mobject,**kwargs)
@ -142,7 +142,7 @@ class FlashThroughHistogram(Animation):
self.cell_indices = [] self.cell_indices = []
for (i,x) in enumerate(x_values): for (i,x) in enumerate(x_values):
nb_cells = int(y_values[i]) nb_cells = y_values[i]
for j in range(nb_cells): for j in range(nb_cells):
self.cell_indices.append((i, j)) self.cell_indices.append((i, j))
@ -151,11 +151,25 @@ class FlashThroughHistogram(Animation):
shuffle(self.reordered_cell_indices) shuffle(self.reordered_cell_indices)
def cell_center_for_index(self,i,j): def cell_for_index(self,i,j):
x = self.mobject.x_values_scaled[i] - self.mobject.x_min_scaled
y = (j + 0.5) * self.cell_height_scaled if self.direction == "vertical":
center = self.mobject.get_lower_left_point() + x * RIGHT + y * UP width = self.mobject.x_scale
return center height = self.mobject.y_scale
x = (i + 0.5) * self.mobject.x_scale
y = (j + 0.5) * self.mobject.y_scale
center = self.mobject.get_lower_left_point() + x * RIGHT + y * UP
elif self.direction == "horizontal":
width = self.mobject.x_scale / self.mobject.y_values[i]
height = self.mobject.y_scale * self.mobject.y_values[i]
x = i * self.mobject.x_scale + (j + 0.5) * width
y = height / 2
center = self.mobject.get_lower_left_point() + x * RIGHT + y * UP
cell = Rectangle(width = width, height = height)
cell.move_to(center)
return cell
def update_mobject(self,t): def update_mobject(self,t):
@ -163,15 +177,16 @@ class FlashThroughHistogram(Animation):
if t == 0: if t == 0:
self.mobject.add(self.prototype_cell) self.mobject.add(self.prototype_cell)
flash_nb = int(t * (len(self.cell_indices) - 1)) flash_nb = int(t * (len(self.cell_indices))) - 1
(i,j) = self.reordered_cell_indices[flash_nb] (i,j) = self.reordered_cell_indices[flash_nb]
cell_center = self.cell_center_for_index(i,j) cell = self.cell_for_index(i,j)
self.prototype_cell.width = self.mobject.x_widths_scaled[i] self.prototype_cell.width = cell.get_width()
self.prototype_cell.height = cell.get_height()
self.prototype_cell.generate_points() self.prototype_cell.generate_points()
self.prototype_cell.move_to(cell_center) self.prototype_cell.move_to(cell.get_center())
if t == 1: #if t == 1:
self.mobject.remove(self.prototype_cell) # self.mobject.remove(self.prototype_cell)
@ -194,13 +209,13 @@ class SampleScene(Scene):
def construct(self): def construct(self):
x_values = np.array([1,2,3,4,5]) x_values = np.array([1,2,3,4,5])
y_values = np.array([15,10,6,3,10]) y_values = np.array([4,3,5,2,3])
hist1 = Histogram( hist1 = Histogram(
x_values = x_values, x_values = x_values,
y_values = y_values, y_values = y_values,
x_scale = 0.5, x_scale = 0.5,
y_scale = 0.2, y_scale = 0.5,
).shift(1*DOWN) ).shift(1*DOWN)
self.add(hist1) self.add(hist1)
self.wait() self.wait()
@ -210,8 +225,8 @@ class SampleScene(Scene):
hist2 = Histogram( hist2 = Histogram(
x_values = x_values, x_values = x_values,
y_values = y_values2, y_values = y_values2,
x_scale = 0.2, x_scale = 0.5,
y_scale = 0.2, y_scale = 0.5,
) )
v1 = hist1.get_lower_left_point() v1 = hist1.get_lower_left_point()
@ -225,8 +240,9 @@ class SampleScene(Scene):
self.play( self.play(
FlashThroughHistogram( FlashThroughHistogram(
hist1, hist1,
mode = "linear_horizontal", direction = "horizontal",
run_time = 3, mode = "linear",
run_time = 10,
rate_func = None, rate_func = None,
) )
) )