Source code for triqs_maxent.plot_utils

# TRIQS application maxent
# Copyright (C) 2018 Gernot J. Kraberger
# Copyright (C) 2018 Simons Foundation
# Authors: Gernot J. Kraberger and Manuel Zingl
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.



import matplotlib.pyplot as plt
from functools import wraps
import numpy as np


[docs] def plot_function(func): """ A decorator for plotting A method decorated with this decorator shall return three arguments, specifically ``x``, ``y`` and ``default`` or a list of tuples, where each tuple consists of ``(x, y, default)`` (in the latter case, more than one line will be plotted). ``x`` and ``y`` represent the coordinates of the curve that shall be plotted and ``default`` is a dictionary of options. These options can either by consumed by the decorated function (in any way that seems suitable) or they are passed on to the matplotlib plotting functions. There is a special keyword argument called element which is constructed from the keyword arguments ``m``, ``n`` (and ``c``) representing the index of the matrix element (with a possible complex index ``c``). Entries starting with ``n_``, e.g. ``n_argname``, in ``default`` mean that there is a keyword argument ``argname`` that can take the values ``0`` to ``n_argname-1``. After decorating the function, it will not return the arguments anymore but rather plot the curves with the corresponding setting. The original function which is decorated is still available using ``function_name.original``. If using this on methods in :py:class:`.MaxEntResultData` or :py:class:`.AnalyzerResult`, the plotting GUI and the ``JupyterPlotMaxEnt`` will automatically detect it and use the entries of ``default`` to present GUI elements to the user (see :ref:`visualization`). """ @wraps(func) def new_func(self, **kwargs): if 'm' in kwargs and 'n' in kwargs and 'c' in kwargs: kwargs['element'] = (kwargs['m'], kwargs['n'], kwargs['c']) del kwargs['m'] del kwargs['n'] del kwargs['c'] elif 'm' in kwargs and 'n' in kwargs: kwargs['element'] = (kwargs['m'], kwargs['n']) del kwargs['m'] del kwargs['n'] to_plot = func(self, **kwargs) if not isinstance(to_plot, list): to_plot = [to_plot] for qty in to_plot: x, y, default = qty for key, val in default.items(): if key not in kwargs: kwargs[key] = val _plotter(x, y, **kwargs) new_func.original = func return new_func
def _plotter(x, y, label=None, x_label=None, y_label=None, log_x=False, log_y=False, **kwargs): """ actually plotting a curve a small wrapper over matplotlib""" plot_command = plt.plot if log_x and log_y: plot_command = plt.loglog elif log_x: plot_command = plt.semilogx elif log_y: plot_command = plt.semilogy if np.any(np.iscomplex(y)): plot_command(x, y.real, label='Re ' + label if label is not None else None) plot_command(x, y.imag, label='Im ' + label if label is not None else None) else: plot_command(x, y, label=label) plt.xlabel(x_label) plt.ylabel(y_label)