示例#1
0
class ImCanvas(HBox, HasTraits):
    image_path = Unicode()
    _image_scale = Float()

    def __init__(self, width=150, height=150):

        self._canvas = Canvas(width=width, height=height)

        super().__init__([self._canvas])

    @observe('image_path')
    def _draw_image(self, change):
        self._image_scale = draw_img(self._canvas, self.image_path, clear=True)

    # Add value as a read-only property
    @property
    def image_scale(self):
        return self._image_scale

    def _clear_image(self):
        self._canvas.clear()

    # needed to support voila
    # https://ipycanvas.readthedocs.io/en/latest/advanced.html#ipycanvas-in-voila
    def observe_client_ready(self, cb=None):
        self._canvas.on_client_ready(cb)
示例#2
0
    def __init__(self, img):

        f = open('app/config.json')
        cfg = json.load(f)

        self.img = img

        self.width = 1080
        self.height = 770
        self.canvas = Canvas(
            width=self.width,
            height=self.height,
        )
        self.output = Output(
            layout=Layout(
                #border='1px solid cyan',
                width='1170px',
                height='770px',
                min_height='90vh',
                overflow='hidden hidden'), )
        with self.output:
            display(self.canvas)

        def put_image():
            resized = cv2.resize(img, (self.width, self.height),
                                 interpolation=cv2.INTER_AREA)
            self.canvas.put_image_data(resized, 0, 0)

        self.canvas.on_client_ready(put_image)
示例#3
0
 def load_sprites(self):
     ' load the sprite sheet and when loaded callback to split it into individual sprites '
     sprites = Image.from_file('images/BabyRobot64_Sprites.png')
     self.sprite_canvas = Canvas(width=132,
                                 height=328,
                                 sync_image_data=True)
     self.sprite_canvas.draw_image(sprites, 0, 0)
     self.sprite_canvas.observe(self.get_array, 'image_data')
示例#4
0
 def __init__(self, stage, cell_size=10, live_color='white', dead_color='black', background_color='gray',
              border_width=1.0):
     self.stage = stage
     self.cell_size = cell_size
     self.live_color = live_color
     self.dead_color = dead_color
     self.background_color = background_color
     self.border_width = border_width
     self.canvas = Canvas(width=self.stage.shape[0] * self.cell_size, height=self.stage.shape[1] * self.cell_size)
     display(self.canvas)
示例#5
0
 def all_rooms(self,canvas=None):
     if canvas == None:
         canvas = Canvas(width=self.max_x, height=self.max_y)
     k=0
     for i in range(0,self.n_grid):
         for j in range(0,self.n_grid):
             if k < self.number_of_rooms:
                 canvas2 = self.Single_Room(self.Rooms[k])
                 canvas.draw_image(canvas2, self.x[i], self.y[j])
             k += 1
     return canvas
示例#6
0
    def __init__(self,
                 image,
                 scale=1,
                 interpolation=transform.interpolation.nearest):
        self.__scale = scale
        self.__interpolation = interpolation
        self.__image = self.transform(image)

        self.__canvas = Canvas(width=self.__image.shape[1],
                               height=self.__image.shape[0],
                               scale=1)
        self.__canvas.put_image_data(self.__image, 0, 0)
示例#7
0
    def __init__(self, globals_dict):
        self.status_text = display(Code(""), display_id=True)
        self._globals_dict = globals_dict
        self._methods = {}

        self.stop_button = Button(description="Stop")
        self.stop_button.on_click(self.on_stop_button_clicked)

        self.canvas = Canvas()
        self.output_text = ""
        self.width, self.height = DEFAULT_CANVAS_SIZE
        self.mouse_x = 0
        self.mouse_y = 0
        self.mouse_is_pressed = False
示例#8
0
def helper_image(self: Core, *args):
    filename: str = args[0]
    x: int = int(args[1])
    y: int = int(args[2])
    w: int = int(args[3])
    h: int = int(args[4])

    key = (filename, abs(w), abs(h))

    if key not in _loaded_images:
        _loaded_images[key] = Canvas(width=abs(w), height=abs(h))
        _loaded_images[key].draw_image(
            Image.from_file(filename, width=abs(w), height=abs(h)), 0, 0,
            abs(w), abs(h))
    self.canvas.translate(x, y)
    if w < 0:
        self.canvas.scale(-1, 1)
    if h < 0:
        self.canvas.scale(1, -1)
    self.canvas.draw_image(_loaded_images[key], 0, 0)
    if h < 0:
        self.canvas.scale(1, -1)
    if w < 0:
        self.canvas.scale(-1, 1)
    self.canvas.translate(-x, -y)
    def __init__(self, parser: Parser, width: int = 500, height: int = 400, colorMap = defaultColorMap, filterFunction = None, backgroundColorRGB = "black", environmentRenderer = defaultRender2DEnvironment):
        """
        Visualize a 2D PhysiCell simulation
        
            parser - a simulation output parser
            width: int = 500 - the width of the canvas to draw to
            height: int = 400 - the height of the canvas to draw to
            colorMap: (cells: numpyArray, variables: Map<string, indicies>, selectedCellID: ?string) => Array<Tuple<fillColor: string, strokeColor: string, cellIndicies: numpyArray>> = defaultColorMap - a function resulting in the cell colors
            filterFunction: (cells: numpyArray, variables: Map<string, indicies>) => numpyArray (boolean/indicies) = None - a function resulting in an array of the indicies of the cells to draw
            backgroundColorRGB: string = "black" - the color to paint the background
            environmentRenderer: (attribute: string, environment: Parser.Environment) => numpyArray<x, y, 1/2/3/4> = defaultRender2DEnvironment - given an environment and the attribute to render, create an image (numpy array) to render (will span the bounds of the attribute)
        
        """
        super().__init__(parser, width, height, colorMap, filterFunction, (constants.MOVE_ACTION, constants.ZOOM_ACTION, constants.SELECT_ACTION))

        frame = parser.getFrame(self._currentFrame)
        mesh = frame.environment.mesh
        self._zoom = max((mesh.boundsX[1] - mesh.boundsX[0]) / width, (mesh.boundsY[1] - mesh.boundsY[0]) / height)
        
        self._xOffset = mesh.boundsX[0]
        self._yOffset = mesh.boundsY[0]
        
        self._environmentRenderer = environmentRenderer
        
        self._buffer = Canvas(width=width, height=height)
        
        self._backgroundColor = backgroundColorRGB
        
        self.update()
