Пример #1
0
    def plot(self, show_IDs=False):
        '''
        Method of ED class
        Plot the energy diagram. Use show_IDs=True for showing the IDs of the
        energy levels and allowing an easy linking.
        E|          4__
        n|   2__    /  \
        e|1__/  \__/5   \
        r|  3\__/       6\__
        g|
        y|

        Parameters
        ----------
        show_IDs : bool
            show the IDs of the energy levels; is False by default

        Returns
        -------
        fig (plt.figure) and ax (fig.add_subplot())

        '''

        fig = plt.figure()
        ax = fig.add_subplot(111, aspect=self.aspect)
        ax.set_ylabel(self.ylabel)
        ax.axes.get_xaxis().set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)

        self.__auto_adjust()

        data = zip(
            self.energies,  # 0
            self.positions,  # 1
            self.bottom_texts,  # 2
            self.top_texts,  # 3
            self.colors,  # 4
            self.left_texts,  # 5
            self.right_texts)  # 6

        for level in data:
            start = level[1] * (self.dimension + self.space
                                )  # Start x position

            # Plot the state's energy level line
            ax.hlines(level[0], start, start + self.dimension, color=level[4])

            # Label the energy level line
            ax.text(
                start + self.dimension / 2.,  # X
                level[0] + self.offset,  # Y
                level[3],  # self.top_texts
                horizontalalignment='center',
                verticalalignment='bottom')

            ax.text(
                start + self.dimension,  # X
                level[0],  # Y
                level[5],  # self.left_texts
                horizontalalignment='left',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start,  # X
                level[0],  # Y
                level[6],  # self.right_texts
                horizontalalignment='right',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start + self.dimension / 2.,  # X
                level[0] - self.offset * 2,  # Y
                level[2],  # self.bottom_text
                horizontalalignment='center',
                verticalalignment='top',
                color=self.color_bottom_text)

        if show_IDs:
            # for showing the ID allowing the user to identify the level
            # csera: This wasn't working with the 'data' zip, so I rewrote this to work directly
            # with the self.[props]

            for l in range(len(self.energies)):
                objNum = l + 1
                start = self.positions[l] * (self.dimension + self.space)
                ax.text(start,
                        self.energies[l] + self.offset,
                        self.positions[l],
                        horizontalalignment='right',
                        color='red')

        for idx, arrow in enumerate(self.arrows):
            # by Kalyan Jyoti Kalita: put arrows between to levels
            # x1, x2   y1, y2
            for i in arrow:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + 0.5 * self.dimension
                x2 = start + 0.5 * self.dimension
                y1 = self.energies[idx]
                y2 = self.energies[i]
                gap = y1 - y2
                gapnew = '{0:.2f}'.format(gap)
                middle = y1 - 0.5 * gap  #warning: this way works for negative H**O/LUMO energies
                ax.annotate("",
                            xy=(x1, y1),
                            xytext=(x2, middle),
                            arrowprops=dict(color='green',
                                            width=1.5,
                                            headwidth=5))
                ax.annotate(s=gapnew,
                            xy=(x2, y2),
                            xytext=(x1, middle),
                            color='green',
                            arrowprops=dict(width=6,
                                            headwidth=15,
                                            color='green'),
                            bbox=dict(boxstyle='round', fc='white'),
                            ha='center',
                            va='center')

        for idx, link in enumerate(self.links):
            # here we connect the levels with the links
            # x1, x2   y1, y2
            for i in link:
                # i is a tuple: (end_level_id,ls,linewidth,color)
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + self.dimension
                x2 = self.positions[i[0]] * (self.dimension + self.space)
                y1 = self.energies[idx]
                y2 = self.energies[i[0]]
                line = Line2D([x1, x2], [y1, y2],
                              ls=i[1],
                              linewidth=i[2],
                              color=i[3])
                ax.add_line(line)

        for box in self.electons_boxes:
            # here we add the boxes
            # x,y,boxes,electrons,side,spacing_f
            x, y, boxes, electrons, side, spacing_f = box
            plot_orbital_boxes(ax, x, y, boxes, electrons, side, spacing_f)

        # Return fig and ax
        self.ax = ax
        self.fig = fig
