diff --git a/mysite/mysite/settings.py b/mysite/mysite/settings.py index 5213243b3da0b8424c51cf8f9b6582755979cbcd..8bf9632aaa1f012ccf6415bd1420dcf48d20144d 100644 --- a/mysite/mysite/settings.py +++ b/mysite/mysite/settings.py @@ -43,7 +43,8 @@ INSTALLED_APPS = [ 'shapely', 'path', 'mplcursors', - 'mpld3' + 'mpld3', + 'jquery', ] MIDDLEWARE = [ diff --git a/mysite/plots/polygon.py b/mysite/plots/polygon.py index db535654921a09dd1ba3b1557523e50dd60dc66e..987d7ee30fe1cc1ed0693c06655d148949a0cc34 100644 --- a/mysite/plots/polygon.py +++ b/mysite/plots/polygon.py @@ -18,7 +18,17 @@ import plotly.graph_objects as go from plotly.offline import plot from bokeh.plotting import figure from bokeh.io import output_notebook, show -from bokeh.layouts import gridplot +from bokeh.layouts import gridplot, row, layout +from bokeh.models import Legend +from bokeh.models import Arrow, NormalHead, OpenHead, VeeHead +from bokeh.core.properties import Enum +from bokeh.layouts import column +from bokeh.models import Div, BoxAnnotation +from bokeh.models import ColumnDataSource, Label, LabelSet, Range1d +from bokeh.palettes import Dark2_5 as palette +from bokeh.palettes import Viridis256 +from bokeh.models import CustomJS +import itertools a = 0.407 @@ -94,7 +104,7 @@ class Polygon2(object): 0]) # m = y2-y1/x2-x1 Formel für die Geradensteigung mithilfe aus zwei verschiedenen Punkten der Geraden return slope - def plot_polygon(self, render=True): + def plot_polygon(self, title="", render=True): """Plotting a Polygon with bokeh""" height = (int(self.height * 10)) / 10 if self.slope == math.inf: @@ -104,22 +114,22 @@ class Polygon2(object): x_data = self.x_values y_data = self.y_values TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ] - title = 'height:{} slope:{}'.format(height, slope) + if title == "": + title = 'height:{} slope:{}'.format(height, slope) + else: + title = '{} height:{} slope:{}'.format(title, height, slope) fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, ) - fig.line(x_data, y_data, legend_label="Shell.", line_width=2, muted_alpha=0.2) + fig.line(x_data, y_data, legend_label="Shell", line_width=2, muted_alpha=0.2) + fig.circle(x_data, y_data, legend_label="Shell", line_width=2, muted_alpha=0.2, size=8) spine_x_values = [x[0] for x in self.spine] spine_y_values = [x[1] for x in self.spine] fig.line(spine_x_values, spine_y_values, line_color="red", legend_label="Spine", line_width=2, muted_alpha=0.2) - fig.legend.location = "top_left" fig.legend.click_policy = "mute" if render: return show(fig) else: return fig - - - def splitter(self): left = [] right = [] @@ -167,6 +177,24 @@ class HighClass(object): self.spine_ordered_polygons = spine_ordered_polygons return spine_ordered_polygons + def plot_hc(self, ordered=False,stretch=False, render=True, plot_width=250, plot_height=250): + plots = [] + if ordered: + polygon_list = self.spine_ordered_polygons + else: + polygon_list = self.polygons + for counter, polygon in enumerate(polygon_list): + title = "Polygon {}".format(counter) + plots.append(polygon.plot_polygon(title=title, render=False)) + if stretch: + grid = gridplot(plots, ncols=4, sizing_mode='stretch_both') + else: + grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height) + if render: + return show(grid) + else: + return grid + def height_classes(polygon_list): ordered_polygons = sorted(polygon_list, key=lambda polygon: polygon.height, reverse=True) @@ -197,52 +225,6 @@ def height_classes(polygon_list): return height_classes -def high_classes_plot(high_classes): - plot_high_class_list = [] - polygon_number = 0 - polygon_title_number = 0 - for hc in high_classes: - polygon_count = len(hc.polygons) - cols = 4 - rows = math.ceil(polygon_count / cols) - - # sub_plot_titles = ['{} height:{} slope:{}'.format(number, - # (int(hc.spine_ordered_polygons[number].height * 10)) / 10, - # (int(hc.spine_ordered_polygons[number].slope * 10)) / 10) - # for number in range(0, polygon_count)] - sub_plot_titles = [] - for polygon in hc.spine_ordered_polygons: - sub_plot_titles.append( - '{} height:{} slope:{}'.format(polygon_title_number, (int(polygon.height * 10)) / 10, - (int(polygon.slope * 10)) / 10)) - polygon_title_number += 1 - fig = make_subplots(rows=rows, cols=cols, subplot_titles=sub_plot_titles) - fig.update_layout(title="Highclass {} heights: {}-{}".format(hc.i, int(hc.min_border), int(hc.max_border))) - counter = 0 - - for polygon in hc.spine_ordered_polygons: - x_data = polygon.x_values - y_data = polygon.y_values - scatter = go.Scatter(x=x_data, y=y_data, - mode='lines', name='{}'.format(polygon_number), - opacity=0.8, marker_color='green') - - spine_x_values = [x[0] for x in polygon.spine] - spine_y_values = [x[1] for x in polygon.spine] - scatter_spine = go.Scatter(x=spine_x_values, y=spine_y_values, - mode='lines', name='{} Spine'.format(polygon_number), - opacity=0.8, marker_color='red') - row = math.ceil((counter + 1) / cols) - col = (counter % cols) + 1 - fig.add_trace(scatter, row=row, col=col) - fig.add_trace(scatter_spine, row=row, col=col) - counter += 1 - polygon_number += 1 - # plt_div = plot(fig, output_type='div') - plot_high_class_list.append(fig) - return plot_high_class_list - - def create_multiple_convex_polygons(number, max_ngon): polygon_list = [] for count in range(0, number): @@ -280,107 +262,585 @@ def create_convex_polygon( return polygon2 -def plot_polygons(polygon_list,render=True, plot_width=250, plot_height=250): +def plot_polygons(polygon_list, render=True, stretch=False,plot_width=250, plot_height=250): plots = [] - for polygon in polygon_list: - plots.append(polygon.plot_polygon(render=False)) - grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height) + for counter, polygon in enumerate(polygon_list): + title = "Polygon {}".format(counter) + plots.append(polygon.plot_polygon(title=title, render=False)) + if stretch: + grid = gridplot(plots, ncols=4, sizing_mode='stretch_both') + else: + grid = gridplot(plots, ncols=4, plot_width=plot_width, plot_height=plot_height) if render: return show(grid) else: return grid -def plotly_plot_polygons(polygons): - plot_polygon_list = [] +def pack_polygons(polygons): + list_hc = height_classes(polygons) + list_containers = building_containers(list_hc) + list_mini_containers = pack_mini_containers(list_containers) + end_container = End_Container(list_mini_containers, True) + return end_container + + +class Container(object): + def __init__(self, hc): + self.hc = hc + self.hc_copy = deepcopy(hc) + self.y_boundary = hc.max_border + self.x_boundary = 0 + self.sigma = [] + self.Tree = plots.avl_tree.AVLTree() + self.root = None + self.box_boundarys_x_values = [] + self.plot_steps = [] + + def plot_container(self, sigma=None, r_l_distances=None, l_r_distances=None, min_distance=None, render=True, + title="", background_c_list=None): + legend_polygons = [] + legend_spine = [] + legend_lr = [] + legend_rl = [] + if sigma == None: + sigma = self.sigma + TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ] + # if title: + # title=title + # else: + # title="" + fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below") + for counter, polygon in enumerate(sigma): + x_values = [] + y_values = [] + for x, y in polygon.shell: + x_values.append(x) + y_values.append(y) + poly_fig = fig.line(x_values, y_values, line_width=2, muted_alpha=0.2) + circle_fig = fig.circle(x_values, y_values, line_width=2, muted_alpha=0.2) + legend_label = "Polygon{}".format(counter) + legend_polygons.append((legend_label, [poly_fig, circle_fig])) + x_spine = [x[0] for x in polygon.spine] + y_spine = [y[1] for y in polygon.spine] + + spine_fig = fig.line(x_spine, y_spine, line_color="red", line_width=2, muted_alpha=0.2) + legend_spine.append(spine_fig) + # mini-Container helper + if self.box_boundarys_x_values != []: + # print("self.box_boundarys_x_values",self.box_boundarys_x_values) + for counter, boundary in enumerate(self.box_boundarys_x_values[0:-1]): + next_boundary = self.box_boundarys_x_values[counter + 1] + if background_c_list != None: + color_box = BoxAnnotation(bottom=0, top=self.y_boundary, left=self.box_boundarys_x_values[counter], + right=next_boundary, fill_color=background_c_list[counter], + fill_alpha=0.1) + fig.add_layout(color_box) + fig.line([next_boundary, next_boundary], [0, self.y_boundary], line_dash="dotted") + fig.title.text = 'hc_{} Container -> Mini Containers'.format(self.hc.i) + if title == "": + fig.title.text = 'hc_{} Container'.format(self.hc.i) + if r_l_distances != None: + for tuple in r_l_distances: + x = tuple[0][0] + corresponding_point_x = x - tuple[1] + y = tuple[0][1] + text_point_x, text_point_y = (x - tuple[1] / 2, y) + distance = int(tuple[1]) + color = "blue" + if distance == int(min_distance): + line_dash = "solid" + else: + line_dash = "dotted" + fig_rl = fig.line([tuple[0][0], corresponding_point_x], [y, y], line_color=color, line_width=2, + muted_alpha=0.2, line_dash=line_dash) + source = ColumnDataSource(data=dict(x=[tuple[0][0] - (tuple[1] / 2)], y=[y], names=[distance])) + labels = LabelSet(x='x', y='y', text='names', level='glyph', x_offset=0, y_offset=0, source=source, + render_mode='canvas') + fig.add_layout(labels) + # fig_triangle_rl=fig.triangle([tuple[0][0],corresponding_point_x],[y,y],line_color=color,line_width=2, muted_alpha=0.2,angle=-90,angle_units="deg",size=6,fill_color=color) + # fig_triangle_rl=fig.triangle([tuple[0][0]-(tuple[1]/2)],[y],line_color=color,line_width=2, muted_alpha=0.2,angle=-90,angle_units="deg",size=6,fill_color=color) + legend_rl.append(fig_rl) + # legend_rl.append(fig_triangle_rl) + if l_r_distances != None: + for tuple in l_r_distances: + x = tuple[0][0] + corresponding_point_x = x + tuple[1] + y = tuple[0][1] + text_point_x, text_point_y = (x + tuple[1] / 2, y) + distance = int(tuple[1]) + color = "green" + if distance == int(min_distance): + line_dash = 'solid' + else: + line_dash = "dotted" + fig_lr = fig.line([tuple[0][0], corresponding_point_x], [y, y], line_color=color, line_width=2, + muted_alpha=0.2, line_dash=line_dash) + # fig_triangle_lr=fig.triangle([tuple[0][0],corresponding_point_x],[y,y],line_color=color,line_width=2, muted_alpha=0.2,angle=90,angle_units="deg",size=6,fill_color=color) + source = ColumnDataSource(data=dict(x=[tuple[0][0] + (tuple[1] / 2)], y=[y], names=[distance])) + labels = LabelSet(x='x', y='y', text='names', level='glyph', x_offset=0, y_offset=0, source=source, + render_mode='canvas') + fig.add_layout(labels) + legend_lr.append(fig_lr) + # legend_lr.append(fig_triangle_lr) + # building the custom legend + fig_boundary = fig.line([0, self.x_boundary, self.x_boundary, 0, 0], + [0, 0, self.y_boundary, self.y_boundary, 0], line_color="black", line_width=2, + muted_alpha=0.2, ) + items = legend_polygons + [("spine", legend_spine)] + if l_r_distances != None: + items.append(("distance-lr", legend_lr)) + if r_l_distances != None: + items.append(("distance-rl", legend_rl)) + items.append(("boundary", [fig_boundary])) + legend = Legend(items=items) + legend.click_policy = "mute" + fig.add_layout(legend, 'right') + if render: + return show(fig) + else: + return fig - polygon_count = len(polygons) - cols = 4 - rows = math.ceil(polygon_count / cols) - number = 0 - sub_plot_titles = [] - for polygon in polygons: - height = (int(polygon.height * 10)) / 10 - if polygon.slope == math.inf: - slope = math.inf + def plot_container_steps(self, render=True, colums=2, plot_width=600, plot_height=600): + grid = gridplot(self.plot_steps, ncols=colums, plot_width=plot_width, plot_height=plot_height) + min_border = (int(self.hc.min_border * 10)) / 10 + max_border = (int(self.hc.max_border * 10)) / 10 + # title = Div( + # text="<h1>Highclass Container {}, Polygon height: {}-{} </h1>".format(self.hc.i, min_border, max_border)) + # r = column(title, grid) + if render: + return show(grid) + else: + return grid + + # if render: + # return show(grid) + # else: + # return grid + + # def plot_container(self, sigma=None, r_l_distances=None,l_r_distances=None,min_distance=None): + # fig, ax = plt.subplots(facecolor='w', edgecolor='k', figsize=(20,12), dpi=90) + # #x,y= self.exterior.xy + # if sigma==None: + # sigma=self.sigma + # for polygon in sigma: + # x=[] + # y=[] + # for x_text, y_text in polygon.shell : + # x.append(x_text) + # y.append(y_text) + # #ax.text(x_text, y_text, '({}, {})'.format(int(x_text*10)/10, int(y_text*10)/10)) + # #print(x,y) + # ax.plot(x, y) + # ax.scatter(x, y, s=60) + # x1 = [x[0]for x in polygon.spine] + # y1= [x[1]for x in polygon.spine] + # ax.plot(x1,y1, linewidth=2,color='black') + # if self.box_boundarys_x_values!=[]: + # for boundary in self.box_boundarys_x_values: + # ax.plot([self.box_boundarys_x_values,self.box_boundarys_x_values],[0,self.y_boundary],linestyle='--') + # ax.set_title('hc_{} Container -> Mini Containers'.format(self.hc.i)) + # else: + # ax.set_title('hc_{} Container'.format(self.hc.i)) + # if r_l_distances!= None: + # for tuple in r_l_distances: + # x = tuple[0][0] + # corresponding_point_x = x-tuple[1] + # y = tuple[0][1] + # text_point_x,text_point_y = (x-tuple[1]/2,y) + # distance = int(tuple[1]) + # ax.text(text_point_x, text_point_y, '{}'.format(distance)) + # if distance==int(min_distance): + # ax.plot([tuple[0][0],corresponding_point_x],[y,y],linestyle='--',marker='<',color='green') + # else: + # ax.plot([tuple[0][0],corresponding_point_x],[y,y],linestyle='--',marker='<',color='red') + # if l_r_distances!= None: + # for tuple in l_r_distances: + # x = tuple[0][0] + # corresponding_point_x = x+tuple[1] + # y = tuple[0][1] + # text_point_x,text_point_y = (x+tuple[1]/2,y) + # distance = int(tuple[1]) + # ax.text(text_point_x, text_point_y, '{}'.format(distance)) + # if distance==int(min_distance): + # ax.plot([tuple[0][0],corresponding_point_x],[y,y],linestyle='--',marker='>',color='green') + # else: + # ax.plot([tuple[0][0],corresponding_point_x],[y,y],linestyle='--',marker='>',color='blue') + # mplcursors.cursor() + # ax.plot([0,self.x_boundary,self.x_boundary,0,0],[0,0,self.y_boundary,self.y_boundary,0]) + # return plt.show() + + def slope3(self, spine, point1): + # y = m*x+n + # (y-n)/m=x + # n = y-m*x + if spine[0][0] == spine[1][0]: # Sonderfall für eine senkrechte + distance = math.sqrt((spine[0][0] - point1[ + 0]) ** 2) # da der spine eine senkrechte ist -> der eintreffpunkt hat den gleichen y wert wie der punkt, in der Abstand formel fällt dieser wert weg + elif spine[0][1] == point1[1]: + distance = math.sqrt((spine[0][0] - point1[0]) ** 2 + (spine[0][1] - point1[1]) ** 2) + else: + slope = (spine[1][1] - spine[0][1]) / (spine[1][0] - spine[0][ + 0]) # m = y2-y1/x2-x1 Formel für die Geradensteigung mithilfe aus zwei verschiedenen Punkten der Geraden + # print("steigung", slope) + # print(point1[1]) + n = spine[0][1] - (slope * spine[0][0]) + # print("y-achsenabnschnitt",n) + point0_x = (point1[1] - n) / slope # x=(y-n)/m + # print("x-wert vom punkt",point0_x) + point0 = (point0_x, point1[1]) + distance = math.sqrt((point0[0] - point1[0]) ** 2 + (point0[1] - point1[1]) ** 2) + return distance + + def find_successor(self, vertex, array): + for counter, top_edge_point in enumerate(array): + if top_edge_point[1] >= vertex[1]: + return (array[counter - 1], top_edge_point) + + def packing_container(self, hc_polygons): + tree = self.Tree + p = [] + l = [] + r = [] + b = [] + sigma_helper = [] # vi + step_counter = 0 + for polygon in hc_polygons: + sigma_helper.append(polygon) + if self.sigma == []: + transform_x = -polygon.min_x + transform_y = -polygon.min_y + # polygon.plot_polygon("before translation") + polygon.translation(transform_x, transform_y) + + # polygon.plot_polygon("after translation") + polygon_vertices = len(polygon.right) + for count in range(0, polygon_vertices - 1): + vertice = polygon.right[count] + vertice_neighbour = polygon.right[count + 1] + self.root = self.Tree.insert_node(self.root, vertice[1], vertice, vertice_neighbour) + self.sigma.append(polygon) + self.x_boundary += polygon.width + t = deepcopy(self.sigma) # vi + # t.append(polygon) # vi + # self.plot_container(t) # vi + + self.plot_steps.append( + self.plot_container(sigma_helper, render=False, title="Step {}".format(step_counter))) + step_counter += 1 + else: + # print("self.x boundary",self.x_boundary)#p + # if polygon.min_x < self.x_boundary: + transform_x = (self.x_boundary + abs(polygon.min_x)) + 10 + # print("x_boundary:",self.x_boundary,"polygon min x abs",abs(polygon.min_x))#p + # print("transform x:",transform_x)#p + # print("polygon min x",polygon.min_x)#p + # else: + # transform_x=0 + transform_y = -polygon.min_y + polygon.translation(transform_x, transform_y) + # print(self.sigma) # vi + min_horizontal_distance = math.inf + # print("tree/n",tree.printHelper(self.root, "", True))#p + helper_0 = [] + for vertex in polygon.left: + vertex_y = vertex[1] + successor_vertex = self.Tree.find_edges(self.root, vertex_y, self.root) + corresponding_edge_points = (successor_vertex.vertice, successor_vertex.vertice_neighbour) + # print("corresponding edge points",corresponding_edge_points,"for vertex",vertex)#p + distance = self.slope3(corresponding_edge_points, vertex) + if distance <= min_horizontal_distance: + min_horizontal_distance = distance + helper_0.append((vertex, distance)) + # print("min_horizontal distance right to left",min_horizontal_distance)#p + # print("helper_0",helper_0)#p + key = polygon.spine[1][1] + # print("key to order tree array", key)#p + tree_array = self.Tree.preOrder_array((self.root), [], key) + # print("tree_array in order ",tree_array)#p + helper_1 = [] + for vertex in tree_array: + # print("vertex",vertex)#p + # print("polygon left vertices",polygon.left)#p + successor = self.find_successor(vertex, polygon.left) + # print(successor)#p + distance = self.slope3(successor, vertex) + # print("distance",distance) #p + if distance <= min_horizontal_distance: + min_horizontal_distance = distance + self.root = self.Tree.delete_node(self.root, vertex[1]) # deleting vertices from B + helper_1.append((vertex, distance)) # ------- + # for count in range(0,polygon_vertices-1): + # vertice = polygon.translated_right[count] + # vertice_neighbour = polygon.translated_right[count+1] + # self.root = self.Tree.insert_node(self.root,vertice[1],vertice,vertice_neighbour) + # print("min_horizontal distance left to right ",min_horizontal_distance) #p + # self.plot_container(sigma_helper,helper_0,helper_1,min_horizontal_distance) #--------------------- + self.plot_steps.append( + self.plot_container(sigma_helper, helper_0, helper_1, min_horizontal_distance, render=False, + title="Step {}".format(step_counter))) + step_counter += 1 + polygon.translation(-(min_horizontal_distance), 0) + # print(polygon.right)# p + for counter, vertex in enumerate(polygon.right[0:-1]): + self.root = self.Tree.insert_node(self.root, vertex[1], vertex, (polygon.right[counter + 1])) + x_boundary = max([vertex[0] for vertex in polygon.right] + [self.x_boundary]) + self.x_boundary = x_boundary + self.sigma.append(polygon) + self.plot_steps.append(self.plot_container(self.sigma, render=False, title="Finished Container")) + return self.sigma + + +def building_containers(height_classes, plot=None): + containers = [] + for height_class in height_classes: + container = Container(height_class) + if plot == True: + container.packing_container(container.hc.spine_ordered_polygons) + else: + container.packing_container(container.hc.spine_ordered_polygons) + containers.append(container) + return containers + + +class Mini_Container(object): + def __init__(self, max_width, max_height, max_polygon_width, hc_i): + self.max_polygon_width = max_polygon_width + self.current_right_boundary = 0 + self.hc_i = hc_i + self.max_width = max_width + self.height = max_height + self.c = 2.214 + self.polygons = [] + self.y_offset = 0 + self.plot_steps = [] + + def plot_container(self, render=True, title="", background_c=None): + legend_polygons = [] + legend_spine = [] + legend_lr = [] + legend_rl = [] + TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ] + fig = figure(title=title, x_axis_label='x', y_axis_label='y', tooltips=TOOLTIPS, toolbar_location="below") + if background_c != None: + # fig.background_fill_color = background_c + # fig.background_fill_alpha = 0.1 + color_box = BoxAnnotation(left=0, right=self.max_width, bottom=self.y_offset, + top=self.y_offset + self.height, fill_color=background_c, + fill_alpha=0.1) + fig.add_layout(color_box) + for counter, polygon in enumerate(self.polygons): + x_values = [] + y_values = [] + for x, y in polygon.shell: + x_values.append(x) + y_values.append(y) + poly_fig = fig.line(x_values, y_values, line_width=2, muted_alpha=0.2) + circle_fig = fig.circle(x_values, y_values, line_width=2, muted_alpha=0.2) + legend_label = "Polygon{}".format(counter) + legend_polygons.append((legend_label, [poly_fig, circle_fig])) + x_spine = [x[0] for x in polygon.spine] + y_spine = [y[1] for y in polygon.spine] + + spine_fig = fig.line(x_spine, y_spine, line_color="red", line_width=2, muted_alpha=0.2) + legend_spine.append(spine_fig) + # mini-Container helper + # old split line + + # building the custom legend + fig_boundary = fig.line([0, self.max_width, self.max_width, 0, 0], + [0 + self.y_offset, 0 + self.y_offset, self.height + self.y_offset, + self.height + self.y_offset, 0 + self.y_offset] + , line_color="black", line_width=2, muted_alpha=0.2, ) + items = legend_polygons + [("spine", legend_spine)] + items.append(("boundary", [fig_boundary])) + legend = Legend(items=items) + legend.click_policy = "mute" + fig.add_layout(legend, 'right') + if render: + return show(fig) + else: + return fig + + +# def plot_container(self,title=None): +# #fig, ax = plt.subplots(facecolor='w', edgecolor='k', figsize=(20,12), dpi=90) +# #x,y= self.exterior.xy + +# for polygon in self.polygons: +# x=[] +# y=[] +# for x_text, y_text in polygon.shell : +# x.append(x_text) +# y.append(y_text) +# ax.text(x_text, y_text-(y_text*0.1), '({}, {})'.format(int(x_text*10)/10, int(y_text*10)/10),) +# #print(x,y) +# ax.plot(x, y) +# ax.scatter(x, y, s=60) +# if title==None: +# ax.set_title('Mini-Container') +# else: +# ax.set_title(title) +# x1 = [x[0]for x in polygon.spine] +# y1= [x[1]for x in polygon.spine] +# ax.plot(x1,y1, linewidth=2,color='black') +# mplcursors.cursor() +# ax.plot([0,self.max_width,self.max_width,0,0],[0+self.y_offset,0+self.y_offset,self.height+self.y_offset,self.height+self.y_offset,0+self.y_offset]) +# return plt.show() + +def pack_mini_containers(container_array, plot_steps=False): + mini_container_array = [] + plot_steps_helper_tuples = [] + + colors = itertools.cycle(palette) + background_color_list = [next(colors)] + for container in container_array: + mini_container_plot = [] + copy_container = container # nochmal schauen ob der Schritt nötig ist bzw. ob nur ein Pointer kopiert wird statt eine deepcopy + box_width = 2.214 * copy_container.hc.w_max + box_width_helper = 0 + + box_counter = 1 + # print("container boundarys",copy_container.x_boundary) + while box_width_helper < copy_container.x_boundary: + container.box_boundarys_x_values.append(box_width_helper) + box_width_helper += box_width + background_color_list.append(next(colors)) + # if plot == True: + # copy_container.plot_container(copy_container.sigma) + # container.plot_steps.append(copy_container.plot_container(copy_container.sigma, render=True)) + container_plot = copy_container.plot_container(copy_container.sigma, render=False, + background_c_list=background_color_list) + max_width_mini_container = box_width + copy_container.hc.w_max + background_counter = 0 + while len(copy_container.sigma) > 0 and (box_width * box_counter) < (copy_container.x_boundary): + # print("max_with,y_boundary",max_width_mini_container,(copy_container.y_boundary)) + b_color = background_color_list[background_counter] + mini_container = Mini_Container(max_width_mini_container, (copy_container.y_boundary), + copy_container.hc.w_max, copy_container.hc.i) + translation_flag = True + while len(copy_container.sigma) > 0 and (copy_container.sigma[0].min_x) < (box_width * box_counter): + if translation_flag: + translation = copy_container.sigma[0].min_x + translation_flag = False + copy_container.sigma[0].translation(-translation, 0) + mini_container.polygons.append(copy_container.sigma.pop(0)) + # mini_container.plot_container() + mini_container.current_right_boundary = mini_container.polygons[-1].max_x + mini_container_array.append(mini_container) + # if plot==True: + # title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i) + # mini_container.plot_container(title) + title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i) + mini_container_plot.append(mini_container.plot_container(title=title, render=False, background_c=b_color)) + box_counter += 1 + background_counter += 1 + if len(copy_container.sigma) > 0: + mini_container = Mini_Container(max_width_mini_container, copy_container.y_boundary, + copy_container.hc.w_max, copy_container.hc.i) + translation_flag = True + while len(copy_container.sigma) > 0 and copy_container.sigma[0].min_x < box_width * box_counter: + if translation_flag: + translation = copy_container.sigma[0].min_x + translation_flag = False + copy_container.sigma[0].translation(-translation, 0) + mini_container.polygons.append(copy_container.sigma.pop(0)) + # mini_container.plot_container() + mini_container.current_right_boundary = mini_container.polygons[-1].max_x + mini_container_array.append(mini_container) + # if plot==True: + title = "Mini-Container {} (hc_{})".format(box_counter, container.hc.i) + # mini_container.plot_container(title) + mini_container_plot.append(mini_container.plot_container(title=title, render=False)) + plot_steps_helper_tuples.append((container_plot, mini_container_plot)) + if plot_steps == True: + return (mini_container_array, plot_steps_helper_tuples) + else: + return mini_container_array + + +def plot_mini_containers(plot_steps, render=True, plot_width=600, plot_height=600): + plots = [] + + # hc_container =plot_steps[0] + for plot_container in plot_steps: + plot_hc = [plot_container[0]] + plot_container[1] + grid = gridplot(plot_hc, ncols=len(plot_container[1]) + 1, plot_width=plot_width, plot_height=plot_height) + # # show(plot1) + # show(grid) + + # plots.append(grid) + # grid=row(plot_container[1]) + plots.append(grid) + # plots.append(grid) + if render: + return show(layout(plots)) + else: + return plots + + +class End_Container(object): + def __init__(self, mini_container_array, angle=0): + self.mini_containers = mini_container_array + self.pack_mini_containers() + self.container_area = self.container_area(self.mini_containers) + self.angle = angle + + def pack_mini_containers(self): + y_offset = self.mini_containers[0].height + for mini_container in self.mini_containers[1:]: + for polygon in mini_container.polygons: + polygon.translation(0, y_offset) + mini_container.y_offset = y_offset + y_offset += mini_container.height + return + + def container_area(self, mini_containers): + container_area = 0 + for mini_container in mini_containers: + container_area += mini_container.max_width * mini_container.height + return container_area + + def plot_container(self, title="", render=True): + legend_polygons = [] + legend_spine = [] + legend_lr = [] + legend_rl = [] + # fig = plt.subplots(facecolor='w', edgecolor='k', figsize=(20,12), dpi=90) + TOOLTIPS = [("index", "$index"), ("(x,y)", "($x, $y)"), ] + if title == "": + title = 'End-Container area:{}'.format((int(self.container_area/10))*10) + fig = figure(title=title, x_axis_label='x', y_axis_label='y', toolbar_location="below", tooltips=TOOLTIPS) + y_offset = 0 + colors = itertools.cycle(palette) + for counter, mini_container in enumerate(self.mini_containers): + color = next(colors) + for polygon in mini_container.polygons: + # mapper = linear_cmap(field_name='x', palette=Viridis256 ,low=min(x) ,high=max(x)) + source = ColumnDataSource(data=dict(x=polygon.x_values, y=polygon.y_values)) + spine_x_values = [x[0] for x in polygon.spine] + spine_y_values = [x[1] for x in polygon.spine] + + legend_label = "Mini-Container {} (hc{})".format(counter, mini_container.hc_i) + fig.line(x="x", y="y", line_width=2, line_color=color, muted_alpha=0.2, source=source, + legend_label=legend_label) + # fig.circle(x="x",y="y",fill_color=linear_cmap(field_name='y', palette= 'Viridis256'),source=source, line_width=2, muted_alpha=0.2,size=8) + fig.circle(x="x", y="y", line_width=2, color=color, fill_color=color, muted_alpha=0.2, size=8, + source=source, legend_label=legend_label) + # ax.scatter(x, y, s=60) + fig.line(spine_x_values, spine_y_values, line_color="red", legend_label="Spine", line_width=2, + muted_alpha=0.2) + fig.legend.click_policy = "mute" + color_box = BoxAnnotation(left=0, right=mini_container.max_width, bottom=mini_container.y_offset, + top=mini_container.y_offset + mini_container.height, fill_color=color, + fill_alpha=0.1) + fig.add_layout(color_box) + fig.line([0, mini_container.max_width, mini_container.max_width, 0, 0], + [0 + y_offset, 0 + y_offset, mini_container.height + y_offset, mini_container.height + y_offset, + 0 + y_offset], line_color=color, muted_alpha=0.2, legend_label=legend_label) + y_offset += mini_container.height + # mplcursors.cursor() + if render: + return show(fig) else: - slope = (int(polygon.slope * 10)) / 10 - sub_plot_titles.append('{} height:{} slope:{}'.format(number, height, slope)) - number += 1 - fig = make_subplots(rows=rows, cols=cols, subplot_titles=sub_plot_titles) - fig.update_layout(title="Convex Polygons") - counter = 0 - for polygon in polygons: - x_data = polygon.x_values - y_data = polygon.y_values - scatter = go.Scatter(x=x_data, y=y_data, - mode='lines', name='{}'.format(counter), - opacity=0.8, marker_color='green') - - spine_x_values = [x[0] for x in polygon.spine] - spine_y_values = [x[1] for x in polygon.spine] - scatter_spine = go.Scatter(x=spine_x_values, y=spine_y_values, - mode='lines', name='{} Spine'.format(counter), - opacity=0.8, marker_color='red') - row = math.ceil((counter + 1) / cols) - col = (counter % cols) + 1 - fig.add_trace(scatter, row=row, col=col) - fig.add_trace(scatter_spine, row=row, col=col) - counter += 1 - # plot_polygons_div = plot(fig, output_type='div') - - return fig - - -def high_class_plot(high_classes): - plot_high_class_list = [] - polygon_number = 0 - polygon_title_number = 0 - for hc in high_classes: - polygon_count = len(hc.polygons) - cols = 4 - rows = math.ceil(polygon_count / cols) - - # sub_plot_titles = ['{} height:{} slope:{}'.format(number, - # (int(hc.spine_ordered_polygons[number].height * 10)) / 10, - # (int(hc.spine_ordered_polygons[number].slope * 10)) / 10) - # for number in range(0, polygon_count)] - sub_plot_titles = [] - for polygon in hc.spine_ordered_polygons: - sub_plot_titles.append( - '{} height:{} slope:{}'.format(polygon_title_number, (int(polygon.height * 10)) / 10, - (int(polygon.slope * 10)) / 10)) - polygon_title_number += 1 - fig = make_subplots(rows=rows, cols=cols, subplot_titles=sub_plot_titles) - fig.update_layout(title="Highclass {} heights: {}-{}".format(hc.i, int(hc.min_border), int(hc.max_border))) - counter = 0 - - for polygon in hc.spine_ordered_polygons: - x_data = polygon.x_values - y_data = polygon.y_values - scatter = go.Scatter(x=x_data, y=y_data, - mode='lines', name='{}'.format(polygon_number), - opacity=0.8, marker_color='green') - - spine_x_values = [x[0] for x in polygon.spine] - spine_y_values = [x[1] for x in polygon.spine] - scatter_spine = go.Scatter(x=spine_x_values, y=spine_y_values, - mode='lines', name='{} Spine'.format(polygon_number), - opacity=0.8, marker_color='red') - row = math.ceil((counter + 1) / cols) - col = (counter % cols) + 1 - fig.add_trace(scatter, row=row, col=col) - fig.add_trace(scatter_spine, row=row, col=col) - counter += 1 - polygon_number += 1 - plt_div = plot(fig, output_type='div') - plot_high_class_list.append(plt_div) - return plot_high_class_list - - -# def pack_polygons(polygons): -# list_hc = height_classes(polygons) -# list_containers = building_containers(list_hc) -# list_mini_containers = pack_mini_containers(list_containers) -# end_container = End_Container(list_mini_containers, True) -# return end_container \ No newline at end of file + return fig \ No newline at end of file diff --git a/mysite/plots/templates/plots/get.html b/mysite/plots/templates/plots/get.html index 8a40fc6fec8684db99fabf118ef1217a728b8417..743bce7b914efe0965f47fe87e94919add9150f4 100644 --- a/mysite/plots/templates/plots/get.html +++ b/mysite/plots/templates/plots/get.html @@ -1,15 +1,83 @@ -<!DOCTYPE HTML> -<html> +<!DOCTYPE html> +<html lang="en"> <head> -<meta charset="utf-8"> + <title>Bootstrap Example</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> - {%for container_plots in containers %} - <h1>Container</h1> - {%for plot in container_plots%} - {{plot|safe}} - {%endfor%} - <hr> -{%endfor%} + {% autoescape off %} +<div style="padding-right: 15px; padding-left: 15px;"> + + <ul class="nav nav-tabs tabs-left"> + <li class="active"><a data-toggle="tab" href="#home">Home</a></li> + {%for tab in containers%} + {% with forloop.counter|stringformat:"i" as strvalue%} + <li><a data-toggle="tab" href={{"#id"|add:strvalue}}>{{"#id"|add:strvalue}}</a></li> + {%endwith%} + {%endfor %} + </ul> + +<div class="tab-content"> + <div id="home" class="tab-pane fade in active"> + <h3>HOME</h3> + <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> + </div> + {%for tab in containers%} + {% with forloop.counter|stringformat:"i" as strrvalue%} + <div id={{"id"|add:strrvalue}} class="tab-pane fade"> + + <h3>{{"id"|add:strrvalue}}</h3> + <p>{{tab|safe}}</p> + + </div> + {%endwith%} + {%endfor %} + + </div> +</div> + +<div style="padding-right: 15px; padding-left: 15px;"> + + <ul class="nav nav-tabs "> + + {%for tab in containers2%} + {% with forloop.counter|stringformat:"i" as str2value%} + {%if forloop.first %} + <li class="active"><a data-toggle="tab" href={{"#idd"|add:str2value}}>{{"#idd"|add:str2value}}</a></li> + {%else%} + <li><a data-toggle="tab" href={{"#idd"|add:str2value}}>{{"#idd"|add:str2value}}</a></li> + + {%endif%} + + {%endwith%} + {%endfor %} + </ul> + +<div class="tab-content"> + {%for tab2 in containers2%} + {% with forloop.counter|stringformat:"i" as str2value%} + {%if forloop.first %} + <div id={{"idd"|add:str2value}} class="tab-pane fade in active"> + <h3>{{"idd"|add:str2value}}</h3> + <p>{{tab2|safe}}</p> + {% else %} + <div id={{"idd"|add:str2value}} class="tab-pane fade"> + <h3>{{"idd"|add:str2value}}</h3> + <p>{{tab2|safe}}</p> + </div> + {% endif %} + + {%endwith%} + {%endfor %} + + </div> +</div> +</div> + +{% endautoescape %} </body> -</html> \ No newline at end of file +</html> diff --git a/mysite/plots/templates/plots/index.html b/mysite/plots/templates/plots/index.html index 0d3cd62d094751ca3dd786f667f9f7d7b4b9c89b..35df7adb5cb8bcc5008cfc85f4d5da8966976981 100644 --- a/mysite/plots/templates/plots/index.html +++ b/mysite/plots/templates/plots/index.html @@ -7,8 +7,37 @@ </head> <body> {% autoescape off %} +<h1>Polygons</h1> {{polygons_plot}} - {% endautoescape %} +<hr> +<h1> Highclasses</h1> +{%for hc in hc_plot%} +<h2>Highclass {{forloop.counter|add:"-1"}}</h2> + {{hc}} +{% if forloop.last is not True%} +<hr style="border: 2px dashed #C0C0C0" > +{%else%} +<hr> +{%endif%} +{%endfor%} + +<h1>Highclasses -> Container</h1> +{{container_plot}} + + +{%for mini_container in mini_container_plot%} +<h2>Highclass-Container {{forloop.counter|add:"-1"}} -> Mini-Containers </h2> +{{mini_container}} +{% if forloop.last is not True%} +<hr style="border: 2px dashed #C0C0C0" > +{%else%} +<hr> +{%endif%} + +{%endfor%} +<h1>End Container</h1> +{{end_container_plot}} +{% endautoescape %} </body> </html> \ No newline at end of file diff --git a/mysite/plots/templates/plots/index0.html b/mysite/plots/templates/plots/index0.html new file mode 100644 index 0000000000000000000000000000000000000000..0008ccb791159fbee4a11989ecf9e7407da8bc74 --- /dev/null +++ b/mysite/plots/templates/plots/index0.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>test</title> +</head> +<body> +<div> +{% autoescape off %} + +<h1>Polygons</h1> +{{polygons_plot}} +<hr> +<h1> Highclasses</h1> +{{hc_plot}} +<hr> +<h1>Highclasses -> Container</h1> +{{container_plot}} +<hr> + + +<h2>Highclass-Container -> Mini-Containers </h2> +{{mini_container_plot}} +<hr> + + + +<h1>End Container</h1> +{{end_container_plot}} +{% endautoescape %} +</div> +</body> +</html> \ No newline at end of file diff --git a/mysite/plots/urls.py b/mysite/plots/urls.py index 27c6795589bc2fedb996e1e53c2804009914c3ac..ad5e0be7cf4a52c9745b2a3f510b460286a0e3a5 100644 --- a/mysite/plots/urls.py +++ b/mysite/plots/urls.py @@ -4,5 +4,5 @@ from . import views urlpatterns = [ path('plot/', views.index, name='index'), - #path('json/', views.get_json_view, name='index2'), + path('json/', views.get_json_view, name='index2'), ] \ No newline at end of file diff --git a/mysite/plots/views.py b/mysite/plots/views.py index 594e4aecbf133e787e317a70459fe340ce4d4fab..035e25bc2946e0c9973955d2306a1d1e2aa4a66b 100644 --- a/mysite/plots/views.py +++ b/mysite/plots/views.py @@ -18,17 +18,93 @@ import math from plots import plot_helpers from bokeh.plotting import figure, output_file, show from bokeh.resources import CDN +from bokeh.models.widgets import Panel, Tabs +from bokeh.layouts import layout +from bokeh.models.widgets import Tabs, Panel +from bokeh.io import curdoc +from bokeh.plotting import figure + + # def index(request): # return HttpResponse("Hello, world. You're at the polls index.") def index(request): + # list_hc = height_classes(polygons) + # list_containers = building_containers(list_hc) + # list_mini_containers = pack_mini_containers(list_containers) + # end_container = End_Container(list_mini_containers, True) #[(0.5, 0), (0, 1), (1, 0), (0.5, 0)] - convex_polygons = poly.create_multiple_convex_polygons(10,3) - polygons_plot=poly.plot_polygons(convex_polygons,False,500,500) + convex_polygons = poly.create_multiple_convex_polygons(14,3) + polygons_plot= poly.plot_polygons(convex_polygons,plot_width=300,plot_height=300,render=False) html_polygons = file_html(polygons_plot, CDN, "my plot") - return render(request, 'plots/index.html', context={'polygons_plot': html_polygons,}) + + high_classes = poly.height_classes(convex_polygons) + # hc_plot_helper=[] + # for hc in high_classes: + # hc_plot = hc.plot_hc(render=False,plot_width=300,plot_height=300) + # html_hc = file_html(hc_plot, CDN, "my plot") + # hc_plot_helper.append(html_hc) + hc_tab_list = [] + counter = 0 + for hc in high_classes: + hc_plot = hc.plot_hc(render=False,plot_width=300,plot_height=300) + # html_container = file_html(container_plot, CDN, "my plot") + # container_plot_helper.append(html_container) + tab = Panel(child=hc_plot, title="High-Class {}".format(counter, counter)) + hc_tab_list.append(tab) + counter += 1 + hc_tabs = Tabs(tabs=hc_tab_list) + hc_plot_helper = file_html(hc_tabs, CDN, "my plot") + + + + + list_containers = poly.building_containers(high_classes) + container_plot_helper = [] + tab_list=[] + counter = 0 + for container in list_containers: + container_plot = container.plot_container_steps(plot_width=500,colums=3,plot_height=500,render=False) + #html_container = file_html(container_plot, CDN, "my plot") + #container_plot_helper.append(html_container) + tab = Panel(child=container_plot, title="High-Class {} -> Container {}".format(counter, counter)) + tab_list.append(tab) + counter += 1 + tabs = Tabs(tabs=tab_list) + container_plot_helper= file_html(tabs, CDN, "my plot") + + + mini_containers_tuple = poly.pack_mini_containers(list_containers,plot_steps=True) + list_mini_containers = mini_containers_tuple[0] + mini_container_plots = mini_containers_tuple[1] + mini_plot = poly.plot_mini_containers(mini_container_plots,render=False) + + mini_plots=[] + mini_plots_tabs=[] + for counter,m_plot in enumerate(mini_plot): + print(m_plot) + # print(m_plot[0]) + # print(m_plot[1]) + tab = Panel(child=m_plot, title="Container {} -> Mini-Container {}".format(counter, counter)) + mini_plots_tabs.append(tab) + + #m_plot = layout([[m_plot]],sizing_mode="scale_both") + #mini_plots.append(file_html( m_plot, CDN, "my plot")) + #tabs.append(Panel(child=m_plot, title="circle {}".format(counter))) + mini_tabs = Tabs(tabs=mini_plots_tabs) + mini_html_plots = file_html(mini_tabs, CDN, "my plot") + #tab =Tabs(tabs=tabs) + + #mini_html_plots= mini_plots + + end_container = poly.End_Container(list_mini_containers) + end_container_plot= end_container.plot_container(render=False) + end_container_html =file_html(end_container_plot, CDN, "my plot2") + return render(request, 'plots/index0.html', context={'polygons_plot': html_polygons,'hc_plot': hc_plot_helper,'container_plot': container_plot_helper, + 'mini_container_plot': mini_html_plots, 'end_container_plot':end_container_html}) + # 'high_classes': plot_high_class_list,}) # 'hc_container': hc_container}) @@ -36,13 +112,54 @@ def index(request): -# def get_json_view(request): -# convex_polygons = poly.create_multiple_convex_polygons(10, 3) -# hc = poly.height_classes(convex_polygons) -# containers = poly.building_containers(hc) -# -# container_plots=[] -# for container in containers: -# container_plots.append(container.plots) -# #g = convex_polygons[0].plot_polygon() -# return render(request, 'plots/get.html', context={'containers': container_plots,}) \ No newline at end of file +def get_json_view(request): + convex_polygons = poly.create_multiple_convex_polygons(14, 3) + #polygons_plot = poly.plot_polygons(convex_polygons, plot_width=300, plot_height=300, render=False) + #html_polygons = file_html(polygons_plot, CDN, "my plot") + list_hc = poly.height_classes(convex_polygons) + list_containers = poly.building_containers(list_hc) + + tab_list=[] + counter=0 + for container in list_containers: + container_plot = container.plot_container_steps(plot_width=500, colums=3, plot_height=500, render=False) + #tab1 = Panel(child=container_plot, title="High-Class {} -> Container {}".format(counter,counter)) + tab_list.append(file_html(container_plot, CDN, "my plot")) + counter +=1 + #html_container = file_html(tab_list, CDN, "my plot") + + #container_plot_helper.append(html_container) + #tabs = Tabs(tabs=tab_list) + response = tab_list + + mini_containers_tuple = poly.pack_mini_containers(list_containers, plot_steps=True) + list_mini_containers = mini_containers_tuple[0] + mini_container_plots = mini_containers_tuple[1] + + mini_plot = poly.plot_mini_containers(mini_container_plots, render=False) + + mini_plots = [] + tabs = [] + for counter, m_plot in enumerate(mini_plot): + + mini_plots.append(file_html(m_plot, CDN, "my plot")) + # tabs.append(Panel(child=m_plot, title="circle {}".format(counter))) + # tab =Tabs(tabs=tabs) + mini_html_plots = mini_plots + + # fig1 = figure() + # fig1.circle([0, 1, 2], [1, 3, 2]) + # fig2 = figure() + # fig2.circle([0, 0, 2], [4, -1, 1]) + # fig3 = figure() + # fig3.circle([0, 4, 3], [1, 2, 0]) + # + # l1 = layout([[fig1, fig2]]) + # l2 = layout([[fig3]]) + # + # tab1 = Panel(child=fig1, title="This is Tab 1") + # tab2 = Panel(child=fig2, title="This is Tab 2") + # tabs = Tabs(tabs=[tab1, tab2]) + # response =file_html(tabs, CDN, "my plot") + #show(tabs) + return render(request, 'plots/get.html', context={'containers': response,'containers2':mini_plots}) \ No newline at end of file diff --git a/mysite/requirements/base.txt b/mysite/requirements/base.txt index 007b0b553f4f41427d861739d0dfaba358f3ff75..a7e87411862532a45874732c3abab9b44e7e9bc0 100644 --- a/mysite/requirements/base.txt +++ b/mysite/requirements/base.txt @@ -4,4 +4,5 @@ path==15.0.0 numpy==1.19.2 mplcursors==0.3 mpld3 -bokeh \ No newline at end of file +bokeh +django-jquery \ No newline at end of file