示例#10
0
class Image:

    def __init__(self, image, scale=1):
        self.scale = scale
        self.image = self.format(image)
    
        self.canvas = Canvas(width=self.image.shape[1], height=self.image.shape[0], scale=1)
        self.canvas.put_image_data(self.image, 0, 0) 

    @utils.as_numpy
    def format(self, image):
        # convert the image to HWC [0-255] format
        if len(image.shape) == 2:
            image = image[np.newaxis,...]

        assert len(image.shape) == 3

        if image.shape[0] in [3,1] and not image.shape[-1] in [3,1]: 
            # in CHW format, otherwise we might be in HWC format...
            image = T.transpose(image, "CHW", "HWC")

        assert image.shape[-1] in [1,3] # TODO alpha blend if 4? 

        if T.is_float(image): # convert to [0-255], ipycanvas has a weird image format
            image = image * 255. # assume
        image = image.astype(np.float32)

        if self.scale != 1: # match image scale
            shape = list(image.shape)
            shape[0] *= self.scale
            shape[1] *= self.scale
            image = skimage.transform.resize(image, shape, order=0, preserve_range=True)

        if image.shape[-1] == 1: # convert to 3 channel image
            image = np.repeat(image, 3, axis=-1)

        return image

    def update(self, image):
        image = self.format(image)
        self.canvas.put_image_data(image, 0, 0) 

    def display(self): # TODO update
        box_layout = ipywidgets.Layout(display='flex',flex_flow='row',align_items='center',width='100%')
        display(ipywidgets.HBox([self.canvas], layout=box_layout))
示例#11
0
    def __init__(self, image: str=None, size=(600, 300), **kwargs):
        """Create a Turtle drawing canvas.
        
        Arguments:

            image: Load the image into the canvas. 
            size: Set the size of the canvas.
        """
        self._size = Turtle.DimPoint(size[0], size[1])
        turtle = numpy.array(PIL.Image.open(pathlib.Path(__file__).parent / "turtle.png"))
        self._turtle = Canvas(width=turtle.shape[0], height=turtle.shape[1])
        self._turtle.put_image_data(turtle)
        self._canvas = MultiCanvas(n_canvases=3, width=self._size.x, height=self._size.y, **kwargs) 
        self._reset()

        if image is not None:
            self.background(image)          

        self.clear()
示例#12
0
 def __init__(self, width=500, height=500, **kwargs):
     # Examples :
     #   Drawing(border=None)            # omit border
     #   Drawing(background='white')     # white rather than default
     #   Drawing(800, 200)               # 800 pixels wide, 200 pixels high
     for key in Drawing.defaults.keys():
         if kwargs.get(key, None) == None:
             kwargs[key] = Drawing.defaults[key]
     kwargs['caching'] = kwargs.get('caching',
                                    Drawing.defaults['cache_default'])
     Canvas.__init__(self, width=width, height=height, **kwargs)
     for key in Drawing.defaults.keys():
         self.__dict__[key] = kwargs[key]
     self.width = width
     self.height = height
     self.caching = kwargs['caching']
     self.components = []
     #
     (self.xll, self.yll) = (0.0, 1.0 * height)
     (self.xur, self.yur) = (1.0 * width, 0.0)
示例#13
0
class ImCanvas(HBox):
    def __init__(self, width=150, height=150, has_border=False):
        self.has_border = has_border
        self._canvas = Canvas(width=width, height=height)
        super().__init__([self._canvas])

    def _draw_image(self, image_path: str):
        self._image_scale = draw_img(
            self._canvas,
            image_path,
            clear=True,
            has_border=self.has_border
        )

    def _clear_image(self):
        self._canvas.clear()

    # needed to support voila
    # https://ipycanvas.readthedocs.io/en/latest/advanced.html#ipycanvas-in-voila
    def observe_client_ready(self, cb=None):
        self._canvas.on_client_ready(cb)
示例#14
0
    def __init__(self, subj_num):
        self.subject_num = subj_num
        self.output_file = 'sdt-' + str(subj_num) + '.csv'

        # create two buttons with these names, randomize the position
        if npr.random() < 0.5:
            self.labels = [[
                'Present',
                widgets.ButtonStyle(button_color='darkseagreen')
            ], ['Absent', widgets.ButtonStyle(button_color='salmon')]]
            self.position = 'left'
        else:
            self.labels = [[
                'Absent', widgets.ButtonStyle(button_color='salmon')
            ], ['Present',
                widgets.ButtonStyle(button_color='darkseagreen')]]
            self.position = 'right'

        self.buttons = [
            widgets.Button(description=desc[0],
                           layout=widgets.Layout(width='auto',
                                                 grid_area=f'button{idx}'),
                           value=idx,
                           style=desc[1])  # create button
            for idx, desc in enumerate(self.labels)
        ]  # puts buttons into a list

        self.canvas = Canvas(width=425,
                             height=425,
                             layout=widgets.Layout(justify_self='center',
                                                   grid_area='canvas'))

        # create output widget for displaying feedback/reward
        self.out = widgets.Output(layout=widgets.Layout(
            width='auto', object_position='center',
            grid_area='output'))  # output widgets wrapped in VBoxes

        np.random.seed(24)
        self.create_trials(25, [10, 15, 25, 60])
        self.done = False
示例#15
0
    def __init__(self, cell_size, colors, croppers, border_ratio=0.05):
        self.croppers = sorted(croppers, key=lambda x: x.rows, reverse=True)
        width = ((sum(cropper.cols
                      for cropper in croppers) + len(croppers) - 1) *
                 cell_size)
        height = max(cropper.rows for cropper in croppers) * cell_size

        self.canvas = Canvas(height=height, width=width)
        self.border_ratio = border_ratio
        self.colors = defaultdict(lambda: self.DEFAULT_COLOR)
        for key, value in colors.items():
            self.colors[ord(key)] = value
        self.cell_size = cell_size
