def UpdateGradient(self, gradient_type): self.gradient_color = GradientColor(gradient_type) # update color schema self.color_schema_dict["Density Map"] = GradientColorSchema( gradient_type) self.color_band = gradient_type self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True return self.color_schema_dict["Density Map"]
def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self, parent, data) try: self.layer_name = layer.name self.title = "Transition probility matrix (%s)" % self.layer_name self.x_label = "LISA transition states (1=HH,2=LH,3=LL,4=HL)" self.y_label = "LISA transition states" self.data = data n = len(self.data) self.enable_axis_labels = False self.enable_axis = True self.enable_axis_x = False self.enable_axis_y = False # a NxN matrix self.x_min = 1 self.x_max = n + 1 self.y_min = 1 self.y_max = n + 1 self.extent = (self.x_min, self.y_min, self.x_max, self.y_max) self.selected_polygon_ids = [] self.status_bar = self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') self.margin_right = 100 # color schema: from blue to red self.color_matrix = [] for i in range(n): color_row = [] for j in range(n): p = self.data[i][j] color_row.append(self.gradient_color.get_color_at(p)) self.color_matrix.append(color_row) except Exception as err: self.ShowMsgBox('Fail to init heat map! ' + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None
def UpdateGradient(self,gradient_type): self.gradient_color = GradientColor(gradient_type) # update color schema self.color_schema_dict["Density Map"] = GradientColorSchema(gradient_type) self.color_band = gradient_type self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True return self.color_schema_dict["Density Map"]
class GradientColorSchema(ColorSchema): def __init__(self, gradient_type): self.gradient_color = GradientColor(gradient_type) ColorSchema.__init__(self,None,[""]) def createNodeBmps(self): node_bmp = wx.EmptyBitmap(self.size[0],self.size[1]) dc = wx.MemoryDC() dc.SelectObject(node_bmp) dc.Clear() dc.DrawBitmap(self.gradient_color.get_bmp(self.size[0],self.size[1]),0,0) #dc.Destroy() self.bmps.append(node_bmp) label = 'Density Map' self.bmp_dict[label] = node_bmp
class GradientColorSchema(ColorSchema): def __init__(self, gradient_type): self.gradient_color = GradientColor(gradient_type) ColorSchema.__init__(self, None, [""]) def createNodeBmps(self): node_bmp = wx.EmptyBitmap(self.size[0], self.size[1]) dc = wx.MemoryDC() dc.SelectObject(node_bmp) dc.Clear() dc.DrawBitmap(self.gradient_color.get_bmp(self.size[0], self.size[1]), 0, 0) #dc.Destroy() self.bmps.append(node_bmp) label = 'Density Map' self.bmp_dict[label] = node_bmp
def __init__(self,parent, layer, data,**kwargs): PlottingCanvas.__init__(self,parent,data) try: self.layer_name = layer.name self.title = "Transition probility matrix (%s)" % self.layer_name self.x_label = "LISA transition states (1=HH,2=LH,3=LL,4=HL)" self.y_label = "LISA transition states" self.data = data n = len(self.data) self.enable_axis_labels = False self.enable_axis = True self.enable_axis_x = False self.enable_axis_y = False # a NxN matrix self.x_min = 1 self.x_max = n+1 self.y_min = 1 self.y_max = n+1 self.extent = (self.x_min, self.y_min, self.x_max,self.y_max) self.selected_polygon_ids = [] self.status_bar = self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') self.margin_right = 100 # color schema: from blue to red self.color_matrix = [] for i in range(n): color_row = [] for j in range(n): p = self.data[i][j] color_row.append( self.gradient_color.get_color_at(p)) self.color_matrix.append(color_row) except Exception as err: self.ShowMsgBox('Fail to init heat map! ' + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None
def compute_densityMap(cls, input, output): """ The function will be executed in each process. """ while True: args = input.get() method = args['method'] id = args['id'] if method == 'compute': # for computing KDE for each cell in grid points = args['data'] kernel = args['kernel'] bandwidth = args['bandwidth'] cellSize = args['cell_size'] grid_left = args['grid_left'] grid_lower = args['grid_lower'] grid_upper = args['grid_upper'] rows, cols = args['rows'], args['cols'] invert = False radius = bandwidth / cellSize tmpGrid = np.zeros((rows, cols)) #print '%s:%s'%(os.getpid(),args.keys()) for pt in points: X, Y = pt float_i = (Y - grid_lower) / cellSize #float_i = (grid_upper -Y) / cellSize i = int(floor(float_i - radius)) i = i if i >= 0 else 0 I = int(floor(float_i + radius)) I = I if I < rows else rows - 1 float_j = (X - grid_left) / cellSize j = int(floor(float_j - radius)) j = j if j >= 0 else 0 J = int(floor(float_j + radius)) J = J if J < cols else cols - 1 for row in xrange(i, I + 1): for col in xrange(j, J + 1): x = grid_left + (col * cellSize) y = grid_lower + (row * cellSize) d = ((x - X)**2 + (y - Y)**2)**(0.5) if d <= bandwidth: z = d / bandwidth if invert: tmpGrid[row, col] -= kernel(z) else: tmpGrid[row, col] += kernel(z) output.put({ 'id': id, 'grid': tmpGrid, 'grid_max': np.max(tmpGrid) }) elif method == 'create': grid = args['grid'] grid_max = args['grid_max'] opaque = args['opaque'] color_band = args['color_band'] gradient_color = GradientColor(color_band) # make Byte Array for bmp rows, cols = grid.shape arr = np.zeros((rows, cols, 4), np.uint8) R, G, B, A = range(4) # flip from real model coords to screen coords raster = grid raster = raster[::-1] raster_min, raster_max = raster.min(), grid_max #raster.max() raster_val_range = raster_max - raster_min if raster_val_range > 0: raster_scaled = (raster - raster_min) / (raster_max - raster_min) else: raster_scaled = raster # tranfer 0~1 value to 0~255 pixel values, red_matrix, blue_matrix, green_matrix, opaque_matrix = \ np.zeros((rows,cols)),\ np.zeros((rows, cols)), \ np.zeros((rows,cols)), \ np.ones((rows,cols))*opaque* (255/100.0) # opaque ranges (0,100) for i, row in enumerate(raster_scaled): for j, item in enumerate(row): clr = gradient_color.get_color_at(item) red_matrix[i][j] = clr.red green_matrix[i][j] = clr.green blue_matrix[i][j] = clr.blue if item < 0.15: opaque_matrix[i][j] = 0 arr[:, :, R] = (red_matrix).astype("B") arr[:, :, G] = (green_matrix).astype("B") arr[:, :, B] = (blue_matrix).astype("B") arr[:, :, A] = (opaque_matrix).astype("B") #self.opaque #alpha output.put({'id': id, 'data': arr})
def __init__(self,parent, layers, **kwargs): ShapeMap.__init__(self,parent,layers) try: self.point_layer = self.layers[0] #self.bg_layer = kwargs["background"] self.cell_size = kwargs["cell_size"] self.bandwidth = kwargs["bandwidth"] self.kernel = kwargs["kernel"] self.color_band = kwargs["color_band"] self.opaque = kwargs["opaque"] self.bufferWidth, self.bufferHeight = kwargs["size"] self.points = self.point_layer.shape_objects self.extent = self.point_layer.extent self.view = View2ScreenTransform( self.extent, self.bufferWidth, self.bufferHeight ) if kwargs.has_key("query_points"): self.query_points = kwargs["query_points"] else: self.query_points = range(len(self.points)) """ if self.bg_layer: self.layers.append(self.bg_layer) """ if len(self.query_points) < len(self.points): id_group = [self.query_points] color_group = [self.color_schema_dict[self.point_layer.name].colors[0]] edge_color_group = [self.color_schema_dict[self.point_layer.name].edge_color] """ non_query_points = list(set(range(len(self.points))) - set(self.query_points)) id_group.append(non_query_points) color_group.append(wx.Colour(255,255,255,0)) edge_color_group.append(wx.Colour(255,255,255,0)) """ self.draw_layers[self.point_layer].set_data_group(id_group) self.draw_layers[self.point_layer].set_fill_color_group(color_group) self.draw_layers[self.point_layer].set_edge_color_group(edge_color_group) # setup gradient color self.gradient_color = GradientColor(self.color_band) # for tree node self.color_schema_dict["Density Map"] = GradientColorSchema(self.color_band) self.isHideDensityMap = False # for export gif self.img_array_rgb = None self.isResizing = False self.cells_Updated = False self.bmp = None self.setup_densityMap() self.createDensityMap() # dummy Layer for density map self.layer_seq_list = [] self.layer_seq_list.insert(0,"Density Map") self.layer_name_list.insert(0,"Density Map") except Exception as err: self.ShowMsgBox("""Density map could not be created. Please choose/input valid parameters. Details: """ + str(err.message)) self.UnRegister() self.parentFrame.Close(True) return None
class DensityMap(ShapeMap): """ wxWindow drawing density map based on points data or POINT SHAPE file """ def __init__(self,parent, layers, **kwargs): ShapeMap.__init__(self,parent,layers) try: self.point_layer = self.layers[0] #self.bg_layer = kwargs["background"] self.cell_size = kwargs["cell_size"] self.bandwidth = kwargs["bandwidth"] self.kernel = kwargs["kernel"] self.color_band = kwargs["color_band"] self.opaque = kwargs["opaque"] self.bufferWidth, self.bufferHeight = kwargs["size"] self.points = self.point_layer.shape_objects self.extent = self.point_layer.extent self.view = View2ScreenTransform( self.extent, self.bufferWidth, self.bufferHeight ) if kwargs.has_key("query_points"): self.query_points = kwargs["query_points"] else: self.query_points = range(len(self.points)) """ if self.bg_layer: self.layers.append(self.bg_layer) """ if len(self.query_points) < len(self.points): id_group = [self.query_points] color_group = [self.color_schema_dict[self.point_layer.name].colors[0]] edge_color_group = [self.color_schema_dict[self.point_layer.name].edge_color] """ non_query_points = list(set(range(len(self.points))) - set(self.query_points)) id_group.append(non_query_points) color_group.append(wx.Colour(255,255,255,0)) edge_color_group.append(wx.Colour(255,255,255,0)) """ self.draw_layers[self.point_layer].set_data_group(id_group) self.draw_layers[self.point_layer].set_fill_color_group(color_group) self.draw_layers[self.point_layer].set_edge_color_group(edge_color_group) # setup gradient color self.gradient_color = GradientColor(self.color_band) # for tree node self.color_schema_dict["Density Map"] = GradientColorSchema(self.color_band) self.isHideDensityMap = False # for export gif self.img_array_rgb = None self.isResizing = False self.cells_Updated = False self.bmp = None self.setup_densityMap() self.createDensityMap() # dummy Layer for density map self.layer_seq_list = [] self.layer_seq_list.insert(0,"Density Map") self.layer_name_list.insert(0,"Density Map") except Exception as err: self.ShowMsgBox("""Density map could not be created. Please choose/input valid parameters. Details: """ + str(err.message)) self.UnRegister() self.parentFrame.Close(True) return None def OnShapesSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event event is an instance of EventHandler.Event class event.object are the data for selecting shape objects """ if not event: return if not self.buffer: return data = event.data if len(data.boundary) >0: # select shape object by boundary # prepare DC for brushing drawing tmp_buffer = wx.EmptyBitmap(self.bufferWidth, self.bufferHeight) tmp_dc = wx.BufferedDC(None, tmp_buffer) tmp_dc.DrawBitmap(self.drawing_backup_buffer,0,0) regions = [] if isinstance(data.boundary[0], int) or isinstance(data.boundary[0], float): regions.append(data.boundary) elif isinstance(data.boundary, list): regions = data.boundary for region in regions: x,y,x0,y0 = region x,y = self.view.view_to_pixel(x,y) x0,y0 = self.view.view_to_pixel(x0,y0) select_region = (x,y,x0,y0) w = abs(x-x0) h = abs(y-y0) start_x,start_y = min(x0,x),min(y,y0) tmp_dc.SetPen(wx.RED_PEN) tmp_dc.SetBrush(wx.TRANSPARENT_BRUSH) tmp_dc.DrawRectangle(int(start_x),int(start_y),int(w),int(h)) self.buffer = tmp_buffer self.Refresh(False) def set_opaque(self, opaque): """ Set the opaque of the Density Map Value range (0-255), less value, more transparent """ self.opaque = opaque """ Overwrite draw_background() to draw MAP buffer and DenstiyMAP buffer as background """ if self.buffer: dc.DrawBitmap(self.buffer,0,0) if self.bmp: # always scale density map to correct window size and draw them scale_x = self.bmp_width / float(self.cols) scale_y = self.bmp_height / float(self.rows) dc.SetUserScale(scale_x, scale_y) dc.DrawBitmap(self.bmp, self.bmp_left/scale_x, self.bmp_upper/scale_y) def createDensityMap(self): # compute density map, just once if self.cells_Updated == False: n = len(self.points) progress_dlg = wx.ProgressDialog( "Progress", "Creating density map... ", maximum = 2, parent=self, style = wx.PD_APP_MODAL|wx.PD_AUTO_HIDE ) progress_dlg.CenterOnScreen() progress_dlg.Update(1) self.grid_to_buffer() progress_dlg.Update(2) def DoDraw(self,dc): """ Implement inhereted DoDraw() function It will be called when window initialize and resize """ # draw layer in buffer for layer_name in self.layer_name_list[::-1]: if layer_name == "Density Map": if self.isHideDensityMap == False: self.drawDensityMap(dc) else: layer = self.layer_dict[layer_name] if self.hide_layers[layer] == False: self.draw_layers[layer].draw(dc,self.view) def drawDensityMap(self,dc): bmp = self.bmp if self.isResizing: # resize bmp self.setup_bitmap() image = wx.ImageFromBitmap(self.bmp) if self.bmp_width > self.bufferWidth or self.bmp_height > self.bufferHeight: cropLeft = 0 if self.bmp_left < 0: cropLeft = abs(self.bmp_left) / self.bmp_width * self.bmp.Width cropUpper = 0 if self.bmp_upper < 0: cropUpper = abs(self.bmp_upper) / self.bmp_height * self.bmp.Height cropWidth = self.bufferWidth / self.bmp_width * self.bmp.Width if self.bmp_left > 0: cropWidth = (self.bufferWidth - self.bmp_left) / self.bmp_width * self.bmp.Width cropHeight = self.bufferHeight / self.bmp_height * self.bmp.Height if self.bmp_upper > 0: cropHeight = (self.bufferHeight - self.bmp_upper) / self.bmp_height * self.bmp.Height if cropWidth > 0 and cropHeight > 0: image = image.GetSubImage(wx.Rect(cropLeft,cropUpper,cropWidth,cropHeight)) image = image.Scale(self.bufferWidth, self.bufferHeight, wx.IMAGE_QUALITY_HIGH) bmp = wx.BitmapFromImage(image) start_x = 0 start_y = 0 if self.bmp_left > 0: start_x = self.bmp_left if self.bmp_upper > 0: start_y = self.bmp_upper dc.DrawBitmap(bmp,start_x,start_y) else: image = image.Scale(self.bmp_width, self.bmp_height, wx.IMAGE_QUALITY_HIGH) bmp = wx.BitmapFromImage(image) dc.DrawBitmap(bmp,self.bmp_left, self.bmp_upper) self.isResizing = False else: # draw density map, by zooming the Density Map dc.DrawBitmap(bmp, self.bmp_left, self.bmp_upper) def UpdateGradient(self,gradient_type): self.gradient_color = GradientColor(gradient_type) # update color schema self.color_schema_dict["Density Map"] = GradientColorSchema(gradient_type) self.color_band = gradient_type self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True return self.color_schema_dict["Density Map"] def UpdateOpaque(self, opaque): self.opaque = opaque self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True def OnSize(self, event): """ overwrittern for resizing kde map""" self.isResizing = True super(DensityMap, self).OnSize(event) def _zoom_end(self, mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h): """ overwrittern for zooming with mouse """ self.isResizing = True super(DensityMap, self)._zoom_end(mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h) def _pan_end(self, mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h): """ overwrittern for panning with mouse """ self.isResizing = True super(DensityMap, self)._pan_end(mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h) self.reInitBuffer = True def restore(self): """ overwritten for restoring/extenting kde map """ self.isResizing = True super(DensityMap, self).restore() def setup_densityMap(self): """ Setup the parameters of Density Map. extent, width, height, grid, view_transformer etc. """ if self.bufferWidth >0 and self.bufferHeight>0: # from extend to grid left, lower, right, upper = self.extent extent_width = self.extent[2] - self.extent[0] extent_height = self.extent[3] - self.extent[1] self.cols = int(ceil(extent_width / float(self.cell_size))) self.rows = int(ceil(extent_height/ float(self.cell_size))) self.grid = np.zeros((self.rows,self.cols)) # grid variables self.grid_lower = lower + ( self.cell_size/2.0) self.grid_upper = self.grid_lower + ( (self.rows -1 ) * self.cell_size) self.grid_left = left + (self.cell_size/2.0) self.grid_right = self.grid_left + ( (self.cols -1) * self.cell_size) def setup_bitmap(self): """ bmp variables, in case of resize/pan/extent/zoom """ left, lower, right, upper = self.extent self.bmp_left, self.bmp_upper = self.view.view_to_pixel( left, upper) self.bmp_right, self.bmp_lower = self.view.view_to_pixel( right, lower) self.bmp_width = self.bmp_right - self.bmp_left self.bmp_height = self.bmp_lower - self.bmp_upper def update_density(self,X,Y,invert=False): """ Go through each point in data, and calculate the density value of cells it impacted. """ cellSize = self.cell_size radius = self.bandwidth / cellSize float_i = (Y - self.grid_lower) / cellSize #float_i = (self.grid_upper -Y) / cellSize i = int(floor(float_i - radius)) i = i if i >= 0 else 0 I = int(floor(float_i + radius)) I = I if I < self.rows else self.rows-1 float_j = (X-self.grid_left) / cellSize j = int(floor(float_j - radius)) j = j if j >= 0 else 0 J = int(floor(float_j + radius)) J = J if J < self.cols else self.cols-1 for row in xrange(i,I+1): for col in xrange(j,J+1): x = self.grid_left + (col*cellSize) y = self.grid_lower + (row*cellSize) d = ((x-X)**2 + (y-Y)**2) ** (0.5) if d <= self.bandwidth: z = d/self.bandwidth if invert: self.grid[row,col] -= self.kernel(z) else: self.grid[row,col] += self.kernel(z) self.cells_Updated = True def grid_to_buffer(self): from stars.core.DKDEWrapper import call_kde x = [] y = [] for i in self.query_points: pt = self.points[i] x.append(pt[0]) y.append(pt[1]) n = len(self.query_points) if n < len(self.points): query_points = range(n) arr,rows,cols,grad_min,grad_max = call_kde( n, x, y, #self.query_points, range(n), self.extent, self.bandwidth, self.cell_size, self.kernel, self.color_band, self.opaque*2.55 ) #from PIL import Image #Image.fromarray(arr).save("test.png") self.bmp = wx.BitmapFromBufferRGBA(cols, rows, arr) #self.bmp.SaveFile("test.png", wx.BITMAP_TYPE_PNG) self.gradient_color_min = grad_min self.gradient_color_max = grad_max def grid_to_buffer1(self): """ Draw GRID based Density Map to wxBitmap. Here, directly drawing GRID map onto a RGBA Bitmap. Then, this Bitmap will be draw to self.buffer. """ if self.grid.max() == 0: return wx.EmptyBitmapRGBA(self.rows, self.cols,255,255,255) self.setup_bitmap() # make Byte Array arr = np.zeros((self.rows, self.cols, 4), np.uint8) R, G, B, A = range(4) # tranfer 0~1 value to 0~255 pixel values, self.raster = self.grid rows,cols = self.rows, self.cols raster_min, raster_max = self.raster.min(), self.raster.max() raster_scaled = (self.raster - raster_min)/(raster_max - raster_min) red_matrix, blue_matrix, green_matrix, opaque_matrix = np.zeros((rows,cols)),\ np.zeros((rows, cols)), np.zeros((rows,cols)), np.ones((rows,cols))*self.opaque* (255/100.0) for i,row in enumerate(raster_scaled): for j,item in enumerate(row): clr = self.gradient_color.get_color_at(item) red_matrix[i][j] = clr.red green_matrix[i][j] = clr.green blue_matrix[i][j] = clr.blue if item <0.15: opaque_matrix[i][j] = 0 arr[:,:,R] = (red_matrix).astype("B") arr[:,:,G] = (green_matrix).astype("B") arr[:,:,B] = (blue_matrix).astype("B") arr[:,:,A] = (opaque_matrix).astype("B")#self.opaque #alpha # for export gif self.img_array_rgb = arr # use the array to create a bitmap return wx.BitmapFromBufferRGBA(cols, rows, arr) def OnCellsSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event event is an instance of EventHandler.Event class event.object are the data for selecting shape objects """ if not event: return def OnNoCellSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event Normally, event could be None, you just need to clean and refresh you selected/highlighted """ self.Refresh(False) def hide_layer(self, layer, isHide=True): # override ShapeMap.hide_layer() add isHideDensityMap if layer == None: # Density Map layer self.isHideDensityMap = isHide else: self.hide_layers[layer] = isHide self.isResizing = True self.reInitBuffer = True
def compute_densityMap(cls, input, output): """ The function will be executed in each process. """ while True: args = input.get() method = args['method'] id = args['id'] if method == 'compute': # for computing KDE for each cell in grid points = args['data'] kernel = args['kernel'] bandwidth = args['bandwidth'] cellSize = args['cell_size'] grid_left = args['grid_left'] grid_lower= args['grid_lower'] grid_upper= args['grid_upper'] rows,cols = args['rows'], args['cols'] invert = False radius = bandwidth / cellSize tmpGrid = np.zeros((rows,cols)) #print '%s:%s'%(os.getpid(),args.keys()) for pt in points: X,Y = pt float_i = (Y - grid_lower) / cellSize #float_i = (grid_upper -Y) / cellSize i = int(floor(float_i - radius)) i = i if i >= 0 else 0 I = int(floor(float_i + radius)) I = I if I < rows else rows-1 float_j = (X-grid_left) / cellSize j = int(floor(float_j - radius)) j = j if j >= 0 else 0 J = int(floor(float_j + radius)) J = J if J < cols else cols-1 for row in xrange(i,I+1): for col in xrange(j,J+1): x = grid_left + (col*cellSize) y = grid_lower + (row*cellSize) d = ((x-X)**2 + (y-Y)**2) ** (0.5) if d <= bandwidth: z = d/bandwidth if invert: tmpGrid[row,col] -= kernel(z) else: tmpGrid[row,col] += kernel(z) output.put({'id':id,'grid':tmpGrid, 'grid_max':np.max(tmpGrid)}) elif method == 'create': grid = args['grid'] grid_max = args['grid_max'] opaque = args['opaque'] color_band = args['color_band'] gradient_color = GradientColor(color_band) # make Byte Array for bmp rows,cols = grid.shape arr = np.zeros((rows, cols, 4), np.uint8) R, G, B, A = range(4) # flip from real model coords to screen coords raster = grid raster = raster[::-1] raster_min, raster_max = raster.min(), grid_max #raster.max() raster_val_range = raster_max - raster_min if raster_val_range > 0: raster_scaled = (raster - raster_min)/(raster_max - raster_min) else: raster_scaled = raster # tranfer 0~1 value to 0~255 pixel values, red_matrix, blue_matrix, green_matrix, opaque_matrix = \ np.zeros((rows,cols)),\ np.zeros((rows, cols)), \ np.zeros((rows,cols)), \ np.ones((rows,cols))*opaque* (255/100.0) # opaque ranges (0,100) for i,row in enumerate(raster_scaled): for j,item in enumerate(row): clr = gradient_color.get_color_at(item) red_matrix[i][j] = clr.red green_matrix[i][j] = clr.green blue_matrix[i][j] = clr.blue if item <0.15: opaque_matrix[i][j] = 0 arr[:,:,R] = (red_matrix).astype("B") arr[:,:,G] = (green_matrix).astype("B") arr[:,:,B] = (blue_matrix).astype("B") arr[:,:,A] = (opaque_matrix).astype("B")#self.opaque #alpha output.put({'id':id,'data':arr})
def __init__(self, parent, layers, **kwargs): ShapeMap.__init__(self, parent, layers) try: self.point_layer = self.layers[0] #self.bg_layer = kwargs["background"] self.cell_size = kwargs["cell_size"] self.bandwidth = kwargs["bandwidth"] self.kernel = kwargs["kernel"] self.color_band = kwargs["color_band"] self.opaque = kwargs["opaque"] self.bufferWidth, self.bufferHeight = kwargs["size"] self.points = self.point_layer.shape_objects self.extent = self.point_layer.extent self.view = View2ScreenTransform(self.extent, self.bufferWidth, self.bufferHeight) if kwargs.has_key("query_points"): self.query_points = kwargs["query_points"] else: self.query_points = range(len(self.points)) """ if self.bg_layer: self.layers.append(self.bg_layer) """ if len(self.query_points) < len(self.points): id_group = [self.query_points] color_group = [ self.color_schema_dict[self.point_layer.name].colors[0] ] edge_color_group = [ self.color_schema_dict[self.point_layer.name].edge_color ] """ non_query_points = list(set(range(len(self.points))) - set(self.query_points)) id_group.append(non_query_points) color_group.append(wx.Colour(255,255,255,0)) edge_color_group.append(wx.Colour(255,255,255,0)) """ self.draw_layers[self.point_layer].set_data_group(id_group) self.draw_layers[self.point_layer].set_fill_color_group( color_group) self.draw_layers[self.point_layer].set_edge_color_group( edge_color_group) # setup gradient color self.gradient_color = GradientColor(self.color_band) # for tree node self.color_schema_dict["Density Map"] = GradientColorSchema( self.color_band) self.isHideDensityMap = False # for export gif self.img_array_rgb = None self.isResizing = False self.cells_Updated = False self.bmp = None self.setup_densityMap() self.createDensityMap() # dummy Layer for density map self.layer_seq_list = [] self.layer_seq_list.insert(0, "Density Map") self.layer_name_list.insert(0, "Density Map") except Exception as err: self.ShowMsgBox( """Density map could not be created. Please choose/input valid parameters. Details: """ + str(err.message)) self.UnRegister() self.parentFrame.Close(True) return None
class DensityMap(ShapeMap): """ wxWindow drawing density map based on points data or POINT SHAPE file """ def __init__(self, parent, layers, **kwargs): ShapeMap.__init__(self, parent, layers) try: self.point_layer = self.layers[0] #self.bg_layer = kwargs["background"] self.cell_size = kwargs["cell_size"] self.bandwidth = kwargs["bandwidth"] self.kernel = kwargs["kernel"] self.color_band = kwargs["color_band"] self.opaque = kwargs["opaque"] self.bufferWidth, self.bufferHeight = kwargs["size"] self.points = self.point_layer.shape_objects self.extent = self.point_layer.extent self.view = View2ScreenTransform(self.extent, self.bufferWidth, self.bufferHeight) if kwargs.has_key("query_points"): self.query_points = kwargs["query_points"] else: self.query_points = range(len(self.points)) """ if self.bg_layer: self.layers.append(self.bg_layer) """ if len(self.query_points) < len(self.points): id_group = [self.query_points] color_group = [ self.color_schema_dict[self.point_layer.name].colors[0] ] edge_color_group = [ self.color_schema_dict[self.point_layer.name].edge_color ] """ non_query_points = list(set(range(len(self.points))) - set(self.query_points)) id_group.append(non_query_points) color_group.append(wx.Colour(255,255,255,0)) edge_color_group.append(wx.Colour(255,255,255,0)) """ self.draw_layers[self.point_layer].set_data_group(id_group) self.draw_layers[self.point_layer].set_fill_color_group( color_group) self.draw_layers[self.point_layer].set_edge_color_group( edge_color_group) # setup gradient color self.gradient_color = GradientColor(self.color_band) # for tree node self.color_schema_dict["Density Map"] = GradientColorSchema( self.color_band) self.isHideDensityMap = False # for export gif self.img_array_rgb = None self.isResizing = False self.cells_Updated = False self.bmp = None self.setup_densityMap() self.createDensityMap() # dummy Layer for density map self.layer_seq_list = [] self.layer_seq_list.insert(0, "Density Map") self.layer_name_list.insert(0, "Density Map") except Exception as err: self.ShowMsgBox( """Density map could not be created. Please choose/input valid parameters. Details: """ + str(err.message)) self.UnRegister() self.parentFrame.Close(True) return None def OnShapesSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event event is an instance of EventHandler.Event class event.object are the data for selecting shape objects """ if not event: return if not self.buffer: return data = event.data if len(data.boundary) > 0: # select shape object by boundary # prepare DC for brushing drawing tmp_buffer = wx.EmptyBitmap(self.bufferWidth, self.bufferHeight) tmp_dc = wx.BufferedDC(None, tmp_buffer) tmp_dc.DrawBitmap(self.drawing_backup_buffer, 0, 0) regions = [] if isinstance(data.boundary[0], int) or isinstance( data.boundary[0], float): regions.append(data.boundary) elif isinstance(data.boundary, list): regions = data.boundary for region in regions: x, y, x0, y0 = region x, y = self.view.view_to_pixel(x, y) x0, y0 = self.view.view_to_pixel(x0, y0) select_region = (x, y, x0, y0) w = abs(x - x0) h = abs(y - y0) start_x, start_y = min(x0, x), min(y, y0) tmp_dc.SetPen(wx.RED_PEN) tmp_dc.SetBrush(wx.TRANSPARENT_BRUSH) tmp_dc.DrawRectangle(int(start_x), int(start_y), int(w), int(h)) self.buffer = tmp_buffer self.Refresh(False) def set_opaque(self, opaque): """ Set the opaque of the Density Map Value range (0-255), less value, more transparent """ self.opaque = opaque """ Overwrite draw_background() to draw MAP buffer and DenstiyMAP buffer as background """ if self.buffer: dc.DrawBitmap(self.buffer, 0, 0) if self.bmp: # always scale density map to correct window size and draw them scale_x = self.bmp_width / float(self.cols) scale_y = self.bmp_height / float(self.rows) dc.SetUserScale(scale_x, scale_y) dc.DrawBitmap(self.bmp, self.bmp_left / scale_x, self.bmp_upper / scale_y) def createDensityMap(self): # compute density map, just once if self.cells_Updated == False: n = len(self.points) progress_dlg = wx.ProgressDialog( "Progress", "Creating density map... ", maximum=2, parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE) progress_dlg.CenterOnScreen() progress_dlg.Update(1) self.grid_to_buffer() progress_dlg.Update(2) def DoDraw(self, dc): """ Implement inhereted DoDraw() function It will be called when window initialize and resize """ # draw layer in buffer for layer_name in self.layer_name_list[::-1]: if layer_name == "Density Map": if self.isHideDensityMap == False: self.drawDensityMap(dc) else: layer = self.layer_dict[layer_name] if self.hide_layers[layer] == False: self.draw_layers[layer].draw(dc, self.view) def drawDensityMap(self, dc): bmp = self.bmp if self.isResizing: # resize bmp self.setup_bitmap() image = wx.ImageFromBitmap(self.bmp) if self.bmp_width > self.bufferWidth or self.bmp_height > self.bufferHeight: cropLeft = 0 if self.bmp_left < 0: cropLeft = abs( self.bmp_left) / self.bmp_width * self.bmp.Width cropUpper = 0 if self.bmp_upper < 0: cropUpper = abs( self.bmp_upper) / self.bmp_height * self.bmp.Height cropWidth = self.bufferWidth / self.bmp_width * self.bmp.Width if self.bmp_left > 0: cropWidth = (self.bufferWidth - self.bmp_left ) / self.bmp_width * self.bmp.Width cropHeight = self.bufferHeight / self.bmp_height * self.bmp.Height if self.bmp_upper > 0: cropHeight = (self.bufferHeight - self.bmp_upper ) / self.bmp_height * self.bmp.Height if cropWidth > 0 and cropHeight > 0: image = image.GetSubImage( wx.Rect(cropLeft, cropUpper, cropWidth, cropHeight)) image = image.Scale(self.bufferWidth, self.bufferHeight, wx.IMAGE_QUALITY_HIGH) bmp = wx.BitmapFromImage(image) start_x = 0 start_y = 0 if self.bmp_left > 0: start_x = self.bmp_left if self.bmp_upper > 0: start_y = self.bmp_upper dc.DrawBitmap(bmp, start_x, start_y) else: image = image.Scale(self.bmp_width, self.bmp_height, wx.IMAGE_QUALITY_HIGH) bmp = wx.BitmapFromImage(image) dc.DrawBitmap(bmp, self.bmp_left, self.bmp_upper) self.isResizing = False else: # draw density map, by zooming the Density Map dc.DrawBitmap(bmp, self.bmp_left, self.bmp_upper) def UpdateGradient(self, gradient_type): self.gradient_color = GradientColor(gradient_type) # update color schema self.color_schema_dict["Density Map"] = GradientColorSchema( gradient_type) self.color_band = gradient_type self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True return self.color_schema_dict["Density Map"] def UpdateOpaque(self, opaque): self.opaque = opaque self.grid_to_buffer() self.isResizing = True self.reInitBuffer = True def OnSize(self, event): """ overwrittern for resizing kde map""" self.isResizing = True super(DensityMap, self).OnSize(event) def _zoom_end(self, mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h): """ overwrittern for zooming with mouse """ self.isResizing = True super(DensityMap, self)._zoom_end(mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h) def _pan_end(self, mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h): """ overwrittern for panning with mouse """ self.isResizing = True super(DensityMap, self)._pan_end(mouse_start_pos, mouse_end_pos, mouse_select_w, mouse_select_h) self.reInitBuffer = True def restore(self): """ overwritten for restoring/extenting kde map """ self.isResizing = True super(DensityMap, self).restore() def setup_densityMap(self): """ Setup the parameters of Density Map. extent, width, height, grid, view_transformer etc. """ if self.bufferWidth > 0 and self.bufferHeight > 0: # from extend to grid left, lower, right, upper = self.extent extent_width = self.extent[2] - self.extent[0] extent_height = self.extent[3] - self.extent[1] self.cols = int(ceil(extent_width / float(self.cell_size))) self.rows = int(ceil(extent_height / float(self.cell_size))) self.grid = np.zeros((self.rows, self.cols)) # grid variables self.grid_lower = lower + (self.cell_size / 2.0) self.grid_upper = self.grid_lower + ( (self.rows - 1) * self.cell_size) self.grid_left = left + (self.cell_size / 2.0) self.grid_right = self.grid_left + ( (self.cols - 1) * self.cell_size) def setup_bitmap(self): """ bmp variables, in case of resize/pan/extent/zoom """ left, lower, right, upper = self.extent self.bmp_left, self.bmp_upper = self.view.view_to_pixel(left, upper) self.bmp_right, self.bmp_lower = self.view.view_to_pixel(right, lower) self.bmp_width = self.bmp_right - self.bmp_left self.bmp_height = self.bmp_lower - self.bmp_upper def update_density(self, X, Y, invert=False): """ Go through each point in data, and calculate the density value of cells it impacted. """ cellSize = self.cell_size radius = self.bandwidth / cellSize float_i = (Y - self.grid_lower) / cellSize #float_i = (self.grid_upper -Y) / cellSize i = int(floor(float_i - radius)) i = i if i >= 0 else 0 I = int(floor(float_i + radius)) I = I if I < self.rows else self.rows - 1 float_j = (X - self.grid_left) / cellSize j = int(floor(float_j - radius)) j = j if j >= 0 else 0 J = int(floor(float_j + radius)) J = J if J < self.cols else self.cols - 1 for row in xrange(i, I + 1): for col in xrange(j, J + 1): x = self.grid_left + (col * cellSize) y = self.grid_lower + (row * cellSize) d = ((x - X)**2 + (y - Y)**2)**(0.5) if d <= self.bandwidth: z = d / self.bandwidth if invert: self.grid[row, col] -= self.kernel(z) else: self.grid[row, col] += self.kernel(z) self.cells_Updated = True def grid_to_buffer(self): from stars.core.DKDEWrapper import call_kde x = [] y = [] for i in self.query_points: pt = self.points[i] x.append(pt[0]) y.append(pt[1]) n = len(self.query_points) if n < len(self.points): query_points = range(n) arr, rows, cols, grad_min, grad_max = call_kde( n, x, y, #self.query_points, range(n), self.extent, self.bandwidth, self.cell_size, self.kernel, self.color_band, self.opaque * 2.55) #from PIL import Image #Image.fromarray(arr).save("test.png") self.bmp = wx.BitmapFromBufferRGBA(cols, rows, arr) #self.bmp.SaveFile("test.png", wx.BITMAP_TYPE_PNG) self.gradient_color_min = grad_min self.gradient_color_max = grad_max def grid_to_buffer1(self): """ Draw GRID based Density Map to wxBitmap. Here, directly drawing GRID map onto a RGBA Bitmap. Then, this Bitmap will be draw to self.buffer. """ if self.grid.max() == 0: return wx.EmptyBitmapRGBA(self.rows, self.cols, 255, 255, 255) self.setup_bitmap() # make Byte Array arr = np.zeros((self.rows, self.cols, 4), np.uint8) R, G, B, A = range(4) # tranfer 0~1 value to 0~255 pixel values, self.raster = self.grid rows, cols = self.rows, self.cols raster_min, raster_max = self.raster.min(), self.raster.max() raster_scaled = (self.raster - raster_min) / (raster_max - raster_min) red_matrix, blue_matrix, green_matrix, opaque_matrix = np.zeros((rows,cols)),\ np.zeros((rows, cols)), np.zeros((rows,cols)), np.ones((rows,cols))*self.opaque* (255/100.0) for i, row in enumerate(raster_scaled): for j, item in enumerate(row): clr = self.gradient_color.get_color_at(item) red_matrix[i][j] = clr.red green_matrix[i][j] = clr.green blue_matrix[i][j] = clr.blue if item < 0.15: opaque_matrix[i][j] = 0 arr[:, :, R] = (red_matrix).astype("B") arr[:, :, G] = (green_matrix).astype("B") arr[:, :, B] = (blue_matrix).astype("B") arr[:, :, A] = (opaque_matrix).astype("B") #self.opaque #alpha # for export gif self.img_array_rgb = arr # use the array to create a bitmap return wx.BitmapFromBufferRGBA(cols, rows, arr) def OnCellsSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event event is an instance of EventHandler.Event class event.object are the data for selecting shape objects """ if not event: return def OnNoCellSelect(self, event): """ Event handler for EVT_OBJ_SELECT. Observer will call this function when any other widgets/panels dispatch EVT_OBJ_SELECT event Normally, event could be None, you just need to clean and refresh you selected/highlighted """ self.Refresh(False) def hide_layer(self, layer, isHide=True): # override ShapeMap.hide_layer() add isHideDensityMap if layer == None: # Density Map layer self.isHideDensityMap = isHide else: self.hide_layers[layer] = isHide self.isResizing = True self.reInitBuffer = True
class Histogram(PlottingCanvas): def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self,parent, data) try: if isinstance(layer,str) or isinstance(layer, unicode): # in case of weights histogram self.layer_name = layer else: self.layer_name = layer.name self.isAutoScale = False self.intervals = 7 #self.title = "Histogram (%s)" % (self.layer_name) self.title = "" self.x_label = data.keys()[0] self.y_label = "Counts in bins" self.data = data[self.x_label] self.enable_axis_x = False self.draw_full_axis = False self.margin_right = 250 # for legend # create a dict for input data for Brushing self.data_dict = sorted(self.data, key=self.data.get) #[obj_id] sorted_data = sorted(self.data.values()) #[value] if self.x_label == 'Connectivity': self.intervals = len(set(sorted_data)) self.intervals = sorted_data[-1] - sorted_data[0] + 1 if self.intervals > 50: self.enable_axis_x = True self.margin_right = 40 if self.intervals > 1: self.hist, low_range, binsize, extrapoints = histogram(sorted_data, self.intervals) else: self.hist = np.array([len(sorted_data)]) cnt = 0; bin_idx = 0 self.bin_index = {} # key: obj_id, value: bin_idx for n in self.hist: for i in range(int(n)): obj_id = self.data_dict[cnt] self.bin_index[obj_id] = bin_idx cnt += 1 bin_idx += 1 data_min, data_max = sorted_data[0], sorted_data[-1] if self.x_label == 'Connectivity': #unique_num_neighbors = list(set(sorted_data)) self.data_intervals = [] for n in range(sorted_data[0], sorted_data[-1]+1): self.data_intervals.append((n,n)) else: end_pos = np.cumsum(self.hist) start_pos = end_pos - self.hist + 1 self.data_intervals = [ (start_pos[i],end_pos[i]) for i in range(len(self.hist))] # a NxN matrix self.x_min = 1 self.x_max = self.intervals +1 self.y_min = 0 self.y_max = np.max(self.hist) +1 self.extent = (self.x_min, self.y_min, self.x_max,self.y_max) self.status_bar = None#self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') # color schema: from blue to red self.color_matrix = [] for i in range(self.intervals): p = float(i+1) / self.intervals self.color_matrix.append( self.gradient_color.get_color_at(p)) self.selected_obj_ids = [] except Exception as err: self.ShowMsgBox(""" Histogram could not be created. Please select a numeric variable. Details: """ + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None # linking-brushing events self.Register(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Register(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect) def OnClose(self,event): self.Unregister(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Unregister(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect) event.Skip() def OnObjsSelected(self, event): if not event: return data = event.data if len(data.shape_ids) > 0: # directly select by shape_ids if data.shape_ids.has_key(self.layer_name): self.selected_obj_ids = data.shape_ids[self.layer_name] self.draw_selected() def OnNoObjSelect(self, event): self.selected_obj_ids = [] self.Refresh(False) def draw_selected(self,dc=None): if len(self.selected_obj_ids) > 0: if dc == None: # draw selected on client DC dc = wx.ClientDC(self) dc.DrawBitmap(self.buffer,0,0) highlight_counts_in_bins = [0] * len(self.hist) for obj_id in self.selected_obj_ids: bin_idx = self.bin_index[obj_id] highlight_counts_in_bins[bin_idx] += 1 # draw highlighted w=1 brush = wx.Brush(wx.Colour(255,255,0), wx.CROSSDIAG_HATCH) for i,count in enumerate(highlight_counts_in_bins): start_x = i+1 start_y = count h = count pixel_x,pixel_y = self.point_to_screen(start_x,start_y) pixel_w,pixel_h = math.ceil(self.length_to_screen(w)),math.ceil(self.length_to_screen(h,axis=1)) dc.SetBrush(brush) dc.DrawRectangle(pixel_x,pixel_y,pixel_w,pixel_h) def draw_selected_by_region(self, dc,select_region, isScreenCoordinates=True): """ this function highlight the points selected by mouse drawing a region """ self.selected_obj_ids= [] x0,y0,x1,y1= select_region ymin = min(y0,y1) ymax = max(y0,y1) y0 = ymin y1 = ymax x0,y0 = self.view.pan_to(x0,y0,-self.margin_left,-self.margin_top) x1,y1 = self.view.pan_to(x1,y1,-self.margin_left,-self.margin_top) x0,y0 = self.view.pixel_to_view(x0,y0) x1,y1 = self.view.pixel_to_view(x1,y1) # test intersection x0,y0,x1,y1 = int(math.floor(x0)),int(math.floor(min(y1,y0))),int(math.ceil(x1)),int(math.ceil(max(y0,y1))) if y0<0: y0=0 if x0<1: x0=1 n = len(self.hist) for x in range(x0,x1): if x <= n: start_pos = int(sum(self.hist[:x-1])) if y0 < self.hist[x-1]: m = y1 if y1 < self.hist[x-1] else self.hist[x-1] m = int(m) for i in range(y0,m): idx = self.data_dict[start_pos+i] self.selected_obj_ids.append(idx) self.draw_selected(dc) if len(self.selected_obj_ids)>0: # draw selected # tell this action to THE OBSERVER data = AbstractData(self) data.shape_ids[self.layer_name] = self.selected_obj_ids self.UpdateEvt(stars.EVT_OBJS_SELECT, data) else: # unselect all # tell this action to THE OBSERVER data = AbstractData(self) self.UpdateEvt(stars.EVT_OBJS_UNSELECT,data) def set_intervals(self): pass def plot_data(self,dc): w = 1 o_x, o_y = self.point_to_screen(1,0) for i in range(self.intervals): binNum = self.hist[i] start_x = i+1 start_y = binNum pixel_x,pixel_y = self.point_to_screen(start_x,start_y) pixel_nx,pixel_ny = self.point_to_screen(start_x+1,start_y) pixel_w = int(pixel_nx) - int(pixel_x) + 1 pixel_h = int(o_y) - int(pixel_y) + 1 """ h = binNum pixel_w,pixel_h = self.length_to_screen(w),self.length_to_screen(h,axis=1) pixel_w = round(int(pixel_w) + pixel_w - int(pixel_w) + pixel_x - int(pixel_x)) pixel_h = round(int(pixel_h) + pixel_h - int(pixel_h) + pixel_y - int(pixel_y)) """ brush = wx.Brush(self.color_matrix[i]) dc.SetBrush(brush) dc.DrawRectangle(pixel_x,pixel_y,pixel_w,pixel_h) if self.x_label == "Connectivity" and self.intervals > 50: return # draw a legend bar pixel_x,pixel_y = self.point_to_screen( start_x+w, self.y_max) pixel_x = self.ax_start_x + self.ax_width + 10 pixel_y = self.ax_start_y pixel_h = self.length_to_screen(self.y_max-self.y_min,axis=1) pixel_w = 30 num_items = self.intervals if num_items == 1: num_items += 1 legend_item_h = pixel_h * 0.7 / num_items dc.SetBrush(wx.Brush(wx.Colour(255,255,0),wx.CROSSDIAG_HATCH)) dc.DrawRectangle( pixel_x, pixel_y, pixel_w, legend_item_h) dc.DrawText( "selected features", pixel_x + pixel_w + 5, pixel_y) for i in range(self.intervals): pixel_y += legend_item_h + 5 dc.SetBrush( wx.Brush(self.color_matrix[i])) dc.DrawRectangle( pixel_x, pixel_y, pixel_w, legend_item_h) label = '%s - %s (%d)' % (self.data_intervals[i][0], self.data_intervals[i][1], self.hist[i]) dc.DrawText( label, pixel_x + pixel_w + 5, pixel_y)
class HeatMatrix(PlottingCanvas): def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self, parent, data) try: self.layer_name = layer.name self.title = "Transition probility matrix (%s)" % self.layer_name self.x_label = "LISA transition states (1=HH,2=LH,3=LL,4=HL)" self.y_label = "LISA transition states" self.data = data n = len(self.data) self.enable_axis_labels = False self.enable_axis = True self.enable_axis_x = False self.enable_axis_y = False # a NxN matrix self.x_min = 1 self.x_max = n + 1 self.y_min = 1 self.y_max = n + 1 self.extent = (self.x_min, self.y_min, self.x_max, self.y_max) self.selected_polygon_ids = [] self.status_bar = self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') self.margin_right = 100 # color schema: from blue to red self.color_matrix = [] for i in range(n): color_row = [] for j in range(n): p = self.data[i][j] color_row.append(self.gradient_color.get_color_at(p)) self.color_matrix.append(color_row) except Exception as err: self.ShowMsgBox('Fail to init heat map! ' + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None def OnClose(self, event): event.Skip() def plot_data(self, dc): # draw a NxN matrix w, h = 1, 1 for i, row in enumerate(self.data): for j, item in enumerate(row): start_x = j + self.x_min start_y = self.y_max - i pixel_x, pixel_y = self.point_to_screen(start_x, start_y) pixel_w, pixel_h = math.ceil( self.length_to_screen(w)), math.ceil( self.length_to_screen(h, axis=1)) brush = wx.Brush(self.color_matrix[i][j]) dc.SetBrush(brush) dc.DrawRectangle(pixel_x, pixel_y, pixel_w, pixel_h) if i == len(self.data) - 1: dc.DrawText(str(j + 1), pixel_x + pixel_w / 2, pixel_y + pixel_h + 5) if j == 0: dc.DrawText(str(len(self.data) - i), pixel_x - 10, pixel_y + pixel_h / 2) text_pixel_x, text_pixel_y = pixel_x + pixel_w / 2.0 - 10, pixel_y + pixel_h / 2.0 dc.SetPen(wx.WHITE_PEN) dc.SetBrush(wx.WHITE_BRUSH) dc.DrawText('%.4f' % (self.data[i][j]), text_pixel_x, text_pixel_y) # draw a legend bar pixel_x, pixel_y = self.point_to_screen(start_x + w, self.y_max) pixel_x += 20 pixel_h = self.length_to_screen(self.y_max - self.y_min, axis=1) pixel_w = 20 gradient_colorbar = self.gradient_color.get_bmp(pixel_w, pixel_h) dc.DrawBitmap(gradient_colorbar, pixel_x, pixel_y) pixel_x = pixel_x + pixel_w + 10 dc.SetPen(wx.BLACK_PEN) dc.DrawText(str('%.2f' % np.max(self.data)), pixel_x, pixel_y) pixel_y = pixel_y + pixel_h - 12 dc.DrawText(str('%.2f' % np.min(self.data)), pixel_x, pixel_y)
def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self, parent, data) try: if isinstance(layer, str) or isinstance(layer, unicode): # in case of weights histogram self.layer_name = layer else: self.layer_name = layer.name self.isAutoScale = False self.intervals = 7 #self.title = "Histogram (%s)" % (self.layer_name) self.title = "" self.x_label = data.keys()[0] self.y_label = "Counts in bins" self.data = data[self.x_label] self.enable_axis_x = False self.draw_full_axis = False self.margin_right = 250 # for legend # create a dict for input data for Brushing self.data_dict = sorted(self.data, key=self.data.get) #[obj_id] sorted_data = sorted(self.data.values()) #[value] if self.x_label == 'Connectivity': self.intervals = len(set(sorted_data)) self.intervals = sorted_data[-1] - sorted_data[0] + 1 if self.intervals > 50: self.enable_axis_x = True self.margin_right = 40 if self.intervals > 1: self.hist, low_range, binsize, extrapoints = histogram( sorted_data, self.intervals) else: self.hist = np.array([len(sorted_data)]) cnt = 0 bin_idx = 0 self.bin_index = {} # key: obj_id, value: bin_idx for n in self.hist: for i in range(int(n)): obj_id = self.data_dict[cnt] self.bin_index[obj_id] = bin_idx cnt += 1 bin_idx += 1 data_min, data_max = sorted_data[0], sorted_data[-1] if self.x_label == 'Connectivity': #unique_num_neighbors = list(set(sorted_data)) self.data_intervals = [] for n in range(sorted_data[0], sorted_data[-1] + 1): self.data_intervals.append((n, n)) else: end_pos = np.cumsum(self.hist) start_pos = end_pos - self.hist + 1 self.data_intervals = [(start_pos[i], end_pos[i]) for i in range(len(self.hist))] # a NxN matrix self.x_min = 1 self.x_max = self.intervals + 1 self.y_min = 0 self.y_max = np.max(self.hist) + 1 self.extent = (self.x_min, self.y_min, self.x_max, self.y_max) self.status_bar = None #self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') # color schema: from blue to red self.color_matrix = [] for i in range(self.intervals): p = float(i + 1) / self.intervals self.color_matrix.append(self.gradient_color.get_color_at(p)) self.selected_obj_ids = [] except Exception as err: self.ShowMsgBox( """ Histogram could not be created. Please select a numeric variable. Details: """ + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None # linking-brushing events self.Register(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Register(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect)
class Histogram(PlottingCanvas): def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self, parent, data) try: if isinstance(layer, str) or isinstance(layer, unicode): # in case of weights histogram self.layer_name = layer else: self.layer_name = layer.name self.isAutoScale = False self.intervals = 7 #self.title = "Histogram (%s)" % (self.layer_name) self.title = "" self.x_label = data.keys()[0] self.y_label = "Counts in bins" self.data = data[self.x_label] self.enable_axis_x = False self.draw_full_axis = False self.margin_right = 250 # for legend # create a dict for input data for Brushing self.data_dict = sorted(self.data, key=self.data.get) #[obj_id] sorted_data = sorted(self.data.values()) #[value] if self.x_label == 'Connectivity': self.intervals = len(set(sorted_data)) self.intervals = sorted_data[-1] - sorted_data[0] + 1 if self.intervals > 50: self.enable_axis_x = True self.margin_right = 40 if self.intervals > 1: self.hist, low_range, binsize, extrapoints = histogram( sorted_data, self.intervals) else: self.hist = np.array([len(sorted_data)]) cnt = 0 bin_idx = 0 self.bin_index = {} # key: obj_id, value: bin_idx for n in self.hist: for i in range(int(n)): obj_id = self.data_dict[cnt] self.bin_index[obj_id] = bin_idx cnt += 1 bin_idx += 1 data_min, data_max = sorted_data[0], sorted_data[-1] if self.x_label == 'Connectivity': #unique_num_neighbors = list(set(sorted_data)) self.data_intervals = [] for n in range(sorted_data[0], sorted_data[-1] + 1): self.data_intervals.append((n, n)) else: end_pos = np.cumsum(self.hist) start_pos = end_pos - self.hist + 1 self.data_intervals = [(start_pos[i], end_pos[i]) for i in range(len(self.hist))] # a NxN matrix self.x_min = 1 self.x_max = self.intervals + 1 self.y_min = 0 self.y_max = np.max(self.hist) + 1 self.extent = (self.x_min, self.y_min, self.x_max, self.y_max) self.status_bar = None #self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') # color schema: from blue to red self.color_matrix = [] for i in range(self.intervals): p = float(i + 1) / self.intervals self.color_matrix.append(self.gradient_color.get_color_at(p)) self.selected_obj_ids = [] except Exception as err: self.ShowMsgBox( """ Histogram could not be created. Please select a numeric variable. Details: """ + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None # linking-brushing events self.Register(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Register(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect) def OnClose(self, event): self.Unregister(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Unregister(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect) event.Skip() def OnObjsSelected(self, event): if not event: return data = event.data if len(data.shape_ids) > 0: # directly select by shape_ids if data.shape_ids.has_key(self.layer_name): self.selected_obj_ids = data.shape_ids[self.layer_name] self.draw_selected() def OnNoObjSelect(self, event): self.selected_obj_ids = [] self.Refresh(False) def draw_selected(self, dc=None): if len(self.selected_obj_ids) > 0: if dc == None: # draw selected on client DC dc = wx.ClientDC(self) dc.DrawBitmap(self.buffer, 0, 0) highlight_counts_in_bins = [0] * len(self.hist) for obj_id in self.selected_obj_ids: bin_idx = self.bin_index[obj_id] highlight_counts_in_bins[bin_idx] += 1 # draw highlighted w = 1 brush = wx.Brush(wx.Colour(255, 255, 0), wx.CROSSDIAG_HATCH) for i, count in enumerate(highlight_counts_in_bins): start_x = i + 1 start_y = count h = count pixel_x, pixel_y = self.point_to_screen(start_x, start_y) pixel_w, pixel_h = math.ceil( self.length_to_screen(w)), math.ceil( self.length_to_screen(h, axis=1)) dc.SetBrush(brush) dc.DrawRectangle(pixel_x, pixel_y, pixel_w, pixel_h) def draw_selected_by_region(self, dc, select_region, isScreenCoordinates=True): """ this function highlight the points selected by mouse drawing a region """ self.selected_obj_ids = [] x0, y0, x1, y1 = select_region ymin = min(y0, y1) ymax = max(y0, y1) y0 = ymin y1 = ymax x0, y0 = self.view.pan_to(x0, y0, -self.margin_left, -self.margin_top) x1, y1 = self.view.pan_to(x1, y1, -self.margin_left, -self.margin_top) x0, y0 = self.view.pixel_to_view(x0, y0) x1, y1 = self.view.pixel_to_view(x1, y1) # test intersection x0, y0, x1, y1 = int(math.floor(x0)), int(math.floor(min( y1, y0))), int(math.ceil(x1)), int(math.ceil(max(y0, y1))) if y0 < 0: y0 = 0 if x0 < 1: x0 = 1 n = len(self.hist) for x in range(x0, x1): if x <= n: start_pos = int(sum(self.hist[:x - 1])) if y0 < self.hist[x - 1]: m = y1 if y1 < self.hist[x - 1] else self.hist[x - 1] m = int(m) for i in range(y0, m): idx = self.data_dict[start_pos + i] self.selected_obj_ids.append(idx) self.draw_selected(dc) if len(self.selected_obj_ids) > 0: # draw selected # tell this action to THE OBSERVER data = AbstractData(self) data.shape_ids[self.layer_name] = self.selected_obj_ids self.UpdateEvt(stars.EVT_OBJS_SELECT, data) else: # unselect all # tell this action to THE OBSERVER data = AbstractData(self) self.UpdateEvt(stars.EVT_OBJS_UNSELECT, data) def set_intervals(self): pass def plot_data(self, dc): w = 1 o_x, o_y = self.point_to_screen(1, 0) for i in range(self.intervals): binNum = self.hist[i] start_x = i + 1 start_y = binNum pixel_x, pixel_y = self.point_to_screen(start_x, start_y) pixel_nx, pixel_ny = self.point_to_screen(start_x + 1, start_y) pixel_w = int(pixel_nx) - int(pixel_x) + 1 pixel_h = int(o_y) - int(pixel_y) + 1 """ h = binNum pixel_w,pixel_h = self.length_to_screen(w),self.length_to_screen(h,axis=1) pixel_w = round(int(pixel_w) + pixel_w - int(pixel_w) + pixel_x - int(pixel_x)) pixel_h = round(int(pixel_h) + pixel_h - int(pixel_h) + pixel_y - int(pixel_y)) """ brush = wx.Brush(self.color_matrix[i]) dc.SetBrush(brush) dc.DrawRectangle(pixel_x, pixel_y, pixel_w, pixel_h) if self.x_label == "Connectivity" and self.intervals > 50: return # draw a legend bar pixel_x, pixel_y = self.point_to_screen(start_x + w, self.y_max) pixel_x = self.ax_start_x + self.ax_width + 10 pixel_y = self.ax_start_y pixel_h = self.length_to_screen(self.y_max - self.y_min, axis=1) pixel_w = 30 num_items = self.intervals if num_items == 1: num_items += 1 legend_item_h = pixel_h * 0.7 / num_items dc.SetBrush(wx.Brush(wx.Colour(255, 255, 0), wx.CROSSDIAG_HATCH)) dc.DrawRectangle(pixel_x, pixel_y, pixel_w, legend_item_h) dc.DrawText("selected features", pixel_x + pixel_w + 5, pixel_y) for i in range(self.intervals): pixel_y += legend_item_h + 5 dc.SetBrush(wx.Brush(self.color_matrix[i])) dc.DrawRectangle(pixel_x, pixel_y, pixel_w, legend_item_h) label = '%s - %s (%d)' % (self.data_intervals[i][0], self.data_intervals[i][1], self.hist[i]) dc.DrawText(label, pixel_x + pixel_w + 5, pixel_y)
def __init__(self, gradient_type): self.gradient_color = GradientColor(gradient_type) ColorSchema.__init__(self,None,[""])
def __init__(self, parent, layer, data, **kwargs): PlottingCanvas.__init__(self,parent, data) try: if isinstance(layer,str) or isinstance(layer, unicode): # in case of weights histogram self.layer_name = layer else: self.layer_name = layer.name self.isAutoScale = False self.intervals = 7 #self.title = "Histogram (%s)" % (self.layer_name) self.title = "" self.x_label = data.keys()[0] self.y_label = "Counts in bins" self.data = data[self.x_label] self.enable_axis_x = False self.draw_full_axis = False self.margin_right = 250 # for legend # create a dict for input data for Brushing self.data_dict = sorted(self.data, key=self.data.get) #[obj_id] sorted_data = sorted(self.data.values()) #[value] if self.x_label == 'Connectivity': self.intervals = len(set(sorted_data)) self.intervals = sorted_data[-1] - sorted_data[0] + 1 if self.intervals > 50: self.enable_axis_x = True self.margin_right = 40 if self.intervals > 1: self.hist, low_range, binsize, extrapoints = histogram(sorted_data, self.intervals) else: self.hist = np.array([len(sorted_data)]) cnt = 0; bin_idx = 0 self.bin_index = {} # key: obj_id, value: bin_idx for n in self.hist: for i in range(int(n)): obj_id = self.data_dict[cnt] self.bin_index[obj_id] = bin_idx cnt += 1 bin_idx += 1 data_min, data_max = sorted_data[0], sorted_data[-1] if self.x_label == 'Connectivity': #unique_num_neighbors = list(set(sorted_data)) self.data_intervals = [] for n in range(sorted_data[0], sorted_data[-1]+1): self.data_intervals.append((n,n)) else: end_pos = np.cumsum(self.hist) start_pos = end_pos - self.hist + 1 self.data_intervals = [ (start_pos[i],end_pos[i]) for i in range(len(self.hist))] # a NxN matrix self.x_min = 1 self.x_max = self.intervals +1 self.y_min = 0 self.y_max = np.max(self.hist) +1 self.extent = (self.x_min, self.y_min, self.x_max,self.y_max) self.status_bar = None#self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') # color schema: from blue to red self.color_matrix = [] for i in range(self.intervals): p = float(i+1) / self.intervals self.color_matrix.append( self.gradient_color.get_color_at(p)) self.selected_obj_ids = [] except Exception as err: self.ShowMsgBox(""" Histogram could not be created. Please select a numeric variable. Details: """ + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None # linking-brushing events self.Register(stars.EVT_OBJS_SELECT, self.OnObjsSelected) self.Register(stars.EVT_OBJS_UNSELECT, self.OnNoObjSelect)
def __init__(self, gradient_type): self.gradient_color = GradientColor(gradient_type) ColorSchema.__init__(self, None, [""])
class HeatMatrix(PlottingCanvas): def __init__(self,parent, layer, data,**kwargs): PlottingCanvas.__init__(self,parent,data) try: self.layer_name = layer.name self.title = "Transition probility matrix (%s)" % self.layer_name self.x_label = "LISA transition states (1=HH,2=LH,3=LL,4=HL)" self.y_label = "LISA transition states" self.data = data n = len(self.data) self.enable_axis_labels = False self.enable_axis = True self.enable_axis_x = False self.enable_axis_y = False # a NxN matrix self.x_min = 1 self.x_max = n+1 self.y_min = 1 self.y_max = n+1 self.extent = (self.x_min, self.y_min, self.x_max,self.y_max) self.selected_polygon_ids = [] self.status_bar = self.parentFrame.status_bar self.gradient_color = GradientColor(gradient_type='rdyibu') self.margin_right = 100 # color schema: from blue to red self.color_matrix = [] for i in range(n): color_row = [] for j in range(n): p = self.data[i][j] color_row.append( self.gradient_color.get_color_at(p)) self.color_matrix.append(color_row) except Exception as err: self.ShowMsgBox('Fail to init heat map! ' + str(err.message)) self.isValidPlot = False self.parentFrame.Close(True) return None def OnClose(self,event): event.Skip() def plot_data(self,dc): # draw a NxN matrix w,h = 1,1 for i,row in enumerate(self.data): for j,item in enumerate(row): start_x = j + self.x_min start_y = self.y_max - i pixel_x,pixel_y = self.point_to_screen(start_x,start_y) pixel_w,pixel_h = math.ceil(self.length_to_screen(w)),math.ceil(self.length_to_screen(h,axis=1)) brush = wx.Brush(self.color_matrix[i][j]) dc.SetBrush(brush) dc.DrawRectangle(pixel_x,pixel_y,pixel_w,pixel_h) if i==len(self.data)-1: dc.DrawText(str(j+1), pixel_x + pixel_w/2, pixel_y+pixel_h+5) if j==0: dc.DrawText(str(len(self.data)-i), pixel_x - 10, pixel_y + pixel_h/2) text_pixel_x, text_pixel_y = pixel_x + pixel_w/2.0 - 10, pixel_y + pixel_h / 2.0 dc.SetPen(wx.WHITE_PEN) dc.SetBrush(wx.WHITE_BRUSH) dc.DrawText('%.4f'%(self.data[i][j]), text_pixel_x,text_pixel_y) # draw a legend bar pixel_x,pixel_y = self.point_to_screen( start_x+w, self.y_max) pixel_x += 20 pixel_h = self.length_to_screen(self.y_max-self.y_min,axis=1) pixel_w = 20 gradient_colorbar = self.gradient_color.get_bmp(pixel_w, pixel_h) dc.DrawBitmap( gradient_colorbar, pixel_x, pixel_y) pixel_x = pixel_x + pixel_w + 10 dc.SetPen(wx.BLACK_PEN) dc.DrawText(str('%.2f'% np.max(self.data)), pixel_x,pixel_y) pixel_y = pixel_y + pixel_h - 12 dc.DrawText(str('%.2f'% np.min(self.data)), pixel_x,pixel_y)