Example #1
0
File: scr.py Project: zbwang/abipy
    def plot_eelf(self, ax=None, xlims=None, fontsize=12, **kwargs):
        r"""
        Plot electron energy loss function.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used
            fontsize: Legend and label fontsize:

        Returns: |matplotlib-Figure|
        """
        eelf = self.reader.read_eelf()
        xx, yy = eelf.mesh * pmgu.Ha_to_eV, eelf.values

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.plot(xx,
                yy,
                linewidth=kwargs.get("linewidth", 2),
                linestyle=kwargs.get("linestyle", "solid"),
                label="EELF")

        set_axlims(ax, xlims, "x")
        ax.grid(True)
        ax.set_xlabel(r"$\omega$ [eV]")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #2
0
File: scr.py Project: gmatteo/abipy
    def plot_eelf(self, ax=None, xlims=None, fontsize=12, **kwargs):
        r"""
        Plot electron energy loss function.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used
            fontsize: Legend and label fontsize:

        Returns: |matplotlib-Figure|
        """
        eelf = self.reader.read_eelf()
        xx, yy = eelf.mesh * pmgu.Ha_to_eV, eelf.values

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.plot(xx, yy, linewidth=kwargs.get("linewidth", 2),
                linestyle=kwargs.get("linestyle", "solid"), label="EELF")

        set_axlims(ax, xlims, "x")
        ax.grid(True)
        ax.set_xlabel(r"$\omega$ (eV)")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #3
0
File: scr.py Project: gmatteo/abipy
    def plot_emacro(self, cplx_mode="re-im", ax=None, xlims=None, fontsize=12, **kwargs):
        r"""
        Plot the macroscopic dielectric function with local-field effects.

        Args:
            cplx_mode: string defining the data to print.
                Possible choices are (case-insensitive):
                "re" for the real part. "im" for the imaginary part.
                "abs" for the absolute value.
                "angle" will display the phase of the complex number in radians.
                Options can be concatenated with ``-`` e.g. ``re-im``.
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. (left, right)
                or scalar e.g. left. If left (right) is None, default values are used.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            fontsize: Legend and title fontsize.

        Returns:
            |matplotlib-Figure|
        """
        emlf = self.reader.read_emacro_lf()
        xx, yy = emlf.mesh * pmgu.Ha_to_eV, emlf.values

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for c in cplx_mode.lower().split("-"):
            ax.plot(xx, data_from_cplx_mode(c, yy),
                    color=_COLOR_CMODE[c], linewidth=kwargs.get("linewidth", 2),
                    linestyle=kwargs.get("linestyle", "solid"),
                    label=_latex_symbol_cplxmode(r"\varepsilon_{M}", c))

        set_axlims(ax, xlims, "x")
        ax.grid(True)
        ax.set_xlabel(r"$\omega$ (eV)")
        ax.legend(loc="best", shadow=True, fontsize=fontsize)

        return fig
Example #4
0
    def plot_linear_epsilon(self, components="all", what="im", itemp=0,
                            ax=None, xlims=None, with_xlabel=True, label=None, fontsize=12, **kwargs):
        """
        Plot components of the linear dielectric function.

        Args:
            components: List of cartesian tensor components to plot e.g. ["xx", "xy"].
                "all" if all components available on file should be plotted on the same ax.
            what: quantity to plot. "re" for real part, "im" for imaginary. Accepts also "abs", "angle".
            itemp: Temperature index.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            with_xlabel: True if x-label should be added.
            label: True to add legend label to each curve.
            fontsize: Legend and label fontsize.

        Returns: |matplotlib-Figure|
        """
        comp2eps = self.reader.read_lineps(components, itemp=itemp)

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for comp, eps in comp2eps.items():
            values = LINEPS_WHAT2EFUNC[what](eps)
            # Note: I'm skipping the first point at w=0 because optic does not compute it!
            # The same trick is used in the other plots.
            ax.plot(self.wmesh[1:], values[1:],
                    label=self.get_linopt_latex_label(what, comp) if label is None else label)

        ax.grid(True)
        if with_xlabel: ax.set_xlabel('Photon Energy (eV)')
        set_axlims(ax, xlims, "x")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #5
0
    def plot_emacro(self, cplx_mode="re-im", ax=None, xlims=None, fontsize=12, **kwargs):
        r"""
        Plot the macroscopic dielectric function with local-field effects.

        Args:
            cplx_mode: string defining the data to print.
                Possible choices are (case-insensitive):
                "re" for the real part. "im" for the imaginary part.
                "abs" for the absolute value.
                "angle" will display the phase of the complex number in radians.
                Options can be concatenated with ``-`` e.g. ``re-im``.
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. (left, right)
                or scalar e.g. left. If left (right) is None, default values are used.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            fontsize: Legend and title fontsize.

        Returns:
            |matplotlib-Figure|
        """
        emlf = self.reader.read_emacro_lf()
        xx, yy = emlf.mesh * pmgu.Ha_to_eV, emlf.values

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for c in cplx_mode.lower().split("-"):
            ax.plot(xx, data_from_cplx_mode(c, yy),
                    color=_COLOR_CMODE[c], linewidth=kwargs.get("linewidth", 2),
                    linestyle=kwargs.get("linestyle", "solid"),
                    label=_latex_symbol_cplxmode(r"\varepsilon_{M}", c))

        set_axlims(ax, xlims, "x")
        ax.grid(True)
        ax.set_xlabel(r"$\omega$ (eV)")
        ax.legend(loc="best", shadow=True, fontsize=fontsize)

        return fig
Example #6
0
    def plot_linear_epsilon(self, components="all", what="im", itemp=0,
                            ax=None, xlims=None, with_xlabel=True, label=None, fontsize=12, **kwargs):
        """
        Plot components of the linear dielectric function.

        Args:
            components: List of cartesian tensor components to plot e.g. ["xx", "xy"].
                "all" if all components available on file should be plotted on the same ax.
            what: quantity to plot. "re" for real part, "im" for imaginary. Accepts also "abs", "angle".
            itemp: Temperature index.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            with_xlabel: True if x-label should be added.
            label: True to add legend label to each curve.
            fontsize: Legend and label fontsize.

        Returns: |matplotlib-Figure|
        """
        comp2eps = self.reader.read_lineps(components, itemp=itemp)

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for comp, eps in comp2eps.items():
            values = LINEPS_WHAT2EFUNC[what](eps)
            # Note: I'm skipping the first point at w=0 because optic does not compute it!
            # The same trick is used in the other plots.
            ax.plot(self.wmesh[1:], values[1:],
                    label=self.get_linopt_latex_label(what, comp) if label is None else label)

        ax.grid(True)
        if with_xlabel: ax.set_xlabel('Photon Energy (eV)')
        set_axlims(ax, xlims, "x")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #7