示例#16
0
    def Single_Zone(self, Zone, fig=None, offset=np.array([0, 0])):
        w = self.margin
        wall_width = self.wall_th * self.scale
        Zone_w = (Zone.x_delta + 2 * w) * self.scale
        Zone_h = (Zone.y_delta + 2 * w) * self.scale
        canvas_w = Zone_w + 2 * wall_width
        canvas_h = Zone_h + 2 * wall_width
        w = w * self.scale
        if fig == None:
            canvas = MultiCanvas(4, width=canvas_w, height=canvas_h)
        else:
            canvas = fig

        # background
        canvas[0].translate(offset[0], offset[1])
        Mars_img = Image.from_file('Images/Mars_surface.jpg')
        canvas3 = Canvas(width=1000, height=1000)
        canvas3.draw_image(Mars_img, 0, 0)
        canvas3.scale(3 * self.scale / 50)
        canvas[0].draw_image(canvas3, 0, 0)
        canvas[0].translate(-offset[0], -offset[1])

        # Draw Zone
        canvas[1].translate(offset[0], offset[1])
        canvas[1].fill_rect(0, 0, canvas_w, height=canvas_h)
        canvas[1].clear_rect(wall_width, wall_width, Zone_w, height=Zone_h)

        # Name of thr Zone
        canvas[1].font = '16px serif'
        canvas[1].fill_text(Zone.name, Zone_w / 2, 4 * wall_width)
        canvas[1].translate(-offset[0], -offset[1])

        # Draw object insised the Zone
        canvas[2].translate(offset[0], offset[1])
        if Zone.type == 'Landing_zone':
            charging = self.problem_2_canvas(Zone.charger)
            trash_bin = self.problem_2_canvas(Zone.deposit)
            canvas[2].fill_style = 'green'
            canvas[2].fill_rect(charging[0] - w / 2, charging[1] - w / 2, w)
            canvas[2].fill_style = 'blue'
            canvas[2].fill_rect(trash_bin[0] - w / 2, trash_bin[1] - w / 2, w)
        else:
            canvas[2].fill_style = 'brown'
            p_r = 0.1
            x, y, radius = [], [], []
            for i in range(0, Zone.max_sample):
                sam_coord = self.problem_2_canvas(Zone.samples_loc[i, :])
                x.append(sam_coord[0])
                y.append(sam_coord[1])
                radius.append(p_r * self.scale)
            canvas[2].fill_circles(x, y, radius)
        for i in Zone.connections['Location']:
            canvas[2].fill_style = 'red'
            c_coord = self.problem_2_canvas(Zone.Location_2_coordinate[i])
            x = c_coord[0]
            y = c_coord[1]
            canvas[2].fill_rect(x - w / 2, y - w / 2, w)
        canvas[2].translate(-offset[0], -offset[1])
        return canvas
示例#17
0
    def get_array(self, *args, **kwargs):
        ' callback to split the sprite sheet into individual sprites '

        # check that the sprites haven't already been created
        if self.get_number_of_sprites() == 0:
            for row in range(5):
                for col in range(2):
                    x = col * (self.robot_size + 1)
                    y = row * (self.robot_size + 1)

                    # copy the sprite from the sprite sheet
                    image_data = self.sprite_canvas.get_image_data(
                        x, y, self.robot_size)

                    # put the sprite onto its own canvas
                    canvas = Canvas(width=self.robot_size,
                                    height=self.robot_size)
                    canvas.put_image_data(image_data, 0, 0)
                    self.canvas_sprites.append(canvas)

        # add a sprite to the display
        self.canvas.clear()
        self.draw()
示例#18
0
class GameOfLifePy:
    def __init__(self, stage, cell_size=10, live_color='white', dead_color='black', background_color='gray',
                 border_width=1.0):
        self.stage = stage
        self.cell_size = cell_size
        self.live_color = live_color
        self.dead_color = dead_color
        self.background_color = background_color
        self.border_width = border_width
        self.canvas = Canvas(width=self.stage.shape[0] * self.cell_size, height=self.stage.shape[1] * self.cell_size)
        display(self.canvas)

    def draw_stage(self):
        with hold_canvas(self.canvas):
            # draw live cells
            cells_index = np.where(self.stage)
            cells_x = cells_index[0] * self.cell_size
            cells_y = cells_index[1] * self.cell_size
            size_array = np.full(cells_x.shape, self.cell_size)
            self.canvas.fill_style = self.live_color
            self.canvas.fill_rects(cells_x, cells_y, size_array)
            # draw "border" of live cells
            if self.border_width != 0.0:
                self.canvas.line_width = self.border_width
                self.canvas.stroke_style = self.background_color
                self.canvas.stroke_rects(cells_x, cells_y, size_array)

            # draw dead cells
            cells_index = np.where(self.stage == False)
            cells_x = cells_index[0] * self.cell_size
            cells_y = cells_index[1] * self.cell_size
            size_array = np.full(cells_x.shape, self.cell_size)
            self.canvas.fill_style = self.dead_color
            self.canvas.fill_rects(cells_x, cells_y, size_array)
            # draw "border" of dead cells
            if self.border_width != 0.0:
                self.canvas.line_width = self.border_width
                self.canvas.stroke_style = self.background_color
                self.canvas.stroke_rects(cells_x, cells_y, size_array)

    def next_stage(self):
        self.stage = get_next_stage(self.stage)