Пример #2
0
    def plot(self, show_IDs=False):
        '''
        Method of ED class
        Plot the energy diagram. Use show_IDs=True for showing the IDs of the
        energy levels and allowing an easy linking.
        E|          4__  
        n|   2__    /  \  
        e|1__/  \__/5   \
        r|  3\__/       6\__
        g|
        y|
        
        Parameters
        ----------
        show_IDs : bool 
            show the IDs of the energy levels 
        
        Returns
        -------
        fig (plt.figure) and ax (fig.add_subplot()) 

        '''
        fig = plt.figure()
        ax = fig.add_subplot(111, aspect='equal')
        ax.set_ylabel("Energy / $kcal$ $mol^{-1}$")
        ax.axes.get_xaxis().set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)

        data = zip(
            self.energies,  # 0
            self.positions,  # 1
            self.bottom_texts,  # 2
            self.top_texts,  # 3
            self.colors)  # 4

        for level in data:
            start = level[1] * (self.dimension + self.space)
            ax.hlines(level[0], start, start + self.dimension, color=level[4])
            ax.text(
                start + self.dimension / 2.,  #X
                level[0] + self.offset,  #Y
                level[3],  # self.top_texts 
                horizontalalignment='center')
            ax.text(
                start + self.dimension / 2.,  # X
                level[0] - self.offset * 2,  # Y
                level[2],  # self.bottom_text
                horizontalalignment='center',
                color=self.color_bottom_text)
        if show_IDs:
            #for showing the ID allowing the user to identify the level
            for ind, level in enumerate(data):
                start = level[1] * (self.dimension + self.space)
                ax.text(start,
                        level[0] + self.offset,
                        str(ind),
                        horizontalalignment='right',
                        color='red')

        for idx, arrow in enumerate(self.arrows):
            # by Kalyan Jyoti Kalita: put arrows between to levels
            # x1, x2   y1, y2
            for i in arrow:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + 0.5 * self.dimension
                x2 = start + 0.5 * self.dimension
                y1 = self.energies[idx]
                y2 = self.energies[i]
                gap = y1 - y2
                gapnew = '{0:.2f}'.format(gap)
                middle = y1 - 0.5 * gap  #warning: this way works for negative H**O/LUMO energies
                ax.annotate("",
                            xy=(x1, y1),
                            xytext=(x2, middle),
                            arrowprops=dict(color='green',
                                            width=1.5,
                                            headwidth=5))
                ax.annotate(s=gapnew,
                            xy=(x2, y2),
                            xytext=(x1, middle),
                            color='green',
                            arrowprops=dict(width=1.5,
                                            headwidth=5,
                                            color='green'),
                            bbox=dict(boxstyle='round', fc='white'),
                            ha='center',
                            va='center')

        for idx, link in enumerate(self.links):
            #here we connect the levels with the links
            # x1, x2   y1, y2
            for i in link:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + self.dimension
                x2 = self.positions[i] * (self.dimension + self.space)
                y1 = self.energies[idx]
                y2 = self.energies[i]
                l = Line2D([x1, x2], [y1, y2],
                           ls='--',
                           linewidth=0.5,
                           color='k')
                ax.add_line(l)

        for box in self.electons_boxes:
            #here we add the boxes
            # x,y,boxes,electrons,side,spacing_f
            x, y, boxes, electrons, side, spacing_f = box
            plot_orbital_boxes(ax, x, y, boxes, electrons, side, spacing_f)

        self.fig = fig
        self.ax = ax
