示例#1
0
def quiver2img(qv):
    fig = Figure(dpi=200)
    canvas = FigureCanvas(fig)
    ax = fig.subplots()
    colors = np.sqrt(qv[2] * qv[2] + qv[3] * qv[3])
    v_length = colors.copy()
    norm.autoscale(colors)
    ax.quiver(qv[0],
              qv[1],
              qv[2] / v_length,
              qv[3] / v_length,
              color=plotcm(norm(colors)),
              angles='xy',
              scale_units='xy',
              scale=1,
              headlength=1.2,
              headaxislength=1.08,
              pivot='mid')
    ax.set_ylim(0, 45)
    ax.set_xlim(0, 80)
    ax.set_aspect('equal')

    canvas.draw()
    im = np.array(fig.canvas.renderer.buffer_rgba())
    im = cv2.cvtColor(im, cv2.COLOR_RGBA2BGR)
    h, w, c = im.shape
    im = cv2.resize(im, (640, int(640 * (h / w))))

    return im
def drop_shadow(Z, l0, l1, sigma=5, alpha=0.5):
    """Compute the drop shadow for a contour between l0 and l1.

    This works by first:
    1. render the contour in black using an offline image
    2. blue the contour using a Guassian filter
    3. set the alpha channel accordingly
    """
    fig = Figure(figsize=(5, 5))
    canvas = FigureCanvas(fig)
    ax = fig.add_axes([0, 0, 1, 1], frameon=False)
    ax.contourf(
        Z,
        vmin=Z.min(),
        vmax=Z.max(),
        levels=[l0, l1],
        origin="lower",
        colors="black",
        extent=[-1, 1, -1, 1],
    )
    ax.set_xlim(-1, 1), ax.set_ylim(-1, 1)
    canvas.draw()
    A = np.array(canvas.renderer.buffer_rgba())[:, :, 0]
    del fig
    A = gaussian_filter(A, sigma)
    A = (A - A.min()) / (A.max() - A.min())
    I = np.zeros((A.shape[0], A.shape[1], 4))
    I[:, :, 3] = (1 - A) * alpha
    return I
def plot(extent):
    """ Offline rendering """

    xmin, xmax, ymin, ymax = extent
    fig = Figure(figsize=(2, 2))
    canvas = FigureCanvas(fig)
    ax = fig.add_axes(
        [0, 0, 1, 1],
        frameon=False,
        xlim=[xmin, xmax],
        xticks=[],
        ylim=[ymin, ymax],
        yticks=[],
    )
    epsilon = 0.1
    I = np.argwhere((X >= (xmin - epsilon))
                    & (X <= (xmax + epsilon))
                    & (Y >= (ymin - epsilon))
                    & (Y <= (ymax + epsilon)))
    ax.scatter(X[I],
               Y[I],
               3,
               clip_on=False,
               color="black",
               edgecolor="None",
               alpha=0.0025)
    canvas.draw()
    return np.array(canvas.renderer.buffer_rgba())
示例#4
0
def image_histogram(image):
    plt.style.use('ggplot')

    fig = Figure()
    canvas = FigureCanvas(fig)
    ax = fig.subplots()
    ax.margins(x=0)

    if len(image.shape) == 3:
        ax.hist(image[:,:,0].flatten(), np.arange(256), color='blue', label='blue', histtype='step', linewidth=1)
        ax.hist(image[:, :, 1].flatten(), np.arange(256), color='green', label='green', histtype='step', linewidth=1)
        ax.hist(image[:, :, 2].flatten(), np.arange(256), color='red', label='red', histtype='step', linewidth=1)
        ax.set_xlabel('Intensity')
        ax.set_ylabel('Count')
        ax.set_xticks([0,51,51*2,51*3,51*4, 51*5])
        canvas.draw()
        histogram_image = np.array(canvas.renderer.buffer_rgba())

    else:
        ax.hist(image.flatten(), np.arange(256), histtype='step', linewidth=1, color='black')
        ax.set_xlabel('Intensity')
        ax.set_ylabel('Count')
        ax.set_xticks([0,51,51*2,51*3,51*4, 51*5])
        canvas.draw()
        histogram_image = np.array(canvas.renderer.buffer_rgba())



    return histogram_image
示例#5
0
def visualize_multiple_explanations(explanations, title):
    '''
    Create a single figure containing bar charts of a list of explanations.
    :param explanations: List of Explanation objects
    :param title: Plot title
    :param file_path: The path (including file name) where to save the resulting image
    '''

    # Create a figure for each explanation and get its image buffer
    n_exps = len(explanations)
    fig_imgs = []
    for i in range(n_exps):
        exp_fig_canvas = FigureCanvas(explanations[i].as_pyplot_figure())
        exp_fig_canvas.draw()   # Force a draw to get access to pixel buffer
        fig_imgs.append(np.array(exp_fig_canvas.renderer.buffer_rgba()))

    # Plot all explanation graphs on the same figure
    plt.clf()
    n_cols = ceil(sqrt(n_exps))
    n_rows = floor(sqrt(n_exps))
    fig, axes = plt.subplots(ncols=n_cols, nrows=n_rows)
    fig.set_size_inches(60, 35)
    for i in range(n_rows * n_cols):
        if i < n_exps:
            axes.ravel()[i].imshow(fig_imgs[i])     # Display explanation image on axes
        axes.ravel()[i].set_axis_off()              # Don't show x-axis and y-axis
    fig.tight_layout(pad=0.01, h_pad=0.01, w_pad=0.01)
    plt.subplots_adjust(left=0, right=1, top=0.95, bottom=0)
    fig.suptitle(title, size=60)
    return fig
示例#6
0
文件: utils.py 项目: lab1055/easy-rfp
def save_and_log_seg_results(img, outputs, img_name, img_save_dir, results_save_dir, log_filename, socketio):
    output_mask = outputs.permute(1,2,0)
    # save input image to images/
    cv2.imwrite(os.path.join(img_save_dir, img_name), img)
    
    # save output mask to results/
#     cv2.imwrite(os.path.join(results_save_dir, img_name), np.array(output_mask, dtype=np.float32))
    
    # save segmentation overlay + mask (side by side) to results/ 
    img_with_mask_fig = overlay_mask(img, output_mask)
    canvas = FigureCanvas(img_with_mask_fig)
    canvas.draw()
    img_with_mask = np.array(canvas.renderer.buffer_rgba())