示例#19
0
    def __init__(self, globals_dict):
        self.status_text = display(Code(""), display_id=True)
        self._globals_dict = globals_dict
        self._methods = {}

        self.stop_button = Button(description="Stop")
        self.stop_button.on_click(self.on_stop_button_clicked)
        self._globals_dict["canvas"] = Canvas()
        self.kb_mon = Event(source=self.canvas,
                            watched_events=['keydown', 'keyup'],
                            wait=1000 // FRAME_RATE,
                            prevent_default_actions=True)
        self.output_text = ""
        self.color_strings = {"default": "#888888"}
        match_255 = r"(?:(?:2(?:(?:5[0-5])|(?:[0-4][0-9])))|(?:[01]?[0-9]{1,2}))"
        match_alpha = r"(?:(?:1(?:\.0*)?)|(?:0(?:\.[0-9]*)?))"
        match_360 = r"(?:(?:3[0-5][0-9])|(?:[0-2]?[0-9]{1,2}))"
        match_100 = r"(?:100|[0-9]{1,2})"
        self.regexes = [
            re.compile(r"#[0-9A-Fa-f]{6}"),
            re.compile(r"rgb\({},{},{}\)".format(match_255, match_255,
                                                 match_255)),
            re.compile(r"rgba\({},{},{},{}\)".format(match_255, match_255,
                                                     match_255, match_alpha)),
            re.compile(r"hsl\({},{}%,{}%\)".format(match_360, match_100,
                                                   match_100)),
            re.compile(r"hsla\({},{}%,{}%,{}\)".format(match_360, match_100,
                                                       match_100, match_alpha))
        ]
        self.width, self.height = DEFAULT_CANVAS_SIZE
        self.mouse_x = 0
        self.mouse_y = 0
        self.mouse_is_pressed = False
        self.key = ""
        self._keys_held = {}

        # Settings for drawing text (https://ipycanvas.readthedocs.io/en/latest/drawing_text.html).
        self.font_settings = {
            'size': 12.0,
            'font': 'sans-serif',
            'baseline': 'top',
            'align': 'left'
        }
示例#20
0
    def robot(self, canvas, x, y, room):
        rbt_img = Image.from_file('Images/robot.jpg')
        x = x * self.scale
        y = y * self.scale
        x += self.offset[room][0] + self.wall_th * self.scale
        y += self.offset[room][1] + self.wall_th * self.scale

        canvas3 = Canvas(width=1000, height=1000)
        canvas3.draw_image(rbt_img, 0, 0)
        canvas3.scale(0.1*self.scale/50)
        canvas.clear_rect(x, y, self.wall_th)
        canvas.draw_image(canvas3, x, y)
        
        return canvas
示例#21
0
    def rover(self, canvas, coord, Zone):
        rvr_img = Image.from_file('Images/rover.jpg')
        canvas3 = Canvas(width=1000, height=1000)
        canvas3.draw_image(rvr_img, 0, 0)
        canvas3.scale(0.025 * self.scale / 50)

        coord_rvr = self.problem_2_canvas(coord)
        x = coord_rvr[0] - 0.25 * self.scale
        y = coord_rvr[1] - 0.25 * self.scale
        offset = Zone.coordinates * self.scale
        canvas[3].translate(offset[0], offset[1])
        canvas[3].clear_rect(x, y, self.wall_th)
        canvas[3].draw_image(canvas3, x, y)
        canvas[3].translate(-offset[0], -offset[1])

        return canvas
示例#22
0
def displayGraph(graph, coef=1):
    """Affiche le graph en plt et en canvas"""
    x, y = calcXY(graph)
    canvas = Canvas(width=200, height=200)
    canvas = printCircles(x, y, canvas)
    canvas = printText(x, y, canvas)
    canvas = printBones(x, y, canvas)

    handGraph = [[1, 5, 9, 13, 17], [0, 2], [1, 3], [2, 4], [3], [0,
                                                                  6], [5, 7],
                 [6, 8], [7], [0, 10], [9, 11], [10, 12], [11], [0, 14],
                 [13, 15], [14, 16], [15], [0, 18], [17, 19], [18, 20], [19]]

    plt.scatter(x, y)
    for index in range(len(x)):
        for link in handGraph[index]:
            if index <= link:
                plt.plot([x[index], x[link]], [y[index], y[link]])

    plt.axis('equal')

    plt.show()

    return canvas
示例#23
0
"""Helper functions for array sorting."""
from ipycanvas import Canvas, hold_canvas
from random import shuffle
import time

CANVAS_WIDTH = 400
CANVAS_HEIGHT = 400
canvas = Canvas(width=CANVAS_WIDTH, height=CANVAS_HEIGHT)


def color(col):
    canvas.fill_style = col


def make_canvas():
    global canvas
    canvas = Canvas(width=CANVAS_WIDTH, height=CANVAS_HEIGHT)
    display(canvas)


def display_list(li, index=-2):
    pos = 0
    min_elem = min(li)
    max_elem = max(li) + 1
    elem_diff = max_elem - min_elem
    elem_height = CANVAS_HEIGHT / elem_diff
    width = CANVAS_WIDTH / len(li)
    with hold_canvas(canvas):
        canvas.clear()
        for elem in li:
            before_color = canvas.fill_style
示例#24
0
    def draw_splash(self, canvas, x, y, scale):

        if scale > 0.:
            splash_canvas = Canvas(width=self.cell_pixels,
                                   height=self.cell_pixels)
            sprite = Image.from_file('images/splash_2.png')

            with hold_canvas(splash_canvas):

                splash_canvas.save()

                pos_x = self.cell_pixels // 2
                pos_y = self.cell_pixels // 2

                # Choose a random rotation angle
                # (but first set the rotation center with `translate`)
                splash_canvas.translate(pos_x, pos_y)
                splash_canvas.rotate(uniform(0., pi))

                # scale the image
                splash_canvas.scale(scale)

                # Restore the canvas center
                splash_canvas.translate(-pos_x, -pos_y)

                # Draw the sprite
                splash_canvas.draw_image(sprite, 0, 0)
                splash_canvas.restore()

            x_px = x * self.cell_pixels + self.padding
            y_px = y * self.cell_pixels + self.padding
            canvas.draw_image(splash_canvas,
                              x_px,
                              y_px,
                              width=self.cell_pixels,
                              height=self.cell_pixels)