Пример #3
0
    def plot(self, show_IDs=False):
        '''
        Method of ED class
        Plot the energy diagram. Use show_IDs=True for showing the IDs of the
        energy levels and allowing an easy linking.
        E|          4__
        n|   2__    /  \
        e|1__/  \__/5   \
        r|  3\__/       6\__
        g|
        y|

        Parameters
        ----------
        show_IDs : bool
            show the IDs of the energy levels

        Returns
        -------
        fig (plt.figure) and ax (fig.add_subplot())

        '''
        fig = plt.figure()
        ax = fig.add_subplot(111, aspect=self.aspect)
        ax.set_ylabel("Energy / $kcal$ $mol^{-1}$")
        ax.axes.get_xaxis().set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)

        self.__auto_adjust()

        # Set reaction steps labels if requested
        if self.reaction_steps_labels:
            xticks_positions = []
            xticks_labels = []
            # Search for defined labels
            for position in set(self.positions):
                # Retrieve associated label
                try:
                    position_label = self.reaction_steps_labels[position - 1]
                except IndexError:
                    continue
                # Compute x-coordinates of reaction step position
                start = position * (self.dimension + self.space)
                xticks_positions.append(start + self.dimension / 2.)
                # Add reaction step label
                xticks_labels.append(position_label)
            # Set defined labels
            if xticks_labels:
                ax.axes.get_xaxis().set_visible(True)
                ax.spines['bottom'].set_visible(True)
                ax.set_xticks(xticks_positions)
                ax.set_xticklabels(xticks_labels)

        data = zip(
            self.energies,  # 0
            self.positions,  # 1
            self.bottom_texts,  # 2
            self.top_texts,  # 3
            self.colors,  # 4
            self.left_texts,  # 5
            self.right_texts)  # 6

        for level in data:
            start = level[1] * (self.dimension + self.space)
            ax.hlines(level[0], start, start + self.dimension, color=level[4])
            ax.text(
                start + self.dimension / 2.,  # X
                level[0] + self.offset,  # Y
                level[3],  # self.top_texts
                horizontalalignment='center',
                verticalalignment='bottom')

            ax.text(
                start + self.dimension,  # X
                level[0],  # Y
                level[5],  # self.bottom_text
                horizontalalignment='left',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start,  # X
                level[0],  # Y
                level[6],  # self.bottom_text
                horizontalalignment='right',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start + self.dimension / 2.,  # X
                level[0] - self.offset * 2,  # Y
                level[2],  # self.bottom_text
                horizontalalignment='center',
                verticalalignment='top',
                color=self.color_bottom_text)
        if show_IDs:
            # for showing the ID allowing the user to identify the level
            for ind, level in enumerate(data):
                start = level[1] * (self.dimension + self.space)
                ax.text(start,
                        level[0] + self.offset,
                        str(ind),
                        horizontalalignment='right',
                        color='red')

        for idx, arrow in enumerate(self.arrows):
            # by Kalyan Jyoti Kalita: put arrows between to levels
            # x1, x2   y1, y2
            for i in arrow:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + 0.5 * self.dimension
                x2 = start + 0.5 * self.dimension
                y1 = self.energies[idx]
                y2 = self.energies[i]
                gap = y1 - y2
                gapnew = '{0:.2f}'.format(gap)
                middle = y1 - 0.5 * gap  #warning: this way works for negative H**O/LUMO energies
                ax.annotate("",
                            xy=(x1, y1),
                            xytext=(x2, middle),
                            arrowprops=dict(color='green',
                                            width=1.5,
                                            headwidth=5))
                ax.annotate(s=gapnew,
                            xy=(x2, y2),
                            xytext=(x1, middle),
                            color='green',
                            arrowprops=dict(width=6,
                                            headwidth=15,
                                            color='green'),
                            bbox=dict(boxstyle='round', fc='white'),
                            ha='center',
                            va='center')

        for idx, link in enumerate(self.links):
            # here we connect the levels with the links
            # x1, x2   y1, y2
            for i in link:
                # i is a tuple: (end_level_id,ls,linewidth,color)
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + self.dimension
                x2 = self.positions[i[0]] * (self.dimension + self.space)
                y1 = self.energies[idx]
                y2 = self.energies[i[0]]
                line = Line2D([x1, x2], [y1, y2],
                              ls=i[1],
                              linewidth=i[2],
                              color=i[3])
                ax.add_line(line)

        for box in self.electons_boxes:
            # here we add the boxes
            # x,y,boxes,electrons,side,spacing_f
            x, y, boxes, electrons, side, spacing_f = box
            plot_orbital_boxes(ax, x, y, boxes, electrons, side, spacing_f)

        # Return fig and ax
        self.ax = ax
        self.fig = fig