0
    def plot_unfolded(self, kbounds, klabels, ylims=None, dist_tol=1e-12, verbose=0,
                      colormap="afmhot", facecolor="black", ax=None, fontsize=12, **kwargs):
        r"""
        Plot unfolded band structure with spectral weights.

        Args:
            klabels: dictionary whose keys are tuple with the reduced coordinates of the k-points.
                The values are the labels. e.g. ``klabels = {(0.0,0.0,0.0): "$\Gamma$", (0.5,0,0): "L"}``.
            ylims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            dist_tol: A point is considered to be on the path if its distance from the line
                is less than dist_tol.
            verbose: Verbosity level.
            colormap: Have a look at the colormaps here and decide which one you like:
                http://matplotlib.sourceforge.net/examples/pylab_examples/show_colormaps.html
            facecolor:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            fontsize: Legend and title fontsize.

        Returns: |matplotlib-Figure|
	"""
        cart_bounds = [self.pc_lattice.reciprocal_lattice.get_cartesian_coords(c)
                       for c in np.reshape(kbounds, (-1, 3))]
        uf_cart = self.uf_kpoints.get_cart_coords()

        p = find_points_along_path(cart_bounds, uf_cart, dist_tol)
        if len(p.ikfound) == 0:
            cprint("Warning: find_points_along_path returned zero points along the path. Try to increase dist_tol.", "yellow")
            return None
        if verbose:
            uf_frac_coords = np.reshape([k.frac_coords for k in self.uf_kpoints], (-1, 3))
            fcoords = uf_frac_coords[p.ikfound]
            print("Found %d points along input k-path" % len(fcoords))
            print("k-points of path in reduced coordinates:")
            print(fcoords)

        fact = 8.0
        e0 = self.ebands.fermie
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.set_facecolor(facecolor)

        xs = np.tile(p.dist_list, self.nband)
        marker_spin = {0: "^", 1: "v"} if self.nss == 2 else {0: "o"}
        for spin in range(self.nss):
            ys = self.uf_eigens[spin, p.ikfound, :] - e0
            ws = self.uf_weights[spin, p.ikfound, :]
            s = ax.scatter(xs, ys.T, s=fact * ws.T, c=ws.T,
                           marker=marker_spin[spin], label=None if self.nss == 1 else "spin %s" % spin,
                           linewidth=1, edgecolors='none', cmap=plt.get_cmap(colormap))
            plt.colorbar(s, ax=ax, orientation='vertical')

        ax.set_xticks(p.path_ticks, minor=False)
        ax.set_xticklabels(klabels, fontdict=None, minor=False, size=kwargs.pop("klabel_size", "large"))
        ax.grid(True)
        ax.set_ylabel('Energy (eV)')
        set_axlims(ax, ylims, "y")
        if self.nss == 2: ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #8
0
    def plot_unfolded(self, kbounds, klabels, ylims=None, dist_tol=1e-12, verbose=0,
                      colormap="afmhot", facecolor="black", ax=None, fontsize=12, **kwargs):
        r"""
        Plot unfolded band structure with spectral weights.

        Args:
            klabels: dictionary whose keys are tuple with the reduced coordinates of the k-points.
                The values are the labels. e.g. ``klabels = {(0.0,0.0,0.0): "$\Gamma$", (0.5,0,0): "L"}``.
            ylims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            dist_tol: A point is considered to be on the path if its distance from the line
                is less than dist_tol.
            verbose: Verbosity level.
            colormap: Have a look at the colormaps here and decide which one you like:
                http://matplotlib.sourceforge.net/examples/pylab_examples/show_colormaps.html
            facecolor:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            fontsize: Legend and title fontsize.

        Returns: |matplotlib-Figure|
	"""
        cart_bounds = [self.pc_lattice.reciprocal_lattice.get_cartesian_coords(c)
                       for c in np.reshape(kbounds, (-1, 3))]
        uf_cart = self.uf_kpoints.get_cart_coords()

        klines, xs, ticks = find_points_along_path(cart_bounds, uf_cart, dist_tol)
        if len(klines) == 0: return None
        if verbose:
            uf_frac_coords = np.reshape([k.frac_coords for k in self.uf_kpoints], (-1, 3))
            fcoords = uf_frac_coords[klines]
            print("Found %d points along input k-path" % len(fcoords))
            print("k-points of path in reduced coordinates:")
            print(fcoords)

        fact = 8.0
        e0 = self.ebands.fermie
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.set_facecolor(facecolor)

        xs = np.tile(xs, self.nband)
        marker_spin = {0: "^", 1: "v"} if self.nss == 2 else {0: "o"}
        for spin in range(self.nss):
            ys = self.uf_eigens[spin, klines, :] - e0
            ws = self.uf_weights[spin, klines, :]
            s = ax.scatter(xs, ys.T, s=fact * ws.T, c=ws.T,
                           marker=marker_spin[spin], label=None if self.nss == 1 else "spin %s" % spin,
                           linewidth=1, edgecolors='none', cmap=plt.get_cmap(colormap))
            plt.colorbar(s, ax=ax, orientation='vertical')

        ax.set_xticks(ticks, minor=False)
        ax.set_xticklabels(klabels, fontdict=None, minor=False, size=kwargs.pop("klabel_size", "large"))
        ax.grid(True)
        ax.set_ylabel('Energy [eV]')
        set_axlims(ax, ylims, "y")
        if self.nss == 2: ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #9
