Beispiel #1
0
    def plotPhaseMap(self, **kwargs):
        """
        Plot a phase map.

        Parameters
        ----------
        cmap : str, optional
            Colour scale to plot with.
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'vmin': -1,
            'vmax': self.numPhases
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, self.phaseArray, **plotParams)

        # add a legend to the plot
        phaseIDs = [-1] + list(range(1, self.numPhases + 1))
        phaseNames = ["Non-indexed"] + self.phaseNames
        plot.addLegend(phaseIDs, phaseNames,
                       bbox_to_anchor=(1.05, 1),
                       loc=2, borderaxespad=0.)

        return plot
Beispiel #2
0
    def plotMaxShear(self, **kwargs):
        """
        Plot a map of maximum shear strain

        Parameters
        ----------
        plotColourBar : bool, optional
            Add a colourbar to plot
        vmin : float, optional
            Minimum value for colour scale, default is max value of data
        vmax : float, optional
            Maximum value for colour scale, default is min value of data
        cmap
        plotGBs : bool, optional
            Add grain boundaries to the plot
        dilateBoundaries : bool, optional
        boundaryColour
        plotScaleBar : bool, optional
            Add scale bar to plot
        highlightGrains

        highlightColours
        ax
        updateCurrent : bool, optional
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'cLabel': "Effective shear strain"
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, self.crop(self.max_shear), **plotParams)

        return plot
Beispiel #3
0
    def plotKamMap(self, **kwargs):
        """
        Plot Kernel Average Misorientaion (KAM) for the EBSD map.

        Parameters
        ----------
        vmin : float, optional
            Minimum of colour scale
        vmax : float, optional
            Maximum of colour scale
        cmap : str, optional
            Colour scale to plot with.
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'cLabel': "Kernel average misorientation (KAM) ($^\circ$)"
        }
        plotParams.update(kwargs)

        self.calcKam()
        # Convert to degrees and plot
        kam = 2 * np.arccos(self.kam) * 180 / np.pi

        plot = MapPlot.create(self, kam, **plotParams)

        return plot
Beispiel #4
0
    def plotPattern(self, **kwargs):
        """Plot BSE image of Map. For use with setting homog points.

        Parameters
        ----------
        kwargs
            All arguments are passed to :func:`defdap.plotting.MapPlot.create`.

        Returns
        -------
        defdap.plotting.MapPlot

        """
        # Set default plot parameters then update with any input
        plotParams = {'cmap': 'gray'}
        try:
            plotParams['scale'] = self.scale / self.patScale * 1e-6
        except (ValueError):
            pass
        plotParams.update(kwargs)

        # Check image path is set
        if self.patternImPath is None:
            raise Exception("First set path to pattern image.")

        bseImage = imread(self.patternImPath)
        bseImage = self.crop(bseImage, binned=False)

        plot = MapPlot.create(self, bseImage, **plotParams)

        return plot
Beispiel #5
0
    def plotGNDMap(self, **kwargs):
        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'cLabel': "Geometrically necessary dislocation (GND) content"
        }
        plotParams.update(kwargs)

        self.calcNye()

        plot = MapPlot.create(self, np.log10(self.GND), **plotParams)

        return plot
Beispiel #6
0
    def plotMisOriMap(self, component=0, **kwargs):
        """
        Plot misorientation map

        :param component: 0: misorientation, 1, 2, 3: rotation about x, y, z
        :param plotGBs: Plot grain boundaries
        :param boundaryColour: Colour of grain boundary
        :param vmin: Minimum of colour scale (optional)
        :type vmin: float
        :param vmax: Maximum of colour scale (optional)
        :type vmax: float
        :param cmap: Colour map (optional)
        :type cmap: str
        :param cBarLabel: Label for colour bar
        :return: Figure
        """

        # Check that grains have been detected in the map
        self.checkGrainsDetected()

        self.misOri = np.ones([self.yDim, self.xDim])

        if component in [1, 2, 3]:
            for grain in self.grainList:
                for coord, misOriAxis in zip(grain.coordList, np.array(grain.misOriAxisList)):
                    self.misOri[coord[1], coord[0]] = misOriAxis[component - 1]

            misOri = self.misOri * 180 / np.pi
            cLabel = "Rotation around {:} axis ($^\circ$)".format(
                ['X', 'Y', 'Z'][component-1]
            )
        else:
            for grain in self.grainList:
                for coord, misOri in zip(grain.coordList, grain.misOriList):
                    self.misOri[coord[1], coord[0]] = misOri

            misOri = np.arccos(self.misOri) * 360 / np.pi
            cLabel = "Grain reference orienation deviation (GROD) ($^\circ$)"

        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'cLabel': cLabel
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, misOri, **plotParams)

        return plot
Beispiel #7
0
    def plotGrainMap(self, **kwargs):
        """
        Plot a map with grains coloured

        :return: Figure
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'cLabel': "Grain number"
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, self.grains, **plotParams)

        return plot