示例#25
0
class Turtle:

    DimPoint = namedtuple('DimPoint', ['x', 'y'])

    def __init__(self, image: str=None, size=(600, 300), **kwargs):
        """Create a Turtle drawing canvas.
        
        Arguments:

            image: Load the image into the canvas. 
            size: Set the size of the canvas.
        """
        self._size = Turtle.DimPoint(size[0], size[1])
        turtle = numpy.array(PIL.Image.open(pathlib.Path(__file__).parent / "turtle.png"))
        self._turtle = Canvas(width=turtle.shape[0], height=turtle.shape[1])
        self._turtle.put_image_data(turtle)
        self._canvas = MultiCanvas(n_canvases=3, width=self._size.x, height=self._size.y, **kwargs) 
        self._reset()

        if image is not None:
            self.background(image)          

        self.clear()
    
    def _reset(self):
        self._current = self._to_native(Turtle.DimPoint(0,0))
        self._cur_heading = (3 * math.pi) / 2 # in Canvas Y is negative.
        self._pendown = True 
        self._show = True

    def clear(self):
        """Clear the canvas and start over."""
        with self._do_draw():
            self._canvas[1].clear()
            self._reset()
        
    def draw(self, distance: float):
        """Move the pen by distance."""
        with self._do_draw():
            start = self._current
            self._current = Turtle.DimPoint(x = self._current.x + math.cos(self._cur_heading) * distance,
                            y = self._current.y + math.sin(self._cur_heading) * distance)                        
            if self._pendown:
                self._canvas[1].begin_path()
                self._canvas[1].move_to(*start)
                self._canvas[1].line_to(*self._current)
                self._canvas[1].stroke()

    def turn(self, degrees: float):
        """Turn the pen by degrees."""
        with self._do_draw():
            self._cur_heading = (self._cur_heading - math.radians(degrees)) % (math.pi * 2)

    def goto(self, *place: Union[Tuple[int,int], Sequence[int], DimPoint]):
        """Goto a point in the coordinate space."""
        if len(place) == 0:
            raise ValueError("Goto where?")
        elif isinstance(place[0], Turtle.DimPoint):
            p = place[0]
        elif isinstance(place[0], tuple):
            p = Turtle.DimPoint._make(*place)
        else:
            p = Turtle.DimPoint._make(place)

        with self._do_draw():
            start = self._current
            self._current = self._to_native(p)
            if self._pendown:
                self._canvas[1].begin_path()
                self._canvas[1].move_to(*start)
                self._canvas[1].line_to(*self._current)
                self._canvas[1].stroke()

    def heading(self, heading: float):
        """Set the pen to face heading in degrees."""
        with self._do_draw():
            self._cur_heading = -math.radians(heading)

    def up(self):
        """Pick the pen up. Movements won't make lines."""
        self._pendown = False

    def down(self):
        """Put the pen down. Movements will make lines."""
        self._pendown = True

    def color(self, color: str):
        """Set the pen color using HTML color notation."""
        self._canvas[1].stroke_style = color
        self._canvas[1].fill_style = color

    def width(self, width: int):
        """Set the line thickness."""
        self._canvas[1].line_width = width 

    def show(self):
        """Show the turtle in the scene.""" 
        with self._do_draw():
            self._show = True 
    
    def hide(self):
        """Hide the turtle in the scene.""" 
        with self._do_draw():
            self._show = False 
    
    def background(self, filename: str):
        """Set the background image"""
        self._reset()
        self._image = numpy.array(PIL.Image.open(filename))
        self.size = (self._image.shape[1], self._image.shape[0])
        self._canvas[0].put_image_data(self._image)
    
    def find_faces(self) -> List[Dict[str, Union[Tuple[int, int], Sequence[Tuple[int, int]]]]]:
        """
        Find the faces in the background image. Returns list of dictionaries, one for each 
        face that's found. Face dictionaries have landmark names as keys and points as 
        values. 

        The face dictionary has two types of values. Single-point values and path values. 
        The single point values are: 

            "top_right", "top_left", "bottom_right", "bottom_left" 

        The points in these keys are the box where the face was found. The other values 
        are paths that form the contour of a facial feature. They are: 

            "bottom_lip", "top_lip", "left_eye", "right_eye", "left_eyebrow", "right_eyebrow", 
            "nose_tip", "nose_bridge", "chin" 
        
        Returns:

            A list of face dictionaries. 
        """
        faces = face_recognition.face_locations(self._image, model='hog')
        features = face_recognition.face_landmarks(self._image, face_locations=faces)
        rval = []        
        for i in range(len(faces)):
            face = {}
            face.update({
                'top_right':    self._to_turtle(Turtle.DimPoint(x=faces[i][1], y=faces[i][0])),
                'top_left':     self._to_turtle(Turtle.DimPoint(x=faces[i][3], y=faces[i][0])),
                'bottom_left':  self._to_turtle(Turtle.DimPoint(x=faces[i][3], y=faces[i][2])),
                'bottom_right': self._to_turtle(Turtle.DimPoint(x=faces[i][1], y=faces[i][2])),                
            })
            for feature in features[i]:
                face[feature] = list(map(self._to_turtle, features[i][feature]))
            rval.append(face)
        return rval

    def polygon(self, points: Sequence[Tuple[int, int]]):
        """Draw a filled polygon.
        
        Arguments:

            points: A list of 2D tuples of (x,y)

        """
        with self._do_draw():
            self._canvas[1].begin_path()
            self._canvas[1].move_to(*self._to_native(points[0]))
            for point in points[1:]:
                self._canvas[1].line_to(*self._to_native(point))
            self._canvas[1].fill()

    def write(self, text: str, font: str="24px sans-serif", text_align: str="center", line_color: str=None, fill_color: str=None):
        """Write text.
        
        Arguments:

            text: The text to write 
            font: The HTML font specification 
            text_align: The alignment of the text relative to the turtle 
            line_color: The color of the outline of the text (defaults to the pen color)
            fill_color: The color of the fill of the text (defaults to the pen color)
        """
        with self._do_draw():
            old_stroke = self._canvas[1].stroke_style
            old_fill = self._canvas[1].fill_style
            if line_color is not None:
                self._canvas[1].stroke_style = line_color
            if fill_color is not None:
                self._canvas[1].fill_style = fill_color
            self._canvas[1].translate(self._current.x, self._current.y)
            self._canvas[1].rotate(self._cur_heading + math.pi/2)
            self._canvas[1].font = font
            self._canvas[1].text_align = text_align
            self._canvas[1].fill_text(text, 0, 0)
            self._canvas[1].stroke_text(text, 0, 0)
            self._canvas[1].reset_transform()
            self._canvas[1].stroke_style = old_stroke
            self._canvas[1].fill_style = old_fill

    @contextlib.contextmanager
    def _do_draw(self):
        """Context manager that combines all drawing operations and re-renders the turtle."""
        with hold_canvas(self._canvas):
            yield 
            self._canvas[2].clear()
            if self._show:
                self._canvas[2].save()
                self._canvas[2].translate(self._current.x, self._current.y)
                self._canvas[2].rotate(self._cur_heading + math.pi / 2)
                self._canvas[2].draw_image(self._turtle, 
                    x=-15, y=-15, 
                    width=30, height=30)
                self._canvas[2].restore()

    def _to_native(self, point: Tuple[int, int]) -> DimPoint:
        """Convert Turtle coordinates to native ones."""
        return Turtle.DimPoint(x=self._size.x//2 + point[0], y=self._size.y//2 - point[1])

    def _to_turtle(self, point: DimPoint) -> Tuple[int, int]:
        """Convert Turtle coordinates to native ones."""
        return (point[0] - self._size.x//2, self._size.y//2 - point[1])
        
    def _ipython_display_(self):
        display(self._canvas)

    @property
    def size(self) -> Tuple[int,int]:
        """Get the size of the canvas' color buffer (not layout size)."""
        return (self._size.x, self._size.y)

    @size.setter
    def size(self, newsize: Tuple[int,int]):
        """Resize the canvas element and adjust they layout size."""
        self._size = Turtle.DimPoint(x=newsize[0], y=newsize[1])
        with self._do_draw():
            self._canvas.width = self._size.x
            self._canvas.height = self._size.y
            if self._size.x >= 800:
                self._canvas.layout.width = "90%"
                self._canvas.layout.max_width = f"{self._size.x}px"
                self._canvas.layout.min_width = "800px"
            else:
                self._canvas.layout.width = "auto"
                self._canvas.layout.max_width = "auto"
                self._canvas.layout.min_width = "auto"
示例#26
0
    def __init__(self, parser: Parser, width: int, height: int, colorMap,
                 filterFunction, availableActions):
        """
        Setup the interactor variables, should be called first in a sub class.
        
            parser - a simulation output parser
            width - the width of the canvas to draw to
            height - the height of the canvas to draw to
            colorMap - a function resulting in the cell colors (distinct results based on subclass, see subclass documentation for necessary return values)
            filterFunction - a function resulting in an array of the indicies of the cells to draw
            availableActions - a list of all the actions that can be performed on the canvas
        
        """
        self._currentFrame = parser.getFrameRange()[0]
        self._canvas = Canvas(width=width, height=height)
        self._parser = parser
        self._colorMap = colorMap
        self._height = height
        self._width = width
        self._filterFunction = filterFunction

        self._cellFigure = None
        self._generalGraph = GeneralPlot(parser)

        frame = parser.getFrame(self._currentFrame)
        mesh = frame.environment.mesh
        self._availableEnvironments = [*frame.environment.current.attributes]

        self._canvas.on_mouse_down(self._onMouseDown)
        self._canvas.on_mouse_move(self._onMouseMove)
        self._canvas.on_mouse_up(self._onMouseUp)
        self._canvas.on_mouse_out(self._onMouseOut)

        self.action = availableActions[0]

        self._buttons = widgets.RadioButtons(
            options=availableActions,
            value=self.action,
            description='Mouse Action:',
            disabled=False,
        )
        self._buttons.observe(self.onToolChange, names='value')

        self._visible = (constants.VISIBLE_CELL, )
        self._environmentButtons = widgets.SelectMultiple(
            options=[constants.VISIBLE_CELL, *self._availableEnvironments],
            description='Visible:',
            disabled=False,
            value=[constants.VISIBLE_CELL],
        )
        self._environmentButtons.observe(self.onVisibilityChange,
                                         names='value')

        self._availableAttributes = [*frame.cells.variables.keys()]
        self._selectedAttribute = self._availableAttributes[0]
        self._previousSelectedAttribute = None
        self._previousSelectedAttributeCell = None
        self._attributes = widgets.RadioButtons(
            options=self._availableAttributes,
            value=self._selectedAttribute,
            description='Attribute Graph:\n',
            disabled=False,
        )
        self._attributes.observe(self.onAttriChange, names='value')

        self._frameSelector = widgets.IntSlider(value=self._currentFrame,
                                                min=parser.getFrameRange()[0],
                                                max=parser.getFrameRange()[1] -
                                                1,
                                                step=1,
                                                description='Frame:',
                                                disabled=False,
                                                continuous_update=False,
                                                orientation='horizontal',
                                                readout=True,
                                                readout_format='d')
        self._frameSelector.observe(self.onFrameChange, names='value')

        self._clicking = False
        self._dragStartX = 0
        self._dragStartY = 0
        self._actionOriginX = 0
        self._actionOriginY = 0

        self._selectedCell = None
示例#27
0
class Interactor:
    """
    Base interactor class. Is an abstract class. Handles shared functionality such as canvases and graphs.
    
    """
    def __init__(self, parser: Parser, width: int, height: int, colorMap,
                 filterFunction, availableActions):
        """
        Setup the interactor variables, should be called first in a sub class.
        
            parser - a simulation output parser
            width - the width of the canvas to draw to
            height - the height of the canvas to draw to
            colorMap - a function resulting in the cell colors (distinct results based on subclass, see subclass documentation for necessary return values)
            filterFunction - a function resulting in an array of the indicies of the cells to draw
            availableActions - a list of all the actions that can be performed on the canvas
        
        """
        self._currentFrame = parser.getFrameRange()[0]
        self._canvas = Canvas(width=width, height=height)
        self._parser = parser
        self._colorMap = colorMap
        self._height = height
        self._width = width
        self._filterFunction = filterFunction

        self._cellFigure = None
        self._generalGraph = GeneralPlot(parser)

        frame = parser.getFrame(self._currentFrame)
        mesh = frame.environment.mesh
        self._availableEnvironments = [*frame.environment.current.attributes]

        self._canvas.on_mouse_down(self._onMouseDown)
        self._canvas.on_mouse_move(self._onMouseMove)
        self._canvas.on_mouse_up(self._onMouseUp)
        self._canvas.on_mouse_out(self._onMouseOut)

        self.action = availableActions[0]

        self._buttons = widgets.RadioButtons(
            options=availableActions,
            value=self.action,
            description='Mouse Action:',
            disabled=False,
        )
        self._buttons.observe(self.onToolChange, names='value')

        self._visible = (constants.VISIBLE_CELL, )
        self._environmentButtons = widgets.SelectMultiple(
            options=[constants.VISIBLE_CELL, *self._availableEnvironments],
            description='Visible:',
            disabled=False,
            value=[constants.VISIBLE_CELL],
        )
        self._environmentButtons.observe(self.onVisibilityChange,
                                         names='value')

        self._availableAttributes = [*frame.cells.variables.keys()]
        self._selectedAttribute = self._availableAttributes[0]
        self._previousSelectedAttribute = None
        self._previousSelectedAttributeCell = None
        self._attributes = widgets.RadioButtons(
            options=self._availableAttributes,
            value=self._selectedAttribute,
            description='Attribute Graph:\n',
            disabled=False,
        )
        self._attributes.observe(self.onAttriChange, names='value')

        self._frameSelector = widgets.IntSlider(value=self._currentFrame,
                                                min=parser.getFrameRange()[0],
                                                max=parser.getFrameRange()[1] -
                                                1,
                                                step=1,
                                                description='Frame:',
                                                disabled=False,
                                                continuous_update=False,
                                                orientation='horizontal',
                                                readout=True,
                                                readout_format='d')
        self._frameSelector.observe(self.onFrameChange, names='value')

        self._clicking = False
        self._dragStartX = 0
        self._dragStartY = 0
        self._actionOriginX = 0
        self._actionOriginY = 0

        self._selectedCell = None

    def setColorMap(self, colorMap):
        """
        Set the cell coloring function.
        
            colorMap: the cell coloring function
        
        """
        self._colorMap = colorMap
        self.update()

    def setFilterFunction(self, filterFunction):
        """
        Set the cell filtering function
        
            filterFunction: the filtering function
        
        """
        self._filterFunction = filterFunction
        self.update()

    def onToolChange(self, action):
        """
        Handle a user action which changes the canvas tool
        
            action: an ipyWidget radio button selection action
        
        """
        self.action = action.new

    @output.capture()
    def onVisibilityChange(self, action):
        """
        Handle a user action which changes the elements which are visibile on the canvas
        
            action: an ipyWidget multi selection action
        
        """
        self._visible = action.new
        self.update()

    @output.capture()
    def onAttriChange(self, action):
        """
        Handle a user action which changes the attribute to display for the selected cell
        
            action: an ipyWidget radio button selection action
        
        """
        self._selectedAttribute = action.new
        self._updateCellPlot()

    @output.capture()
    def _updateCellPlot(self):
        """
        Update the plot which shows how the currently selected attribute changes over time for the selected cell
        
        """
        if (self._previousSelectedAttribute == self._selectedAttribute
                and self._previousSelectedAttributeCell
                == self._selectedCell) or self._selectedCell is None:
            return

        self._previousSelectedAttribute = self._selectedAttribute
        self._previousSelectedAttributeCell = self._selectedCell

        data = []
        timestamps = []
        time = 0
        variables = self.getCellVariables()
        for frameNumber in range(*self._parser.getFrameRange()):
            cell = self.getSelectedCell(frameNumber)
            if cell.shape[0] == 0:
                continue
            data.append(cell[variables[self._selectedAttribute]])
            timestamps.append(time)
            time += 1

        if self._cellFigure is not None:
            plt.figure(self._cellFigure.get_label())
            self._cellAx.clear()
            ln, = self._cellAx.plot(timestamps, data)
            self._cellAx.set_xlabel('time')
            self._cellAx.set_ylabel(self._selectedAttribute)
            self._cellAx.set_title(self._selectedAttribute + " for cell " +
                                   str(int(self._selectedCell)))
            ln.set_color('orange')

    def onFrameChange(self, action):
        """
        Handle a user action which changes the frame to view
        
            action: an ipyWidget slider action
        
        """
        self._currentFrame = action.new
        self.update()

    def getCellVariables(self, frame: int = None):
        """
        Get the cell varaibles for the frame
        
            frame: int - the frame number to get the variables from
        
        """
        if frame is None:
            frame = self._currentFrame
        return self._parser.getFrame(frame).cells.variables

    def getCell(self, cellId: int, frame: int = None):
        """
        Get the cell from the frame (used current frame if not specified)
        
            cellId: int - the id of the cell to get
            frame: int = currentFrame - the frame number to get the cell from
        
        """
        if frame is None:
            frame = self._currentFrame
        cells = self.getCells(frame)
        variables = self.getCellVariables()
        cellColumn = cells[variables['ID']] == cellId
        return cells[:, cellColumn].reshape(-1)

    def getCells(self, frame: int = None):
        """
        Get the cells from the frame (uses the current frame if not specified)
        
            frame: int = currentFrame - the frame number to get the cells from
        
        """
        if frame is None:
            frame = self._currentFrame
        return self._parser.getFrame(frame).cells.data

    def getCellsToRender(self, frame: int = None):
        """
        Get the cells to render from the given frame (uses the current frame if not specified). Applies
        the current cell filtering function on the result.
        
            frame: int = currentFrame - the frame number to get the cells from
        
        """
        cells = self.getCells(frame)

        if self._filterFunction:
            cellVariables = self.getCellVariables(frame)
            cells = cells[:, self._filterFunction(cells, cellVariables)]

        return cells

    def getSelectedCell(self, frame: int = None):
        """
        Get the cell data for the cell which is currently selected on the specified frame (uses the current frame if not specified).
        Will be None if no cell is selected.
        
            frame: int = currentFrame - the frame number to get the cells from
        
        """
        if self._selectedCell is None:
            return None

        return self.getCell(self._selectedCell, frame)

    @output.capture()
    def _onMouseDown(self, x: int, y: int):
        """
        Handle user mouse down action from ipyCanvas canvas
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        self._dragStartX = x
        self._dragStartY = y
        self._actionOriginX = x
        self._actionOriginY = y

        self.onMouseDown(x, y)

        if self.action == constants.SELECT_ACTION:
            self.selectCell(x, y)
        else:
            self._clicking = True

    def selectCell(self, x: int, y: int):
        """
        Select the cell at the given x and y coordinates.
        Abstract function, should be implemented by subclass.
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        pass

    def _onMouseUp(self, x: int, y: int):
        """
        Handle user mouse up action from ipyCanvas canvas
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        self._clicking = False
        self.onMouseUp(x, y)

    def _onMouseOut(self, x: int, y: int):
        """
        Handle user mouse out (mouse moves off the canvas) action from ipyCanvas canvas
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        self._clicking = False
        self.onMouseOut(x, y)

    @output.capture()
    def _onMouseMove(self, x: int, y: int):
        """
        Handle user mouse move action from ipyCanvas canvas
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas. 
                        The current X position of the mouse.
            y: int - the y position the mouse event occured based on the top left corner of the canvas.
                        The current y position of the mouse.
        
        """
        self.onMouseMove(x, y)

    def onMouseUp(self, x: int, y: int):
        """
        Handle a mouse up event at the given x and y coordinates.
        Abstract function, can be implemented by subclass.
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        pass

    def onMouseOut(self, x: int, y: int):
        """
        Handle a mouse out event at the given x and y coordinates.
        Abstract function, can be implemented by subclass.
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        pass

    def onMouseMove(self, x: int, y: int):
        """
        Handle a mouse move event at the given x and y coordinates.
        Abstract function, can be implemented by subclass.
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        pass

    def onMouseDown(self, x: int, y: int):
        """
        Handle a mouse down event at the given x and y coordinates.
        Abstract function, can be implemented by subclass.
        
            x: int - the x position the mouse event occured based on the top left corner of the canvas
            y: int - the y position the mouse event occured based on the top left corner of the canvas
        
        """
        pass

    def update(self):
        """
        Update UI, should be called after subclass updates. Puts shared data onto the canas.
        
        """
        canvas = self._canvas

        selectedCell = self.getSelectedCell()
        if selectedCell is not None and selectedCell.shape[0] != 0:
            cellVaraibles = self.getCellVariables()

            canvas.fill_style = '#A0A0A0'
            canvas.font = '10px serif'

            identity = selectedCell[cellVaraibles["ID"]]
            volume = selectedCell[cellVaraibles["total_volume"]]
            phase = selectedCell[cellVaraibles["current_phase"]]

            canvas.fill_text(
                f"(ID: {identity}, Volume: {volume}, Phase: {phase})", 10,
                self._height - 10)

        self._updateCellPlot()

    def radiusOfCells(self, cells, variables):
        """
        Determines the radius of the cells based on the cell (3D) volume. Results in a numpy array.
        
            cells - the cells to get the radius of
            variables - the variables of the cells
        
        """
        return (cells[variables['total_volume']] * (3 / (4 * math.pi)))**(1 /
                                                                          3)

    def show(self):
        """
        Displays the widgets to the screen
        
        """
        display(self._canvas, self._frameSelector, self._buttons,
                self._environmentButtons, self._attributes, output)
        if self._cellFigure is None:
            global figureNumber
            fig, ax = plt.subplots()
            self._cellAx = ax
            self._cellFigure = fig
            figureNumber += 1
        plt.figure()
        self._generalGraph.plotPop()
示例#28
0
def make_canvas():
    global canvas
    canvas = Canvas(width=CANVAS_WIDTH, height=CANVAS_HEIGHT)
    display(canvas)
示例#29
0
from ipycanvas import Canvas
import turtle

canvas = Canvas(size=(200, 200))
t = turtle.Turtle(canvas)
canvas
示例#30
0
class SimpleImage:
    def __init__(self,
                 image,
                 scale=1,
                 interpolation=transform.interpolation.nearest):
        self.__scale = scale
        self.__interpolation = interpolation
        self.__image = self.transform(image)

        self.__canvas = Canvas(width=self.__image.shape[1],
                               height=self.__image.shape[0],
                               scale=1)
        self.__canvas.put_image_data(self.__image, 0, 0)

    @property
    def fig(self):
        return self.__canvas

    def transform(self, image):
        if transform.isCHW(image) and not transform.isHWC(image):
            image = transform.HWC(
                image)  #transform to HWC format for display...
        elif not transform.isHWC(image):
            raise ValueError("Argument: \"image\" must be in HWC format")

        if transform.is_integer(image):
            image = transform.to_float(image)
        else:
            image = image.astype(np.float32)  #must be float32...

        if image.shape[-1] != 3:
            image = transform.colour(
                image, components=(1, 1, 1))  #requires HWC float format...
        if self.__scale != 1:
            image = transform.scale(image,
                                    self.__scale,
                                    interpolation=self.__interpolation)

        return transform.to_integer(image)  #finally transform to int

    def display(self):
        box_layout = widgets.Layout(display='flex',
                                    flex_flow='row',
                                    align_items='center',
                                    width='100%')
        display(HBox([self.__canvas], layout=box_layout))

    def update(self, image):
        self.set_image(image)

    def set_image(self, image):
        #TODO if this is live there might be problems... give the option of preprocessing via transform

        image = self.transform(image)
        assert image.shape == self.__image.shape  #shapes must be equal after scaling
        self.__image = image
        self.__canvas.put_image_data(image)

    @property
    def widget(self):
        return self.__canvas

    def scale(self):
        raise NotImplementedError("TODO scale the image?")