0
    def plot_chi2(self,
                  key,
                  components="all",
                  what="abs",
                  itemp=0,
                  decompose=False,
                  ax=None,
                  xlims=None,
                  with_xlabel=True,
                  label=None,
                  fontsize=12,
                  **kwargs):
        """
        Low-level function to plot chi2 tensor.

        Args:
            key:
            components: List of cartesian tensor components to plot e.g. ["xxx", "xyz"].
                "all" if all components available on file should be plotted on the same ax.
            what: quantity to plot. "re" for real part, "im" for imaginary, Accepts also "abs", "angle".
            itemp: Temperature index.
            decompose: True to plot individual contributions.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            with_xlabel: True to add x-label.
            label: True to add legend label to each curve.
            fontsize: Legend and label fontsize.

        Returns: |matplotlib-Figure|
        """
        if not self.reader.computed_components[key]: return None
        comp2terms = self.reader.read_tensor3_terms(key,
                                                    components,
                                                    itemp=itemp)

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for comp, terms in comp2terms.items():
            for name, values in terms.items():
                if not decompose and not name.endswith("tot"): continue
                values = data_from_cplx_mode(what, values)
                ax.plot(
                    self.wmesh[1:],
                    values[1:],
                    label=self.get_chi2_latex_label(key, what, comp)
                    if label is None else label,
                )

        ax.grid(True)
        if with_xlabel: ax.set_xlabel('Photon Energy [eV]')
        set_axlims(ax, xlims, "x")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #10
0
File: bse.py Project: gmatteo/abipy
    def plot_mdftype_cplx(self, mdf_type, cplx_mode, qpoint=None, ax=None, xlims=None, ylims=None,
                          with_legend=True, with_xlabel=True, with_ylabel=True, fontsize=8, **kwargs):
        """
        Helper function to plot data corresponds to ``mdf_type``, ``cplx_mode``, ``qpoint``.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            mdf_type:
            cplx_mode: string defining the data to print (case-insensitive).
                Possible choices are `re` for the real part, `im` for imaginary part only. `abs` for the absolute value.
            qpoint: index of the q-point or :class:`Kpoint` object or None to plot emacro_avg.
            xlims: Set the data limits for the y-axis. Accept tuple e.g. `(left, right)`
                  or scalar e.g. `left`. If left (right) is None, default values are used
            ylims: Same meaning as `ylims` but for the y-axis
            with_legend: True if legend should be added
            with_xlabel:
            with_ylabel:
            fontsize: Legend and label fontsize.

        Return: |matplotlib-Figure|
        """
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.grid(True)

        if with_xlabel: ax.set_xlabel("Frequency (eV)")
        if with_ylabel: ax.set_ylabel(self.MDF_TYPECPLX2TEX[mdf_type][cplx_mode.lower()])

        can_use_basename = self._can_use_basenames_as_labels()
        qtag = "avg" if qpoint is None else repr(qpoint)

        lines, legends = [], []
        for label, mdf_dict in self._mdfs.items():
            mdf = mdf_dict[mdf_type]
            # Plot the average value
            l = mdf.plot_ax(ax, qpoint, cplx_mode=cplx_mode, **kwargs)[0]
            lines.append(l)
            if can_use_basename:
                label = os.path.basename(label)
            else:
                # Use relative paths if label is a file.
                if os.path.isfile(label): label = os.path.relpath(label)

            legends.append(r"%s: %s, %s $\varepsilon$" % (cplx_mode, qtag, label))

        set_axlims(ax, xlims, "x")
        set_axlims(ax, ylims, "y")

        # Set legends.
        if with_legend:
            ax.legend(lines, legends, loc='best', fontsize=fontsize, shadow=True)

        return fig
Example #11
0
    def plot_doses(self,
                   xlims=None,
                   dos_names="all",
                   with_idos=True,
                   **kwargs):
        r"""
        Plot the different doses stored in the GRUNS.nc file.

        Args:
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            dos_names: List of strings defining the DOSes to plot. Use "all" to plot all DOSes available.
            with_idos: True to display integrated doses.

        Return: |matplotlib-Figure|
        """
        if not self.doses: return None

        dos_names = _ALL_DOS_NAMES.keys(
        ) if dos_names == "all" else list_strings(dos_names)
        wmesh = self.doses["wmesh"]

        nrows, ncols = len(dos_names), 1
        ax_list, fig, plt = get_axarray_fig_plt(None,
                                                nrows=nrows,
                                                ncols=ncols,
                                                sharex=True,
                                                sharey=False,
                                                squeeze=False)
        ax_list = ax_list.ravel()

        for i, (name, ax) in enumerate(zip(dos_names, ax_list)):
            dos, idos = self.doses[name][0], self.doses[name][1]
            ax.plot(wmesh, dos, color="k")
            ax.grid(True)
            set_axlims(ax, xlims, "x")
            ax.set_ylabel(_ALL_DOS_NAMES[name]["latex"])
            #ax.yaxis.set_ticks_position("right")

            if with_idos:
                other_ax = ax.twinx()
                other_ax.plot(wmesh, idos, color="k")
                other_ax.set_ylabel(_ALL_DOS_NAMES[name]["latex"].replace(
                    "DOS", "IDOS"))

            if i == len(dos_names) - 1:
                ax.set_xlabel(r"$\omega$ (eV)")
            #ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #12
0
    def plot(self,
             ax=None,
             cplx_mode="Im",
             qpoint=None,
             xlims=None,
             ylims=None,
             fontsize=12,
             **kwargs):
        """
        Get a matplotlib plot showing the MDFs.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            cplx_mode: string defining the data to print (case-insensitive).
                Possible choices are ``re`` for the real part, ``im`` for imaginary part only. ``abs`` for the absolute value.
                Options can be concated with "-".
            qpoint: index of the q-point or :class:`Kpoint` object or None to plot emacro_avg.
            xlims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            ylims: Same meaning as ``ylims`` but for the y-axis
            fontsize: Legend and label fontsize.

        Return: |matplotlib-Figure|
        """
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.grid(True)
        ax.set_xlabel('Frequency (eV)')
        ax.set_ylabel('Macroscopic DF')

        cmodes = cplx_mode.split("-")
        qtag = "avg" if qpoint is None else repr(qpoint)

        lines, legends = [], []
        for label, mdf in self._mdfs.items():
            for cmode in cmodes:
                # Plot the average value
                l = mdf.plot_ax(ax, qpoint, cplx_mode=cmode, **kwargs)[0]
                lines.append(l)
                legends.append(r"%s: %s, %s $\varepsilon$" %
                               (cmode, qtag, label))

        # Set legends.
        ax.legend(lines, legends, loc='best', fontsize=fontsize, shadow=True)
        set_axlims(ax, xlims, "x")
        set_axlims(ax, ylims, "y")

        return fig