Beispiel #8
0
    def plotBoundaryMap(self, **kwargs):
        """Plot grain boundary map

        :param dilate: Dilate boundary by one pixel
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'plotGBs': True,
            'boundaryColour': 'black'
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, None, **plotParams)

        return plot
Beispiel #9
0
    def plotEulerMap(self, **kwargs):
        """
        Plot an orientation map in Euler colouring

        Parameters
        ----------
        ax
        makeInteractive
        plotGBs
        dilateBoundaries
        boundaryColour
        plotScaleBar
        kwargs
        updateCurrent : bool, optional

        highlightGrains : iterable(int), optional
            List of grain ids to highlight
        highlightColours : str, optional
            Colour of list of colours to highlight grains. If less
            colours are given than grains, then the final colour is
            used for the remaining grains.
        """
        self.checkDataLoaded()

        # Set default plot parameters then update with any input
        plotParams = {}
        plotParams.update(kwargs)

        eulerMap = np.transpose(self.eulerAngleArray, axes=(1, 2, 0))
        # this is the normalisation - different foreach crystal symmetry!
        if self.crystalSym == 'cubic':
            norm = np.tile(np.array([2 * np.pi, np.pi / 2, np.pi / 2]),
                           (self.yDim, self.xDim))
            norm = np.reshape(norm, (self.yDim, self.xDim, 3))
        elif self.crystalSym == 'hexagonal':
            norm = np.tile(np.array([np.pi, np.pi, np.pi / 3]),
                           (self.yDim, self.xDim))
            norm = np.reshape(norm, (self.yDim, self.xDim, 3))
        else:
            Exception("Only hexagonal and cubic symGroup supported")
        # make non-indexed points green
        eulerMap = np.where(eulerMap != [0., 0., 0.], eulerMap, [0., 1., 0.])
        eulerMap /= norm

        plot = MapPlot.create(self, eulerMap, **plotParams)

        return plot
Beispiel #10
0
    def plotIPFMap(self, direction, **kwargs):
        # Set default plot parameters then update with any input
        plotParams = {}
        plotParams.update(kwargs)

        # calculate IPF colours
        IPFcolours = Quat.calcIPFcolours(
            self.quatArray.flatten(),
            direction,
            self.crystalSym
        )
        # reshape back to map shape array
        IPFcolours = np.reshape(IPFcolours, (self.yDim, self.xDim, 3))

        plot = MapPlot.create(self, IPFcolours, **plotParams)

        return plot
Beispiel #11
0
    def plotBandContrastMap(self, **kwargs):
        """
        Plot band contrast map
        """
        self.checkDataLoaded()

        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'cmap:': 'grey',
            'cLabel': "Band contrast"
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, self.bandContrastArray, **plotParams)

        return plot
Beispiel #12
0
    def plotPhaseBoundaryMap(self, dilate=False, **kwargs):
        """Plot phase boundary map

        :param dilate: Dilate boundary by one pixel
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'vmax': 1,
            'plotColourBar': True,
            'cmap': 'grey'
        }
        plotParams.update(kwargs)

        boundariesImage = -self.phaseBoundaries
        if dilate:
            boundariesImage = mph.binary_dilation(boundariesImage)

        plot = MapPlot.create(self, boundariesImage, **plotParams)

        return plot
Beispiel #13
0
    def plotGrainDataMap(self,
                         mapData=None,
                         grainData=None,
                         grainIds=-1,
                         bg=0,
                         **kwargs):
        # Set default plot parameters then update with any input
        plotParams = {}
        plotParams.update(kwargs)

        if grainData is None:
            if mapData is None:
                raise ValueError("Either 'mapData' or 'grainData' must "
                                 "be supplied.")
            else:
                grainData = self.calcGrainAv(mapData, grainIds=grainIds)

        # Check that grains have been detected in the map
        self.checkGrainsDetected()

        if type(grainIds) is int and grainIds == -1:
            grainIds = range(len(self))

        if len(grainData) != len(grainIds):
            raise Exception("Must be 1 value for each grain in grainData.")

        grainMap = np.full([self.yDim, self.xDim],
                           bg,
                           dtype=type(grainData[0]))
        for grainId, grainValue in zip(grainIds, grainData):
            grain = self.grainList[grainId]
            for coord in grain.coordList:
                grainMap[coord[1], coord[0]] = grainValue

        plot = MapPlot.create(self, grainMap, **plotParams)

        return plot
Beispiel #14
0
    def plotMaxShear(self, **kwargs):
        """Plot a map of maximum shear strain.

        Parameters
        ----------
        kwargs
            All arguments are passed to :func:`defdap.plotting.MapPlot.create`.

        Returns
        -------
        defdap.plotting.MapPlot
            Plot containing BSE image of map.

        """
        # Set default plot parameters then update with any input
        plotParams = {
            'plotColourBar': True,
            'clabel': "Effective shear strain"
        }
        plotParams.update(kwargs)

        plot = MapPlot.create(self, self.crop(self.eMaxShear), **plotParams)

        return plot