Пример #4
0
    def plot(self, show_IDs=False, show_labels=True):
        '''
        Method of ED class
        Plot the energy diagram. Use show_IDs=True for showing the IDs of the
        energy levels and allowing an easy linking.
        E|          4__
        n|   2__    /  \
        e|1__/  \__/5   \
        r|  3\__/       6\__
        g|
        y|

        Parameters
        ----------
        show_IDs : bool
            show the IDs of the energy levels

        Returns
        -------
        fig (plt.figure) and ax (fig.add_subplot())

        '''
        fig = plt.figure()
        ax = fig.add_subplot(111, aspect=self.aspect)
        if self.eunit == 'kcalmol-1':
            ax.set_ylabel("Energy / $kcal$ $mol^{-1}$")
        elif self.eunit == 'kJmol-1':
            ax.set_ylabel("Energy / $kJ$ $mol^{-1}$")
        ax.axes.get_xaxis().set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)

        self.__auto_adjust()

        data = zip(
            self.energies,  # 0
            self.positions,  # 1
            self.bottom_texts,  # 2
            self.top_texts,  # 3
            self.colors,  # 4
            self.left_texts,  # 5
            self.right_texts)  # 6

        for level in data:
            start = level[1] * (self.dimension + self.space)
            ax.hlines(level[0], start, start + self.dimension, color=level[4])
            if type(level[3]) == float:
                toptxt = format(level[3],
                                '.1f')  #self.top_text, formatfix for energy
            else:
                toptxt = level[3]  #leave as if, if not float

            ax.text(
                start + self.dimension / 2.,  # X
                level[0] + self.offset,  # Y
                toptxt,  # self.top_text
                horizontalalignment='center',
                verticalalignment='bottom')
            if show_labels:
                ax.text(
                    start + self.dimension,  # X
                    level[0],  # Y
                    level[5],  # self.bottom_text
                    horizontalalignment='left',
                    verticalalignment='center',
                    color=self.color_bottom_text)

                ax.text(
                    start,  # X
                    level[0],  # Y
                    level[6],  # self.bottom_text
                    horizontalalignment='right',
                    verticalalignment='center',
                    color=self.color_bottom_text)

                ax.text(
                    start + self.dimension / 2.,  # X
                    level[0] - self.offset * 2,  # Y
                    level[2],  # self.bottom_text
                    horizontalalignment='center',
                    verticalalignment='top',
                    color=self.color_bottom_text)
        if show_IDs:
            # for showing the ID allowing the user to identify the level
            for ind, level in enumerate(data):
                start = level[1] * (self.dimension + self.space)
                ax.text(start,
                        level[0] + self.offset,
                        str(ind),
                        horizontalalignment='right',
                        color='red')

        for idx, arrow in enumerate(self.arrows):
            # by Kalyan Jyoti Kalita: put arrows between to levels
            # x1, x2   y1, y2
            for i in arrow:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + 0.5 * self.dimension
                x2 = start + 0.5 * self.dimension
                y1 = self.energies[idx]
                y2 = self.energies[i]
                gap = y1 - y2
                gapnew = '{0:.2f}'.format(gap)
                middle = y1 - 0.5 * gap  #warning: this way works for negative H**O/LUMO energies
                ax.annotate("",
                            xy=(x1, y1),
                            xytext=(x2, middle),
                            arrowprops=dict(color='green',
                                            width=1.5,
                                            headwidth=5))
                ax.annotate(s=gapnew,
                            xy=(x2, y2),
                            xytext=(x1, middle),
                            color='green',
                            arrowprops=dict(width=6,
                                            headwidth=15,
                                            color='green'),
                            bbox=dict(boxstyle='round', fc='white'),
                            ha='center',
                            va='center')

        for idx, link in enumerate(self.links):
            # here we connect the levels with the links
            # x1, x2   y1, y2
            for i in link:
                # i is a tuple: (end_level_id,ls,linewidth,color)
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + self.dimension
                x2 = self.positions[i[0]] * (self.dimension + self.space)
                y1 = self.energies[idx]
                y2 = self.energies[i[0]]
                line = Line2D([x1, x2], [y1, y2],
                              ls=i[1],
                              linewidth=i[2],
                              color=i[3])
                ax.add_line(line)

        for box in self.electons_boxes:
            # here we add the boxes
            # x,y,boxes,electrons,side,spacing_f
            x, y, boxes, electrons, side, spacing_f = box
            plot_orbital_boxes(ax, x, y, boxes, electrons, side, spacing_f)

        for t in self.bottom_labels:
            level_id, y, text = t
            #start = level_id*(self.dimension+self.space)
            #print(start + self.dimension/2., y, text)
            #ax.text(start + self.dimension/2., y, text)
            ax.text(level_id, y, text, horizontalalignment='center')

        # Return fig and ax
        self.ax = ax
        self.fig = fig