Example #13
0
    def plot(self, eb_ylims=None, **kwargs):
        """
        Plot electrons with possible (phonon-mediated) scattering channels for the CBM and VBM.
        Also plot phonon band structure and phonon PJDOS.

        Args:
            eb_ylims: Set the data limits for the y-axis of the electron band. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If None, limits are selected automatically.

        Return: |matplotlib-Figure|
        """
        # Build grid. Share y-axis for Phbands and Phdos
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax0 = plt.subplot2grid((3, 3), (0, 0), colspan=3, rowspan=2)
        ax1 = plt.subplot2grid((3, 3), (2, 0), colspan=2, rowspan=1)
        ax2 = plt.subplot2grid((3, 3), (2, 2), colspan=1, rowspan=1)
        ax1.get_shared_y_axes().join(ax1, ax2)

        # Plot electrons with possible e-ph scattering channels.
        self.eb_kpath.plot(ax=ax0,
                           with_gaps=True,
                           ylims=eb_ylims,
                           max_phfreq=self.phb_qpath.maxfreq,
                           show=False)

        # Plot phonon bands
        self.phb_qpath.plot(ax=ax1, show=False)
        #ax1.yaxis.set_visible(False)
        #set_visible(ax1, False, "ylabel")

        # Plot phonon PJDOS
        self.phdos_file.plot_pjdos_type(ax=ax2,
                                        fontsize=8,
                                        exchange_xy=True,
                                        show=False)
        set_visible(ax2, False, "ylabel")
        ax2.tick_params("y", left=False, labelleft=False)
        ax2.tick_params("y", right=True, labelright=True)

        # Adjust y-limits for phonons
        ylims = self.phb_qpath.minfreq, self.phb_qpath.maxfreq + 0.1 * abs(
            self.phb_qpath.maxfreq)
        for ax in (ax1, ax2):
            set_axlims(ax, ylims, "y")

        return fig
Example #14
0
    def plot_doses(self, xlims=None, dos_names="all", with_idos=True, **kwargs):
        r"""
        Plot the different doses stored in the GRUNS.nc file.

        Args:
            xlims: Set the data limits for the x-axis in eV. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            dos_names: List of strings defining the DOSes to plot. Use "all" to plot all DOSes available.
            with_idos: True to display integrated doses.

        Return: |matplotlib-Figure|
        """
        if not self.doses: return None

        dos_names = _ALL_DOS_NAMES.keys() if dos_names == "all" else list_strings(dos_names)
        wmesh = self.doses["wmesh"]

        nrows, ncols = len(dos_names), 1
        ax_list, fig, plt = get_axarray_fig_plt(None, nrows=nrows, ncols=ncols,
                                                sharex=True, sharey=False, squeeze=False)
        ax_list = ax_list.ravel()

        for i, (name, ax) in enumerate(zip(dos_names, ax_list)):
            dos, idos = self.doses[name][0], self.doses[name][1]
            ax.plot(wmesh, dos, color="k")
            ax.grid(True)
            set_axlims(ax, xlims, "x")
            ax.set_ylabel(_ALL_DOS_NAMES[name]["latex"])
            #ax.yaxis.set_ticks_position("right")

            if with_idos:
                other_ax = ax.twinx()
                other_ax.plot(wmesh, idos, color="k")
                other_ax.set_ylabel(_ALL_DOS_NAMES[name]["latex"].replace("DOS", "IDOS"))

            if i == len(dos_names) - 1:
                ax.set_xlabel(r"$\omega$ (eV)")
            #ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #15
0
File: bse.py Project: gmatteo/abipy
    def plot(self, ax=None, cplx_mode="Im", qpoint=None, xlims=None, ylims=None, fontsize=12, **kwargs):
        """
        Get a matplotlib plot showing the MDFs.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            cplx_mode: string defining the data to print (case-insensitive).
                Possible choices are ``re`` for the real part, ``im`` for imaginary part only. ``abs`` for the absolute value.
                Options can be concated with "-".
            qpoint: index of the q-point or :class:`Kpoint` object or None to plot emacro_avg.
            xlims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            ylims: Same meaning as ``ylims`` but for the y-axis
            fontsize: Legend and label fontsize.

        Return: |matplotlib-Figure|
        """
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.grid(True)
        ax.set_xlabel('Frequency (eV)')
        ax.set_ylabel('Macroscopic DF')

        cmodes = cplx_mode.split("-")
        qtag = "avg" if qpoint is None else repr(qpoint)

        lines, legends = [], []
        for label, mdf in self._mdfs.items():
            for cmode in cmodes:
                # Plot the average value
                l = mdf.plot_ax(ax, qpoint, cplx_mode=cmode, **kwargs)[0]
                lines.append(l)
                legends.append(r"%s: %s, %s $\varepsilon$" % (cmode, qtag, label))

        # Set legends.
        ax.legend(lines, legends, loc='best', fontsize=fontsize, shadow=True)
        set_axlims(ax, xlims, "x")
        set_axlims(ax, ylims, "y")

        return fig
Example #16
0
    def plot_chi2(self, key, components="all", what="abs", itemp=0, decompose=False,
                  ax=None, xlims=None, with_xlabel=True, label=None, fontsize=12, **kwargs):
        """
        Low-level function to plot chi2 tensor.

        Args:
            key:
            components: List of cartesian tensor components to plot e.g. ["xxx", "xyz"].
                "all" if all components available on file should be plotted on the same ax.
            what: quantity to plot. "re" for real part, "im" for imaginary, Accepts also "abs", "angle".
            itemp: Temperature index.
            decompose: True to plot individual contributions.
            ax: |matplotlib-Axes| or None if a new figure should be created.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            with_xlabel: True to add x-label.
            label: True to add legend label to each curve.
            fontsize: Legend and label fontsize.

        Returns: |matplotlib-Figure|
        """
        if not self.reader.computed_components[key]: return None
        comp2terms = self.reader.read_tensor3_terms(key, components, itemp=itemp)

        ax, fig, plt = get_ax_fig_plt(ax=ax)
        for comp, terms in comp2terms.items():
            for name, values in terms.items():
                if not decompose and not name.endswith("tot"): continue
                values = data_from_cplx_mode(what, values)
                ax.plot(self.wmesh[1:], values[1:],
                        label=self.get_chi2_latex_label(key, what, comp) if label is None else label,
                )

        ax.grid(True)
        if with_xlabel: ax.set_xlabel('Photon Energy (eV)')
        set_axlims(ax, xlims, "x")
        ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig
