def drawLevelSetContour2D(distribution,
                          numberOfPointsInXAxis,
                          alpha,
                          threshold,
                          sampleSize=500):
    '''
    Compute the minimum volume LevelSet of measure equal to alpha and get the 
    corresponding density value (named threshold).
    Generate a sample of the distribution and draw it. 
    Draw a contour plot for the distribution, where the PDF is equal to threshold. 
    '''
    sample = distribution.getSample(sampleSize)
    X1min = sample[:, 0].getMin()[0]
    X1max = sample[:, 0].getMax()[0]
    X2min = sample[:, 1].getMin()[0]
    X2max = sample[:, 1].getMax()[0]
    xx = ot.Box([numberOfPointsInXAxis], ot.Interval([X1min],
                                                     [X1max])).generate()
    yy = ot.Box([numberOfPointsInXAxis], ot.Interval([X2min],
                                                     [X2max])).generate()
    xy = ot.Box([numberOfPointsInXAxis, numberOfPointsInXAxis],
                ot.Interval([X1min, X2min], [X1max, X2max])).generate()
    data = distribution.computePDF(xy)
    graph = ot.Graph('', 'X1', 'X2', True, 'topright')
    labels = ["%.2f%%" % (100 * alpha)]
    contour = ot.Contour(xx, yy, data, [threshold], labels)
    contour.setColor('black')
    graph.setTitle("%.2f%% of the distribution, sample size = %d" %
                   (100 * alpha, sampleSize))
    graph.add(contour)
    cloud = ot.Cloud(sample)
    graph.add(cloud)
    return graph
Beispiel #2
0
    def drawLimitState(self, bounds, nX=50, nY=50):
        """
        Draw the limit state of an event.

        Parameters
        ----------
        event : an ot.Event
            The event we want to draw.

        bounds: an ot.Interval
            The lower and upper bounds of the interval.

        nX : an int
            The number of points in the X axis.

        nY : an int
            The number of points in the Y axis.

        Returns
        -------
        None.

        """
        if bounds.getDimension() != 2:
            raise ValueError("The input dimension of the bounds "
                             "is equal to %d but should be 2." %
                             (bounds.getDimension()))
        #
        threshold = self.event.getThreshold()
        g = self.event.getFunction()
        #
        boxExperiment = ot.Box([nX, nY], bounds)
        inputSample = boxExperiment.generate()
        outputSample = g(inputSample)
        #
        description = g.getInputDescription()
        graph = ot.Graph("Limit state surface", description[0], description[1],
                         True, "")
        # Create the contour
        levels = ot.Point([threshold])
        labels = [str(threshold)]
        drawLabels = True
        lowerBound = bounds.getLowerBound()
        upperBound = bounds.getUpperBound()
        x = LinearSample(lowerBound[0], upperBound[0], nX + 2)
        y = LinearSample(lowerBound[1], upperBound[1], nY + 2)
        contour = ot.Contour(x, y, outputSample, levels, labels, drawLabels)
        graph.add(contour)
        return graph