#     output_img_loc = os.path.join(results_save_dir, f"{img_name.split('.')[0]}_mask_overlay.{img_name.split('.')[1]}")
    output_img_loc = os.path.join(results_save_dir, img_name)
    cv2.imwrite(output_img_loc, img_with_mask)
    
    return log_seg_results(output_mask, output_img_loc, log_filename, socketio)
示例#7
0
def visualize_planning_result(filename: str, obstacle_idx: int,
                              states: np.ndarray, goal: np.ndarray):
    obs_center = load_obstacles(obstacle_idx)
    obstacles = [Rectangle((xy[0] - 4, xy[1] - 4), 8, 8) for xy in obs_center]
    obstacles = PatchCollection(obstacles, facecolor="gray", edgecolor="black")

    car = PatchCollection(
        [Rectangle((-1, -0.5), 2, 1),
         Arrow(0, 0, 2, 0, width=1.0)],
        facecolor="blue",
        edgecolor="blue")

    fig = Figure()
    canvas = FigureCanvas(fig)
    ax = fig.subplots()
    ax.set_aspect('equal', 'box')
    ax.set_xlim([-25, 25])
    ax.set_ylim([-35, 35])

    canvas.draw()
    image = np.array(canvas.buffer_rgba())
    H, W, _ = image.shape
    writer = cv2.VideoWriter(filename, cv2.VideoWriter_fourcc(*'mp4v'), 30.,
                             (W, H), True)

    T = states.shape[0]
    for t in range(T):
        # obstacles
        ax.add_collection(obstacles)
        # target
        ax.scatter(goal[0], goal[1], marker='*', c="red")
        # current position
        transform = Affine2D().rotate(states[t, 2]).translate(
            states[t, 0], states[t, 1])
        car.set_transform(transform + ax.transData)
        ax.add_collection(car)
        # plot
        canvas.draw()
        image = np.array(canvas.buffer_rgba())[:, :, :3]
        writer.write(image)
        ax.clear()

    writer.release()
    h264_converter(filename)
示例#8
0
def mnist_latent(encoder, test, device):
    """test is the test dataloader"""

    a, b = zip(*[i for i in test])
    data = encoder(torch.cat(a, dim=0).to(device)).detach().cpu()
    label = torch.cat(b)

    fig, ax = plt.subplots(figsize=[8, 8], dpi=72)

    for i, c in enumerate(kelly_colors[2:12]):
        idx = label == i
        ax.plot(data[idx, 0], data[idx, 1], "o", c=c, label=str(i))
        ax.set_xlim([-5, 5])
        ax.set_ylim([-5, 5])
        ax.legend(loc=1)

    plt.tight_layout()
    plt.close(fig)
    canvas = FigureCanvas(fig)
    canvas.draw()
    img = np.array(canvas.renderer.buffer_rgba())
    return torch.tensor(img[..., :3]).permute(2, 0, 1)
示例#9
0
    def activation_clip(self, input, filename='outpy.avi'):
        print('Saving clip...')
        out = cv2.VideoWriter(filename,
                              cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), 2,
                              (1920, 1080))
        for i in range(input.shape[0]):
            pH_V, hidden = self.sample_hidden_given_visible(input[i, :])
            pV_H, visible = self.sample_visible_given_hidden(hidden)
            frame = numpy.ones((1080, 1920, 3), dtype='float32')
            fig = plt.figure(figsize=(14, 14), dpi=100)
            canvas = FigureCanvas(fig)
            for j in range(hidden.size):
                lin = numpy.sqrt(hidden.size)
                fig.add_subplot(numpy.floor(lin), numpy.ceil(lin), j + 1)
                plt.axis('off')
                if hidden[j]:
                    plt.imshow(self.W[:, j].reshape((28, 28)), cmap="hot")
                else:
                    plt.imshow(self.W[:, j].reshape((28, 28)), cmap="gray")
            canvas.draw()
            w_image = numpy.array(canvas.renderer.buffer_rgba())
            w_image = cv2.cvtColor(w_image, cv2.COLOR_RGBA2BGR)
            w_image = cv2.resize(w_image, (1080, 1080),
                                 interpolation=cv2.INTER_NEAREST)
            source = cv2.resize(numpy.ceil(input[i, :].reshape(
                (28, 28)) * 255), (420, 420),
                                interpolation=cv2.INTER_NEAREST)
            visible = visible.astype('float32')
            dest = cv2.resize(numpy.ceil(pV_H.reshape((28, 28)) * 255),
                              (420, 420),
                              interpolation=cv2.INTER_NEAREST)
            frame[:, 420:1500, :] = w_image[:, :, :3].astype('float32')
            plt.close('all')
            for i in range(3):
                frame[330:330 + 420, 0:420, i] = source
                frame[330:330 + 420, 1500:1920, i] = dest

            out.write(frame.astype('uint8'))
        out.release()
示例#10
0
def umap(data,
         group2cellname,
         leiden_dict,
         coord_tuple,
         clusters,
         leiden,
         expr_path,
         output_dir,
         figure_pix_size=200):
    my_dpi = 100

    fig = plt.figure(figsize=(figure_pix_size / my_dpi,
                              figure_pix_size / my_dpi),
                     dpi=my_dpi)
    canvas = FigureCanvas(fig)
    ax = plt.Axes(fig, [0., 0., 1., 1.])
    ax.set_axis_off()
    fig.add_axes(ax)

    #Plot clustering
    color_map = dict(
        zip(range(len(clusters)), data.uns[str(leiden) + '_colors']))
    im = plt.scatter([x[0] for x in coord_tuple], [x[1] for x in coord_tuple],
                     c='white',
                     s=0.1)
    for i in np.unique(clusters):
        selected = [k for k, v in leiden_dict.items() if v == i]
        im = plt.scatter([x[0] for x in selected], [x[1] for x in selected],
                         c=color_map[int(i)],
                         s=1,
                         marker='s')  #s=0.1)
    fig.savefig(os.path.join(output_dir, "umap.png"), dpi=my_dpi)

    # Force a draw so we can grab the pixel buffer
    canvas.draw()
    # grab the pixel buffer and dump it into a numpy array
    X = np.array(canvas.renderer.buffer_rgba())
    return img2info(X, color_map, group2cellname, expr_path, output_dir)