Example #17
0
    def plot_phbands_with_gruns(self, fill_with="gruns", gamma_fact=1, alpha=0.6, with_doses="all", units="eV",
                                ylims=None, match_bands=False, qlabels=None, branch_range=None, **kwargs):
        r"""
        Plot the phonon bands corresponding to ``V0`` (the central point) with markers
        showing the value and the sign of the Grunesein parameters.

        Args:
            fill_with: Define the quantity used to plot stripes. "gruns" for Grunesein parameters, "gruns_fd" for
                Grunesein parameters calculated with finite differences,  "groupv" for phonon group velocities.
            gamma_fact: Scaling factor for Grunesein parameters.
                Up triangle for positive values, down triangles for negative values.
            alpha: The alpha blending value for the markers between 0 (transparent) and 1 (opaque).
            with_doses: "all" to plot all DOSes available, ``None`` to disable DOS plotting,
                else list of strings with the name of the DOSes to plot.
            units: Units for phonon plots. Possible values in ("eV", "meV", "Ha", "cm-1", "Thz"). Case-insensitive.
            ylims: Set the data limits for the y-axis in eV. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            match_bands: if True tries to follow the band along the path based on the scalar product of the eigenvectors.
            qlabels: dictionary whose keys are tuples with the reduced coordinates of the q-points.
                The values are the labels. e.g. ``qlabels = {(0.0,0.0,0.0): "$\Gamma$", (0.5,0,0): "L"}``.
            branch_range: Tuple specifying the minimum and maximum branch index to plot (default: all branches are plotted).

        Returns: |matplotlib-Figure|.
        """
        if not self.phbands_qpath_vol: return None
        phbands = self.phbands_qpath_vol[self.iv0]
        factor = phbands.phfactor_ev2units(units)
        gamma_fact *= factor

        # Build axes (ax_bands and ax_doses)
        if with_doses is None:
            ax_bands, fig, plt = get_ax_fig_plt(ax=None)
        else:
            import matplotlib.pyplot as plt
            from matplotlib.gridspec import GridSpec
            dos_names = list(_ALL_DOS_NAMES.keys()) if with_doses == "all" else list_strings(with_doses)
            ncols = 1 + len(dos_names)
            fig = plt.figure()
            width_ratios = [2] + len(dos_names) * [0.2]
            gspec = GridSpec(1, ncols, width_ratios=width_ratios, wspace=0.05)
            ax_bands = plt.subplot(gspec[0])
            ax_doses = []
            for i in range(len(dos_names)):
                ax_doses.append(plt.subplot(gspec[i + 1], sharey=ax_bands))

        # Plot phonon bands.
        phbands.plot(ax=ax_bands, units=units, match_bands=match_bands, show=False, qlabels=qlabels,
                     branch_range=branch_range)

        if fill_with == "gruns":
            max_gamma = np.abs(phbands.grun_vals).max()
            values = phbands.grun_vals
        elif fill_with == "groupv":
            # TODO: units?
            dwdq_qpath = self.reader.read_value("gruns_dwdq_qpath")
            values = np.linalg.norm(dwdq_qpath, axis=-1)
            max_gamma = np.abs(values).max()
        elif fill_with == "gruns_fd":
            max_gamma = np.abs(self.grun_vals_finite_differences(match_eigv=True)).max()
            values = self.grun_vals_finite_differences(match_eigv=True)
        else:
            raise ValueError("Unsupported fill_with: `%s`" % fill_with)

        # Plot gruneisen markers on top of band structure.
        xvals = np.arange(len(phbands.phfreqs))
        max_omega = np.abs(phbands.phfreqs).max()

        # Select the band range.
        if branch_range is None:
            branch_range = range(phbands.num_branches)
        else:
            branch_range = range(branch_range[0], branch_range[1], 1)

        for nu in branch_range:
            omegas = phbands.phfreqs[:, nu].copy() * factor

            if fill_with.startswith("gruns"):
                # Must handle positive-negative values
                sizes = values[:, nu].copy() * (gamma_fact * 0.02 * max_omega / max_gamma)
                yup = omegas + np.where(sizes >= 0, sizes, 0)
                ydown = omegas + np.where(sizes < 0, sizes, 0)
                ax_bands.fill_between(xvals, omegas, yup, alpha=alpha, facecolor="red")
                ax_bands.fill_between(xvals, ydown, omegas, alpha=alpha, facecolor="blue")

            elif fill_with == "groupv":
                sizes = values[:, nu].copy() * (gamma_fact * 0.04 * max_omega / max_gamma)
                ydown, yup = omegas - sizes / 2, omegas + sizes / 2
                ax_bands.fill_between(xvals, ydown, yup, alpha=alpha, facecolor="red")

        set_axlims(ax_bands, ylims, "x")

        if with_doses is None:
            return fig

        # Plot Doses.
        wmesh = self.doses["wmesh"] * factor
        for i, (name, ax) in enumerate(zip(dos_names, ax_doses)):
            dos, idos = self.doses[name][0], self.doses[name][1]
            ax.plot(dos, wmesh, label=name, color="k")
            set_axlims(ax, ylims, "x")
            ax.grid(True)
            ax.set_ylabel("")
            ax.tick_params(labelbottom=False)
            if i == len(dos_names) - 1:
                ax.yaxis.set_ticks_position("right")
            else:
                ax.tick_params(labelleft=False)
            ax.set_title(_ALL_DOS_NAMES[name]["latex"])

        return fig
