Ejemplo n.º 1
0
 def __init__(self, stop_list):
     pygame.init()
     self.stop_list = stop_list
     self.screen = pygame.display.set_mode(SIZE)
     pygame.display.set_caption("bus-stop")
     self.set_screen()
     self.clock = pygame.time.Clock()
     self.all_bus = pygame.sprite.Group()
     self.legend = Legend()
     self.running = True
Ejemplo n.º 2
0
    def __init__(self, data=None, **kwtraits):
        if 'origin' in kwtraits:
            self.default_origin = kwtraits.pop('origin')
        if "title" in kwtraits:
            title = kwtraits.pop("title")
        else:
            title = None
        super(Plot, self).__init__(**kwtraits)
        if data is not None:
            if isinstance(data, AbstractPlotData):
                self.data = data
            elif type(data) in (ndarray, tuple, list):
                self.data = ArrayPlotData(data)
            else:
                raise ValueError, "Don't know how to create PlotData for data" \
                                  "of type " + str(type(data))

        if not self._title:
            self._title = PlotLabel(font="swiss 16", visible=False,
                                   overlay_position="top", component=self)
        if title is not None:
            self.title = title

        if not self.legend:
            self.legend = Legend(visible=False, align="ur", error_icon="blank",
                                 padding=10, component=self)

        # ensure that we only get displayed once by new_window()
        self._plot_ui_info = None

        return
Ejemplo n.º 3
0
    def legend(self, handles, labels, loc, **kwargs):
        """
        Place a legend in the figure.  Labels are a sequence of
        strings, handles is a sequence of line or patch instances, and
        loc can be a string or an integer specifying the legend
        location

        USAGE: 
          legend( (line1, line2, line3),
                  ('label1', 'label2', 'label3'),
                  'upper right')

        The LOC location codes are

          'best' : 0,          (currently not supported, defaults to upper right)
          'upper right'  : 1,  (default)
          'upper left'   : 2,
          'lower left'   : 3,
          'lower right'  : 4,
          'right'        : 5,
          'center left'  : 6,
          'center right' : 7,
          'lower center' : 8,
          'upper center' : 9,
          'center'       : 10,

        The legend instance is returned
        """

        handles = flatten(handles)
        l = Legend(self, handles, labels, loc, isaxes=False, **kwargs)
        self._set_artist_props(l)
        self.legends.append(l)
        return l
Ejemplo n.º 4
0
    def __init__(self, figure, axis=None):
        """
		Create the drawable with the figure.

		:param figure: The figure that the :class:`~Drawable` class wraps.
					   This is mainly used to get the figure renderer.
		:type figure: :class:`matplotlib.figure.Figure`
		:param axis: The axis (or subplot) where to plot visualizations.
					 If `None` is not given, the plot's main subplot is used instead.
		:type axis: `None` or :class:`matplotlib.axis.Axis`
		"""

        self.figure = figure
        self.axis = plt.gca() if axis is None else axis
        self.caption = Annotation(self)

        self.annotations = []
        self.legend = Legend(self)
        self.timeseries = None
Ejemplo n.º 5
0
    def createLegendWidget(self):
        # Create the map legend widget and associate to the canvas """
        self.legend = Legend(self)
        self.legend.setObjectName("theMapLegend")

        self.LegendDock = QDockWidget("Layers", self)
        self.LegendDock.setObjectName("legend")
        self.LegendDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.LegendDock.setWidget(self.legend)
        self.LegendDock.setContentsMargins(9, 9, 9, 9)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.LegendDock)
Ejemplo n.º 6
0
    def legend(self, handles, labels, *args, **kwargs):
        """
        Place a legend in the figure.  Labels are a sequence of
        strings, handles is a sequence of line or patch instances, and
        loc can be a string or an integer specifying the legend
        location

        USAGE:
          legend( (line1, line2, line3),
                  ('label1', 'label2', 'label3'),
                  'upper right')

        The LOC location codes are

          'best' : 0,          (currently not supported for figure legends)
          'upper right'  : 1,
          'upper left'   : 2,
          'lower left'   : 3,
          'lower right'  : 4,
          'right'        : 5,
          'center left'  : 6,
          'center right' : 7,
          'lower center' : 8,
          'upper center' : 9,
          'center'       : 10,

        loc can also be an (x,y) tuple in figure coords, which
        specifies the lower left of the legend box.  figure coords are
        (0,0) is the left, bottom of the figure and 1,1 is the right,
        top.

        The legend instance is returned.  The following kwargs are supported:

        loc = "upper right" #
        numpoints = 4         # the number of points in the legend line
        prop = FontProperties(size='smaller')  # the font property
        pad = 0.2             # the fractional whitespace inside the legend border
        markerscale = 0.6     # the relative size of legend markers vs. original
        shadow                # if True, draw a shadow behind legend
        labelsep = 0.005     # the vertical space between the legend entries
        handlelen = 0.05     # the length of the legend lines
        handletextsep = 0.02 # the space between the legend line and legend text
        axespad = 0.02       # the border between the axes and legend edge

        """

        handles = flatten(handles)
        l = Legend(self, handles, labels, *args, **kwargs)
        self._set_artist_props(l)
        self.legends.append(l)
        return l
Ejemplo n.º 7
0
class Window:
    def __init__(self, stop_list):
        pygame.init()
        self.stop_list = stop_list
        self.screen = pygame.display.set_mode(SIZE)
        pygame.display.set_caption("bus-stop")
        self.set_screen()
        self.clock = pygame.time.Clock()
        self.all_bus = pygame.sprite.Group()
        self.legend = Legend()
        self.running = True

    def draw_stop(self, stop):
        pos = stop.pos
        pygame.draw.circle(self.bground, (200, 0, 20), pos, RAD_STOP)

    def draw_line(self, p1, p2, color):
        pygame.draw.line(self.bground, color, p1, p2)

    def add_bus(self, bus):
        b = sprite.Bus(bus)
        self.all_bus.add(b)

    def set_screen(self):
        self.screen.fill((0, 0, 0))
        self.bground = self.screen.copy()
        for stop in self.stop_list:
            self.draw_stop(stop)
        pygame.display.flip()

    def loop(self):
        while self.running:
            self.clock.tick(60)
            self.screen.blit(self.bground, (0, 0))
            self.legend.draw(self.screen)
            self.all_bus.update()
            self.all_bus.draw(self.screen)
            pygame.display.flip()
Ejemplo n.º 8
0
def add_legend_to_map(the_map):
    """Add a default legend to a folium map.

    Parameters
    ----------
    the_map : object like folium.folium.Map
        The map we are to add the tiles to.

    """
    labels = []
    for key, val in COLORS_PARTY.items():
        labels.append({'text': key, 'color': val, 'opacity': OPACITY})
    legend = Legend(title='Partier', labels=labels)
    the_map.add_child(legend)
Ejemplo n.º 9
0
 def __init__(self):
     self.img = None
     self.legend = Legend()
     self.title = Title()
     self.autosize = App.cfg['image']['autosize']
     self.autosize_minpx = App.cfg['image']['autosize_minpx']
     self.basewidth = App.cfg['image']['basewidth']
     self.baseheight = App.cfg['image']['baseheight']
     self.padding = App.cfg['image']['padding']
     self.showborder = App.cfg['image']['border']
     self.showtitle = App.cfg['title']['show']
     self.showlegend = App.cfg['legend']['show']
     self.showgrid = App.cfg['axis']['grid']
     self.showaxis = App.cfg['axis']['show']
     self.showflat = App.cfg['image']['flatline']
     self.showtimestamp = App.cfg['image']['timestamp']
     self.timestampcolor = App.cfg['image']['timestampcolor']
     self.bordercolor = App.cfg['image']['bordercolor']
     self.streetcolor = App.cfg['image']['streetcolor']
     self.flatcolor = App.cfg['image']['flatcolor']
     self.gridcolor = App.cfg['axis']['gridcolor']
     self.axiscolor = App.cfg['axis']['color']
     self.axisfont = App.cfg['axis']['font']
     self.bgcolor = App.cfg['image']['bgcolor']
Ejemplo n.º 10
0
    def __init__(self, json_obj):
        self.title = json_obj["title"]
        self.label = json_obj["label"]
        self.legend = []

        for legend in json_obj["legend"]:
            self.legend.append(Legend(legend))

        self.rows = json_obj["rows"]
        self.columns = json_obj["columns"]

        self.bars = []

        for bar in json_obj["bars"]:
            self.bars.append(Bar(bar))

        self.bar_height = json_obj["bar_height"]
Ejemplo n.º 11
0
def processTrackerGGLegendData(o, all_legend_names):
	legend_data = list()
	#process reponse data
	for legend in all_legend_names:
		#set default kills to 0
		kills = 0;
		for item in o["data"]:
			#if legend name matches a player data legend name then attempt to get kill data
			if item.get("metadata").get("name") == legend:
				#if kill data is available then set value of kills
				if item.get("stats") and item.get("stats").get("kills") and item.get("stats").get("kills").get("value"):
					kills = int(item["stats"]["kills"]["value"])
		#initialise Legend object for each legend using name and kills as parameters.
		legend_data.append(Legend(legend, kills))
		pass

	return legend_data
Ejemplo n.º 12
0
    def update(self, string):

        QObjectCleanupHandler().add(self.layout())

        scroll_bar_position = self.scroll.horizontalScrollBar().value()

        for widgets in self.findChildren(QWidget):
            widgets.deleteLater()

        dictionary = json.loads(string)
        credit = dictionary["creditos"]
        dictionary = dictionary["malla"]

        hbox = QHBoxLayout()

        legend = Legend()
        hbox.addWidget(legend)

        for semester_number in [
                str(index) for index in range(1,
                                              len(dictionary) + 1)
        ]:
            height = self.geometry().height() * semester_height_scale
            semester = Semester(number=semester_number,
                                credit=credit[semester_number],
                                height=height)
            semester.add_subjects(dictionary[semester_number])
            hbox.addWidget(semester)
            semester.send_semester_update.connect(self.receive_semester_update)
            semester.send_subject_state_update.connect(
                self.receive_subject_state_update)

        groupBox = QGroupBox()
        groupBox.setLayout(hbox)
        self.scroll = QScrollArea()
        self.scroll.setWidget(groupBox)
        self.scroll.setWidgetResizable(True)

        self.scroll.horizontalScrollBar().setValue(scroll_bar_position)

        hbox = QHBoxLayout()
        hbox.addWidget(self.scroll)
        self.setLayout(hbox)
Ejemplo n.º 13
0
 def addLegend (self, pairs):
     if len (pairs) == 0:
         return
     """self.leg = Legend (width = self.settings.width, textHeight = self.settings.legendTextHeight)
     keys = pairs.keys ()
     keys.sort ()
     for k in keys:
         self.leg.addKey (k, pairs[k])
     self.leg.y = self.settings.height - self.leg.height
     self.canvas.move (0, self.leg.height + 20)
     self.canvas.changeSize (0, -(self.leg.height + 20))
     self.draw (self.leg)"""
     self.leg = Legend (width = self.settings.width / 4.0, textHeight = self.settings.legendTextHeight)
     keys = pairs.keys ()
     keys.sort ()
     for k in keys:
         self.leg.addKey (k, pairs[k])
     self.canvas.changeSize (-self.leg.width, 0)
     self.leg.y = self.settings.height - (self.canvas.height + self.canvas.y)
     self.leg.x = self.canvas.x + self.canvas.width
     #self.leg.y = self.settings.height - self.leg.height
     #self.canvas.move (0, self.leg.height + 20)
     self.draw (self.leg)