示例#11
0
    def renderHelper(self, done=False, showGenerators=False):

        fig = Figure()
        canvas = FigureCanvas(fig)
        ax = fig.subplots()
        ax.imshow(self.infoMap,
                  cmap="viridis",
                  interpolation="none",
                  alpha=0.8)
        ax.imshow(self.renderMap, cmap="RdGy", interpolation="none", alpha=0.8)
        fig.suptitle("Threshold: {}".format(self.COLL_THRESH))
        # plt.show()
        # time.sleep(0.2)
        # plt.clf()
        # Force a draw so we can grab the pixel buffer
        canvas.draw()
        # grab the pixel buffer and dump it into a numpy array
        X = np.array(canvas.renderer.buffer_rgba())
        # self.plot2D(X)
        # time.sleep(0.2)
        # plt.clf()
        # figs.append(X)
        return X
示例#12
0
 def mask(self, byclass, height, width, margin=0, figsize=(10, 10), dpi=180):
     """Create a mask to find the boundary of the sample"""
     # make ~binary mask using available classes
     style = {cls: ('k', '-') for cls in byclass}
     fig = Figure(figsize=figsize)
     fig.tight_layout(pad=0)
     fig.subplots_adjust(hspace=0, wspace=0, left=0, right=1, bottom=0, top=1)
     canvas = FigureCanvas(fig)
     ax = fig.subplots(1, 1)
     self.show_style(ax, style, byclass)
     ax.set_xlim(0 - margin, height + margin)
     ax.set_ylim(0 - margin, width  + margin)
     canvas.draw()
     mask = self.figure_buffer(fig, dpi=dpi)
     mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
     # fill in the gaps via:
     # https://www.learnopencv.com/filling-holes-in-an-image-using-opencv-python-c/
     _, thresholded = cv2.threshold(mask, 220, 255, cv2.THRESH_BINARY_INV);
     floodfilled = thresholded.copy()
     h, w = thresholded.shape[:2]
     mask = np.zeros((h + 2, w + 2), np.uint8)
     cv2.floodFill(floodfilled, mask, (0, 0), 255);
     mask = cv2.bitwise_not(thresholded | cv2.bitwise_not(floodfilled))
     return mask