Example #18
0
    def plot_phbands_with_gruns(self, fill_with="gruns", gamma_fact=1, alpha=0.6, with_doses="all", units="eV",
                                ylims=None, match_bands=False, qlabels=None, branch_range=None, **kwargs):
        """
        Plot the phonon bands corresponding to ``V0`` (the central point) with markers
        showing the value and the sign of the Grunesein parameters.

        Args:
            fill_with: Define the quantity used to plot stripes. "gruns" for Grunesein parameters, "gruns_fd" for
                Grunesein parameters calculated with finite differences,  "groupv" for phonon group velocities.
            gamma_fact: Scaling factor for Grunesein parameters.
                Up triangle for positive values, down triangles for negative values.
            alpha: The alpha blending value for the markers between 0 (transparent) and 1 (opaque).
            with_doses: "all" to plot all DOSes available, ``None`` to disable DOS plotting,
                else list of strings with the name of the DOSes to plot.
            units: Units for phonon plots. Possible values in ("eV", "meV", "Ha", "cm-1", "Thz"). Case-insensitive.
            ylims: Set the data limits for the y-axis in eV. Accept tuple e.g. ``(left, right)``
                or scalar e.g. ``left``. If left (right) is None, default values are used
            match_bands: if True tries to follow the band along the path based on the scalar product of the eigenvectors.
            qlabels: dictionary whose keys are tuples with the reduced coordinates of the q-points.
                The values are the labels. e.g. ``qlabels = {(0.0,0.0,0.0): "$\Gamma$", (0.5,0,0): "L"}``.
            branch_range: Tuple specifying the minimum and maximum branch index to plot (default: all branches are plotted).

        Returns: |matplotlib-Figure|.
        """
        if not self.phbands_qpath_vol: return None
        phbands = self.phbands_qpath_vol[self.iv0]
        factor = phbands.phfactor_ev2units(units)
        gamma_fact *= factor

        # Build axes (ax_bands and ax_doses)
        if with_doses is None:
            ax_bands, fig, plt = get_ax_fig_plt(ax=None)
        else:
            import matplotlib.pyplot as plt
            from matplotlib.gridspec import GridSpec
            dos_names = list(_ALL_DOS_NAMES.keys()) if with_doses == "all" else list_strings(with_doses)
            ncols = 1 + len(dos_names)
            fig = plt.figure()
            width_ratios = [2] + len(dos_names) * [0.2]
            gspec = GridSpec(1, ncols, width_ratios=width_ratios, wspace=0.05)
            ax_bands = plt.subplot(gspec[0])
            ax_doses = []
            for i in range(len(dos_names)):
                ax_doses.append(plt.subplot(gspec[i + 1], sharey=ax_bands))

        # Plot phonon bands.
        phbands.plot(ax=ax_bands, units=units, match_bands=match_bands, show=False, qlabels=qlabels,
                     branch_range=branch_range)

        if fill_with == "gruns":
            max_gamma = np.abs(phbands.grun_vals).max()
            values = phbands.grun_vals
        elif fill_with == "groupv":
            # TODO: units?
            dwdq_qpath = self.reader.read_value("gruns_dwdq_qpath")
            values = np.linalg.norm(dwdq_qpath, axis=-1)
            max_gamma = np.abs(values).max()
        elif fill_with == "gruns_fd":
            max_gamma = np.abs(self.grun_vals_finite_differences(match_eigv=True)).max()
            values = self.grun_vals_finite_differences(match_eigv=True)
        else:
            raise ValueError("Unsupported fill_with: `%s`" % fill_with)

        # Plot gruneisen markers on top of band structure.
        xvals = np.arange(len(phbands.phfreqs))
        max_omega = np.abs(phbands.phfreqs).max()

        # Select the band range.
        if branch_range is None:
            branch_range = range(phbands.num_branches)
        else:
            branch_range = range(branch_range[0], branch_range[1], 1)

        for nu in branch_range:
            omegas = phbands.phfreqs[:, nu].copy() * factor

            if fill_with.startswith("gruns"):
                # Must handle positive-negative values
                sizes = values[:, nu].copy() * (gamma_fact * 0.02 * max_omega / max_gamma)
                yup = omegas + np.where(sizes >= 0, sizes, 0)
                ydown = omegas + np.where(sizes < 0, sizes, 0)
                ax_bands.fill_between(xvals, omegas, yup, alpha=alpha, facecolor="red")
                ax_bands.fill_between(xvals, ydown, omegas, alpha=alpha, facecolor="blue")

            elif fill_with == "groupv":
                sizes = values[:, nu].copy() * (gamma_fact * 0.04 * max_omega / max_gamma)
                ydown, yup = omegas - sizes / 2, omegas + sizes / 2
                ax_bands.fill_between(xvals, ydown, yup, alpha=alpha, facecolor="red")

        set_axlims(ax_bands, ylims, "x")

        if with_doses is None:
            return fig

        # Plot Doses.
        wmesh = self.doses["wmesh"] * factor
        for i, (name, ax) in enumerate(zip(dos_names, ax_doses)):
            dos, idos = self.doses[name][0], self.doses[name][1]
            ax.plot(dos, wmesh, label=name, color="k")
            set_axlims(ax, ylims, "x")
            ax.grid(True)
            ax.set_ylabel("")
            ax.tick_params(labelbottom=False)
            if i == len(dos_names) - 1:
                ax.yaxis.set_ticks_position("right")
            else:
                ax.tick_params(labelleft=False)
            ax.set_title(_ALL_DOS_NAMES[name]["latex"])

        return fig