Ejemplo n.º 14
0
    def __init__(self, *args, **kwargs):
        """
        Sets up the UI, binds the events etc
        """
        super(French75, self).__init__(*args, **kwargs)
        #WorldState.Instance() = WorldState.Instance()
        self.Maximize()
        (WorldState.Instance().dispW,
         WorldState.Instance().dispH) = self.GetSize()

        splitter_far_right = wx.SplitterWindow(self, -1)
        splitter_horiz_middle = wx.SplitterWindow(splitter_far_right, -1)
        splitter_vert_middle = wx.SplitterWindow(splitter_horiz_middle)
        splitter_far_right_middle = wx.SplitterWindow(splitter_far_right, -1)

        self.legend_panel = scrolled.ScrolledPanel(splitter_vert_middle, -1)
        self.graph_panel = wx.Panel(splitter_vert_middle, -1)

        self.legend_panel.SetBackgroundColour(_BG_COLOUR)
        self.graph_panel.SetBackgroundColour(_BG_COLOUR)
        """
        Animation Panel Setup
        """
        self.animation_panel = scrolled.ScrolledPanel(splitter_horiz_middle,
                                                      -1)
        self.animation_panel.SetBackgroundColour(_BG_COLOUR)

        self.btn_animate_play = wx.Button(self.animation_panel, -1, 'Play')
        self.btn_animate_play.Bind(wx.EVT_BUTTON, self.play_animation)

        self.slider_time = wx.Slider(
            self.animation_panel,
            -1,
            value=0,
            minValue=0,
            maxValue=WorldState.Instance().session_dict['max_time'],
            style=wx.SL_AUTOTICKS | wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.slider_time.Bind(wx.EVT_SLIDER, self.move_animation)
        self.slider_time.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.released_slider)

        self.drop_down_species = wx.ComboBox(self.animation_panel,
                                             -1,
                                             style=wx.CB_READONLY)
        self.drop_down_species.Bind(wx.wx.EVT_COMBOBOX,
                                    self.change_animation_species)

        self.switch_animation_button = wx.Button(self.animation_panel, -1,
                                                 "<->")
        self.switch_animation_button.Bind(wx.EVT_BUTTON, self.switch_animation)

        self.drop_down_files = wx.ComboBox(self.animation_panel,
                                           -1,
                                           style=wx.CB_READONLY)
        self.drop_down_files.Bind(wx.wx.EVT_COMBOBOX,
                                  self.change_animation_file)

        line1 = wx.StaticLine(self.animation_panel, -1, style=wx.LI_VERTICAL)
        line3 = wx.StaticLine(self.animation_panel, -1, style=wx.LI_VERTICAL)
        line2 = wx.StaticLine(self.animation_panel)

        animation_vbox = wx.BoxSizer(wx.VERTICAL)
        animation_hbox = wx.BoxSizer(wx.HORIZONTAL)
        self.animation_panels_hbox = wx.BoxSizer(wx.HORIZONTAL)

        animation_hbox.Add(self.drop_down_files, 0, wx.ALL, 10)
        animation_hbox.Add(self.switch_animation_button, 0, wx.TOP, 12)
        animation_hbox.Add(self.drop_down_species, 0, wx.ALL, 10)
        animation_hbox.Add(line1, 0, wx.EXPAND | wx.ALL, 5)
        animation_hbox.Add(self.btn_animate_play, 0, wx.TOP, 12)
        animation_hbox.Add(line3, 0, wx.EXPAND | wx.ALL, 5)
        animation_hbox.Add(self.slider_time, 0,
                           wx.BOTTOM | wx.EXPAND | wx.ALIGN_RIGHT, 5)

        animation_vbox.Add(animation_hbox, 0)
        animation_vbox.Add(line2, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
        animation_vbox.Add(self.animation_panels_hbox)

        self.animation_panel.SetSizer(animation_vbox)
        self.animation_panel.Layout()
        self.animation_panel.SetupScrolling(scroll_y=False)
        """
        Attached Files Panel Setup
        """
        attachment_panel = wx.Panel(splitter_far_right_middle, -1)
        attachment_panel.SetBackgroundColour(_BG_COLOUR)

        attached_files_vbox = wx.BoxSizer(wx.VERTICAL)
        attached_file_toolbar = wx.BoxSizer(wx.HORIZONTAL)

        attached_label = wx.StaticText(attachment_panel, -1, "Attached Files:")
        attached_files_vbox.Add(attached_label, 0,
                                wx.EXPAND | wx.TOP | wx.LEFT, 5)

        self.attached_file_list = wx.ListBox(attachment_panel,
                                             -1,
                                             size=(300, 300))
        attached_files_vbox.Add(self.attached_file_list)

        self.add_files_button = wx.Button(attachment_panel, -1, "Add")
        self.add_files_button.Bind(wx.EVT_BUTTON, self.attach_file)

        self.open_files_button = wx.Button(attachment_panel, -1, "Open")
        self.open_files_button.Bind(wx.EVT_BUTTON, self.open_attached_file)

        attached_file_toolbar.Add(self.add_files_button, 0, wx.ALL, 5)
        attached_file_toolbar.Add(self.open_files_button, 0, wx.ALL, 5)

        attached_files_vbox.Add(attached_file_toolbar, 0,
                                wx.ALL | wx.ALIGN_CENTRE, 5)

        attachment_panel.SetSizer(attached_files_vbox)
        attached_files_vbox.Fit(self)
        """
        Animation Annotations Panel Setup
        """

        annotation_panel = wx.Panel(splitter_far_right_middle, -1)
        annotation_panel.SetBackgroundColour(_BG_COLOUR)

        anime_annotations_vbox = wx.BoxSizer(wx.VERTICAL)
        anime_annotations_toolbar = wx.BoxSizer(wx.HORIZONTAL)

        anime_annotations_label = wx.StaticText(annotation_panel, -1,
                                                "Animation Annotations:")
        anime_annotations_vbox.Add(anime_annotations_label, 0,
                                   wx.EXPAND | wx.TOP | wx.LEFT, 5)

        self.anime_annotations_list = wx.ListBox(annotation_panel,
                                                 -1,
                                                 size=(300, 300))
        anime_annotations_vbox.Add(self.anime_annotations_list)

        self.add_anime_annotation_button = wx.Button(annotation_panel, -1,
                                                     "Add")
        self.add_anime_annotation_button.Bind(wx.EVT_BUTTON,
                                              self.add_anime_annotation)

        self.delete_anime_annotation_button = wx.Button(
            annotation_panel, -1, "Remove")
        self.delete_anime_annotation_button.Bind(wx.EVT_BUTTON,
                                                 self.remove_anime_annotation)

        anime_annotations_toolbar.Add(self.add_anime_annotation_button, 0,
                                      wx.ALL, 5)
        anime_annotations_toolbar.Add(self.delete_anime_annotation_button, 0,
                                      wx.ALL, 5)

        anime_annotations_vbox.Add(anime_annotations_toolbar, 0,
                                   wx.ALL | wx.ALIGN_CENTRE, 5)

        annotation_panel.SetSizer(anime_annotations_vbox)
        anime_annotations_vbox.Fit(self)
        """
        Graph Panel Setup
        """

        (graph_width, graph_height) = calc_graph_size(_DPI, _COLS,
                                                      _NUM_OF_SIDEBARS, _PHI)

        graph_fig = Figure((graph_width, graph_height))
        graph_fig.set_facecolor('white')

        self.graph_canvas = FigCanvas(self.graph_panel, -1, graph_fig)
        self.graph_axes = graph_fig.add_subplot(111)

        graph_vbox = wx.BoxSizer(wx.VERTICAL)
        graph_vbox.Add(self.graph_canvas)

        self.toolbar = BioPepaToolbar(self.graph_canvas)
        (toolW, toolH) = self.toolbar.GetSizeTuple()
        graph_vbox.Add(self.toolbar)

        self.graph_panel.SetSizer(graph_vbox)
        graph_vbox.Fit(self)

        self.graph_canvas.mpl_connect('button_press_event', self.onclick)
        self.graph_canvas.mpl_connect('motion_notify_event', self.move_mouse)
        """
        Legend Panel Setup
        """
        title = wx.StaticText(self.legend_panel,
                              wx.ID_ANY,
                              'Legend',
                              style=wx.ALIGN_LEFT)
        font = wx.Font(28, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        title.SetFont(font)

        vbox_leg = wx.BoxSizer(wx.VERTICAL)
        vbox_leg.Add(title, flag=wx.CENTER)

        self.legend_panel.SetSizer(vbox_leg)
        self.legend_panel.Layout()
        """
        Menubar Setup
        """
        self.SetMenuBar(self.build_menu_bar())
        """
        WorldState Stuff
        """
        WorldState.Instance().drop_down_species = self.drop_down_species
        WorldState.Instance().drop_down_files = self.drop_down_files
        WorldState.Instance(
        ).create_cell_segments_by_species = self.create_cell_segments_by_species
        WorldState.Instance(
        ).create_cell_segments_by_file = self.create_cell_segments_by_file
        WorldState.Instance().graph_canvas = self.graph_canvas
        WorldState.Instance().play_animation = self.real_play_animation
        WorldState.Instance(
        ).create_cell_segments_by_file = self.create_cell_segments_by_file
        WorldState.Instance(
        ).create_cell_segments_by_species = self.create_cell_segments_by_species
        WorldState.Instance().time_slider = self.slider_time
        WorldState.Instance(
        ).anime_annotations_list = self.anime_annotations_list
        WorldState.Instance().graph_axes = self.graph_axes
        WorldState.Instance().graph_width = graph_width
        WorldState.Instance().graph_height = graph_height
        WorldState.Instance().legend = Legend(self.legend_panel)
        WorldState.Instance().update_title = self.SetTitle
        WorldState.Instance().get_title = self.GetTitle
        """
        Whole UI Setup
        """

        splitter_far_right.SplitVertically(splitter_horiz_middle,
                                           splitter_far_right_middle)
        splitter_horiz_middle.SplitHorizontally(splitter_vert_middle,
                                                self.animation_panel)
        splitter_vert_middle.SplitVertically(self.graph_panel,
                                             self.legend_panel)
        splitter_far_right_middle.SplitHorizontally(attachment_panel,
                                                    annotation_panel)

        splitter_far_right.SetSashPosition((5 * WorldState.Instance().dispW /
                                            6) + 10)
        splitter_vert_middle.SetSashPosition((4 * WorldState.Instance().dispW /
                                              6) - 10)
        splitter_horiz_middle.SetSashPosition((graph_height * _DPI) + toolH +
                                              5)
        splitter_far_right_middle.SetSashPosition(WorldState.Instance().dispH /
                                                  2)

        self.SetTitle(_TITLE)

        self.enable_all(False)
        self.filem_new_session.Enable(True)
        self.filem_load_session.Enable(True)

        self.Maximize()
Ejemplo n.º 15
0
if __name__ == "__main__":
    args = args()
    map_fp_lst = args.input_imgs
    print("Running mapping")

    # Open image files
    layers = []
    for map_fp in map_fp_lst:
        im = Image.open(map_fp)
        print(map_fp, im.format, im.size, im.mode)
        layers.append(im)
    #im.show()

    # Get a legend for this map
    legend = Legend()
    if args.legend:
        legend = Legend(layers)
    else:
        print("Loading legend.json")
        legend = Legend.load('legend.json')

    if args.specials_dir:
        if not os.path.isdir(args.specials_dir):
            print("Cannot open directory of special composites: {}".format(args.specials_dir))
            print("Skipping special composites")
        else:
            print("Using specials directory '{}'".format(args.specials_dir))
    else:
        print("Skipping special composites")
Ejemplo n.º 16
0
class BaseGraph (PrintableCanvas):
    def __init__ (self, canvasType, **attr):
        if attr.has_key ('settings') and attr['settings']:
            self.applySettings (attr['settings'])
        else:
            self.formatSettings (blank ())
        if attr.has_key ('width'):
            self.settings.width = attr['width']
        if attr.has_key ('height'):
            self.settings.height = attr['height']
        
        view = ViewBox (0, 0, self.settings.width, self.settings.height)
        PrintableCanvas.__init__ (self, viewBox = view, **attr)

        self.addScript (self.jsUtils ())
        self.addScript (self.jsHighlight ())

        self.dataGroup = Grouping ()
        if canvasType:
            self.attachCanvas (canvasType, **attr)
        else:
            self.canvas = None
        self.draw (self.dataGroup)
        self.initialFormatting ()

    def attachCanvas (self, canvasType, **attr):
        self.canvas = canvasType (width = self.settings.width - self.settings.leftMargin - self.settings.rightMargin, 
                                  height = self.settings.height - self.settings.topMargin - self.settings.bottomMargin, 
                                  x = self.settings.leftMargin,
                                  y = self.settings.topMargin,
                                  id='canvas-root',
                                  **attr)
        self.dataGroup.draw (self.canvas)

    def jsUtils (self):
        return """
  function registerEvent (object, event, method, scope, capture) {
    if (!scope)
      scope = window;
    if (!capture)
      capture = false;
    var func = function (event) {
      if (!event)
        event = window.event;
      return method.call (scope, event);
    }

    if (object.addEventListener)
      object.addEventListener (event, func, capture);
    else if (object.attachEvent)
      object.attachEvent (event, method, func, capture);
    else
      return false;
    return true;
  }

  function ViewBox (x, y, width, height) {
    this.x = parseFloat (x);
    this.y = parseFloat (y);
    this.width = parseFloat (width);
    this.height = parseFloat (height);

    this.quadrant = function (v) {
      var midX = this.x + (this.width / 2.0);
      var midY = this.y + (this.height / 2.0);

      if (v.y <= midY) {
	if (v.x >= midX)
	  return 1;
	else
	  return 2;
      }
      else {
	if (v.x <= midX)
	  return 3;
	else
	  return 4;
      }
    }
  }

  function getView (viewer) {
    var view = viewer.getAttribute ('viewBox');
    view = view.split (' ');
    return new ViewBox (view[0], view[1], view[2], view[3]);
  }

  function vect (x, y) {
    this.x = x;
    this.y = y;
  }

  function pos (node) {
    var x, y;
    if (node.getAttribute ('x')) {
      x = node.getAttribute ('x');
      y = node.getAttribute ('y');
    }
    else if (node.getAttribute ('cx')) {
      x = node.getAttribute ('cx');
      y = node.getAttribute ('cy');
    }
    x = parseFloat (x);
    y = parseFloat (y);
    return new vect (x, y);
  }
"""

    def jsHighlight (self):
        return """
  function highlight (event) {
    this.setAttribute ('fill', this.getAttribute ('highlight-fill'));
  }

  function unHighlight (event) {
    this.setAttribute ('fill', this.getAttribute ('default-fill'));
  }

  function addHighlights (node) {
    if (node.getAttribute) {
      if (node.getAttribute ('has-highlight')) {
        node.setAttribute ('default-fill', node.getAttribute ('fill'));
        registerEvent (node, 'mouseover', highlight, node);
        registerEvent (node, 'mouseout', unHighlight, node);
      }
      for (var i = 0; i < node.childNodes.length; i ++) {
        addHighlights (node.childNodes[i]);
      }
    }
  }

  registerEvent (window, 'load', function () {
                                   var root = document.getElementById ('canvas-root');
                                   addHighlights (root); 
                                 });
"""

    def applySettings (self, filenameOrDict):
        if type (filenameOrDict) == str:
            file = open (filenameOrDict)
            buffer = file.read ()
            setList = []
            for child in buffer.split ('\n'):
                if len (child) == 0:
                    continue
                if child.startswith ('#'):
                    continue
                pair = match ('^([^=]+)=(.*)$', child)
                if pair is None:
                    print 'Warning, Bad formatting in line: ' + child
                    continue
                key = pair.group (1)
                value = pair.group (2)
                setList.append ((key.strip (), value.strip ()))
            settings = blank ()
            for key, value in setList:
                setattr (settings, key, value)
        elif type (filenameOrDict) == dict:
            settings = blank ()
            for key, value in filenameOrDict.iteritems ():
                setattr (settings, key, str (value))
        else:
            raise RuntimeError ('Bad type for settings')
        self.formatSettings (settings)

    def formatSettings (self, settings):
        addAttr (settings, 'width', float, 300.0)
        addAttr (settings, 'height', float, 200.0)
        addAttr (settings, 'fixedWidth', float, None)

        addAttr (settings, 'titleSize', float, 10.0)
        addAttr (settings, 'xLabelSize', float, 8.0)
        addAttr (settings, 'yLabelSize', float, 8.0)
        addAttr (settings, 'y2LabelSize', float, 8.0)

        addAttr (settings, 'leftMargin', float, 10.0)
        addAttr (settings, 'rightMargin', float, 10.0)
        addAttr (settings, 'topMargin', float, 10.0)
        addAttr (settings, 'bottomMargin', float, 10.0)

        addAttr (settings, 'titleSpace', float, 10.0)
        addAttr (settings, 'xLabelSpace', float, 10.0)
        addAttr (settings, 'yLabelSpace', float, 10.0)
        addAttr (settings, 'y2LabelSpace', float, 10.0)

        addAttr (settings, 'tooltipSize', float, 7.0)

        addAttr (settings, 'legendTextHeight', float, 7.0)

        self.settings = settings

    def initialFormatting  (self):
        # Format Label Group
        self.labels = Group (className = 'labels')

        # Format Title
        self.title = Text (text = '', 
                           id = 'title', 
                           textHeight= self.settings.titleSize, 
                           horizontalAnchor = 'center')

        # Format X Label
        self.xlabel = Text (text = '', 
                            id = 'xlabel', 
                            textHeight = self.settings.xLabelSize, 
                            verticalAnchor = 'top', 
                            horizontalAnchor = 'center')

        # Format Y Label
        self.ylabel = Group ()
        ylabelRotate = Rotate (-90)
        self.ylabel.appendTransform (ylabelRotate)
        self.ylabelText = Text (text = '',
                                id = 'ylabel', 
                                textHeight = self.settings.yLabelSize,  
                                horizontalAnchor = 'center')
        self.ylabel.draw (self.ylabelText)

        # Format Y2 Label
        self.y2label = Group ()
        y2labelRotate = Rotate (90, self.settings.width, 0)
        self.y2label.appendTransform (y2labelRotate)
        self.y2labelText = Text (text = '', 
                                 id = 'y2label', 
                                 textHeight = self.settings.y2LabelSize,  
                                 horizontalAnchor = 'center')
        self.y2label.draw (self.y2labelText)

        self.leg = None

    def positionLabels (self):
        if self.canvas:
            topY = self.settings.height - (self.canvas.height + self.canvas.y)
            midX = self.canvas.x + (self.canvas.width) / 2.0
            midY = topY + (self.canvas.height) / 2.0 
        else:
            midX = self.settings.width / 2.0
            midY = self.settings.height / 2.0

        # Title Position
        self.title.move (self.settings.width / 2.0, self.settings.topMargin)    
        #self.title.move (midX, self.settings.topMargin)

        # Y Label Position
        self.ylabelText.move (-midY, self.settings.leftMargin)
    
        # X Label Position
        if self.leg:
            modX = self.leg.height + 30
        else:
            modX = 0
        self.xlabel.move (midX, self.settings.height -modX - self.settings.bottomMargin) 
        #self.xlabel.move (midX, self.settings.height - self.canvas.y + self.xlabel.textHeight + 10)

        # Y2 Label Position
        self.y2labelText.move (self.settings.width + midY, self.settings.rightMargin)

    def setTitle (self, title):
        self.title.setText (title)
        self.labels.draw (self.title)
        if self.canvas:
            deltaY = self.title.height + self.settings.titleSpace
            self.canvas.changeSize (0, -deltaY)

    def setXLabel (self, xlabel):
        self.xlabel.setText (xlabel)
        self.labels.draw (self.xlabel)
        if self.canvas:
            deltaY = self.xlabel.height + self.settings.xLabelSpace
            self.canvas.move (0, deltaY)
            self.canvas.changeSize (0, -deltaY) 

    def setYLabel (self, ylabel):
        self.ylabelText.setText (ylabel)
        self.labels.draw (self.ylabel)
        if self.canvas:
            deltaX = self.ylabelText.height + self.settings.yLabelSpace
            self.canvas.move (deltaX, 0)
            self.canvas.changeSize (-deltaX, 0)

    def addSubtitle (self, text):
        t = Text (text = text,
                  x = self.settings.width - 5,
                  y = self.settings.height - 5,
                  horizontalAnchor = 'right',
                  verticalAnchor = 'bottom',
                  textHeight = 6,
                 )
        self.canvas.move (0, 12)
        self.canvas.changeSize (0, -12)
        self.draw (t)

    def addLegend (self, pairs):
        if len (pairs) == 0:
            return
        """self.leg = Legend (width = self.settings.width, textHeight = self.settings.legendTextHeight)
        keys = pairs.keys ()
        keys.sort ()
        for k in keys:
            self.leg.addKey (k, pairs[k])
        self.leg.y = self.settings.height - self.leg.height
        self.canvas.move (0, self.leg.height + 20)
        self.canvas.changeSize (0, -(self.leg.height + 20))
        self.draw (self.leg)"""
        self.leg = Legend (width = self.settings.width / 4.0, textHeight = self.settings.legendTextHeight)
        keys = pairs.keys ()
        keys.sort ()
        for k in keys:
            self.leg.addKey (k, pairs[k])
        self.canvas.changeSize (-self.leg.width, 0)
        self.leg.y = self.settings.height - (self.canvas.height + self.canvas.y)
        self.leg.x = self.canvas.x + self.canvas.width
        #self.leg.y = self.settings.height - self.leg.height
        #self.canvas.move (0, self.leg.height + 20)
        self.draw (self.leg)


    def setY2Label (self, ylabel):
        self.y2labelText.setText (ylabel)
        self.labels.draw (self.y2label)
        if self.canvas:
            deltaX = self.y2labelText.height + self.settings.y2LabelSpace
            self.canvas.changeSize (-deltaX, 0)

    def setSVG (self):
        self.finalize ()
        attr = PrintableCanvas.setSVG (self)
        if self.settings.fixedWidth:
            height = self.settings.fixedWidth * (self.settings.height / self.settings.width)
            attr.update ([('width', self.settings.fixedWidth),
                          ('height', height)]) 
        return attr

    def finalize (self):
        self.dataGroup.transform.set (-1, 1, 1)
        self.dataGroup.transform.set (self.viewBox.y + self.viewBox.height, 1, 2)
        self.positionLabels ()
        if len (self.labels) > 0:
            self.drawAt (self.labels, 1)
Ejemplo n.º 17
0
	def visualize(self):
		import matplotlib.patches as mpatches

		self.fig, self.ax = plt.subplots(3, 1, sharex=True)
		self.ax[0].set_title('Click on legend rectangle to toggle data on/off', fontdict={'fontsize' : 8 })
		self.fig.set_size_inches(12, 7, forward=True)
		plt.subplots_adjust(left=0.05, bottom=0.15, right=0.98, hspace=0.15)
		# bpdiff_trans = [] # major transition

		self.ax = self.ax[::-1]

		# major가 같은 것 들만
		print('Run matplotlib...')
		for i in range(len(self.bpdiff)):
			sc = [ {'major' : [], 'minor': [] }, {'major' : [], 'minor': [] }, 
			       {'major' : [], 'minor': [] }, {'major' : [], 'minor': [] } ]

			self.draw_vspans(self.ax[i], self.B.range_dumas)
			
			for a in range(4):

				cond1 = self.bpdiff[i]['Mj_seq_x'] == a

				# major a -> minor b
				for b in range(4):
					if a == b:
						# sc[a]['major'].append(None)
						# sc[a]['minor'].append(None)
						continue

					# 1. minor가 같은 것들 처리 : 같은 색상
					cond2 = self.bpdiff[i]['Mn_seq_y'] == b
					# x는 
					cond3 = logical_or(self.bpdiff[i]['minor_x'] == 0, self.bpdiff[i]['Mn_seq_x'] == b)				
					cond3 = logical_and(cond2, cond3)

					d = self.B.get_bpdiff_cond(index=i, cond=logical_and(cond1, cond3)) #bpdiff[i][ logical_and(cond1, cond3).values ]
					if len(d) > 0:
						y_ = [ linspace(d_.maf_x, d_.maf_y, self.seq_size) for d_ in d[['maf_x', 'maf_y']].itertuples() ]					
						x_ = array(y_)
						for j in range(len(d)):
							x_[j].fill( d[self.duma_position].values[j] )
						c = [ self.xlin for _ in range(len(x_))]
						sc[a]['minor'].append(self.ax[i].scatter(x_, y_, c=c, cmap=mcols.cmap(self.mcolor[b]), s=self.markersize, linewidth=0.0))

						# draw major scatter
						y_ = self.get_uppery(y_)
						x_ = [ ii[0] for ii in x_]
						sc[a]['major'].append(self.ax[i].scatter(x_, y_, color=self.basecolors[a], label=self.basepair[a], s=self.markersize-1))
					
					# # 2. minor가 바뀌는 것들 처리 : colors diverging
					# 각 basetype -> b type, target이 b, 즉, b로 변한것
					cond2 = logical_and(self.bpdiff[i]['Mn_seq_x'] != b, self.bpdiff[i]['minor_x'] > 0)				
					cond3 = logical_and(cond2, self.bpdiff[i]['Mn_seq_y'] == b)
					d = self.bpdiff[i][ logical_and(cond1, cond3).values ]
					if len(d) > 0:
						self.draw_minor_transition(self.ax[i], sc, d, a, b)
				# end for b
			#end for a
			self.sct.append(sc)

			self.ax[i].set_ylim([0, 50])
			self.ax[i].set_ylabel('Variation of MAF(%)')
			self.ax[i].set_title(self.ylabel[i], loc='left', fontdict={'fontsize':13, 'verticalalignment':'top', 'color':'black', 'backgroundcolor':'#FEFEFE'})

		# ZoomSlider of Dumas position
		zaxes = plt.axes([0.08, 0.07, 0.90, 0.03], facecolor='lightgoldenrodyellow')
		self.zslider = ZoomSlider(zaxes, 'Dumas Position', valmin=self.B.minpos, valmax=self.B.maxpos, valleft=self.B.minpos, valright=self.B.maxpos, color='lightblue', valstep=1.0)
		self.zslider.on_changed(self.update_xlim)


		from legend import Legend
		spatches = [ mpatches.Patch(color=self.basecolors[idx], label=self.basepair[idx]) for idx in range(4) ]
		leg_basepair = Legend(self.fig, { 'spatches' : spatches, 'label' : self.basepair, 'bbox':(0.66, .91, 0.33, .102), 'loc' : 3,
					'ncol' : 4, 'mode' : 'expand', 'borderaxespad' : 0.})

		dumalabels = [ key for key in self.dumas.keys()]
		spatches = [ mpatches.Patch(color='grey', label=dumalabels[idx]) for idx in range(3) ]
		leg_dumas = Legend(self.fig, { 'spatches' : spatches, 'label' : dumalabels, 'bbox':(0.05, .91, 0.33, .102), 'loc' : 3,
					'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

		spatches = [ mpatches.Patch(color=['black', 'magenta'][idx], label=['base', 'variation'][idx]) for idx in range(2) ]
		self.leg_filter = Legend(self.fig, { 'spatches' : spatches, 'label' : ['base_0.0', 'variation_5.0'], 'bbox':(0.40, .91, 0.24, .102), 'loc' : 3,
					'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

		for x in self.ax:
			self.annot.append(x.annotate("", xy=(0,0), xytext=(20,-30),textcoords="offset points",
	                    bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")))
			# annotate over other axes
			x.figure.texts.append(x.texts.pop())

			# 
			# x.callbacks.connect('xlim_changed', xlim_changed_event)

		for c in self.B.range_dumas.keys():
			self.annot_gere[c] = []
			ay_ = 0.85 if c == self.duma_Repeat else 0.7
			if c == self.duma_ORF: ay_ = 1.
			for d in self.dumas[c]:
				self.annot_gere[c].append(self.ax[-1].annotate(d, xy=(self.B.range_dumas[c][d]['min'], 50*ay_), xytext=(-20,10),
					textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="fancy")))

		for an_ in self.annot:
			an_.set_visible(False)
			an_.set_zorder(10)

		for c in self.B.range_dumas.keys():
			for an_ in self.annot_gere[c]:
				an_.set_visible(False)

		# legend pick event
		self.fig.canvas.mpl_connect('pick_event', self.onpick)
		leg_dumas.pick()

		self.fig.canvas.mpl_connect("button_press_event", self.click_)
		
		# ax[-1].text(105500, 49, 'IRS', fontdict={'fontsize':5})
		# buttonaxes = plt.axes([0.89, .95, 0.1, 0.025])
		# bnext = Button(buttonaxes, 'Export')
		# bnext.on_clicked(ExportToParallelCoordGraph)

		plt.show()
Ejemplo n.º 18
0
class visualization:
	def __init__(self, book):
		# from pandas import ExcelFile, DataFrame, merge
		from VizBook import vizbook

		self.duma_position = book.col_DumaPosition
		self.duma_Genome = book.col_GenomeStructure
		self.duma_Repeat = book.col_RepeatRegion
		self.duma_ORF = book.col_ORF

		self.dumas_col = [ self.duma_position, self.duma_Genome, self.duma_Repeat, self.duma_ORF ]
		self.dumas = { self.duma_Genome : [], self.duma_Repeat: [], self.duma_ORF : [] }
		self.spans = dict() #{ duma_Genome : dict(), duma_Repeat : dict(), duma_ORF : dict()}

		self.seq_size, self.markersize = 100, 10
		self.xlin = linspace(0.0, 1.0, self.seq_size)
		self.mcolor = [ 'Blues', 'Orgs', 'Grns', 'Reds' ]
		self.dcolor = [ [None, 'BuOg', 'BuGn', 'BuRd' ], 
					 ['OgBu', None, 'OgGn', 'OgRd'], 
				 	 ['GnBu', 'GnOg', None, 'GnRd'], 
				 	 ['RdBu', 'RdOg', 'RdGn', None] ]
		self.basecolors = ['blue', 'orange', 'lightgreen', 'red']
		self.basepair = ['A', 'G', 'C', 'T']
		self.annot, self.sct, self.leg = [], [], None
		self.annot_gere = dict()
		self.B = None
		self.bpdiff = None
		self.major_visiable = [ True, True, True, True]
		self.base_range, self.bidx = [ 0., 5., 10., 15., 20., 25., 30., 35., 40., 45.], 0
		self.variation_range, self.vidx = [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], 0

		self.B = vizbook(book)
		self.B.preprocessing()
		self.dumas = self.B.dumas_info
		self.nsheet = self.B.nsheet
		self.bpdiff = self.B.bpdiff
		self.ylabel = self.B.datalabel

		# 임의지정을 통한 교환
		self.ylabel[1], self.ylabel[2] = self.ylabel[2], self.ylabel[1]
		self.bpdiff[1], self.bpdiff[2] = self.bpdiff[2], self.bpdiff[1]
		# bpdiff_trans[1], bpdiff_trans[2] = bpdiff_trans[2], bpdiff_trans[1]
	

	def visualize(self):
		import matplotlib.patches as mpatches

		self.fig, self.ax = plt.subplots(3, 1, sharex=True)
		self.ax[0].set_title('Click on legend rectangle to toggle data on/off', fontdict={'fontsize' : 8 })
		self.fig.set_size_inches(12, 7, forward=True)
		plt.subplots_adjust(left=0.05, bottom=0.15, right=0.98, hspace=0.15)
		# bpdiff_trans = [] # major transition

		self.ax = self.ax[::-1]

		# major가 같은 것 들만
		print('Run matplotlib...')
		for i in range(len(self.bpdiff)):
			sc = [ {'major' : [], 'minor': [] }, {'major' : [], 'minor': [] }, 
			       {'major' : [], 'minor': [] }, {'major' : [], 'minor': [] } ]

			self.draw_vspans(self.ax[i], self.B.range_dumas)
			
			for a in range(4):

				cond1 = self.bpdiff[i]['Mj_seq_x'] == a

				# major a -> minor b
				for b in range(4):
					if a == b:
						# sc[a]['major'].append(None)
						# sc[a]['minor'].append(None)
						continue

					# 1. minor가 같은 것들 처리 : 같은 색상
					cond2 = self.bpdiff[i]['Mn_seq_y'] == b
					# x는 
					cond3 = logical_or(self.bpdiff[i]['minor_x'] == 0, self.bpdiff[i]['Mn_seq_x'] == b)				
					cond3 = logical_and(cond2, cond3)

					d = self.B.get_bpdiff_cond(index=i, cond=logical_and(cond1, cond3)) #bpdiff[i][ logical_and(cond1, cond3).values ]
					if len(d) > 0:
						y_ = [ linspace(d_.maf_x, d_.maf_y, self.seq_size) for d_ in d[['maf_x', 'maf_y']].itertuples() ]					
						x_ = array(y_)
						for j in range(len(d)):
							x_[j].fill( d[self.duma_position].values[j] )
						c = [ self.xlin for _ in range(len(x_))]
						sc[a]['minor'].append(self.ax[i].scatter(x_, y_, c=c, cmap=mcols.cmap(self.mcolor[b]), s=self.markersize, linewidth=0.0))

						# draw major scatter
						y_ = self.get_uppery(y_)
						x_ = [ ii[0] for ii in x_]
						sc[a]['major'].append(self.ax[i].scatter(x_, y_, color=self.basecolors[a], label=self.basepair[a], s=self.markersize-1))
					
					# # 2. minor가 바뀌는 것들 처리 : colors diverging
					# 각 basetype -> b type, target이 b, 즉, b로 변한것
					cond2 = logical_and(self.bpdiff[i]['Mn_seq_x'] != b, self.bpdiff[i]['minor_x'] > 0)				
					cond3 = logical_and(cond2, self.bpdiff[i]['Mn_seq_y'] == b)
					d = self.bpdiff[i][ logical_and(cond1, cond3).values ]
					if len(d) > 0:
						self.draw_minor_transition(self.ax[i], sc, d, a, b)
				# end for b
			#end for a
			self.sct.append(sc)

			self.ax[i].set_ylim([0, 50])
			self.ax[i].set_ylabel('Variation of MAF(%)')
			self.ax[i].set_title(self.ylabel[i], loc='left', fontdict={'fontsize':13, 'verticalalignment':'top', 'color':'black', 'backgroundcolor':'#FEFEFE'})

		# ZoomSlider of Dumas position
		zaxes = plt.axes([0.08, 0.07, 0.90, 0.03], facecolor='lightgoldenrodyellow')
		self.zslider = ZoomSlider(zaxes, 'Dumas Position', valmin=self.B.minpos, valmax=self.B.maxpos, valleft=self.B.minpos, valright=self.B.maxpos, color='lightblue', valstep=1.0)
		self.zslider.on_changed(self.update_xlim)


		from legend import Legend
		spatches = [ mpatches.Patch(color=self.basecolors[idx], label=self.basepair[idx]) for idx in range(4) ]
		leg_basepair = Legend(self.fig, { 'spatches' : spatches, 'label' : self.basepair, 'bbox':(0.66, .91, 0.33, .102), 'loc' : 3,
					'ncol' : 4, 'mode' : 'expand', 'borderaxespad' : 0.})

		dumalabels = [ key for key in self.dumas.keys()]
		spatches = [ mpatches.Patch(color='grey', label=dumalabels[idx]) for idx in range(3) ]
		leg_dumas = Legend(self.fig, { 'spatches' : spatches, 'label' : dumalabels, 'bbox':(0.05, .91, 0.33, .102), 'loc' : 3,
					'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

		spatches = [ mpatches.Patch(color=['black', 'magenta'][idx], label=['base', 'variation'][idx]) for idx in range(2) ]
		self.leg_filter = Legend(self.fig, { 'spatches' : spatches, 'label' : ['base_0.0', 'variation_5.0'], 'bbox':(0.40, .91, 0.24, .102), 'loc' : 3,
					'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

		for x in self.ax:
			self.annot.append(x.annotate("", xy=(0,0), xytext=(20,-30),textcoords="offset points",
	                    bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")))
			# annotate over other axes
			x.figure.texts.append(x.texts.pop())

			# 
			# x.callbacks.connect('xlim_changed', xlim_changed_event)

		for c in self.B.range_dumas.keys():
			self.annot_gere[c] = []
			ay_ = 0.85 if c == self.duma_Repeat else 0.7
			if c == self.duma_ORF: ay_ = 1.
			for d in self.dumas[c]:
				self.annot_gere[c].append(self.ax[-1].annotate(d, xy=(self.B.range_dumas[c][d]['min'], 50*ay_), xytext=(-20,10),
					textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="fancy")))

		for an_ in self.annot:
			an_.set_visible(False)
			an_.set_zorder(10)

		for c in self.B.range_dumas.keys():
			for an_ in self.annot_gere[c]:
				an_.set_visible(False)

		# legend pick event
		self.fig.canvas.mpl_connect('pick_event', self.onpick)
		leg_dumas.pick()

		self.fig.canvas.mpl_connect("button_press_event", self.click_)
		
		# ax[-1].text(105500, 49, 'IRS', fontdict={'fontsize':5})
		# buttonaxes = plt.axes([0.89, .95, 0.1, 0.025])
		# bnext = Button(buttonaxes, 'Export')
		# bnext.on_clicked(ExportToParallelCoordGraph)

		plt.show()

	def draw_vspans(self, ax_, range_dumas):
		from numpy import random
		# global range_dumas
		# random.seed(1234)
		ymax = 50
		for c in range_dumas.keys():
			if c == self.duma_Genome:
				ymax = 0.7
			elif c == self.duma_Repeat:
				ymax = 0.85
			else:		
				ymax = 1
			for d in range_dumas[c].keys():
				# r, g, b = random.uniform(0, 1, 3)
				self.spans[c+str(d)] = self.spans.get(c+str(d), [])

				self.spans[c+str(d)].append(ax_.axvspan(range_dumas[c][d]['min'], range_dumas[c][d]['max'], 
					0, ymax, color=scols.get_color(), alpha=0.1))

		scols.cur = 0

	def update_xlim(self, val):
		if self.zslider.valleft > self.zslider.valright:
			return
		for x in self.ax:
			x.axes.set_xlim([self.zslider.valleft, self.zslider.valright])
		self.fig.canvas.draw_idle()	

	def onpick(self, event):
		patch = event.artist
		vis = True if patch.get_alpha()==0.3 else False
		label = patch.get_label()
		color = 'grey'

		# basepair 클릭시 일관성을 위해... (필터링과)
		# color랑 몇가지 변수만 잘 설정해서 filtering로 넘어가기
		if label == 'A' or label == 'G' or label == 'C' or label == 'T':
			nmajor = self.basepair.index( label )
			color = self.basecolors[nmajor]
			self.major_visiable[ nmajor ] = vis
			for sc in self.sct:
				for mj, mn in zip(sc[nmajor]['major'], sc[nmajor]['minor']):
					mj.set_visible( vis )
					mn.set_visible( vis )
		elif label == self.duma_ORF or label ==self.duma_Repeat or label ==self.duma_Genome:
			for d in self.B.range_dumas[label].keys():
				for sc in self.spans[label+str(d)]:
					sc.set_visible(vis)
			for an_ in self.annot_gere[label]:
				an_.set_visible(vis)
		else:
			if label == 'base' : self.bidx += 1
			else: self.vidx += 1
			if self.bidx == len(self.base_range): self.bidx = 0
			if self.vidx == len(self.variation_range): self.vidx = 0

			range_, pid, color = (str(self.base_range[self.bidx]), 0, 'black') if label == 'base' else (str(self.variation_range[self.vidx]), 1, 'magenta')
			
			self.leg_filter.get_legend().get_texts()[pid].set_text(label +'_'+ range_)

			for i in range(len(self.bpdiff)):
				for a in range(4):
					if not self.major_visiable[a]: continue
					cond1 = self.bpdiff[i]['Mj_seq_x'] == a			

					if len( self.bpdiff[i][ cond1.values ] ) > 0:
						cond2 = logical_and(self.bpdiff[i]['maf_x'] >= self.base_range[self.bidx], abs(self.bpdiff[i]['maf_y'] - self.bpdiff[i]['maf_x']) >=  self.variation_range[self.vidx])					
						vis_d = logical_and(cond1, cond2)

						from numpy import isin
						for scmj, scmn in zip(self.sct[i][a]['major'], self.sct[i][a]['minor']):
							mj_vis_arr = isin(scmj.get_offsets()[:,0], self.bpdiff[i][vis_d.values][self.duma_position].tolist() )
							mn_vis_arr = isin(scmn.get_offsets()[:,0], self.bpdiff[i][vis_d.values][self.duma_position].tolist() )

							mjcolors_ = scmj.get_facecolors()
							mncolors_ = scmn.get_facecolors()
							if len(mjcolors_) == len(mj_vis_arr):
								mjcolors_[:,-1][ mj_vis_arr ] = 1
								mjcolors_[:,-1][ logical_not(mj_vis_arr) ] = 0
							else:
								mjc = list(mjcolors_[0][:-1])
								# !!
								mjcolors_ = [ mjc + [1.] if mi else mjc+[0.]  for mi in mj_vis_arr ]

							if len(mncolors_) == len(mn_vis_arr):
								mncolors_[:,-1][ mn_vis_arr ] = 1
								mncolors_[:,-1][ logical_not(mn_vis_arr) ] = 0
							
							scmj.set_facecolors(mjcolors_)
							scmj.set_edgecolors(mjcolors_)
							scmn.set_facecolors(mncolors_)
							scmn.set_edgecolors(mncolors_)
		if vis:
			patch.set_alpha(1.0)
		else:
			patch.set_facecolor(color)
			patch.set_alpha(0.3)
		self.fig.canvas.draw_idle()

	def click_(self, event):
		if event.xdata is None:
			return
		pos = int(event.xdata)
		# print(pos)
		epos = 20.
		minpos = pos - epos
		maxpos = pos + epos
		for i in range(len(self.bpdiff)):
			self.annot[i].set_visible(False)
			# bpdiff 0에서 찾기 ->  일관성..
			# binary search pos
			ind_ = self.bpdiff[i][[self.duma_position]].values.ravel().searchsorted(pos, side='left')
			if ind_ >= len(self.bpdiff[i][[self.duma_position]].values):
				ind_ = ind_ - 1
				
			spos = self.bpdiff[i][[self.duma_position]].values[ ind_ ]
			ind_1 = ind_ - 1
			spos_1 = self.bpdiff[i][[self.duma_position]].values[ ind_1 ]
			# print(ind_, spos, spos_1)
			ind_, spos = (ind_, spos) if abs(pos-spos) < abs(pos-spos_1) else (ind_1,spos_1)
			# print(ind_, spos)

			# print(bpdiff[i].values[ind_])
			ge = self.bpdiff[i][[self.duma_Genome]].values[ind_][0]
			re = self.bpdiff[i][[self.duma_Repeat]].values[ind_][0]
			orf_ = self.bpdiff[i][[self.duma_ORF]].values[ind_][0]
			# print(ge, re, orf_)

			bp_ = self.bpdiff[i].iloc[ind_]
			if spos < minpos or maxpos < spos:
				pass
				# tagging

			else: # minpos <= spos and spos <= maxpos:
				for sc_ in self.sct[i]:
					for s_ in sc_['major']:
						if s_ == None:
							continue
						# xy data -> xy (position in scatter)로 변환하는 방법
						if s_.get_offsets().__contains__(spos):
							ind = where(s_.get_offsets() == spos)
							pos_ = s_.get_offsets()[ind[0]]
							pos_[0][1] = bp_['maf_y']
							# print(pos_)
							self.annot[i].xy = pos_[0]
							text = "mj/mn : {}/{}\nmaf :{}->{}\nGnSt : {}\nRpRg : {}\nORF : {}".format(self.basepair[int(bp_[['Mj_seq_y']].values[0])], 
								self.basepair[int(bp_[['Mn_seq_y']].values[0])].lower(), round(float(bp_['maf_x']), 2), round(float(bp_['maf_y']), 2), 
								ge,re,orf_)
							self.annot[i].set_text(text)
							self.annot[i].get_bbox_patch().set_facecolor(self.basecolors[self.basepair.index(s_.get_label())])
							self.annot[i].get_bbox_patch().set_alpha(0.5)
							self.annot[i].set_visible(True)
		self.fig.canvas.draw_idle()

	def get_uppery(self, y):
		y_ = [ i[-1] for i in y ]
		return y_

	def draw_minor_transition(self, ax, sc, d, a, b):
		# transition from i to b
		for i in range(4):
			if i == b:
				continue
			d_ = d[ d['Mn_seq_x'] == i ]
			if len(d_) == 0: continue

			y_ = [ linspace(p_.maf_x, p_.maf_y, self.seq_size) for p_ in d_[['maf_x', 'maf_y']].itertuples() ]
			x_ = array(y_)
			for j in range(len(d_)):
				x_[j].fill( d_[self.duma_position].values[j] )
			c = [ self.xlin for _ in range(len(x_))]
			
			sc[a]['minor'].append(ax.scatter(x_, y_, c=c, cmap=mcols.cmap(self.dcolor[i][b]), s=self.markersize))

			# draw major scatter
			y_ = self.get_uppery(y_)
			x_ = [ i[0] for i in x_]
			sc[a]['major'].append(ax.scatter(x_, y_, color=self.basecolors[a], label=self.basepair[a], s=self.markersize-1))
Ejemplo n.º 19
0
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle("Running jobs")
        self.setMinimumWidth(250)
        #self.setMinimumHeight(250)

        self.ctrl = SimulationsDialogController(self)

        self.simulationProgress = QtGui.QProgressBar()
        self.simulationProgress.setValue(0)
        self.connect(self.simulationProgress, QtCore.SIGNAL('setValue(int)'),
                     self.updateProgress)

        self.cogwheel = Cogwheel(size=20)

        memberLayout = QtGui.QVBoxLayout()

        progressLayout = QtGui.QHBoxLayout()
        progressLayout.addWidget(self.simulationProgress)
        progressLayout.addWidget(self.cogwheel)
        memberLayout.addLayout(progressLayout)

        simulationLayout = QtGui.QHBoxLayout()
        self.simulationList = SimulationList()
        self.simulationList.contextMenuEvent = self._contextMenu
        self.connect(self.simulationList,
                     QtCore.SIGNAL('itemSelectionChanged()'),
                     self.ctrl.selectSimulation)
        simulationLayout.addWidget(self.simulationList)
        self.simulationPanel = SimulationPanel()
        simulationLayout.addWidget(self.simulationPanel)
        memberLayout.addLayout(simulationLayout)

        legendLayout = QtGui.QHBoxLayout()
        legendLayout.addLayout(
            Legend("Not active", SimulationItemDelegate.notactive))
        legendLayout.addLayout(
            Legend("Waiting", SimulationItemDelegate.waiting))
        legendLayout.addLayout(
            Legend("Pending", SimulationItemDelegate.pending))
        legendLayout.addLayout(
            Legend("Running", SimulationItemDelegate.running))
        legendLayout.addLayout(
            Legend("User killed", SimulationItemDelegate.userkilled))
        legendLayout.addLayout(Legend("Failed", SimulationItemDelegate.failed))
        legendLayout.addLayout(
            Legend("Finished", SimulationItemDelegate.finished))
        memberLayout.addLayout(legendLayout)

        self.doneButton = QtGui.QPushButton("Done", self)
        self.connect(self.doneButton, QtCore.SIGNAL('clicked()'), self.accept)

        buttonLayout = QtGui.QHBoxLayout()

        self.estimateLabel = QtGui.QLabel()
        buttonLayout.addWidget(self.estimateLabel)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.doneButton)

        memberLayout.addSpacing(10)
        memberLayout.addLayout(buttonLayout)

        self.setLayout(memberLayout)
Ejemplo n.º 20
0
class Drawable():
    """
	The :class:`~Drawable` class wraps a matplotlib figure and axis to provide additional functionality.
	If no axis is given, the default plot axis (:code:`plt.gca()`) is used.
	The :class:`~Drawable` class can be used as a normal :class:`matplotlib.axis.Axis` object with additional functionality.
	The axis functionality can be called on the :class:`~Drawable` class.
	The :class:`~Drawable` instance re-routes method and attribute calls to the :class:`matplotlib.axis.Axis` instance.

	To create a :class:`~Drawable` instance from a normal plot:

	.. code-block:: python

	  viz = drawable.Drawable(plt.figure(figsize=(10, 5)))

	To create a :class:`~Drawable` instance from an axis, or a subplot:

	.. code-block:: python

	  figure, axis = plt.subplots(2, 1, figsize=(10, 10))
	  viz = drawable.Drawable(figure, axis[0])

	:ivar figure: The figure that the :class:`~Drawable` class wraps.
	:vartype figure: :class:`matplotlib.figure.Figure`
	:ivar axis: The axis where the drawable will draw.
	:vartype axis: :class:`matplotlib.axis.Axis`
	:var caption: The caption, displayed under the title.
	:vartype caption: :class:`~text.annotation.Annotation`

	:ivar timeseries: The time series object that is being used.
	:vartype timeseries: :class:`~timeseries.timeseries.TimeSeries`
	:ivar legend: The figure's legend.
	:vartype legend: :class:`~legend.Legend`
	:ivar annotations: The annotations in the visualization.
	:vartype annotations: list of :class:`~text.annotation.Annotation`
	"""
    def __init__(self, figure, axis=None):
        """
		Create the drawable with the figure.

		:param figure: The figure that the :class:`~Drawable` class wraps.
					   This is mainly used to get the figure renderer.
		:type figure: :class:`matplotlib.figure.Figure`
		:param axis: The axis (or subplot) where to plot visualizations.
					 If `None` is not given, the plot's main subplot is used instead.
		:type axis: `None` or :class:`matplotlib.axis.Axis`
		"""

        self.figure = figure
        self.axis = plt.gca() if axis is None else axis
        self.caption = Annotation(self)

        self.annotations = []
        self.legend = Legend(self)
        self.timeseries = None

    def set_caption(self,
                    caption,
                    alpha=0.8,
                    lineheight=1.25,
                    *args,
                    **kwargs):
        """
		Add a caption to the subplot.
		The caption is added just beneath the title.
		The method re-draws the title to make space for the caption.

		The caption is a :class:`~text.text.Annotation` object.
		Any arguments that the constructor accepts can be provided to this method.

		:param caption: The caption to add to the axis.
		:type caption: str
		:param alpha: The opacity of the caption between 0 and 1.
		:type alpha: float
		:param lineheight: The space between lines.
		:type lineheight: float

		:return: The drawn caption.
		:rtype: :class:`~text.annotation.Annotation`
		"""

        self.caption = Annotation(self)
        self.caption.draw(caption, (0, 1),
                          1,
                          va='bottom',
                          alpha=alpha,
                          lineheight=lineheight,
                          *args,
                          **kwargs,
                          transform=self.axis.transAxes)
        self.redraw()
        return self.caption

    def redraw(self):
        """
		Re-create the title with the necessary padding to fit the caption and the legend.
		"""
        """
		Move the caption up to make space for the legend.
		"""
        legend_bb = self.legend.get_virtual_bb(transform=self.axis.transAxes)
        self.caption.set_position((0, 1 + 0.01 + legend_bb.height),
                                  ha='left',
                                  va='bottom',
                                  transform=self.axis.transAxes)
        """
		Get the height of the caption and the height of the legend.
		The title should allow enough padding to make space for both.
		"""
        title = self.axis.get_title(loc='left')
        caption_bb = self.axis.transData.transform(
            self.caption.get_virtual_bb())
        height = abs(caption_bb[0][1] - caption_bb[1][1])
        legend_bb = self.axis.transData.transform(self.legend.get_virtual_bb())
        height += abs(legend_bb[0][1] - legend_bb[1][1])
        pad_px = self.axis.transAxes.transform(
            (0, 0.01))[1] - self.axis.transAxes.transform((0, 0))[1]
        self.axis.set_title(title, loc='left', pad=(5 + height + pad_px * 2))

    def __getattr__(self, name):
        """
		Get an attribute indicated by `name` from the class.
		If it gets to this point, then the attribute does not exist.
		Instead, it is retrieved from the :class:`~Drawable` axis.

		:param name: The name of the attribute.
		:type name: str

		:return: The function applied on the axis.
		:rtype: function
		"""
        def method(*args, **kwargs):
            """
			Try to get the attribute from the axis.
			If arguments were given, then the attribute is treated as a method call.
			Otherwise, it is treated as a normal attribute call.
			"""

            if callable(getattr(self.axis, name)):
                return getattr(self.axis, name)(*args, **kwargs)
            else:
                return getattr(self.axis, name)

        return method

    """
	Visualizations
	"""

    def draw_text_annotation(self, *args, **kwargs):
        """
		Draw a text annotation visualization on this :class:`~Drawable`.
		The arguments and keyword arguments are those supported by :meth:`~text.annotation.TextAnnotation.draw` method.

		:return: The drawn text annotation's lines.
				 Each line is made up of tuples of lists.
				 The first list in each tuple is the list of legend labels.
				 The second list in each tuple is the list of actual tokens.
		:rtype: list of tuple
		"""

        text_annotation = TextAnnotation(self)
        return text_annotation.draw(*args, **kwargs)

    def draw_time_series(self, *args, **kwargs):
        """
		Draw a time series visualization on this :class:`~Drawable`.
		The arguments and keyword arguments are those supported by :meth:`~text.annotation.TextAnnotation.draw` method.

		:return: A tuple made up of the drawn plot and label.
		:rtype: tuple
		"""

        self.timeseries = self.timeseries if self.timeseries is not None else TimeSeries(
            self)
        return self.timeseries.draw(*args, **kwargs)

    def annotate(self, text, x, y, marker=None, pad=0.01, *args, **kwargs):
        """
		Add an annotation to the plot.
		Any additional arguments and keyword arguments are passed on to the annotation's :meth:`~text.text.Annotation.draw` function.
		For example, the `va` can be provided to specify the vertical alignment.
		The `align` parameter can be used to specify the text's alignment.

		:param text: The text of the annotation to draw.
		:type text: str
		:param x: A tuple containing the start and end x-coordinates of the annotation.
		:type x: tuple
		:param y: The y-coordinate of the annotation.
		:type y: float
		:param marker: The marker style.
					   If it is not given, no marker is drawn.
		:type marker: None or dict
		:param pad: The amount of padding applied to the annotation.
		:type pad: float
		"""

        annotation = Annotation(self)
        """
		Draw the marker if it is given.
		The color is obtained from the kwargs if a marker color is not given.
		The point of the marker is based on the alignment of the annotation.
		"""
        if marker is not None:
            marker['color'] = marker.get('color', kwargs.get('color'))
            if kwargs.get('align', 'left') == 'left':
                self.axis.plot(x[0], y, *args, **marker)
            elif kwargs.get('align') == 'right':
                self.axis.plot(x[1], y, *args, **marker)
            elif kwargs.get('align') == 'center':
                self.axis.plot((x[0] + x[1]) / 2., y, *args, **marker)

        tokens = annotation.draw(text, x, y, pad=pad, *args, **kwargs)
        self.annotations.append(annotation)

        return tokens
Ejemplo n.º 21
0
class ShapeViewer(QMainWindow, Ui_MainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.activeCanvas = None
        self.activeTool = None
        # Required by Qt4 to initialize the UI
        self.setupUi(self)

        # Set the title for the app
        self.setWindowTitle("APCartOS v0.2")

        # Create the legend widget
        self.createLegendWidget()

        self.actionAdd_new_window.triggered.connect(self.newWindow)
        self.mapArea.subWindowActivated.connect(self.subActive)
        self.actionTile.triggered.connect(self.tileWindows)
        self.actionStart_editing.triggered.connect(self.toogleEditing)
        self.actionStart_editing.setEnabled(False)
        # self.actionAddWms.triggered.connect(self.addWms)

        # create the actions
        self.actionAddLayer = QAction(QIcon(":/icons/grass_add_map.png"), QString("Add Layer"), self)
        self.actionZoomIn = QAction(QIcon(":/icons/zoom-in.png"), QString("Zoom in"), self)
        self.actionZoomOut = QAction(QIcon(":/icons/zoom-out.png"), QString("Zoom out"), self)
        self.actionPan = QAction(QIcon(":/icons/pan.png"), QString("Pan"), self)

        self.actionAddLayer.setCheckable(True)
        self.actionZoomIn.setCheckable(True)
        self.actionZoomOut.setCheckable(True)
        self.actionPan.setCheckable(True)

        # This is the new syntax to connect to events (signals) of objects
        self.actionAddLayer.triggered.connect(self.addLayer)
        self.actionZoomIn.triggered.connect(self.zoomIn)
        self.actionZoomOut.triggered.connect(self.zoomOut)
        self.actionPan.triggered.connect(self.pan)
        QObject.connect(self.legend, SIGNAL("activeLayerChanged"), self.enableEditingButton)

        self.toolBar.addAction(self.actionAddLayer)
        self.toolBar.addAction(self.actionZoomIn)
        self.toolBar.addAction(self.actionZoomOut)
        self.toolBar.addAction(self.actionPan)
        self.newWindow()

    def createLegendWidget(self):
        # Create the map legend widget and associate to the canvas """
        self.legend = Legend(self)
        self.legend.setObjectName("theMapLegend")

        self.LegendDock = QDockWidget("Layers", self)
        self.LegendDock.setObjectName("legend")
        self.LegendDock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.LegendDock.setWidget(self.legend)
        self.LegendDock.setContentsMargins(9, 9, 9, 9)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.LegendDock)

    def tileWindows(self):
        self.mapArea.tileSubWindows()

    def subActive(self, window):

        if window is None:
            return

        if window.widget() == self.activeCanvas:
            return

        # Disconnect the last
        if not self.activeCanvas is None:
            self.activeCanvas.extentsChanged.disconnect(self.extentsChanged)

        self.activeCanvas = window.widget()
        self.legend.setCanvas(self.activeCanvas)
        self.activeCanvas.extentsChanged.connect(self.extentsChanged)

        self.legend.clear()
        for layer in reversed(self.activeCanvas.layers()):
            self.legend.addLayerToLegend(layer)

        if self.activeTool == "ZoomIn":
            self.zoomIn()
        elif self.activeTool == "ZoomOut":
            self.zoomOut()
        elif self.activeTool == "Pan":
            self.pan()
        else:
            return

    def extentsChanged(self):
        for window in self.mapArea.subWindowList():
            if not window.widget() == self.activeCanvas:
                extent = self.activeCanvas.extent()
                can = window.widget()
                can.setExtent(extent)
                can.refresh()

    def newWindow(self):
        canvas = MyCanvas()
        canvas.useImageToRender(False)
        self.mapArea.addSubWindow(canvas)

        zoomIn = QgsMapToolZoom(canvas, False)
        zoomIn.setAction(self.actionZoomIn)
        canvas.setZoomInTool(zoomIn)

        zoomOut = QgsMapToolZoom(canvas, True)
        zoomOut.setAction(self.actionZoomOut)
        canvas.setZoomOutTool(zoomOut)

        panTool = QgsMapToolPan(canvas)
        panTool.setAction(self.actionPan)
        canvas.setPanTool(panTool)
        canvas.show()
        self.tileWindows()

    def zoomIn(self):
        self.activeCanvas.setMapTool(self.activeCanvas.getZoomInTool())
        self.activeTool = "ZoomIn"

    def zoomOut(self):
        self.activeCanvas.setMapTool(self.activeCanvas.getZoomOutTool())
        self.activeTool = "ZoomOut"

    def pan(self):
        self.activeCanvas.setMapTool(self.activeCanvas.getPanTool())
        self.activeTool = "Pan"

    def addLayer(self):
        # layout is set - open a layer
        # Add an OGR layer to the map
        file = QFileDialog.getOpenFileName(self, "Open File", ".", "Shapefile (*.shp);; Raster (*.tif)")
        fileInfo = QFileInfo(file)

        # Add the layer
        extn = os.path.splitext(str(file))[1]
        if extn.lower() == ".shp":
            layer = QgsVectorLayer(file, fileInfo.fileName(), "ogr")
        else:
            layer = QgsRasterLayer(file, fileInfo.fileName())

        if not layer.isValid():
            tryagain = QMessageBox.question(
                self, "APCartOS", "Layer failed to load! Try again?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No
            )
            if tryagain == QMessageBox.Yes:
                self.addLayer()
            else:
                return

        # Add layer to the registry
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        # QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayerToLegend)

        # Set extent to the extent of our layer
        self.activeCanvas.setExtent(layer.extent())

        # Set up the map canvas layer set
        cl = QgsMapCanvasLayer(layer)
        self.activeCanvas.innerlayers.append(cl)
        self.activeCanvas.setLayerSet(self.activeCanvas.innerlayers)

        # print layers

    def enableEditingButton(self):
        layer = self.legend.activeLayer().layer()
        if type(layer).__name__ == "QgsVectorLayer":
            self.actionStart_editing.setEnabled(1)
        else:
            self.actionStart_editing.setEnabled(0)

    def toogleEditing(self):
        layer = self.legend.activeLayer().layer()
        if not layer.isEditable():
            layer.startEditing()
            self.activeCanvas.refresh()
            self.actionStart_editing.setText("Stop editing")
        else:
            if not layer.isModified():
                layer.commitChanges()
            else:
                reply = QMessageBox.question(
                    self, "APCartOS", "Save changes?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No
                )
                if reply == QMessageBox.Yes:
                    layer.commitChanges()
                else:
                    layer.rollBack()
            self.actionStart_editing.setText("Start editing")
Ejemplo n.º 22
0
    def legend(self, handles, labels, *args, **kwargs):
        """
        Place a legend in the figure.  Labels are a sequence of
        strings, handles is a sequence of
        :class:`~matplotlib.lines.Line2D` or
        :class:`~matplotlib.patches.Patch` instances, and loc can be a
        string or an integer specifying the legend location

        USAGE::

          legend( (line1, line2, line3),
                  ('label1', 'label2', 'label3'),
                  'upper right')

        The *loc* location codes are::

          'best' : 0,          (currently not supported for figure legends)
          'upper right'  : 1,
          'upper left'   : 2,
          'lower left'   : 3,
          'lower right'  : 4,
          'right'        : 5,
          'center left'  : 6,
          'center right' : 7,
          'lower center' : 8,
          'upper center' : 9,
          'center'       : 10,

        *loc* can also be an (x,y) tuple in figure coords, which
        specifies the lower left of the legend box.  figure coords are
        (0,0) is the left, bottom of the figure and 1,1 is the right,
        top.

        The legend instance is returned.  The following kwargs are supported

        *loc*
            the location of the legend
        *numpoints*
            the number of points in the legend line
        *prop*
            a :class:`matplotlib.font_manager.FontProperties` instance
        *pad*
            the fractional whitespace inside the legend border
        *markerscale*
            the relative size of legend markers vs. original
        *shadow*
            if True, draw a shadow behind legend
        *labelsep*
            the vertical space between the legend entries
        *handlelen*
            the length of the legend lines
        *handletextsep*
            the space between the legend line and legend text
        *axespad*
            the border between the axes and legend edge

        .. plot:: mpl_examples/pylab_examples/figlegend_demo.py
        """
        handles = flatten(handles)
        l = Legend(self, handles, labels, *args, **kwargs)
        self.legends.append(l)
        return l
Ejemplo n.º 23
0
class Drawable():
    """
    The :class:`~Drawable` class wraps a matplotlib figure and axes to provide additional functionality.
    If no axes is given, the default plot axes (:code:`plt.gca()`) is used.
    The :class:`~Drawable` class can be used as a normal `matplotlib.axes.Axes <https://matplotlib.org/api/axes_api.html>`_ object with additional functionality.
    The axes functionality can be called on the :class:`~Drawable` class.
    The :class:`~Drawable` instance re-routes method and attribute calls to the `matplotlib.axes.Axes <https://matplotlib.org/api/axes_api.html>`_ instance.

    :ivar figure: The figure that the :class:`~Drawable` class wraps.
    :vartype figure: :class:`matplotlib.figure.Figure`
    :ivar axes: The axes where the drawable will draw.
    :vartype axes: :class:`matplotlib.axes.Axes`
    :ivar secondary: The secondary axes.
                     Some visualizations, such as the :class:`~slope.slope.Slope` graph uses them to draw different ticks on each y-axis.
    :vartype secondary: :class:`matplotlib.axes.Axes`
    :var caption: The caption, displayed under the title.
    :vartype caption: :class:`~text.annotation.Annotation`

    :ivar bar100: The 100% bar chart visualization that is being used.
                  When no visualization has been created, it is set to `None`.
                  It is instantiated the first time a 100% bar chart is drawn.
    :vartype bar100: None or :class:`~bar.100.Bar100`
    :ivar population: The population visualization that is being used.
                      When no visualization has been created, it is set to `None`.
                      It is instantiated the first time a population is drawn.
    :vartype population: None or :class:`~population.population.Population`
    :ivar timeseries: The time series object that is being used.
                      When no visualization has been created, it is set to `None`.
                      It is instantiated the first time a time series is drawn.
    :vartype timeseries: None or :class:`~timeseries.timeseries.TimeSeries`

    :ivar legend: The figure's legend.
    :vartype legend: :class:`~legend.Legend`
    :ivar annotations: The annotations in the visualization.
    :vartype annotations: list of :class:`~text.annotation.Annotation`
    """
    def __init__(self, figure, axes=None):
        """
        Create the drawable with the figure.

        :param figure: The figure that the :class:`~Drawable` class wraps.
                       This is mainly used to get the figure renderer.
        :type figure: :class:`matplotlib.figure.Figure`
        :param axes: The axes (or subplot) where to plot visualizations.
                     If `None` is given, the plot's main subplot is used instead.
        :type axes: `None` or :class:`matplotlib.axes.Axes`
        """

        self.figure = figure
        self.axes = plt.gca() if axes is None else axes
        self.secondary = self.axes
        self.caption = None

        self.annotations = []
        self.legend = Legend(self)
        self.bar100 = None
        self.population = None
        self.slope = None
        self.timeseries = None

    def set_caption(self,
                    caption,
                    alpha=0.8,
                    lineheight=1.25,
                    *args,
                    **kwargs):
        """
        Add a caption to the subplot.
        The caption is added just beneath the title.
        The method re-draws the title to make space for the caption.

        The caption is a :class:`~text.text.Annotation` object.
        Any arguments that the constructor accepts can be provided to this method.

        :param caption: The caption to add to the axes.
        :type caption: str
        :param alpha: The opacity of the caption between 0 and 1.
        :type alpha: float
        :param lineheight: The space between lines.
        :type lineheight: float

        :return: The drawn caption.
        :rtype: :class:`~text.annotation.Annotation`
        """

        self.caption = Annotation(self,
                                  caption, (0, 1),
                                  1,
                                  va='bottom',
                                  alpha=alpha,
                                  lineheight=lineheight,
                                  transform=self.axes.transAxes,
                                  *args,
                                  **kwargs)
        self.caption.draw()
        self.redraw()
        return self.caption

    def redraw(self):
        """
        Re-create the title, with the goal of leaving enough space to fit the caption and the legend.
        Afterwards, it redraws the legend.
        """

        self.figure.canvas.draw()

        # redraw all visualizations
        for viz in [self.bar100, self.population, self.slope, self.timeseries]:
            if viz:
                viz.redraw()

        # redraw all annotations
        for annotation in self.annotations:
            annotation.redraw()

        self.legend.redraw()
        self._redraw_caption()
        self._redraw_title()

    def _redraw_caption(self):
        """
        Re-draw the caption, re-positioning so that it does not overlap with the legend or axes.
        """

        if not self.caption:
            return

        figure, axes = self.figure, self.axes
        """
        Move the caption up to make space for the legend and the label.
        """
        y = 1.015
        y += self.legend.get_virtual_bb(transform=self.axes.transAxes).height
        """
        If the x-label is on top, make space for it in the caption.
        In this case, it is assumed that the ticks are also at the top.
        This is because for some reason they may be set to 'unknown'.
        """
        if axes.xaxis.get_label_position() == 'top':
            y += self._get_xlabel(transform=self.axes.transAxes).height * 2

            xtick_labels_bb = self._get_xtick_labels(transform=axes.transAxes)
            if xtick_labels_bb:
                y += max(xtick_labels_bb, key=lambda bb: bb.height).height * 2

        self.caption.redraw()
        self.caption.set_position((0, y),
                                  ha='left',
                                  va='bottom',
                                  transform=self.axes.transAxes)

    def _redraw_title(self):
        """
        Re-draw the title, adding enough padding so that there is enough space for the axes label, the legend and the caption.
        """

        figure, axes = self.figure, self.axes

        title = axes.get_title(loc='left')
        """
        Get the height of the caption and the height of the legend.
        The title should allow enough padding to make space for both.
        """
        caption_height = 0
        if self.caption:
            caption_height = util.to_px(
                axes,
                self.caption.get_virtual_bb(transform=axes.transAxes),
                transform=axes.transAxes).height

        legend_height = util.to_px(
            axes,
            self.legend.get_virtual_bb(transform=axes.transAxes),
            transform=axes.transAxes).height
        """
        If the x-label is on top, make space for it in the title.
        In this case, it is assumed that the ticks are also at the top.
        This is because for some reason they may be set to 'unknown'.
        """
        label_height = 0
        if axes.xaxis.get_label_position() == 'top':
            label_bb = self._get_xlabel(transform=axes.transData)
            label_height = util.to_px(axes, label_bb,
                                      transform=axes.transData).height * 2
            xtick_labels_bb = self._get_xtick_labels(transform=axes.transData)
            if xtick_labels_bb:
                label_bb = max(xtick_labels_bb, key=lambda bb: bb.height)
                label_height += util.to_px(
                    axes, label_bb, transform=axes.transData).height * 2
        """
        Add some extra padding to the height.
        """
        height = abs(caption_height) + abs(legend_height) + abs(label_height)
        pad_px = abs(
            self.axes.transAxes.transform((0, 0.015))[1] -
            self.axes.transAxes.transform((0, 0))[1])
        pad = pad_px * 2
        self.axes.set_title(title, loc='left', pad=(height + pad))

    def _get_xlabel(self, transform=None):
        """
        Get the bounding box of the x-axis label.

        :param transform: The bounding box transformation.
                          If `None` is given, the data transformation is used.
        :type transform: None or :class:`matplotlib.transforms.TransformNode`

        :return: The bounding box of the x-axis label.
        :rtype: :class:`matplotlib.transforms.Bbox`
        """

        figure, axes = self.figure, self.axes

        transform = transform or axes.transData
        return util.get_bb(figure,
                           axes,
                           axes.xaxis.get_label(),
                           transform=transform)

    def _get_xtick_labels(self, transform=None):
        """
        Get the bounding box of the x-axis tick labels.

        :param transform: The bounding box transformation.
                          If `None` is given, the data transformation is used.
        :type transform: None or :class:`matplotlib.transforms.TransformNode`

        :return: The bounding box of the x-axis label.
        :rtype: :class:`matplotlib.transforms.Bbox`
        """

        figure, axes = self.figure, self.axes

        figure.canvas.draw()
        transform = transform or axes.transData
        return [
            util.get_bb(figure, axes, label, transform=transform)
            for label in axes.xaxis.get_ticklabels(which='both')
        ]

    def savefig(self, *args, **kwargs):
        """
        A special function that calls the `matplotlib.pyplot.savefig <https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.savefig.html>`_ function.
        Before doing that, the function first redraws the drawable.

        This function is very important when the title and caption are set before drawing the visualization.
        In these cases, it is possible that the legend or the plot labels cause the caption or title to overlap with the plot.
        """

        self.redraw()
        plt.savefig(*args, **kwargs)

    def show(self, *args, **kwargs):
        """
        A special function that calls the `matplotlib.pyplot.show <https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.show.html>`_ function.
        Before doing that, the function first redraws the drawable.

        This function is very important when the title and caption are set before drawing the visualization.
        In these cases, it is possible that the legend or the plot labels cause the caption or title to overlap with the plot.
        """

        self.redraw()
        plt.show(*args, **kwargs)

    def __getattr__(self, name):
        """
        The magic function through which most of :class:`~Drawable`'s functionality passes.
        This function receives any unknown call and passes it on to the :class:`~Drawable`'s `matplotlib.axes.Axes <https://matplotlib.org/api/axes_api.html>`_.
        This function automatically checks whether the call is referencing a function or a variable.

        :param name: The name of the attribute.
        :type name: str

        :return: The function applied on the axes.
        :rtype: function
        """
        def method(*args, **kwargs):
            """
            Try to get the attribute from the axes.
            If arguments were given, then the attribute is treated as a method call.
            Otherwise, it is treated as a normal attribute call.
            """

            if callable(getattr(self.axes, name)):
                return getattr(self.axes, name)(*args, **kwargs)
            else:
                return getattr(self.axes, name)

        return method

    """
    Visualizations
    """

    def annotate(self, text, x, y, marker=None, pad=0.01, *args, **kwargs):
        """
        Add a text annotation to the plot.
        This function can be used to draw attention to certain or describe the visualization on the plot itself.

        Any additional arguments and keyword arguments are passed on to the :class:`~text.annotation.Annotation`'s :func:`~text.annotation.Annotation.draw` function.
        For example, the `va` can be provided to specify the text's vertical alignment, andthe `align` parameter can be used to specify the text's alignment.

        :param text: The text of the annotation to draw.
        :type text: str
        :param x: A tuple containing the start and end x-coordinates of the annotation.
        :type x: tuple
        :param y: The y-coordinate of the annotation.
        :type y: float
        :param marker: The marker style.
                       If it is not given, no marker is drawn.
        :type marker: None or dict
        :param pad: The amount of padding applied to the annotation.
        :type pad: float

        :return: The drawn annotation.
        :rtype: :class:`~text.annotation.Annotation`
        """

        annotation = Annotation(self, text, x, y, pad=pad, *args, **kwargs)
        self.figure.canvas.draw()
        """
        Draw the marker if it is given.
        The color is obtained from the kwargs if a marker color is not given.
        The point of the marker is based on the alignment of the annotation.
        """
        if marker is not None:
            marker = dict(
                marker)  # make a copy to avoid overwriting dictionaries
            marker['color'] = marker.get('color', kwargs.get('color'))
            if kwargs.get('align', 'left') == 'left':
                self.axes.plot(x[0], y, *args, **marker)
            elif kwargs.get('align') == 'right':
                self.axes.plot(x[1], y, *args, **marker)
            elif kwargs.get('align') == 'center':
                self.axes.plot((x[0] + x[1]) / 2., y, *args, **marker)

        self.annotations.append(annotation)

        return annotation

    def draw_bar_100(self, *args, **kwargs):
        """
        Draw a bar chart that stacks up to 100% on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~bar.bar100.Bar100`'s :func:`~bar.bar100.Bar100.draw` method.

        :return: A list of drawn bars.
        :rtype: list of :class:`matplotlib.patches.Rectangle`
        """

        self.bar100 = self.bar100 or Bar100(self)
        return self.bar100.draw(*args, **kwargs)

    def draw_graph(self, *args, **kwargs):
        """
        Draw a graph visualization on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~graph.graph.Graph`'s :func:`~graph.graph.Graph.draw` method.

        :return: A tuple containing the list of drawn nodes, the rendered node names, edges, and the rendered edge names.
        :rtype: tuple
        """

        graph = Graph(self)
        return graph.draw(*args, **kwargs)

    def draw_population(self, *args, **kwargs):
        """
        Draw a population chart on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~population.population.Population`'s :func:`~population.population.Population.draw` method.

        :return: A list of drawn scatter points, separated by column.
        :rtype: list of list of :class:`matplotlib.collections.PathCollection`
        """

        self.population = self.population if self.population else Population(
            self)
        return self.population.draw(*args, **kwargs)

    def draw_slope(self, *args, **kwargs):
        """
        Draw a slope graph with two points on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~slope.slope.Slope`'s :func:`~slope.slope.Slope.draw` method.

        :return: A tuple made up of the drawn plot and label.
        :rtype: tuple (:class:`matplotlib.lines.Line2D`, list of :class:`~text.annotation.Annotation`)
        """

        self.slope = self.slope or Slope(self)
        return self.slope.draw(*args, **kwargs)

    def draw_text_annotation(self, *args, **kwargs):
        """
        Draw a text annotation visualization on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~text.text.TextAnnotation`'s :func:`~text.text.TextAnnotation.draw` method.

        :return: The drawn text annotation's lines.
                 Each line is made up of tuples of lists.
                 The first list in each tuple is the list of legend labels.
                 The second list in each tuple is the list of actual tokens.
        :rtype: list of tuple
        """

        text_annotation = TextAnnotation(self)
        return text_annotation.draw(*args, **kwargs)

    def draw_time_series(self, *args, **kwargs):
        """
        Draw a time series visualization on this :class:`~Drawable`.
        The arguments and keyword arguments are those supported by the :class:`~timeseries.timeseries.TimeSeries`' :func:`~timeseries.timeseries.TimeSeries.draw` method.

        :return: A tuple made up of the drawn plot and label.
        :rtype: tuple
        """

        self.timeseries = self.timeseries or TimeSeries(self)
        return self.timeseries.draw(*args, **kwargs)
Ejemplo n.º 24
0
class WaferMap:
 
    def __init__(self):
        self.img = None
        self.legend = Legend()
        self.title = Title()
        self.autosize = App.cfg['image']['autosize']
        self.autosize_minpx = App.cfg['image']['autosize_minpx']
        self.basewidth = App.cfg['image']['basewidth']
        self.baseheight = App.cfg['image']['baseheight']
        self.padding = App.cfg['image']['padding']
        self.showborder = App.cfg['image']['border']
        self.showtitle = App.cfg['title']['show']
        self.showlegend = App.cfg['legend']['show']
        self.showgrid = App.cfg['axis']['grid']
        self.showaxis = App.cfg['axis']['show']
        self.showflat = App.cfg['image']['flatline']
        self.showtimestamp = App.cfg['image']['timestamp']
        self.timestampcolor = App.cfg['image']['timestampcolor']
        self.bordercolor = App.cfg['image']['bordercolor']
        self.streetcolor = App.cfg['image']['streetcolor']
        self.flatcolor = App.cfg['image']['flatcolor']
        self.gridcolor = App.cfg['axis']['gridcolor']
        self.axiscolor = App.cfg['axis']['color']
        self.axisfont = App.cfg['axis']['font']
        self.bgcolor = App.cfg['image']['bgcolor']
      
    def buildmap(self, lot, wfr, testset):
    
        #---------------------------------------------------------------------------
        # Get actual extents... that is number of rows & cols in the wafermap, 
        # If the demodata routine was used, a random number of rows/cols were
        # generated.
        #--------------------------------------------------------------------------- 
        
        min_Y = min(d.Y for d in wfr.dielist)
        max_Y = max(d.Y for d in wfr.dielist)
        min_X = min(d.X for d in wfr.dielist)
        max_X = max(d.X for d in wfr.dielist)
        
        col_count = max_X - min_X+1
        row_count = max_Y - min_Y+1
        
        log.debug('Die Extents: X = {} to {}  Y = {} to {}'.format(min_X, max_X, min_Y, max_Y))
        log.debug('Columns (X) = {}, Rows (Y) = {} (Total Die={})'.format(col_count, row_count, len(wfr.dielist)))
        
         
        if self.basewidth >= self.baseheight:
            sizeRatio = float(self.basewidth) / float(self.baseheight)
        else:
            sizeRatio = float(self.baseheight) / float(self.basewidth)
             
        log.debug('Size Ratio: {:.2f}, width={}, height={}'.format(sizeRatio, self.basewidth, self.baseheight))
        
        
        #---------------------------------------------------------------------------
        # If image autosize is enabled, the canvas size may be increased to ensure
        # die are visible.  This will force a minimum pixel size of "autosize_minpx".
        # The original aspect ratio will be maintained.
        #---------------------------------------------------------------------------
        
        if self.autosize:
            
            autominX = (self.autosize_minpx * col_count) + (2 * self.padding)
            autominY = (self.autosize_minpx * row_count) + (2 * self.padding)
            log.debug('Autosize Minimum Map Size X={} Y={} at Autopx = {}'.format( 
                      autominX, autominY, self.autosize_minpx))
        
            if(autominX > self.basewidth):
                self.basewidth = autominX
                self.baseheight = int (float(self.basewidth) * float(sizeRatio))
                log.debug('Autosize (autominX > bw) Updated sizes - width={}, height={}, sizeRatio={}'.format(
                    self.basewidth, self.baseheight, float(sizeRatio)))
            elif (autominY > self.baseheight):
                self.baseheight = autominY
                self.basewidth = int (float(self.baseheight) * float(sizeRatio))
                log.debug('Autosize (autominY > bh) Updated sizes - width={}, height={}, sizeRatio={}'.format(
                    self.basewidth, self.baseheight, float(sizeRatio)))
            else:
                log.debug('Autosize sizing not required, width={}, height={}, autominX={}, autominY={}'.format(
                    self.basewidth, self.baseheight, autominX, autominY)) 
    
            
            #Store updated values back in cfg 
#             App.cfg['image']['basewidth'] = bw
#             App.cfg['image']['baseheight'] = bh
        
    
        
        # Nominal size of map excluding padding
        mapX = self.basewidth - (self.padding *2)
        mapY = self.baseheight - (self.padding *2)
        log.debug('Map Space (BaseSize - 2*Padding)  (X,Y)=({},{})  Padding = {}'.format(
            mapX, mapY, self.padding))
        
        
        # Calculate the die's pixel size - width (X) and height (Y) based on map size 
        # divided by the number of rows & columns
        X_pixels = mapX / col_count     #X-diesize in pixels
        Y_pixels = mapY / row_count     #Y diesize in pixels
        log.debug('Pixels per die: X={}, Y={}'.format(X_pixels, Y_pixels))
        
        #---------------------------------------------------------------------------
        # Unless the nominal image size (Canvas size minus padding) happens to be an
        # exact multiple of the calculated die size in pixels, we will have some 
        # space left on all sides.
        # Calculate the extra space so we can center the image on the canvas
        #---------------------------------------------------------------------------   
        slackX = (mapX - (X_pixels * col_count)) / 2
        slackY = (mapY - (Y_pixels * row_count)) / 2
        log.debug('Slack: X={}, Y={}'.format(slackX, slackY))
        log.debug('Calculated Map Size (excluding slack) - (X,Y) = ({},{})'.format( 
                  X_pixels * col_count, Y_pixels * row_count))
    #     
        #-------------------------------------------------------------------------
        # Have the legend calculate its size, it will be rendered later, but we
        # need to know the space it will take up so we can adjust the canvas size 
        # Actual Map width is then adjusted to allow for legend.
        #--------------------------------------------------------------------------
        actualWidth = self.basewidth
        if self.showlegend:
            self.legend.getsize(wfr.dielist, testset)
            actualWidth += self.legend.width
            log.debug('Legend Width = {}'.format(self.legend.width))
           
        #--------------------------------------------------------------------------
        # baseheight and fontsize adjusted for title
        #--------------------------------------------------------------------------
        # Start with a reasonable guess for the size of the title font and then
        # autosize it from there.   May not be the most efficient way to do 
        # this, but it works for now...
        #--------------------------------------------------------------------------
        actualHeight = self.baseheight
        titleheight = 0
        if self.showtitle:
            
            #A guess...
            title_fontsize = actualWidth//40    
            titlekeys = self.title.autosize(lot.mir, wfr, title_fontsize, testset)
            upsearch=False
            
            # While title string width at current font size is > canvas width, decrease 
            # font size and re-evaluate 
            if(titlekeys['maxfw'] > actualWidth):
                while titlekeys['maxfw'] > actualWidth:
                    upsearch=False
                    title_fontsize -= 1
                    titlekeys = self.title.autosize(lot.mir, wfr, title_fontsize, testset)
        #             print "D:imageWith = {}, fontsize = {}, maxfw={}, height={}".format(actualWidth, title_fontsize, titlekeys['maxfw'], titlekeys['maxfh'])
            # Otherwise, font is too small, increase it and re-evaluate
            else:
                while titlekeys['maxfw'] < actualWidth:
                    upsearch=True
                    title_fontsize += 1
                    titlekeys = self.title.autosize(lot.mir, wfr, title_fontsize, testset)
        #             print "U:imageWith = {}, fontsize = {}, maxfw={}, height={}".format(actualWidth, title_fontsize, titlekeys['maxfw'], titlekeys['maxfh'])    
        
            # If we were decreasing font size when the while condition became false, all the titlekeys are properly set, 
            # from the last loop cycle.... but if we were increasing font size, the last loop cycle left the titlekeys 
            # in a state for a larger font, so decrease the font size by one and re-evaluate the titlekeys
            if(upsearch):
                title_fontsize -=1
                titlekeys = self.title.autosize(lot.mir, wfr, title_fontsize, testset)
        
            titleheight = titlekeys['maxfh']
            
            # Increase canvas size to allow for title
            actualHeight += titleheight
            log.debug('Title Height = {}, Title Fontsize = {}'.format(titleheight, title_fontsize))
    
        #--------------------------------------------------------------------------
        # Adjust Width and Height for axis space
        #--------------------------------------------------------------------------
#         if self.showaxis:
#             actualWidth += axis_space
#             actualHeight += axis_space
        #--------------------------------------------------------------------------
        # Get axis space, add in 10 pixels for flat spacing.  (the axes are 
        # shifted left or up by 10 pixels when they are drawn to account for the
        # 10 pixels).
        #--------------------------------------------------------------------------
        axis_space = 0
        if self.showaxis:
            axis_space = maputil.do_axis(self, wfr.dielist, X_pixels, Y_pixels) + 10
            log.debug('Axis Space = {}'.format(axis_space))
            
        actualWidth += axis_space
        actualHeight += axis_space           
                      
        log.debug('Axis space = {}'.format(axis_space))    
        log.debug('Actual Image Size (X,Y) = ({},{})'.format(actualWidth, actualHeight))     

                            
        #--------------------------------------------------------------------------
        # Create the canvas and draw the wafermap
        #--------------------------------------------------------------------------
        self.img = Image.new('RGB', (actualWidth,actualHeight), self.bgcolor)
    
        # Get the drawable object...
        dr = ImageDraw.Draw(self.img)
        
        # map_extents are used for tracking the actual pixel extents of the drawn map which makes
        # calculating the location to draw the flat & axis labels a bit easier...
        
        map_extents = {'minx':65535, 'miny':65535, 'maxx':0, 'maxy':0}
        
        # limit flag_size factor to a minimum of 1.0 (or else flag will exceed die boundary)
        App.cfg['flag']['size_factor'] = max(App.cfg['flag']['size_factor'], 1.0)
        
        # if we want the grid, draw it first so it's behind everything else...
        if self.showgrid:   
            maputil.do_grid(self, wfr.dielist, X_pixels, Y_pixels, self.padding, axis_space, slackX, slackY, titleheight)
       
        idx=0       
        imap = []
        #-----------------------------------------------------------
        # Draw All die loop
        #-----------------------------------------------------------
        for eachDie in wfr.dielist:
            mybin=getattr(eachDie,App.cfg['binmap'])
            idx+=1      
            x1 = self.padding + axis_space + ((eachDie.X - min_X) * X_pixels) + slackX
            y1 = self.padding + axis_space + ((eachDie.Y - min_Y) * Y_pixels) + slackY + titleheight
            x2 = x1 + X_pixels
            y2 = y1 + Y_pixels
            
            # Draw the die and file with bincolor
            if eachDie.testset == testset:
                dr.rectangle([x1,y1,x2,y2], fill=App.cfg['bin'][str(mybin)]['color'], outline=self.streetcolor)
                imap.append({'Row':eachDie.Y,'Col':eachDie.X,'x':x1,'y':y1,'width':x2-x1,'height':y2-y1})
                # Draw any specified symbols, if enabled 
                if App.cfg['enable_symbols']:
                    maputil.do_symbol(dr,x1,y1,x2,y2, False, **App.cfg['bin'][str(mybin)])
            
            # Draw flags if appropriate        
            xystr="{}|{}".format(eachDie.X, eachDie.Y)   # Bindict Key 
            if (wfr.diedict[xystr]['flags'] & constants.FLAG_MULTITEST) and App.cfg['flag']['show']:
                if wfr.diedict[xystr]['flags'] & constants.FLAG_DUPLICATE_BIN:
                    flagcolor= App.cfg['flag']['duplicate_color']
                else:
                    flagcolor= App.cfg['flag']['split_color'] 
                flagX = int(float(x2-x1)/float(App.cfg['flag']['size_factor']))
                flagY = int(float(y2-y1)/float(App.cfg['flag']['size_factor'])) 
                dr.polygon([(x1,y1+flagY),(x1,y1),(x1+flagX,y1)], fill=flagcolor, outline=(0,0,0))  
       
        
            # track minimum and maximums of actual drawn wafermap.
            map_extents['minx']= min(map_extents['minx'],x1)
            map_extents['maxx']= max(map_extents['maxx'],x2)
            map_extents['miny']= min(map_extents['miny'],y1)
            map_extents['maxy']= max(map_extents['maxy'],y2)
        
        #-----------------------------------------------------------
           
        log.debug('Drawn Map Extents = {}'.format(map_extents))
    
    #     do_html(imap, actualWidth, actualHeight)
            
        #--------------------------------------------------------------------------
        # Draw title area
        #--------------------------------------------------------------------------
        if self.showtitle:
            dr.rectangle([0,0,actualWidth-1,titleheight], fill=self.title.bgcolor, outline=self.bordercolor)
            self.title.render(self.img, wfr, titlekeys)
        
        #--------------------------------------------------------------------------
        # Draw legend, border, flat indicator, timestamp, axis labels
        #--------------------------------------------------------------------------
        if self.showlegend:
            self.legend.render(self.img, self.basewidth + axis_space , self.padding + titleheight)
        
        if self.showborder:
            dr.rectangle([0,0,actualWidth-1,actualHeight-1], fill=None, outline=self.bordercolor)
        
        if self.showflat:
            maputil.do_flat(self, lot.wcr['WF_FLAT'], map_extents, self.flatcolor)
        
        if self.showtimestamp:
            maputil.do_timestamp(self, color=self.timestampcolor) 
    
        if self.showaxis:
            maputil.do_axis(self, wfr.dielist, X_pixels, Y_pixels, map_extents, True)
       
        return(self.img)
Ejemplo n.º 25
0
def buildmap(lot, wfr, testset):
          
    #---------------------------------------------------------------------------
    # Get actual extents... that is number of rows & cols in the wafermap, 
    # If the demodata routine was used, a random number of rows/cols were
    # generated.
    #--------------------------------------------------------------------------- 
    
    min_Y = min(d.Y for d in wfr.dielist)
    max_Y = max(d.Y for d in wfr.dielist)
    min_X = min(d.X for d in wfr.dielist)
    max_X = max(d.X for d in wfr.dielist)
    
    col_count = max_X - min_X+1
    row_count = max_Y - min_Y+1
    
    log.debug('Die Extents: X = {} to {}  Y = {} to {}'.format(min_X, max_X, min_Y, max_Y))
    log.debug('Columns (X) = {}, Rows (Y) = {} (Total Die={})'.format(col_count, row_count, len(wfr.dielist)))
    
    
    baseWidth=App.cfg['image']['basewidth']
    baseHeight=App.cfg['image']['baseheight']
     
    if baseWidth >= baseHeight:
        sizeRatio = float(baseWidth) / float(baseHeight)
    else:
        sizeRatio = float(baseHeight) / float(baseWidth)
         
    log.debug('Size Ratio: {:.2f}, width={}, height={}'.format(sizeRatio, baseWidth, baseHeight))
    
    
    #---------------------------------------------------------------------------
    # If image autosize is enabled, the canvas size may be increased to ensure
    # die are visible.  This will force a minimum pixel size of "autosize_minpx".
    # The original aspect ratio will be maintained.
    #---------------------------------------------------------------------------
    padding=App.cfg['image']['padding']
    autosize_minpx = App.cfg['image']['autosize_minpx']
    
    if App.cfg['image']['autosize']:
        # conveniences for calculations...
        bw = App.cfg['image']['basewidth']
        bh = App.cfg['image']['baseheight']
        
        autominX = (autosize_minpx * col_count) + (2 * padding)
        autominY = (autosize_minpx * row_count) + (2 * padding)
        log.debug('Autosize Minimum Map Size X={} Y={} at Autopx = {}'.format( 
                  autominX, autominY, autosize_minpx))
    
        if(autominX > bw):
            bw = autominX
            bh = int (float(bw) * float(sizeRatio))
            log.debug('Autosize (autominX > bw) Updated sizes - width={}, height={}, sizeRatio={}'.format(bw, bh, float(sizeRatio)))
        elif (autominY > bh):
            bh = autominY
            bw = int (float(bh) * float(sizeRatio))
            log.debug('Autosize (autominY > bh) Updated sizes - width={}, height={}, sizeRatio={}'.format(bw, bh, float(sizeRatio)))
        else:
            log.debug('Autosize sizing not required, width={}, height={}, autominX={}, autominY={}'.format(bw, bh, autominX, autominY)) 

        
        #Store updated values back in cfg 
        App.cfg['image']['basewidth'] = bw
        App.cfg['image']['baseheight'] = bh
    

    
    # Nominal size of map excluding padding
    mapX = App.cfg['image']['basewidth'] - (padding *2)
    mapY = App.cfg['image']['baseheight'] - (padding *2)
    log.debug('Map Space (BaseSize - 2*Padding)  (X,Y)=({},{})'.format(mapX,mapY))
    
    
    #Calculate the die's pixel size  width (X) and height (Y)
    X_pixels = mapX / col_count     #X-diesize in pixels
    Y_pixels = mapY / row_count     #Y diesize in pixels
    log.debug('Pixels per die: X={}, Y={}'.format(X_pixels, Y_pixels))
    
    #---------------------------------------------------------------------------
    # Unless the nominal image size (Canvas size minus padding) happens to be an
    # exact multiple of the calculated die size in pixels, we will have some 
    # space left on all sides.
    # Calculate the extra space so we can center the image on the canvas
    #---------------------------------------------------------------------------   
    slackX = (mapX - (X_pixels * col_count)) / 2
    slackY = (mapY - (Y_pixels * row_count)) / 2
    log.debug('Slack: X={}, Y={}'.format(slackX, slackY))
    log.debug('Calculated Map Size (excluding slack) - (X,Y) = ({},{})'.format( 
              X_pixels * col_count, Y_pixels * row_count))
#     
    #-------------------------------------------------------------------------
    # Generate the legend data, it will be rendered later, but we require
    # knowing the space it will take up so we can adjust the canvas size 
    #-------------------------------------------------------------------------
    wfr.legend = Legend(wfr.dielist, testset)
    
    #--------------------------------------------------------------------------
    # baseWidth adjusted to allow for legend.
    #--------------------------------------------------------------------------
    actualWidth = App.cfg['image']['basewidth']
    if App.cfg['legend']['show']:
        actualWidth += wfr.legend.legend['legendwidth']
        log.debug('Legend Width = {}'.format(wfr.legend.legend['legendwidth']))
           
    #--------------------------------------------------------------------------
    # Get axis space, add in 10 pixels for flat spacing.  (the axes are 
    # shifted left or up by 10 pixels when they are drawn to account for these
    # 10 pixels).
    #--------------------------------------------------------------------------
    axis_space = 0
    if App.cfg['axis']['show']:
        axis_space = _do_axis(wfr.dielist,X_pixels,Y_pixels) + 10
        log.debug('Axis Space = {}'.format(axis_space))
        
       
    #--------------------------------------------------------------------------
    # baseheight and fontsize adjusted for title
    #--------------------------------------------------------------------------
    # Start with a reasonable guess for the size of the title font and then
    # autosize it from there.   May not be the most efficient way to do 
    # this, but it works for now...
    #--------------------------------------------------------------------------
    actualHeight = App.cfg['image']['baseheight']
    titleheight = 0
    if App.cfg['title']['show']:
        
        #A guess...
        title_fontsize = actualWidth//40    
        titlekeys = wfr.legend.titlesize(lot.mir, wfr, title_fontsize, testset)
        upsearch=False
        
        if(titlekeys['maxfw'] > actualWidth):
            while titlekeys['maxfw'] > actualWidth:
                upsearch=False
                title_fontsize -= 1
                titlekeys = wfr.legend.titlesize(lot.mir, wfr, title_fontsize, testset)
    #             print "D:imageWith = {}, fontsize = {}, maxfw={}, height={}".format(actualWidth, title_fontsize, titlekeys['maxfw'], titlekeys['maxfh'])
    
        else:
            while titlekeys['maxfw'] < actualWidth:
                upsearch=True
                title_fontsize += 1
                titlekeys = wfr.legend.titlesize(lot.mir, wfr, title_fontsize, testset)
    #             print "U:imageWith = {}, fontsize = {}, maxfw={}, height={}".format(actualWidth, title_fontsize, titlekeys['maxfw'], titlekeys['maxfh'])    
    
        # If we were decreasing font size when the while condition became false, all the titlekeys are properly set, 
        # from the last loop cycle.... but if we were increasing font size, the last loop cycle left the titlekeys 
        # in a state for a larger font, so decrease the font size by one and re-evaluate the titlekeys
        if(upsearch):
            title_fontsize -=1
            titlekeys = wfr.legend.titlesize(lot.mir, wfr, title_fontsize, testset)
    
        titleheight = titlekeys['maxfh']
        actualHeight += titleheight
        log.debug('Title Height = {}, Title Fontsize = {}'.format(titleheight, title_fontsize))

    #--------------------------------------------------------------------------
    # Adjust Width and Height for axis space
    #--------------------------------------------------------------------------
    if(App.cfg['axis']['show']):
        actualWidth += axis_space
        actualHeight += axis_space
        
    log.debug('Actual Image Size (X,Y) = ({},{})'.format(actualWidth, actualHeight))
 
    log.debug('Padding = {}'.format(padding))
                        
    #--------------------------------------------------------------------------
    # Create the canvas and draw the wafermap
    #--------------------------------------------------------------------------
    img = Image.new('RGB', (actualWidth,actualHeight), App.cfg['image']['bgcolor'])

    # Get the drawable object...
    dr = ImageDraw.Draw(img)
    
    # map_extents are used for tracking the actual pixel extents of the drawn map which makes
    # calculating the location to draw the flat & axis labels a bit easier...
    
    map_extents = {'minx':65535, 'miny':65535, 'maxx':0, 'maxy':0}
    
    # limit flag_size factor to a minimum of 1.0 (or else flag will exceed die boundary)
    App.cfg['flag']['size_factor'] = max(App.cfg['flag']['size_factor'], 1.0)
    
    # if we want the grid, draw it first so it's behind everything else...
    if App.cfg['axis']['grid']:   
        _do_grid(wfr.dielist, img, X_pixels, Y_pixels, padding, axis_space, slackX, slackY, titleheight)
    idx=0
    
    imap = []
    
    for eachDie in wfr.dielist:
        mybin=getattr(eachDie,App.cfg['binmap'])
        idx+=1      
        x1 = padding + axis_space + ((eachDie.X - min_X) * X_pixels) + slackX
        y1 = padding + axis_space + ((eachDie.Y - min_Y) * Y_pixels) + slackY + titleheight
        x2 = x1 + X_pixels
        y2 = y1 + Y_pixels
        
        # Draw the die and file with bincolor
        if eachDie.testset == testset:
            dr.rectangle([x1,y1,x2,y2], fill=App.cfg['bin'][str(mybin)]['color'], outline=(0,0,0))
            imap.append({'Row':eachDie.Y,'Col':eachDie.X,'x':x1,'y':y1,'width':x2-x1,'height':y2-y1})
            # Draw any specified symbols, if enabled 
            if App.cfg['enable_symbols']:
                do_symbol(dr,x1,y1,x2,y2, False, **App.cfg['bin'][str(mybin)])
        
        # Draw flags if appropriate        
        xystr="{}|{}".format(eachDie.X, eachDie.Y)   # Bindict Key 
        if (wfr.diedict[xystr]['flags'] & constants.FLAG_MULTITEST) and App.cfg['flag']['show']:
            if wfr.diedict[xystr]['flags'] & constants.FLAG_DUPLICATE_BIN:
                flagcolor= App.cfg['flag']['duplicate_color']
            else:
                flagcolor= App.cfg['flag']['split_color'] 
            flagX = int(float(x2-x1)/float(App.cfg['flag']['size_factor']))
            flagY = int(float(y2-y1)/float(App.cfg['flag']['size_factor'])) 
            dr.polygon([(x1,y1+flagY),(x1,y1),(x1+flagX,y1)], fill=flagcolor, outline=(0,0,0))  
   
    
        # track minimum and maximums of actual drawn wafermap.
        map_extents['minx']= min(map_extents['minx'],x1)
        map_extents['maxx']= max(map_extents['maxx'],x2)
        map_extents['miny']= min(map_extents['miny'],y1)
        map_extents['maxy']= max(map_extents['maxy'],y2)
       
    log.debug('Drawn Map Extents = {}'.format(map_extents))

#     do_html(imap, actualWidth, actualHeight)
        
    #--------------------------------------------------------------------------
    # Draw title area
    #--------------------------------------------------------------------------
    if App.cfg['title']['show']:
        dr.rectangle([0,0,actualWidth,titleheight], fill=App.cfg['title']['bgcolor'], outline=(0,0,0))
        wfr.legend.render_title(img, wfr, titlekeys)
    
    #--------------------------------------------------------------------------
    # Draw legend, border, flat indicator, timestamp, axis labels
    #--------------------------------------------------------------------------
    if App.cfg['legend']['show']:
        wfr.legend.render(App.cfg['image']['basewidth'] + axis_space , padding + titleheight, img)
    
    if App.cfg['image']['border']:
        dr.rectangle([0,0,actualWidth-1,actualHeight-1], fill=None, outline=(0,0,0))
    
    if App.cfg['image']['flatline']:
        wfr.legend.render_flat(img, lot.wcr['WF_FLAT'], map_extents, (127,0,0))
#        wfr.legend.render_flat(img, 'L', map_extents, (127,0,0))
    
    if App.cfg['image']['timestamp']:
        wfr.legend.timestamp(img, color=(0,0,127)) 

    if App.cfg['axis']['show']:
        _do_axis(wfr.dielist, X_pixels, Y_pixels, map_extents, img, True)
        
# # Add some debug entries to the configuration for examination during a dump
# # (-z command option) 
#     App.cfg['debug']={}
#     
#     App.cfg['debug']['Map'] = {'mapX':mapX, 'mapY':mapY, 'X_pixels':X_pixels, 'Y_pixels':Y_pixels,
#                            'Actual Width':actualWidth, 'Actual Height':actualHeight,
#                            'Title Height':titleheight, 'Axis Space':axis_space,
#                            'Slack X':slackX, 'Slack Y':slackY,
#                            'Drawn Map Extents':map_extents}  
# 
# #   print "Map X,Y............... {},{}".format(mapX,mapY)
# #   print "Die Pixels X,Y........ {},{}".format(X_pixels,Y_pixels)
# #   print "Actual Image Size..... {},{}".format(actualWidth,actualHeight)
# #   print "Title Height.......... {}".format(titleheight)
# #   print "Axis Space............ {}".format(axis_space) 
# #   print "Padding............... {}".format(padding) 
# #   print "Drawn Map Extents..... {}".format(map_extents) 
   
    return(img)
Ejemplo n.º 26
0
    def legend(self, handles, labels, *args, **kwargs):
        """
        Place a legend in the figure.  Labels are a sequence of
        strings, handles is a sequence of
        :class:`~matplotlib.lines.Line2D` or
        :class:`~matplotlib.patches.Patch` instances, and loc can be a
        string or an integer specifying the legend location

        USAGE::

          legend( (line1, line2, line3),
                  ('label1', 'label2', 'label3'),
                  'upper right')

        The *loc* location codes are::

          'best' : 0,          (currently not supported for figure legends)
          'upper right'  : 1,
          'upper left'   : 2,
          'lower left'   : 3,
          'lower right'  : 4,
          'right'        : 5,
          'center left'  : 6,
          'center right' : 7,
          'lower center' : 8,
          'upper center' : 9,
          'center'       : 10,

        *loc* can also be an (x,y) tuple in figure coords, which
        specifies the lower left of the legend box.  figure coords are
        (0,0) is the left, bottom of the figure and 1,1 is the right,
        top.

        Keyword arguments:

          *prop*: [ None | FontProperties | dict ]
            A :class:`matplotlib.font_manager.FontProperties`
            instance. If *prop* is a dictionary, a new instance will be
            created with *prop*. If *None*, use rc settings.

          *numpoints*: integer
            The number of points in the legend line, default is 4

          *scatterpoints*: integer
            The number of points in the legend line, default is 4

          *scatteroffsets*: list of floats
            a list of yoffsets for scatter symbols in legend

          *markerscale*: [ None | scalar ]
            The relative size of legend markers vs. original. If *None*, use rc
            settings.

          *fancybox*: [ None | False | True ]
            if True, draw a frame with a round fancybox.  If None, use rc

          *shadow*: [ None | False | True ]
            If *True*, draw a shadow behind legend. If *None*, use rc settings.

          *ncol* : integer
            number of columns. default is 1

          *mode* : [ "expand" | None ]
            if mode is "expand", the legend will be horizontally expanded
            to fill the axes area (or *bbox_to_anchor*)

          *title* : string
            the legend title

        Padding and spacing between various elements use following keywords
        parameters. The dimensions of these values are given as a fraction
        of the fontsize. Values from rcParams will be used if None.

        ================   ==================================================================
        Keyword            Description
        ================   ==================================================================
        borderpad          the fractional whitespace inside the legend border
        labelspacing       the vertical space between the legend entries
        handlelength       the length of the legend handles
        handletextpad      the pad between the legend handle and text
        borderaxespad      the pad between the axes and legend border
        columnspacing      the spacing between columns
        ================   ==================================================================

        .. Note:: Not all kinds of artist are supported by the legend.
                  See LINK (FIXME) for details.

        **Example:**

        .. plot:: mpl_examples/pylab_examples/figlegend_demo.py
        """
        handles = flatten(handles)
        l = Legend(self, handles, labels, *args, **kwargs)
        self.legends.append(l)
        return l
Ejemplo n.º 27
0
		#end for a
		sct.append(sc)

		ax[i].set_ylim([0, 50])
		ax[i].set_ylabel('Variation of MAF(%)')
		ax[i].set_title(ylabel[i], loc='left', fontdict={'fontsize':13, 'verticalalignment':'top', 'color':'black', 'backgroundcolor':'#FEFEFE'})

	# ZoomSlider of Dumas position
	zaxes = plt.axes([0.08, 0.07, 0.90, 0.03], facecolor='lightgoldenrodyellow')
	zslider = ZoomSlider(zaxes, 'Dumas Position', valmin=B.minpos, valmax=B.maxpos, valleft=B.minpos, valright=B.maxpos, color='lightblue', valstep=1.0)
	zslider.on_changed(update_xlim)


	from legend import Legend
	spatches = [ mpatches.Patch(color=colors[idx], label=basepair[idx]) for idx in range(4) ]
	leg_basepair = Legend(fig, { 'spatches' : spatches, 'label' : basepair, 'bbox':(0.66, .91, 0.33, .102), 'loc' : 3,
				'ncol' : 4, 'mode' : 'expand', 'borderaxespad' : 0.})

	dumalabels = [ key for key in dumas.keys()]
	spatches = [ mpatches.Patch(color='grey', label=dumalabels[idx]) for idx in range(3) ]
	leg_dumas = Legend(fig, { 'spatches' : spatches, 'label' : dumalabels, 'bbox':(0.05, .91, 0.33, .102), 'loc' : 3,
				'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

	spatches = [ mpatches.Patch(color=['black', 'magenta'][idx], label=['base', 'variation'][idx]) for idx in range(2) ]
	leg_filter = Legend(fig, { 'spatches' : spatches, 'label' : ['base_0.0', 'variation_5.0'], 'bbox':(0.40, .91, 0.24, .102), 'loc' : 3,
				'ncol' : 3, 'mode' : 'expand', 'borderaxespad' : 0.})	

	for x in ax:
		annot.append(x.annotate("", xy=(0,0), xytext=(20,-30),textcoords="offset points",
                    bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")))
		# annotate over other axes
		x.figure.texts.append(x.texts.pop())
Ejemplo n.º 28
0
def legend(*args, **kwargs):
    return Legend(*args, **kwargs)
Ejemplo n.º 29
0
 def _do_layout(self):
     Legend._do_layout(self)
     self._compute_label_dims()
Ejemplo n.º 30
0
import json
from legend import Legend
import logging

with open("config/config.json") as f:
    config = json.load(f)

logging.basicConfig(level=logging.CRITICAL)

legend = Legend(config)
Ejemplo n.º 31
0
 def _do_layout(self):
     Legend._do_layout(self)
     self._compute_label_dims()