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
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
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
# 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")
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
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"]))
# 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()