Beispiel #3
0
    def drawLimitStateCrossCut(self, bounds, i=0, j=1, nX=50, nY=50):
        """
        Draw the cross-cut of the limit state of an event on a cross-cut.

        Parameters
        ----------
        bounds: an ot.Interval
            The lower and upper bounds of the cross-cut interval.
        i : int
            The index of the first marginal of the cross-cut.
        j : int
            The index of the second marginal of the cross-cut.
        nX : an int
            The number of points in the X axis.
        nY : an int
            The number of points in the Y axis.

        Returns
        -------
        graph : ot.Graph
            The plot of the (i, j) cross cut.
        """
        if bounds.getDimension() != 2:
            raise ValueError("The input dimension of the bounds "
                             "is equal to %d but should be 2." %
                             (bounds.getDimension()))
        #
        threshold = self.event.getThreshold()
        description = self.g.getInputDescription()
        boxExperiment = ot.Box([nX, nY], bounds)
        reducedInputSample = boxExperiment.generate()
        crosscutFunction = self.buildCrossCutFunction(i, j)
        outputSample = crosscutFunction(reducedInputSample)
        #
        graph = ot.Graph("Limit state surface", description[i], description[j],
                         True, "")
        # Create the contour
        levels = ot.Point([threshold])
        labels = [str(threshold)]
        drawLabels = True
        lowerBound = bounds.getLowerBound()
        upperBound = bounds.getUpperBound()
        x = LinearSample(lowerBound[0], upperBound[0], nX + 2)
        y = LinearSample(lowerBound[1], upperBound[1], nY + 2)
        contour = ot.Contour(x, y, outputSample, levels, labels, drawLabels)
        graph.add(contour)
        return graph
    def draw(self, drawInliers=False, drawOutliers=True):
        """
        Draw the high density regions.

        Parameters
        ----------
        drawInliers : bool
            If True, draw inliers points.
        drawOutliers : bool
            If True, draw outliers points.
        """
        plabels = self.sample.getDescription()

        # Bivariate space
        grid = ot.GridLayout(self.dim, self.dim)
        # Axis are created and stored top to bottom, left to right
        for i in range(self.dim):
            for j in range(self.dim):
                if i >= j:  # lower triangle
                    graph = ot.Graph("", "", "", True, "topright")

                if i == j:  # diag
                    marginal_distribution = self.distribution.getMarginal(i)
                    curve = marginal_distribution.drawPDF()
                    graph.add(curve)
                    if drawInliers:
                        marginal_sample = self.sample[self.inlier_indices, i]
                        data = ot.Sample(marginal_sample.getSize(), 2)
                        data[:, 0] = marginal_sample
                        cloud = ot.Cloud(data)
                        cloud.setColor(self.inlier_color)
                        graph.add(cloud)
                    if drawOutliers:
                        marginal_sample = self.sample[self.outlier_indices, i]
                        data = ot.Sample(marginal_sample.getSize(), 2)
                        data[:, 0] = marginal_sample
                        cloud = ot.Cloud(data)
                        cloud.setColor(self.outlier_color)
                        graph.add(cloud)

                elif i > j:  # lower corners
                    # Use a regular grid to compute probability response surface
                    X1min = self.sample[:, j].getMin()[0]
                    X1max = self.sample[:, j].getMax()[0]
                    X2min = self.sample[:, i].getMin()[0]
                    X2max = self.sample[:, i].getMax()[0]

                    xx = ot.Box([self.numberOfPointsInXAxis],
                                ot.Interval([X1min], [X1max])).generate()

                    yy = ot.Box([self.numberOfPointsInXAxis],
                                ot.Interval([X2min], [X2max])).generate()

                    xy = ot.Box(
                        [
                            self.numberOfPointsInXAxis,
                            self.numberOfPointsInXAxis
                        ],
                        ot.Interval([X1min, X2min], [X1max, X2max]),
                    ).generate()

                    data = self.distribution.getMarginal([j, i]).computePDF(xy)

                    # Label using percentage instead of probability
                    n_contours = len(self.alphaLevels)
                    labels = [
                        "%.0f %%" % (self.alphaLevels[i] * 100)
                        for i in range(n_contours)
                    ]

                    contour = ot.Contour(xx, yy, data, self.pvalues,
                                         ot.Description(labels))
                    contour.setColor(self.contour_color)

                    graph.add(contour)

                    sample_ij = self.sample[:, [j, i]]

                    if drawInliers:
                        cloud = self._drawInliers(sample_ij)

                        if cloud is not None:
                            graph.add(cloud)

                    if drawOutliers:
                        cloud = self._drawOutliers(sample_ij)
                        if cloud is not None:
                            graph.add(cloud)

                if j == 0 and i > 0:
                    graph.setYTitle(plabels[i])
                if i == self.dim - 1:
                    graph.setXTitle(plabels[j])

                if i >= j:  # lower triangle
                    graph.setLegends([""])
                    grid.setGraph(i, j, graph)

        return grid