Example #19
0
    def plot_tensor(self,
                    tstart=0,
                    tstop=600,
                    num=50,
                    components="all",
                    what="displ",
                    view="inequivalent",
                    select_symbols=None,
                    colormap="jet",
                    xlims=None,
                    ylims=None,
                    fontsize=10,
                    verbose=0,
                    **kwargs):
        """
        Plot tensor(T) for each atom in the unit cell.
        One subplot for each component, each subplot show all inequivalent sites.
        By default, only "inequivalent" atoms are shown.

        Args:
            tstart: The starting value (in Kelvin) of the temperature mesh.
            tstop: The end value (in Kelvin) of the mesh.
            num: int, optional Number of samples to generate.
            components: "all" for all components. "diag" for diagonal elements, "offdiag" for off-diagonal terms only.
            what: "displ" for displament, "vel" for velocity.
            view: "inequivalent" to show only inequivalent atoms. "all" for all sites.
            select_symbols: String or list of strings with chemical symbols. Used to select only atoms of this type.
            colormap: matplotlib colormap.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            ylims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used
            fontsize: Legend and title fontsize.
            verbose: Verbosity level.

        Returns: |matplotlib-Figure|
        """
        # Select atoms.
        aview = self._get_atomview(view,
                                   select_symbols=select_symbols,
                                   verbose=verbose)

        # One subplot for each component
        diag = ["xx", "yy", "zz"]
        offdiag = ["xy", "xz", "yz"]
        components = {
            "all": diag + offdiag,
            "diag": diag,
            "offdiag": offdiag,
        }[components]

        components = self._get_components(components)
        shape = np.reshape(components, (-1, 3)).shape
        nrows, ncols = shape[0], shape[1]

        ax_list, fig, plt = get_axarray_fig_plt(None,
                                                nrows=nrows,
                                                ncols=ncols,
                                                sharex=True,
                                                sharey=True,
                                                squeeze=True)
        ax_list = np.reshape(ax_list, (nrows, ncols)).ravel()
        cmap = plt.get_cmap(colormap)

        # Compute U(T)
        tmesh = np.linspace(tstart, tstop, num=num)
        msq = self.get_msq_tmesh(tmesh,
                                 iatom_list=aview.iatom_list,
                                 what_list=what)
        # [natom,3,3,nt] array
        values = getattr(msq, what)

        for ix, (ax, comp) in enumerate(zip(ax_list, components)):
            irow, icol = divmod(ix, ncols)
            ax.grid(True)
            set_axlims(ax, xlims, "x")
            set_axlims(ax, ylims, "y")
            ylabel = comp.get_tavg_label(what, with_units=True)
            ax.set_ylabel(ylabel, fontsize=fontsize)

            # Plot this component for all inequivalent atoms on the same subplot.
            for ii, (iatom, site_label) in enumerate(
                    zip(aview.iatom_list, aview.site_labels)):
                color = cmap(float(ii) / max((len(aview.iatom_list) - 1), 1))
                ys = comp.eval33w(values[iatom])
                ax.plot(msq.tmesh,
                        ys,
                        label=site_label if ix == 0 else None,
                        color=color)  #, marker="o")
                if ix == 0:
                    ax.legend(loc="best", fontsize=fontsize, shadow=True)

            if irow == 1:
                ax.set_xlabel('Temperature (K)')
            else:
                set_visible(ax, False, "xlabel", "xticklabels")

        return fig
Example #20
0
    def plot_uiso(self,
                  tstart=0,
                  tstop=600,
                  num=50,
                  what="displ",
                  view="inequivalent",
                  select_symbols=None,
                  colormap="jet",
                  xlims=None,
                  ylims=None,
                  sharey=False,
                  fontsize=10,
                  verbose=0,
                  **kwargs):
        """
        Plot phonon PJDOS for each atom in the unit cell.
        One subplot for each component, each subplot show all inequivalent sites.
        By default, only "inequivalent" atoms are shown.

        comparison of Ueq values, which
        are calculated as the mean of the diagonal elements of the harmonic ADP tensor, (d)
        comparison of the ADP anisotropy factor, which is defined as the ratio between maximum Uii
        and minimum Uii values. A ratio of 1 would correspond to an isotropic displacement.

        Args:
            tstart: The starting value (in Kelvin) of the temperature mesh.
            tstop: The end value (in Kelvin) of the mesh.
            num: int, optional Number of samples to generate.
            components: "all" for all components. "diag" for diagonal elements, "offdiag" for off-diagonal terms only.
            what: "displ" for displament, "vel" for velocity.
            view: "inequivalent" to show only inequivalent atoms. "all" for all sites.
            select_symbols: String or list of strings with chemical symbols. Used to select only atoms of this type.
            colormap: matplotlib colormap.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            ylims: Set the data limits for the y-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used
            sharey: True if y-axis should be shared.
            fontsize: Legend and title fontsize.
            verbose: Verbosity level.

        Returns: |matplotlib-Figure|
        """
        # Select atoms.
        aview = self._get_atomview(view,
                                   select_symbols=select_symbols,
                                   verbose=verbose)

        ax_list, fig, plt = get_axarray_fig_plt(None,
                                                nrows=2,
                                                ncols=1,
                                                sharex=True,
                                                sharey=sharey,
                                                squeeze=True)
        cmap = plt.get_cmap(colormap)

        # Compute U(T)
        tmesh = np.linspace(tstart, tstop, num=num)
        msq = self.get_msq_tmesh(tmesh,
                                 iatom_list=aview.iatom_list,
                                 what_list=what)
        # [natom, 3, 3, nt]
        values = getattr(msq, what)
        ntemp = len(msq.tmesh)

        for ix, ax in enumerate(ax_list):
            ax.grid(True)
            set_axlims(ax, xlims, "x")
            set_axlims(ax, ylims, "y")
            if what == "displ":
                ylabel = r"$U_{iso}\;(\AA^2)$" if ix == 0 else \
                         r"Anisotropy factor ($\dfrac{\epsilon_{max}}{\epsilon_{min}}}$)"
            elif what == "vel":
                ylabel = r"$V_{iso}\;(m/s)^2$" if ix == 0 else \
                         r"Anisotropy factor ($\dfrac{\epsilon_{max}}{\epsilon_{min}}}$)"
            else:
                raise ValueError("Unknown value for what: `%s`" % str(what))
            ax.set_ylabel(ylabel, fontsize=fontsize)

            # Plot this component for all inequivalent atoms on the same subplot.
            for ii, (iatom, site_label) in enumerate(
                    zip(aview.iatom_list, aview.site_labels)):
                color = cmap(float(ii) / max((len(aview.iatom_list) - 1), 1))
                #msq.displ[iatom, 3, 3, nt]
                if ix == 0:
                    # ISO calculated as the mean of the diagonal elements of the harmonic ADP tensor
                    ys = np.trace(values[iatom]) / 3.0
                elif ix == 1:
                    # Ratio between maximum Uii and minimum Uii values.
                    # A ratio of 1 would correspond to an isotropic displacement.
                    ys = np.empty(ntemp)
                    for itemp in range(ntemp):
                        eigs = np.linalg.eigvalsh(values[iatom, :, :, itemp],
                                                  UPLO='U')
                        ys[itemp] = eigs.max() / eigs.min()
                else:
                    raise ValueError("Invalid ix index: `%s" % ix)

                ax.plot(msq.tmesh,
                        ys,
                        label=site_label if ix == 0 else None,
                        color=color)  #, marker="o")
                if ix == 0:
                    ax.legend(loc="best", fontsize=fontsize, shadow=True)

            if ix == len(ax_list) - 1:
                ax.set_xlabel("Temperature (K)")
            else:
                set_visible(ax, False, "xlabel", "xticklabels")

        return fig
