def toImage()

in analysis/webservice/algorithms/Tomogram.py [0:0]


    def toImage(self, i=0):
        ds, peaks = self.results()

        options = self.__computeOptions

        if 'longitude' in self.__slice:
            lon = self.__slice['longitude'][0]
            title_row = f'Longitude: {lon}'
            xlabel = 'Latitude'
            coord = 'longitude'
        elif 'latitude' in self.__slice:
            lat = self.__slice['latitude'][0]
            title_row = f'Latitude: {lat}'
            xlabel = 'Longitude'
            coord = 'latitude'
        else:
            start = self.__slice['start_point']
            end = self.__slice['end_point']

            start = (start.x, start.y)
            end = (end.x, end.y)

            title_row = f'Slice from: {start} to {end}'
            xlabel = 'Distance along slice [m]'
            coord = 'slice'

        ds = ds.isel({coord: i}).transpose(self.__coords['y'].name, self.__coords['x'].name)

        rows = ds.tomo.to_numpy()
        if peaks is not None:
            peaks = peaks[i]

        logger.info('Building plot')

        plt.figure(figsize=(11, 7))
        if self.__style == 'db':
            opt_min = options.get_float_arg('cbarMin', None)
            opt_max = options.get_float_arg('cbarMax', None)

            v = dict(vmin=-30, vmax=-10)

            if opt_min is not None:
                v['vmin'] = opt_min
            if opt_max is not None:
                v['vmax'] = opt_max

            if v['vmin'] >= v['vmax']:
                logger.warning('cbarMin >= cbarMax. Using defaults')
                v = dict(vmin=-30, vmax=-10)
        else:
            v = dict(vmin=0, vmax=1)
        plt.pcolormesh(self.__coords['x'], self.__coords['y'], rows, cmap=self.__cmap, **v)
        plt.colorbar()
        plt.title(f'{self.meta()["dataset"]} tomogram slice\n{title_row}')
        plt.xlabel(xlabel)
        plt.ylabel(f'Elevation w.r.t. {self.meta()["dataset"]} reference (m)')

        legend_handles = []

        if 'ch' in ds.data_vars and 'ch_secondary' in ds.data_vars:
            x_dim = ds['ch'].dims[0]

            # Plot secondary first so primary covers it
            second_ch = plt.plot(
                ds[x_dim].to_numpy(),
                ds.ch_secondary.to_numpy(),
                label=f'Secondary canopy height: {ds.ch_secondary.attrs["_source"]}'
            )

            prim_ch = plt.plot(
                ds[x_dim].to_numpy(),
                ds.ch.to_numpy(),
                label=f'Primary canopy height: {ds.ch.attrs["_source"]}'
            )

            legend_handles.extend(prim_ch)
            legend_handles.extend(second_ch)

        if 'gh' in ds.data_vars and 'gh_secondary' in ds.data_vars:
            x_dim = ds['gh'].dims[0]

            # Plot secondary first so primary covers it
            second_ch = plt.plot(
                ds[x_dim].to_numpy(),
                ds.gh_secondary.to_numpy(),
                label=f'Secondary ground height: {ds.gh_secondary.attrs["_source"]}'
            )

            prim_ch = plt.plot(
                ds[x_dim].to_numpy(),
                ds.gh.to_numpy(),
                label=f'Primary ground height: {ds.gh.attrs["_source"]}'
            )

            legend_handles.extend(prim_ch)
            legend_handles.extend(second_ch)

        if peaks is not None:
            peak_plot = plt.plot(
                peaks[0], peaks[1], color='red', alpha=0.75, label='Peak value', linestyle='--'
            )

            legend_handles.extend(peak_plot)

        plt.legend(handles=legend_handles)

        plt.ticklabel_format(useOffset=False)

        buffer = BytesIO()

        logger.info('Writing plot to buffer')
        plt.savefig(buffer, format='png', facecolor='white')

        buffer.seek(0)
        plt.close()
        return buffer.read()