Beispiel #15
0
    def plotGrainDataMap(self,
                         mapData=None,
                         grainData=None,
                         grainIds=-1,
                         bg=0,
                         **kwargs):
        """
        Plot a grain map with grains coloured by given data. The data
        can be provided as a list of values per grain or as a map which
        a grain average will be applied.

        Parameters
        ----------
        mapData : numpy.ndarray, optional
            Array of map data. This must be cropped! You must supply either
            mapData or grainData.
        grainData : list or numpy.array, optional
            Grain values. This an be a single value per grain or RGB
            values. You must supply either mapData or grainData.
        grainIds : list(int) or int, optional
            IDs of grains to plot for. Use -1 for all grains in the map.
        bg : int or real, optional
            Value to fill the background with.
        kwargs :
            Other parameters are passed to defdap.plotting.MapPlot.create.

        Returns
        -------
        plot : defdap.plotting.MapPlot
            Plot object created.

        """
        # Set default plot parameters then update with any input
        plotParams = {}
        plotParams.update(kwargs)

        if grainData is None:
            if mapData is None:
                raise ValueError("Either 'mapData' or 'grainData' must "
                                 "be supplied.")
            else:
                grainData = self.calcGrainAv(mapData, grainIds=grainIds)

        # Check that grains have been detected in the map
        self.checkGrainsDetected()

        if type(grainIds) is int:
            if grainIds == -1:
                grainIds = range(len(self))
            else:
                grainIds = [grainIds]

        grainData = np.array(grainData)
        if grainData.shape[0] != len(grainIds):
            raise Exception("The length of supplied grain data does not"
                            "match the number of grains.")
        if len(grainData.shape) == 1:
            mapShape = [self.yDim, self.xDim]
        elif len(grainData.shape) == 2 and grainData.shape[1] == 3:
            mapShape = [self.yDim, self.xDim, 3]
        else:
            raise Exception("The grain data supplied must be either a"
                            "single value or RGB values per grain.")

        grainMap = np.full(mapShape, bg, dtype=grainData.dtype)
        for grainId, grainValue in zip(grainIds, grainData):
            grain = self.grainList[grainId]
            for coord in grain.coordList:
                grainMap[coord[1], coord[0]] = grainValue

        plot = MapPlot.create(self, grainMap, **plotParams)

        return plot
Beispiel #16
0
    def plotAverageGrainSchmidFactorsMap(self, planes=None, directions=None,
                                         **kwargs):
        """
        Plot maximum Schmid factor map, based on average grain orientation (for all slip systems unless specified)

        :param planes: Plane ID(s) to consider (optional)
        :type planes: list
        :param directions: Direction ID(s) to consider (optional)
        :type directions: list
        :param plotGBs: Plots grain boundaries if True
        :param boundaryColour:  Colour of grain boundaries
        :param dilateBoundaries: Dilates grain boundaries if True
        :type boundaryColour: string
        :return:
        """
        # Set default plot parameters then update with any input
        plotParams = {
            'vmin': 0,
            'vmax': 0.5,
            'cmap': 'gray',
            'plotColourBar': True,
            'cLabel': "Schmid factor"
        }
        plotParams.update(kwargs)

        # Check that grains have been detected in the map
        self.checkGrainsDetected()
        self.averageSchmidFactor = np.zeros([self.yDim, self.xDim])

        if self[0].averageSchmidFactors is None:
            raise Exception("Run 'calcAverageGrainSchmidFactors' first")

        for grain in self.grainList:
            currentSchmidFactor = []

            if planes is not None:
                # Error catching
                if np.max(planes) > len(self.slipSystems) - 1:
                    raise Exception("Check plane IDs exists, IDs range from 0 "
                                    "to {0}".format(len(self.slipSystems) - 1))

                for plane in planes:
                    if directions is not None:
                        for direction in directions:
                            currentSchmidFactor.append(grain.averageSchmidFactors[plane][direction])
                    else:
                        currentSchmidFactor.append(grain.averageSchmidFactors[plane])
                # TODO: what is this doing?
                currentSchmidFactor = [max(s) for s in zip(*currentSchmidFactor)]
            else:
                currentSchmidFactor = [max(s) for s in zip(*grain.averageSchmidFactors)]

            # Fill grain with colour
            for coord in grain.coordList:
                self.averageSchmidFactor[coord[1], coord[0]] = currentSchmidFactor[0]

        self.averageSchmidFactor[self.averageSchmidFactor == 0] = 0.5

        plot = MapPlot.create(self, self.averageSchmidFactor, **plotParams)

        return plot