示例#13
0
class NSGAIIpanel(wx.Panel):
    def __init__(self, parent, Population):
        wx.Panel.__init__(self, parent)

        self.NSGAIIpopulation = Population
        self.plotoptions = NSGAIIPlotOptions()
        self.Xobjective = 0
        self.Yobjective = 1
        self.Zobjective = 2
        self.Cobjective = 3
        self.Sobjective = 4
        self.filter = []

        self.plotoptions.LowerBounds = numpy.zeros(5)
        self.plotoptions.UpperBounds = 1.0e+50 * numpy.ones(5)

        #first we want an array of [Objective # label, combobox to select objective, lowerbound for objective display, upperbound for objective display]
        #we want one of these rows for every objective in the population file
        #each combobox after the second should have an option for "do not display"
        #put the array of objective selectors in a frame
        self.AxisOptionsBox = wx.StaticBox(self, -1, "Axis options")
        font = self.GetFont()
        font.SetWeight(wx.FONTWEIGHT_BOLD)
        self.AxisOptionsBox.SetFont(font)
        AxisOptionsBoxSizer = wx.StaticBoxSizer(self.AxisOptionsBox,
                                                wx.VERTICAL)

        self.objective_selectors = []
        self.objective_upperbound_fields = []
        self.objective_lowerbound_fields = []
        self.objective_row_sizers = []

        #x axis
        xaxislabel = wx.StaticText(self, -1, "X axis", size=(100, -1))
        self.objective_selectors.append(
            wx.ComboBox(self,
                        -1,
                        choices=self.NSGAIIpopulation.objective_column_headers,
                        style=wx.CB_READONLY,
                        size=(200, -1)))
        self.objective_selectors[-1].SetSelection(self.Xobjective)
        self.objective_lowerbound_fields.append(wx.TextCtrl(
            self, -1, str(0.0)))
        self.objective_upperbound_fields.append(
            wx.TextCtrl(self, -1, str(1.0e+50)))
        self.objective_selectors[-1].Bind(wx.EVT_COMBOBOX,
                                          self.ChangeXObjective)
        self.objective_lowerbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                  self.ChangeXLowerBound)
        self.objective_upperbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                  self.ChangeXUpperBound)
        XaxisSizer = wx.BoxSizer(wx.HORIZONTAL)
        XaxisSizer.AddMany([
            xaxislabel, self.objective_selectors[-1],
            self.objective_lowerbound_fields[-1],
            self.objective_upperbound_fields[-1]
        ])
        AxisOptionsBoxSizer.Add(XaxisSizer)

        #y axis
        yaxislabel = wx.StaticText(self, -1, "Y axis", size=(100, -1))
        self.objective_selectors.append(
            wx.ComboBox(self,
                        -1,
                        choices=self.NSGAIIpopulation.objective_column_headers,
                        style=wx.CB_READONLY,
                        size=(200, -1)))
        self.objective_selectors[-1].SetSelection(self.Yobjective)
        self.objective_lowerbound_fields.append(wx.TextCtrl(
            self, -1, str(0.0)))
        self.objective_upperbound_fields.append(
            wx.TextCtrl(self, -1, str(1.0e+50)))
        self.objective_selectors[-1].Bind(wx.EVT_COMBOBOX,
                                          self.ChangeYObjective)
        self.objective_lowerbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                  self.ChangeYLowerBound)
        self.objective_upperbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                  self.ChangeYUpperBound)
        YaxisSizer = wx.BoxSizer(wx.HORIZONTAL)
        YaxisSizer.AddMany([
            yaxislabel, self.objective_selectors[-1],
            self.objective_lowerbound_fields[-1],
            self.objective_upperbound_fields[-1]
        ])
        AxisOptionsBoxSizer.Add(YaxisSizer)

        #z axis
        if len(self.NSGAIIpopulation.objective_column_headers) > 2:
            zaxislabel = wx.StaticText(self, -1, "Z axis", size=(100, -1))
            zaxischoices = copy.deepcopy(
                self.NSGAIIpopulation.objective_column_headers)
            zaxischoices.append('do not display')
            self.objective_selectors.append(
                wx.ComboBox(self,
                            -1,
                            choices=zaxischoices,
                            style=wx.CB_READONLY,
                            size=(200, -1)))
            self.objective_selectors[-1].SetSelection(self.Zobjective)
            self.objective_lowerbound_fields.append(
                wx.TextCtrl(self, -1, str(0.0)))
            self.objective_upperbound_fields.append(
                wx.TextCtrl(self, -1, str(1.0e+50)))
            self.objective_selectors[-1].Bind(wx.EVT_COMBOBOX,
                                              self.ChangeZObjective)
            self.objective_lowerbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeZLowerBound)
            self.objective_upperbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeZUpperBound)
            ZaxisSizer = wx.BoxSizer(wx.HORIZONTAL)
            ZaxisSizer.AddMany([
                zaxislabel, self.objective_selectors[-1],
                self.objective_lowerbound_fields[-1],
                self.objective_upperbound_fields[-1]
            ])
            AxisOptionsBoxSizer.Add(ZaxisSizer)

        #color axis
        if len(self.NSGAIIpopulation.objective_column_headers) > 3:
            caxislabel = wx.StaticText(self, -1, "Color axis", size=(100, -1))
            caxischoices = copy.deepcopy(
                self.NSGAIIpopulation.objective_column_headers)
            caxischoices.append('do not display')
            self.objective_selectors.append(
                wx.ComboBox(self,
                            -1,
                            choices=caxischoices,
                            style=wx.CB_READONLY,
                            size=(200, -1)))
            self.objective_selectors[-1].SetSelection(self.Cobjective)
            self.objective_lowerbound_fields.append(
                wx.TextCtrl(self, -1, str(0.0)))
            self.objective_upperbound_fields.append(
                wx.TextCtrl(self, -1, str(1.0e+50)))
            self.objective_selectors[-1].Bind(wx.EVT_COMBOBOX,
                                              self.ChangeCObjective)
            self.objective_lowerbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeCLowerBound)
            self.objective_upperbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeCUpperBound)
            CaxisSizer = wx.BoxSizer(wx.HORIZONTAL)
            CaxisSizer.AddMany([
                caxislabel, self.objective_selectors[-1],
                self.objective_lowerbound_fields[-1],
                self.objective_upperbound_fields[-1]
            ])
            AxisOptionsBoxSizer.Add(CaxisSizer)

        #size axis
        if len(self.NSGAIIpopulation.objective_column_headers) > 4:
            saxislabel = wx.StaticText(self, -1, "Size axis", size=(100, -1))
            saxischoices = copy.deepcopy(
                self.NSGAIIpopulation.objective_column_headers)
            saxischoices.append('do not display')
            self.objective_selectors.append(
                wx.ComboBox(self,
                            -1,
                            choices=saxischoices,
                            style=wx.CB_READONLY,
                            size=(200, -1)))
            self.objective_selectors[-1].SetSelection(self.Sobjective)
            self.objective_lowerbound_fields.append(
                wx.TextCtrl(self, -1, str(0.0)))
            self.objective_upperbound_fields.append(
                wx.TextCtrl(self, -1, str(1.0e+50)))
            self.objective_selectors[-1].Bind(wx.EVT_COMBOBOX,
                                              self.ChangeSObjective)
            self.objective_lowerbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeSLowerBound)
            self.objective_upperbound_fields[-1].Bind(wx.EVT_KILL_FOCUS,
                                                      self.ChangeSUpperBound)
            SaxisSizer = wx.BoxSizer(wx.HORIZONTAL)
            SaxisSizer.AddMany([
                saxislabel, self.objective_selectors[-1],
                self.objective_lowerbound_fields[-1],
                self.objective_upperbound_fields[-1]
            ])
            AxisOptionsBoxSizer.Add(SaxisSizer)

        #next we want checkboxes for any other plot options
        self.lblTimeUnit = wx.StaticText(self,
                                         -1,
                                         "Display time unit",
                                         size=(200, -1))
        TimeUnitChoices = ['years', 'days']
        self.cmbTimeUnit = wx.ComboBox(self,
                                       -1,
                                       choices=TimeUnitChoices,
                                       style=wx.CB_READONLY)
        self.cmbTimeUnit.SetSelection(self.plotoptions.TimeUnit)
        self.cmbTimeUnit.Bind(wx.EVT_COMBOBOX, self.ChangeTimeUnit)
        TimeUnitSizer = wx.BoxSizer(wx.HORIZONTAL)
        TimeUnitSizer.AddMany([self.lblTimeUnit, self.cmbTimeUnit])

        self.lblEpochUnit = wx.StaticText(self,
                                          -1,
                                          "Display epoch unit",
                                          size=(200, -1))
        EpochUnitChoices = ['TDB Gregorian', 'TDB MJD']
        self.cmbEpochUnit = wx.ComboBox(self,
                                        -1,
                                        choices=EpochUnitChoices,
                                        style=wx.CB_READONLY)
        self.cmbEpochUnit.SetSelection(self.plotoptions.EpochUnit)
        self.cmbEpochUnit.Bind(wx.EVT_COMBOBOX, self.ChangeEpochUnit)
        EpochUnitSizer = wx.BoxSizer(wx.HORIZONTAL)
        EpochUnitSizer.AddMany([self.lblEpochUnit, self.cmbEpochUnit])

        #marker size control
        self.lblMarkerSize = wx.StaticText(self, -1, "Base marker size")
        self.spnctrlMarkerSizeControl = wx.SpinCtrl(self,
                                                    -1,
                                                    min=1,
                                                    max=10000000,
                                                    initial=20,
                                                    name="Marker size")
        self.spnctrlMarkerSizeControl.Bind(wx.EVT_SPINCTRL,
                                           self.ChangeMarkerSize)

        #font size control
        self.lblFontSize = wx.StaticText(self, -1, "Font size")
        self.spnctrlFontSizeControl = wx.SpinCtrl(self,
                                                  -1,
                                                  min=1,
                                                  max=100,
                                                  initial=10,
                                                  name="Font size")
        self.spnctrlFontSizeControl.Bind(wx.EVT_SPINCTRL, self.ChangeFontSize)

        FormatBoxSizer = wx.FlexGridSizer(2, 2, 5, 5)
        FormatBoxSizer.AddMany([
            self.lblMarkerSize, self.spnctrlMarkerSizeControl,
            self.lblFontSize, self.spnctrlFontSizeControl
        ])

        self.PlotOptionsBox = wx.StaticBox(self,
                                           -1,
                                           "Plot Options",
                                           size=(300, 300))
        font = self.GetFont()
        font.SetWeight(wx.FONTWEIGHT_BOLD)
        self.PlotOptionsBox.SetFont(font)
        PlotOptionsSizer = wx.StaticBoxSizer(self.PlotOptionsBox, wx.VERTICAL)
        PlotOptionsSizer.AddMany(
            [TimeUnitSizer, EpochUnitSizer, FormatBoxSizer])

        #button to make the plot
        self.btnPlotPopulation = wx.Button(self, -1, "Plot Population")
        self.btnPlotPopulation.Bind(wx.EVT_BUTTON, self.ClickPlotPopulation)

        #output window
        self.lblOutputTextWindow = wx.StaticText(self, -1, "Output window")
        self.lblOutputTextWindow.SetFont(font)
        self.txtOutputTextWindow = wx.TextCtrl(self,
                                               -1,
                                               size=(800, 200),
                                               style=wx.TE_MULTILINE)
        self.btnClearOutputTextWindow = wx.Button(self, -1, "Clear output")
        self.btnClearOutputTextWindow.Bind(wx.EVT_BUTTON,
                                           self.ClickClearOutputTextWindow)

        #filter panel
        ObjectFilterBox = wx.StaticBox(self, -1, "NSGAII object filter")
        ObjectFilterBox.SetFont(font)
        ObjectFilterBoxSizer = wx.StaticBoxSizer(ObjectFilterBox, wx.VERTICAL)

        self.lblObjectFilterFile = wx.StaticText(self, -1,
                                                 "NSGAII object filter file")
        self.txtObjectFilterFile = wx.TextCtrl(self,
                                               -1,
                                               "ObjectFilterFile",
                                               size=(600, -1))
        self.btnObjectFilterFile = wx.Button(self, -1, "...")
        ObjectFilterFileSizer = wx.BoxSizer(wx.HORIZONTAL)
        ObjectFilterFileSizer.AddMany([
            self.lblObjectFilterFile, self.txtObjectFilterFile,
            self.btnObjectFilterFile
        ])

        self.txtObjectFilterFile.Bind(wx.EVT_KILL_FOCUS,
                                      self.ChangeObjectFilterFile)
        self.btnObjectFilterFile.Bind(wx.EVT_BUTTON,
                                      self.ClickObjectFilterFileButton)

        self.lbxObjectFilterList = wx.ListBox(self,
                                              -1,
                                              size=(600, 200),
                                              style=wx.LB_EXTENDED)
        #self.lbxObjectFilterList.Bind(wx.EVT_LISTBOX, self.ChangeFilterListSelections)

        ObjectFilterBoxSizer.AddMany(
            [ObjectFilterFileSizer, self.lbxObjectFilterList])

        #plot panel
        self.PopulationFigure = Figure(facecolor='white', figsize=(10, 10))

        self.PlotCanvas = FigureCanvas(self, -1, self.PopulationFigure)

        if len(self.NSGAIIpopulation.ordered_list_of_objectives) == 2:
            self.PopulationAxes = self.PopulationFigure.add_axes([0, 0, 1, 1])
        else:
            self.PopulationAxes = self.PopulationFigure.add_axes(
                [0, 0, 1, 1], projection='3d')

        #put everything in a big sizer

        leftsizer = wx.BoxSizer(wx.VERTICAL)
        leftsizer.AddMany([
            AxisOptionsBoxSizer, PlotOptionsSizer, self.btnPlotPopulation,
            self.lblOutputTextWindow, self.txtOutputTextWindow,
            self.btnClearOutputTextWindow, ObjectFilterBoxSizer
        ])

        mainsizer = wx.BoxSizer(wx.HORIZONTAL)
        mainsizer.AddMany([leftsizer, (self.PlotCanvas, wx.SHAPED | wx.ALL)])
        self.SetSizer(mainsizer)

    #methods
    def ChangeXObjective(self, event):
        self.Xobjective = self.objective_selectors[0].GetSelection()

    def ChangeYObjective(self, event):
        self.Yobjective = self.objective_selectors[1].GetSelection()

    def ChangeZObjective(self, event):
        self.Zobjective = self.objective_selectors[2].GetSelection()

    def ChangeCObjective(self, event):
        self.Cobjective = self.objective_selectors[3].GetSelection()

    def ChangeSObjective(self, event):
        self.Sobjective = self.objective_selectors[4].GetSelection()

    def ChangeXLowerBound(self, event):
        event.Skip()
        self.plotoptions.LowerBounds[0] = float(
            eval(self.objective_lowerbound_fields[0].GetValue()))
        self.objective_lowerbound_fields[0].SetValue(
            str(self.plotoptions.LowerBounds[0]))

    def ChangeXUpperBound(self, event):
        event.Skip()
        self.plotoptions.UpperBounds[0] = float(
            eval(self.objective_upperbound_fields[0].GetValue()))
        self.objective_upperbound_fields[0].SetValue(
            str(self.plotoptions.UpperBounds[0]))

    def ChangeYLowerBound(self, event):
        event.Skip()
        self.plotoptions.LowerBounds[1] = float(
            eval(self.objective_lowerbound_fields[1].GetValue()))
        self.objective_lowerbound_fields[1].SetValue(
            str(self.plotoptions.LowerBounds[1]))

    def ChangeYUpperBound(self, event):
        event.Skip()
        self.plotoptions.UpperBounds[1] = float(
            eval(self.objective_upperbound_fields[1].GetValue()))
        self.objective_upperbound_fields[1].SetValue(
            str(self.plotoptions.UpperBounds[1]))

    def ChangeZLowerBound(self, event):
        event.Skip()
        self.plotoptions.LowerBounds[2] = float(
            eval(self.objective_lowerbound_fields[2].GetValue()))
        self.objective_lowerbound_fields[2].SetValue(
            str(self.plotoptions.LowerBounds[2]))

    def ChangeZUpperBound(self, event):
        event.Skip()
        self.plotoptions.UpperBounds[2] = float(
            eval(self.objective_upperbound_fields[2].GetValue()))
        self.objective_upperbound_fields[2].SetValue(
            str(self.plotoptions.UpperBounds[2]))

    def ChangeCLowerBound(self, event):
        event.Skip()
        self.plotoptions.LowerBounds[3] = float(
            eval(self.objective_lowerbound_fields[3].GetValue()))
        self.objective_lowerbound_fields[3].SetValue(
            str(self.plotoptions.LowerBounds[3]))

    def ChangeCUpperBound(self, event):
        event.Skip()
        self.plotoptions.UpperBounds[3] = float(
            eval(self.objective_upperbound_fields[3].GetValue()))
        self.objective_upperbound_fields[3].SetValue(
            str(self.plotoptions.UpperBounds[3]))

    def ChangeSLowerBound(self, event):
        event.Skip()
        self.plotoptions.LowerBounds[4] = float(
            eval(self.objective_lowerbound_fields[4].GetValue()))
        self.objective_lowerbound_fields[4].SetValue(
            str(self.plotoptions.LowerBounds[4]))

    def ChangeSUpperBound(self, event):
        event.Skip()
        self.plotoptions.UpperBounds[4] = float(
            eval(self.objective_upperbound_fields[4].GetValue()))
        self.objective_upperbound_fields[4].SetValue(
            str(self.plotoptions.UpperBounds[4]))

    def ChangeTimeUnit(self, event):
        self.plotoptions.TimeUnit = self.cmbTimeUnit.GetSelection()

    def ChangeEpochUnit(self, event):
        self.plotoptions.EpochUnit = self.cmbEpochUnit.GetSelection()

    def ChangeMarkerSize(self, event):
        self.plotoptions.BaseMarkerSize = self.spnctrlMarkerSizeControl.GetValue(
        )

    def ChangeFontSize(self, e):
        self.plotoptions.FontSize = self.spnctrlFontSizeControl.GetValue()

    def ClickPlotPopulation(self, event):
        #first assemble the ordered list of objectives
        #note that if C is set but not Z, throw an error

        if self.Cobjective < len(
                self.NSGAIIpopulation.objective_column_headers
        ) - 1 and self.Zobjective == len(
                self.NSGAIIpopulation.objective_column_headers):
            errordlg = wx.MessageDialog(
                self,
                "You cannot set the color axis without setting the Z axis first",
                "EMTG Error", wx.OK)
            errordlg.ShowModal()
            errordlg.Destroy()

        if self.Sobjective < len(
                self.NSGAIIpopulation.objective_column_headers
        ) - 1 and self.Cobjective == len(
                self.NSGAIIpopulation.objective_column_headers):
            errordlg = wx.MessageDialog(
                self,
                "You cannot set the size axis without setting the color axis first",
                "EMTG Error", wx.OK)
            errordlg.ShowModal()
            errordlg.Destroy()

        else:
            ordered_list_of_objectives = [self.Xobjective, self.Yobjective]

            if self.Zobjective < len(
                    self.NSGAIIpopulation.objective_column_headers):
                ordered_list_of_objectives.append(self.Zobjective)

            if self.Cobjective < len(
                    self.NSGAIIpopulation.objective_column_headers):
                ordered_list_of_objectives.append(self.Cobjective)

            if self.Sobjective < len(
                    self.NSGAIIpopulation.objective_column_headers):
                ordered_list_of_objectives.append(self.Sobjective)

            #check for duplicate objectives. If present, throw an error
            s = set()
            if any(obj in s or s.add(obj)
                   for obj in ordered_list_of_objectives):
                errordlg = wx.MessageDialog(self,
                                            "Objective axes must be unique",
                                            "EMTG Error", wx.OK)
                errordlg.ShowModal()
                errordlg.Destroy()

            else:
                if not self.filter == []:
                    filter_indices = self.lbxObjectFilterList.GetSelections()
                    self.filter.filter_list = []
                    for index in filter_indices:
                        self.filter.filter_list.append(
                            self.filter.object_list[index])
                #now make the plot
                self.NSGAIIpopulation.plot_population(
                    ordered_list_of_objectives,
                    LowerBounds=self.plotoptions.LowerBounds,
                    UpperBounds=self.plotoptions.UpperBounds,
                    TimeUnit=self.plotoptions.TimeUnit,
                    EpochUnit=self.plotoptions.EpochUnit,
                    FontSize=self.plotoptions.FontSize,
                    BaseMarkerSize=self.plotoptions.BaseMarkerSize,
                    OutputWindow=self.txtOutputTextWindow,
                    PopulationFigure=self.PopulationFigure,
                    PopulationAxes=self.PopulationAxes,
                    Filter=self.filter)
                self.PlotCanvas.draw()

    def ClickClearOutputTextWindow(self, e):
        e.Skip()
        self.txtOutputTextWindow.Clear()

    def ChangeObjectFilterFile(self, e):
        e.Skip()
        self.ObjectFilterFile = self.txtObjectFilterFile.GetValue()
        self.filter = NSGAIIFilter.NSGAIIFilter(ObjectFilterFile)
        self.lbxObjectFilterList.Clear()
        self.lbxObjectFilterList.InsertItems(self.filter.object_list, 0)

    def ClickObjectFilterFileButton(self, e):
        dlg = wx.FileDialog(self, "Select an NSGAII object filter file",
                            self.GetParent().dirname, "", '*.NSGAIIfilter',
                            wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.ObjectFilterFile = dlg.GetPath()
            self.txtObjectFilterFile.SetValue(self.ObjectFilterFile)
            self.filter = NSGAIIFilter.NSGAIIFilter(self.ObjectFilterFile)
            self.lbxObjectFilterList.Clear()
            self.lbxObjectFilterList.InsertItems(self.filter.object_list, 0)
        dlg.Destroy()
示例#14
0
    def render(self, mode='human', ax=None):
        """Renders the environment.
        Supported Modes:
        - human: Print the current board state in the current terminal
        - rgb_array: Return an numpy.ndarray with shape (x, y, 3),
          representing RGB values for an x-by-y pixel image, suitable
          for turning into a video.
        - ansi: Return a string (str) or StringIO.StringIO containing a
          terminal-style text representation. The text can include newlines
          and ANSI escape sequences (e.g. for colors).
        """

        if mode == "human" or mode == "ansi":
            white_board = self.white_history[-1]
            black_board = self.black_history[-1]

            for y in range(black_board.shape[0]):
                if y < 10:
                    row = "0" + str(y)
                else:
                    row = str(y)
                for x in range(black_board.shape[1]):
                    if white_board[y, x]:
                        row += "W"
                    elif black_board[y, x]:
                        row += "B"
                    else:
                        row += "-"
                print(row)
        elif mode == "rgb_array":
            # draw the grid
            fig = plt.figure()
            canvas = FigureCanvas(fig)
            ax = fig.gca()
            ax.set_facecolor((0.7843, 0.6314, 0.3961))
            ax.grid()
            ax.set_axisbelow(True)
            ax.set_xlim(left=-1, right=19)
            ax.set_xticks(range(0, 19))
            ax.set_ylim((-1, 19))
            ax.set_yticks(range(0, 19))
            for x in range(self.board_size[1]):
                for y in range(self.board_size[0]):
                    if self.white_history[-1][y, x]:
                        circ = plt.Circle((x, y), radius=0.49, color=(1, 1, 1))
                        ax.add_artist(circ)
                    if self.black_history[-1][y, x]:
                        circ = plt.Circle((x, y), radius=0.49, color=(0, 0, 0))
                        ax.add_artist(circ)
            canvas.draw()
            width, height = fig.get_size_inches() * fig.get_dpi()
            img = np.fromstring(canvas.tostring_rgb(), dtype='uint8').reshape(
                (int(height), int(width), 3))
            plt.close(fig)
            return img
        elif mode == "axes":
            ax.clear()
            ax.set_facecolor((0.7843, 0.6314, 0.3961))
            ax.grid()
            ax.set_axisbelow(True)
            ax.set_xlim(left=-1, right=19)
            ax.set_xticks(range(0, 19))
            ax.set_ylim((-1, 19))
            ax.set_yticks(range(0, 19))
            for x in range(self.board_size[1]):
                for y in range(self.board_size[0]):
                    if self.white_history[-1][y, x]:
                        circ = plt.Circle((x, y), radius=0.49, color=(1, 1, 1))
                        ax.add_artist(circ)
                    if self.black_history[-1][y, x]:
                        circ = plt.Circle((x, y), radius=0.49, color=(0, 0, 0))
                        ax.add_artist(circ)
        else:
            raise NotImplementedError
示例#15
0
def get_batch_figure(*,
                     tensors: OrderedDict[str, numpy.ndarray],
                     return_array: bool = False,
                     meta: Optional[List[dict]] = None):
    ncols = len(tensors)
    nrows = tensors[list(tensors.keys())[0]].shape[0]

    fig, ax = plt.subplots(ncols=ncols,
                           nrows=nrows,
                           squeeze=False,
                           figsize=(ncols * 3, nrows * 3))
    if return_array:
        canvas = FigureCanvas(fig)
    else:
        canvas = None

    def make_subplot(ax,
                     title: str,
                     img,
                     boxes: Iterable[Box] = tuple(),
                     side_view=None,
                     with_colorbar=True):
        assert len(img.shape) == 2, img.shape
        if title:
            ax.set_title(title)

        if side_view is not None:
            assert len(side_view.shape) == 2, img.shape
            img = numpy.concatenate(
                [
                    img,
                    numpy.full(shape=(img.shape[0], 5),
                               fill_value=max(img.max(), side_view.max())),
                    numpy.repeat(side_view,
                                 max(1,
                                     (img.shape[1] / side_view.shape[1]) // 3),
                                 axis=1),
                ],
                axis=1,
            )

        im = ax.imshow(img, cmap=turbo_colormap)
        ax.set_xticklabels([])
        ax.set_yticklabels([])
        ax.axis("off")
        for box in boxes:
            box.apply_to_ax(ax)

        if with_colorbar:
            # from https://stackoverflow.com/questions/18195758/set-matplotlib-colorbar-size-to-match-graph
            # create an axes on the right side of ax. The width of cax will be 5%
            # of ax and the padding between cax and ax will be fixed at 0.05 inch.
            divider = make_axes_locatable(ax)
            cax = divider.append_axes("right", size="3%", pad=0.03)
            fig.colorbar(im, cax=cax)
            # ax.set_title(f"min-{img.min():.2f}-max-{img.max():.2f}")  # taking too much space!

    for c, (name, tensor) in enumerate(tensors.items()):
        assert tensor.shape[0] == nrows, name
        for r, t in enumerate(tensor):
            t = numpy.squeeze(t)
            if len(t.shape) == 2:
                img = t
                side_view = None
            elif len(t.shape) == 3:
                img = t.max(axis=0)
                side_view = t.max(axis=2).T
            else:
                raise NotImplementedError(t.shape)
                # side_view = vl.max(axis=0).max(axis=2).T

            title = name
            if "slice" in name:
                try:
                    z_slice = meta[r][name]["z_slice"]
                except Exception as e:
                    logger.debug("Could not retrieve z_slice for %s: %s", name,
                                 e)
                    try:
                        z_slice = meta[r]["ls_slice"]["z_slice"]
                    except Exception as e:
                        logger.error(
                            "Could not retrieve z_slice for fallback ls_slice: %s",
                            e)
                    else:
                        title = f"{name} z: {z_slice}"
                else:
                    title = f"{name} z: {z_slice}"

            make_subplot(ax[r, c], title=title, img=img, side_view=side_view)

    fig.subplots_adjust(hspace=0, wspace=0, bottom=0, top=1, left=0, right=1)
    fig.tight_layout()
    if return_array:
        # Force a draw so we can grab the pixel buffer
        canvas.draw()
        # grab the pixel buffer and dump it into a numpy array
        fig_array = numpy.array(canvas.renderer.buffer_rgba())

        return fig_array
    else:
        return fig
示例#16
0
def visualize_global_map(filename: str, obstacle_idx: int,
                         observations: torch.Tensor,
                         predictions: torch.Tensor):
    observations = observations[:, 3 * 64 * 64:].cpu().numpy()
    observations = observations * np.array(
        [25.0, 35.0, np.pi, 25.0, 35.0, np.pi], dtype=np.float32) * 2.0

    predictions = predictions[:, 3 * 64 * 64:].cpu().numpy()
    predictions = predictions * np.array(
        [25.0, 35.0, np.pi, 25.0, 35.0, np.pi], dtype=np.float32) * 2.0

    obs_center = load_obstacles(obstacle_idx)
    obstacles = [Rectangle((xy[0] - 4, xy[1] - 4), 8, 8) for xy in obs_center]
    obstacles = PatchCollection(obstacles, facecolor="gray", edgecolor="black")

    car_observation = PatchCollection(
        [Rectangle((-1, -0.5), 2, 1),
         Arrow(0, 0, 2, 0, width=1.0)],
        facecolor="blue",
        edgecolor="blue")
    car_prediction = PatchCollection(
        [Rectangle((-1, -0.5), 2, 1),
         Arrow(0, 0, 2, 0, width=1.0)],
        facecolor="yellow",
        edgecolor="yellow")

    fig = Figure()
    canvas = FigureCanvas(fig)
    ax = fig.subplots()
    ax.set_aspect('equal', 'box')
    ax.set_xlim([-25, 25])
    ax.set_ylim([-35, 35])

    canvas.draw()
    image = np.array(canvas.buffer_rgba())
    H, W, _ = image.shape
    writer = cv2.VideoWriter(filename, cv2.VideoWriter_fourcc(*'mp4v'), 30.,
                             (W, H), True)

    T = observations.shape[0]
    for t in range(T):
        # obstacles
        ax.add_collection(obstacles)
        # target
        ax.scatter(observations[-1, 3],
                   observations[-1, 4],
                   marker='*',
                   c="red")
        # current position
        transform = Affine2D().rotate(observations[t, 2]).translate(
            observations[t, 0], observations[t, 1])
        car_observation.set_transform(transform + ax.transData)
        ax.add_collection(car_observation)
        # predicted position
        transform = Affine2D().rotate(predictions[t, 2]).translate(
            predictions[t, 0], predictions[t, 1])
        car_prediction.set_transform(transform + ax.transData)
        ax.add_collection(car_prediction)
        # plot
        ax.set_xlim([-25, 25])
        ax.set_ylim([-35, 35])
        canvas.draw()
        image = np.array(canvas.buffer_rgba())[:, :, :3]
        writer.write(image)
        ax.clear()

    writer.release()
    h264_converter(filename)
示例#17
0
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvas
from scipy.ndimage import gaussian_filter

# First pass for drop-shadow
fig = Figure(figsize=(6, 1.5))
canvas = FigureCanvas(fig)
ax = fig.add_axes([0, 0, 1, 1], frameon=False,
                  xlim=[0, 1], xticks=[], ylim=[0, 1], yticks=[])
ax.text(0.5, 0.5, "Matplotlib", transform=ax.transAxes,
        ha="center", va="center", size=64, color="black")
canvas.draw()
Z = np.array(canvas.renderer.buffer_rgba())[:, :, 0]
Z = gaussian_filter(Z, sigma=9)

# Second pass for text + drop-shadow
fig = plt.figure(figsize=(6, 1.5))
ax = fig.add_axes([0, 0, 1, 1], frameon=False,
                  xlim=[0, 1], xticks=[], ylim=[0, 1], yticks=[])
ax.imshow(Z, extent=[0, 1, 0, 1], cmap=plt.cm.gray, alpha=0.65, aspect='auto')
ax.text(0.5, 0.5, "Matplotlib", transform=ax.transAxes,
        ha="center", va="center", size=64, color="black")

plt.savefig("../figures/tip-post-processing.pdf", dpi=600)
# plt.show()
示例#18
0
def readpyart(
        file, outdir, detdir, cint,
        vis):  # Function to unpack the NOAA radar files, and evaluate them
    r, dr, allr = [], [], []

    #file = file[len(fdir):]                           # (1)
    radar = pyart.io.read(fdir + file)
    name, date, btime, dtstr = stringed(file)
    print('\n')
    print('Checking ' + name + ' at ' + btime)

    for x in range(radar.nsweeps):
        plotter = pyart.graph.RadarDisplay(radar)
        fig = plt.figure(figsize=(25, 25), frameon=False)
        ax = plt.Axes(fig, [0., 0., 1., 1.])
        fig.add_axes(ax)
        plotter.set_limits(xlim=(-250, 250), ylim=(-250, 250), ax=ax)
        data = plotter._get_data('velocity',
                                 x,
                                 mask_tuple=None,
                                 filter_transitions=True,
                                 gatefilter=None)

        if np.any(data) > 0:
            xDat, yDat = plotter._get_x_y(x,
                                          edges=True,
                                          filter_transitions=True)
            data = data * (70 / np.max(np.abs(data)))
            ax.pcolormesh(xDat, yDat, data)
            canvas = FigureCanvas(fig)
            canvas.draw()  # (1)
            buf, (w, h) = fig.canvas.print_to_buffer()
            img = np.frombuffer(buf, np.uint8).reshape((h, w, 4))
            # This whole segment is converting the data to a standard size
            if img.shape != ():
                img = np.delete(img, 3,
                                2)  # and readable image using matplotlib (MPL)

                sweepangle = str(format(radar.fixed_angle['data'][x], ".2f"))
                print('Reading velocity at sweep angle: ', sweepangle)
                t = radar.time['data'][x]
                locDat = [xDat, yDat, t]
                v = detect(radar, img, file, locDat, sweepangle, detdir, vis,
                           cint)  # detect is a function from torchdet.py
                if v is not None:
                    vc, vall = v  # two types of output, for either point or square displays
                    vc.append(x)
                    r.append(vc)
                    allr.append(vall)
                plt.cla()
                plt.clf()
                plt.close('all')
            plt.cla()
            plt.clf()
            plt.close('all')
    if (len(r) >= 2):
        #squareout(file, radar, allr, outdir)
        pointout(file, radar, r, outdir)
        rlsp = org(r)
        rv = kin(rlsp)
        prop = backprop(rv, 360)
        if (vis == True):
            propvis(prop, detdir, name, dtstr)
        txtout(prop, file, outdir)