Example #21
0
    def plot_mdftype_cplx(self,
                          mdf_type,
                          cplx_mode,
                          qpoint=None,
                          ax=None,
                          xlims=None,
                          ylims=None,
                          with_legend=True,
                          with_xlabel=True,
                          with_ylabel=True,
                          fontsize=8,
                          **kwargs):
        """
        Helper function to plot data corresponds to ``mdf_type``, ``cplx_mode``, ``qpoint``.

        Args:
            ax: |matplotlib-Axes| or None if a new figure should be created.
            mdf_type:
            cplx_mode: string defining the data to print (case-insensitive).
                Possible choices are `re` for the real part, `im` for imaginary part only. `abs` for the absolute value.
            qpoint: index of the q-point or :class:`Kpoint` object or None to plot emacro_avg.
            xlims: Set the data limits for the y-axis. Accept tuple e.g. `(left, right)`
                  or scalar e.g. `left`. If left (right) is None, default values are used
            ylims: Same meaning as `ylims` but for the y-axis
            with_legend: True if legend should be added
            with_xlabel:
            with_ylabel:
            fontsize: Legend and label fontsize.

        Return: |matplotlib-Figure|
        """
        ax, fig, plt = get_ax_fig_plt(ax=ax)
        ax.grid(True)

        if with_xlabel: ax.set_xlabel("Frequency (eV)")
        if with_ylabel:
            ax.set_ylabel(self.MDF_TYPECPLX2TEX[mdf_type][cplx_mode.lower()])

        can_use_basename = self._can_use_basenames_as_labels()
        qtag = "avg" if qpoint is None else repr(qpoint)

        lines, legends = [], []
        for label, mdf_dict in self._mdfs.items():
            mdf = mdf_dict[mdf_type]
            # Plot the average value
            l = mdf.plot_ax(ax, qpoint, cplx_mode=cplx_mode, **kwargs)[0]
            lines.append(l)
            if can_use_basename:
                label = os.path.basename(label)
            else:
                # Use relative paths if label is a file.
                if os.path.isfile(label): label = os.path.relpath(label)

            legends.append(r"%s: %s, %s $\varepsilon$" %
                           (cplx_mode, qtag, label))

        set_axlims(ax, xlims, "x")
        set_axlims(ax, ylims, "y")

        # Set legends.
        if with_legend:
            ax.legend(lines,
                      legends,
                      loc='best',
                      fontsize=fontsize,
                      shadow=True)

        return fig
Example #22
0
    def plot(self,
             components="upper",
             view="inequivalent",
             units="eV",
             select_symbols=None,
             xlims=None,
             ylims=None,
             sharey=False,
             fontsize=8,
             verbose=0,
             **kwargs):
        """
        Plot the generalized phonon DOS g_ij(omega, atom) for each atom in the unit cell.
        One subplot per atom. Each subplot shows the 9 independent components of the symmetric tensor.
        as a function of frequency. By default, only "inequivalent" atoms are shown.

        Args:
            view: "inequivalent" to show only inequivalent atoms. "all" for all sites.
            components: List of cartesian tensor components to plot e.g. ["xx", "xy"].
                "all" for all components. "upper" for the upper triangle, "diag" for diagonal elements.
            units: Units energy axis. Possible values in ("eV", "meV", "Ha", "cm-1", "Thz").
                Case-insensitive.
            select_symbols: String or list of strings with chemical symbols. Used to select only atoms of this type.
            xlims: Set the data limits for the x-axis. Accept tuple e.g. ``(left, right)``
                   or scalar e.g. ``left``. If left (right) is None, default values are used.
            ylims: Set the data limits for the y-axis.
            sharey: True if y-axis should be shared.
            fontsize: Legend and title fontsize.
            verbose: Verbosity level.

        Returns: |matplotlib-Figure|
        """
        # TODO Decide units for internal arrays.
        factor = abu.phfactor_ev2units(units)

        # Select atoms.
        aview = self._get_atomview(view, select_symbols, verbose=verbose)

        num_plots = len(aview.iatom_list)
        nrows, ncols = 1, 1
        if num_plots > 1:
            ncols = 2
            nrows = num_plots // ncols + num_plots % ncols

        ax_list, fig, plt = get_axarray_fig_plt(None,
                                                nrows=nrows,
                                                ncols=ncols,
                                                sharex=True,
                                                sharey=sharey,
                                                squeeze=True)
        ax_list = np.reshape(ax_list, (nrows, ncols)).ravel()
        # don't show the last ax if num_plots is odd.
        if num_plots % ncols != 0: ax_list[-1].axis("off")

        xx = self.wmesh * factor
        components = self._get_components(components)

        # For each atom in the view.
        for ix, (ax, iatom, site_label) in enumerate(
                zip(ax_list, aview.iatom_list, aview.site_labels)):
            irow, icol = divmod(ix, ncols)
            ax.grid(True)
            set_axlims(ax, xlims, "x")
            set_axlims(ax, ylims, "y")
            ax.set_title(site_label, fontsize=fontsize)
            #site = self.structure[iatom]
            #color = cmap(float(iatom) / max((len(iatom_list) - 1), 1))

            # Plot components for this atom on the same ax.
            for c in components:
                yw = c.eval33w(self.values[iatom])
                label = r"$G_{%s}$" % c.name if ix == 0 else None
                ax.plot(xx, yw / factor, label=label, **c.plot_kwargs)

            # Handle labels.
            if irow == nrows - 1:
                ax.set_xlabel('Frequency %s' % abu.phunit_tag(units))
            else:
                set_visible(ax, False, "xlabel", "xticklabels")

            if ix == 0:
                ax.set_ylabel(r"$g_{ij}(\omega)$ 1/%s (Cart coords)" %
                              abu.phunit_tag(units))
                ax.legend(loc="best", fontsize=fontsize, shadow=True)

        return fig