//  [python]
def plot(self, output_directory, *args, **kwargs) :
        if not len(self.utilization) :
            return {}
        results = self.report()
        output_directory = Path(output_directory)
        output_directory = Path(output_directory)
        output_filenames = {}
        ## plot gpu usage
        output_filename = output_directory / '{}_utilization.png'.format(self.name)
        plt.cla()
        plt.clf()
        sns.set(style="whitegrid")
        fig, (ax1, ax2) = plt.subplots(2)
        plt.gcf().set_size_inches((6.4,9.6))
        gpu_data = np.asarray(self.utilization)
        linewidth, columns = 0.5, ['utilization']
        gpu_data = pd.DataFrame(
            gpu_data, columns=columns
        )
        sns.lineplot(data=gpu_data, palette="tab10", linewidth=linewidth, dashes=False, ax=ax1)
        ax1.set_title("GPU Utilization (%)")
        ax1.set(xlabel='time (x{0:.2f}s)'.format(self.dt), ylabel='Utilization (%)')

        ax2.set_title("GPU Utilization (%)")
        percentile = np.percentile(gpu_data, q=np.arange(100))
        ax2.boxplot(percentile, showfliers=False)
        plt.autoscale()
        plt.tight_layout()
        plt.savefig(output_filename)
        plt.close()
        output_filenames.update(dict(gpu_utilization=output_filename))

        ## plot gpu usage
        output_filename = output_directory / '{}_temperature.png'.format(self.name)
        plt.cla()
        plt.clf()
        sns.set(style="whitegrid")
        fig, (ax1, ax2) = plt.subplots(2)
        plt.gcf().set_size_inches((6.4,9.6))
        gpu_data = np.asarray(self.temperature)
        linewidth, columns = 0.5, ['temperature']
        gpu_data = pd.DataFrame(
            gpu_data, columns=columns
        )
        sns.lineplot(data=gpu_data, palette="tab10", linewidth=linewidth, dashes=False, ax=ax1)
        ax1.set_title("GPU Temperature")
        ax1.set(xlabel='time (x{0:.2f}s)'.format(self.dt), ylabel='Temperature')

        ax2.set_title("GPU Temperature")
        percentile = np.percentile(gpu_data, q=np.arange(100))
        ax2.boxplot(percentile, showfliers=False)
        plt.autoscale()
        plt.tight_layout()
        plt.savefig(output_filename)
        plt.close()
        output_filenames.update(dict(gpu_temperature=output_filename))

        ## plot gpu memory
        output_filename = output_directory / '{}_memory.png'.format(self.name)
        plt.cla()
        plt.clf()
        sns.set(style="whitegrid")
        fig, (ax1, ax2) = plt.subplots(2)
        plt.gcf().set_size_inches((6.4,9.6))
        gpu_data = {}
        for key, memory in self.process_memory.items() :
            memory_used = memory['memory']
            field_name = '{} ({})'.format(memory['name'], np.mean(memory_used))
            columns.append(field_name)  # e.g. python (500), python3.5 (1024)
            gpu_data[field_name] = memory_used
        gpu_data['system'] = np.asarray(self.memory)
        # make sure values in gpu_data have same length, so pandas won't complains
        n_data = min(map(lambda v: len(v), gpu_data.values()))
        for key, value in gpu_data.items():
            gpu_data[key] = value[:n_data]
        linewidth = 0.5
        gpu_df = pd.DataFrame(
            data=gpu_data
        )
        sns.lineplot(data=gpu_df, palette="tab10", linewidth=linewidth, dashes=False, ax=ax1)
        ax1.set(xlabel='time (x{0:.2f}s)'.format(self.dt), ylabel='GPU Memory')
        ax1.set_title("GPU Memory")

        ax2.set_title("GPU Memory")
        ax2.boxplot(gpu_data.values(), showfliers=False)
        plt.autoscale()
        plt.tight_layout()
        plt.savefig(output_filename)
        output_filenames.update(dict(gpu_memory=output_filename))

        plt.gcf().set_size_inches((6.4,4.8)) ## reset back to matplotlib default
        sns.reset_defaults()

        return output_filenames