Beispiel #5
0
# If :math:`y =  x_1 x_2 = 10.0`, then the boundary of the domain of failure is the curve :
#
# .. math::
#
#    h : x_1 \mapsto \frac{10.0}{x_1}
#

# %%
# We shall represent this curve using a :class:`~openturns.Contour` object.
nx, ny = 15, 15
xx = ot.Box([nx], ot.Interval([0.0], [10.0])).generate()
yy = ot.Box([ny], ot.Interval([-10.0], [10.0])).generate()
inputData = ot.Box([nx, ny], ot.Interval([0.0, -10.0],
                                         [10.0, 10.0])).generate()
outputData = f(inputData)
mycontour = ot.Contour(xx, yy, outputData, [10.0], ["10.0"])
myGraph = ot.Graph("Representation of the failure domain", r"$X_1$", r"$X_2$",
                   True, "")
myGraph.add(mycontour)

# %%
texts = [r" Event : $\mathcal{D} = \{Y \geq 10.0\}$"]
myText = ot.Text([[4.0, 4.0]], texts)
myText.setTextSize(1)
myGraph.add(myText)
view = otv.View(myGraph)

# %%
# We can superimpose the event boundary with the 2D-PDF ot the input variables :
#
mycontour.setColor("black")
Beispiel #6
0
import openturns as ot
from matplotlib import pyplot as plt
from openturns.viewer import View

# Create a function
f = ot.Function(["x", "y"], ["z"], ["exp(-sin(cos(y)^2*x^2+sin(x)^2*y^2))"])

# Generate the data for the curves to be drawn
nX = 75
nY = 75
inputData = ot.Box([nX, nY]).generate()
inputData *= [10.0] * 2
inputData += [-5.0] * 2
data = f(inputData)
levels = [(0.5 + i) / 5 for i in range(5)]
# Create an empty graph
graph = ot.Graph("Complex iso lines", "u1", "u2", True, "")

# Create the contour
contour = ot.Contour(nX + 2, nY + 2, data)
contour.setLevels(levels)

# Then, draw it
graph.add(contour)

fig = plt.figure(figsize=(4, 4))
plt.suptitle("Complex iso lines example")
axis = fig.add_subplot(111)
axis.set_xlim(auto=True)
View(graph, figure=fig, axes=[axis], add_legend=False)
graphModel1.setXTitle(r'$x_1$')
graphModel1.setYTitle(r'$x_2$')
graphModel1.setTitle(r'Isolines of the model : $Y = f(X)$, second marginal')

# %%
# We shall now represent the curves delimiting the domain of interest :
#
nx, ny = 15, 15
xx = ot.Box([nx], ot.Interval([-5.0], [5.0])).generate()
yy = ot.Box([ny], ot.Interval([-5.0], [5.0])).generate()
inputData = ot.Box([nx, ny], ot.Interval([-5.0, -5.0], [5.0, 5.0])).generate()
outputData = f(inputData)

# %%
# The contour line associated with the 0.0 value for the first marginal.
mycontour0 = ot.Contour(xx, yy, outputData.getMarginal(0), [0.0], ["0.0"])
mycontour0.setColor("black")
mycontour0.setLineStyle("dashed")
graphModel0.add(mycontour0)

# %%
# The contour line associated with the 1.0 value for the first marginal.
mycontour1 = ot.Contour(xx, yy, outputData.getMarginal(0), [1.0], ["1.0"])
mycontour1.setColor("black")
mycontour1.setLineStyle("dashed")
graphModel0.add(mycontour1)
view = otv.View(graphModel0)

# %%
# The contour line associated with the 0.0 value for the second marginal.
mycontour2 = ot.Contour(xx, yy, outputData.getMarginal(1), [0.0], ["0.0"])
# %%
# We discretize the domain with 22 points (N inside points and 2 endpoints) :
N = 20
inputData = ot.Box([N, N]).generate()