Пример #5
0
    def plot(self, show_IDs=False, ylabel=None, yunit=None):
        '''
        Method of ED class
        Plot the energy diagram. Use show_IDs=True for showing the IDs of the
        energy levels and allowing an easy linking.
        E|          4__
        n|   2__    /  \
        e|1__/  \__/5   \
        r|  3\__/       6\__
        g|
        y|

        Parameters
        ----------
        show_IDs : bool
            show the IDs of the energy levels
        ylabel : string
            determines the y-axis label, if None is given "Energies" is selected
        yunit : string
            determines the y-axis unit, if None is given "kcal/mol" is selected

        Returns
        -------
        fig (plt.figure) and ax (fig.add_subplot())

        '''
        # Check for unit and label
        if ylabel == None:
            label = "Energy"
        elif ylabel == "g":
            label = "$\Delta$G"
        else:
            label = ylabel
        if yunit == None:
            unit = "kcal/mol"
        elif yunit == "kj":
            unit = "kJ/mol"
        elif yunit == "ha":
            unit = "Ha"
        else:
            unit = yunit
        # Check for figure size
        fig = plt.figure(figsize=self.size)
        ax = fig.add_subplot(111, aspect=self.aspect)
        ax.set_ylabel(label + " [" + unit + "]")
        ax.axes.get_xaxis().set_visible(False)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.spines['bottom'].set_visible(False)

        self.__auto_adjust()

        data = zip(
            self.energies,  # 0
            self.positions,  # 1
            self.bottom_texts,  # 2
            self.top_texts,  # 3
            self.colors,  # 4
            self.left_texts,  # 5
            self.right_texts)  # 6

        for level in data:
            start = level[1] * (self.dimension + self.space)
            ax.hlines(level[0], start, start + self.dimension, color=level[4])
            ax.text(
                start + self.dimension / 2.,  # X
                level[0] + self.offset,  # Y
                level[3],  # self.top_texts
                horizontalalignment='center',
                verticalalignment='bottom')

            ax.text(
                start + self.dimension,  # X
                level[0],  # Y
                level[5],  # self.bottom_text
                horizontalalignment='left',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start,  # X
                level[0],  # Y
                level[6],  # self.bottom_text
                horizontalalignment='right',
                verticalalignment='center',
                color=self.color_bottom_text)

            ax.text(
                start + self.dimension / 2.,  # X
                level[0] - self.offset * 2,  # Y
                level[2],  # self.bottom_text
                horizontalalignment='center',
                verticalalignment='top',
                color=self.color_bottom_text)
        if show_IDs:
            # for showing the ID allowing the user to identify the level
            for ind, level in enumerate(data):
                start = level[1] * (self.dimension + self.space)
                ax.text(start,
                        level[0] + self.offset,
                        str(ind),
                        horizontalalignment='right',
                        color='red')

        for idx, arrow in enumerate(self.arrows):
            # by Kalyan Jyoti Kalita: put arrows between to levels
            # x1, x2   y1, y2
            for i in arrow:
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + 0.5 * self.dimension
                x2 = start + 0.5 * self.dimension
                y1 = self.energies[idx]
                y2 = self.energies[i]
                gap = y1 - y2
                gapnew = '{0:.2f}'.format(gap)
                middle = y1 - 0.5 * gap  #warning: this way works for negative H**O/LUMO energies
                ax.annotate("",
                            xy=(x1, y1),
                            xytext=(x2, middle),
                            arrowprops=dict(color='green',
                                            width=1.5,
                                            headwidth=5))
                ax.annotate(s=gapnew,
                            xy=(x2, y2),
                            xytext=(x1, middle),
                            color='green',
                            arrowprops=dict(width=6,
                                            headwidth=15,
                                            color='green'),
                            bbox=dict(boxstyle='round', fc='white'),
                            ha='center',
                            va='center')

        for idx, link in enumerate(self.links):
            # here we connect the levels with the links
            # x1, x2   y1, y2
            for i in link:
                # i is a tuple: (end_level_id,ls,linewidth,color)
                start = self.positions[idx] * (self.dimension + self.space)
                x1 = start + self.dimension
                x2 = self.positions[i[0]] * (self.dimension + self.space)
                y1 = self.energies[idx]
                y2 = self.energies[i[0]]
                line = Line2D([x1, x2], [y1, y2],
                              ls=i[1],
                              linewidth=i[2],
                              color=i[3])
                ax.add_line(line)

        for box in self.electons_boxes:
            # here we add the boxes
            # x,y,boxes,electrons,side,spacing_f
            x, y, boxes, electrons, side, spacing_f = box
            plot_orbital_boxes(ax, x, y, boxes, electrons, side, spacing_f)

        # Return fig and ax
        self.ax = ax
        self.fig = fig