# %%
# We compute the conditional variance of the model and take the square root to get the deviation :
condCov = result.getConditionalMarginalVariance(inputData, 0)
condCovSd = sqrt(condCov)

# %%
# As we have previously done we build contours with the following levels ans labels :
levels = [0.01, 0.025, 0.050, 0.075, 0.1, 0.125, 0.150, 0.175]
labels = ['0.01', '0.025', '0.050', '0.075', '0.1', '0.125', '0.150', '0.175']
contour = ot.Contour(N + 2, N + 2, condCovSd)
graph = ot.Graph('', 'x', 'y', True, '')
graph.add(contour)

# %%
# We use fancy colored isolines for the contour plot :
contour = graph.getDrawable(0)
ot.ResourceMap.SetAsUnsignedInteger('Drawable-DefaultPalettePhase',
                                    len(levels))
palette = ot.Drawable.BuildDefaultPalette(len(levels))
drawables = list()
for i in range(len(levels)):
    contour.setLevels([levels[i]])
    contour.setDrawLabels(True)
    drawables.append(ot.Drawable(contour))
    def drawContour(self, drawData=False, drawOutliers=True):
        """Draw contour.

        If :attr:`drawData`, the whole sample is drawn. Otherwise, depending on
        :attr:`drawOutliers` it will either show the outliers or the inliers
        only.

        :param bool drawData: Plot inliers and outliers.
        :param bool drawOutliers: Whether to draw inliers or outliers.
        :returns: figure, axes and OpenTURNS Graph object.
        :rtypes: Matplotlib figure instances, Matplotlib AxesSubplot instances,
          :class:`openturns.Graph`
        """
        plabels = self.sample.getDescription()

        # Bivariate space
        fig = plt.figure(figsize=(10, 10))
        sub_ax = []  # Axis stored as a list
        sub_graph = []
        # Axis are created and stored top to bottom, left to right
        for i in range(self.dim):
            for j in range(self.dim):
                k = i + j * self.dim + 1

                if i <= j:  # lower triangle
                    ax = fig.add_subplot(self.dim, self.dim, k)
                    graph = ot.Graph('', '', '', True, 'topright')

                if i == j:  # diag
                    pdf_graph = self.distribution.getMarginal(i).drawPDF()
                    graph.add(pdf_graph)

                elif i < j:  # lower corners
                    # Use a regular grid to compute probability response surface
                    X1min = self.sample[:, i].getMin()[0]
                    X1max = self.sample[:, i].getMax()[0]
                    X2min = self.sample[:, j].getMin()[0]
                    X2max = self.sample[:, j].getMax()[0]

                    xx = ot.Box([self.numberOfPointsInXAxis],
                                ot.Interval([X1min], [X1max])).generate()

                    yy = ot.Box([self.numberOfPointsInXAxis],
                                ot.Interval([X2min], [X2max])).generate()

                    xy = ot.Box([self.numberOfPointsInXAxis, self.numberOfPointsInXAxis],
                                ot.Interval([X1min, X2min], [X1max, X2max])).generate()

                    data = self.distribution.getMarginal([i, j]).computePDF(xy)

                    # Label using percentage instead of probability
                    n_contours = len(self.contoursAlpha)
                    labels = ["%.0f %%" % (self.contoursAlpha[i] * 100)
                              for i in range(n_contours)]

                    contour = ot.Contour(xx, yy, data, self.pvalues,
                                         ot.Description(labels))
                    contour.setColor('black')

                    graph.add(contour)

                    sample_ = np.array(self.sample)[:, [i, j]]

                    if drawData:
                        inliers_ = self.drawInliers(sample=sample_)
                        outliers_ = self.drawOutliers(sample=sample_)

                        if inliers_ is not None:
                            graph.add(inliers_)
                        if outliers_ is not None:
                            graph.add(outliers_)

                    elif drawOutliers:
                        outliers_ = self.drawOutliers(sample=sample_)
                        if outliers_ is not None:
                            graph.add(outliers_)
                    else:
                        inliers_ = self.drawInliers(sample=sample_)
                        if inliers_ is not None:
                            graph.add(inliers_)

                if i == 0:
                    graph.setYTitle(plabels[j])
                if j == (self.dim - 1):
                    graph.setXTitle(plabels[i])

                graph.setLegends([''])
                sub_graph.append(ot.viewer.View(graph, figure=fig, axes=[ax]))
                sub_ax.append(ax)

        return fig, sub_ax, sub_graph
Beispiel #10
0
graphModel1.setXTitle(r'$x_1$')
graphModel1.setYTitle(r'$x_2$')
graphModel1.setTitle(r'Isolines of the model : $Y = f(X)$, second marginal')

# %%
# We shall now represent the curves delimiting the domain of interest :
# 
nx, ny = 15, 15
xx = ot.Box([nx], ot.Interval([-5.0], [5.0])).generate()
yy = ot.Box([ny], ot.Interval([-5.0], [5.0])).generate()
inputData = ot.Box([nx,ny], ot.Interval([-5.0, -5.0], [5.0, 5.0])).generate()
outputData = f(inputData)

# %%
# The contour line associated with the 0.0 value for the first marginal.
mycontour0 = ot.Contour(xx, yy, outputData.getMarginal(0), ot.Point([0.0]), ot.Description(["0.0"]))
mycontour0.setColor("black")
mycontour0.setLineStyle("dashed")
graphModel0.add(mycontour0)

# %%
# The contour line associated with the 1.0 value for the first marginal.
mycontour1 = ot.Contour(xx, yy, outputData.getMarginal(0), ot.Point([1.0]), ot.Description(["1.0"]))
mycontour1.setColor("black")
mycontour1.setLineStyle("dashed")
graphModel0.add(mycontour1)
view = otv.View(graphModel0)

# %%
# The contour line associated with the 0.0 value for the second marginal.
mycontour2 = ot.Contour(xx, yy, outputData.getMarginal(1), ot.Point([0.0]), ot.Description(["0.0"]))
Beispiel #11
0
# We create random vectors for the input and output variables :
X = ot.RandomVector(dist)
Y = ot.CompositeRandomVector(f, X)

# %%
# The failure domain :math:`\mathcal{D}` is :math:`\mathcal{D} = \{ x=(x_1, x_2) \in \mathbb{R}^2 / f(x) \geq 0 \}`
failureEvent = ot.ThresholdEvent(Y, ot.Less(), 0.0)

# %%
# We shall represent the failure domain event using a :class:`~openturns.Contour` object.
nx, ny = 25, 25
xx = ot.Box([nx], ot.Interval([-8.0], [8.0])).generate()
yy = ot.Box([ny], ot.Interval([-8.0], [8.0])).generate()
inputData = ot.Box([nx, ny], ot.Interval([-8.0, -8.0], [8.0, 8.0])).generate()
outputData = f(inputData)
mycontour = ot.Contour(xx, yy, outputData, ot.Point([0.0]),
                       ot.Description(["0.0"]))
mycontour.setColor("black")
mycontour.setLineStyle("dashed")
graphModel.add(mycontour)
view = otv.View(graphModel)

# %%
# In the physical space the failure domain boundary is the dashed black curve. We recall that one of
# the steps of the FORM method is to find the closest point of the failure domain boundary to the origin.
# Here we see that the symmetry of the domain implies that two points exist, one in the :math:`x_1 \geq 0` half-space and the other in the :math:`x_1 \leq 0` half-space.

# %%
# We build the :class:`~openturns.MultiFORM` algorithm in a similar fashion as the :class:`~openturns.FORM` algorithm. We choose an optimization solver, here the Cobyla solver, and a starting point, the mean
# of the distribution `dist`.
solver = ot.Cobyla()
starting_pt = dist.getMean()