def __init__(self, bb=None): from yanntricks.src.BoundingBox import BoundingBox if bb is None: bb = BoundingBox() ObjectGraph.__init__(self, self) self.BB = bb self.separator_name = "GRID" # Default values, have to be integer. self.add_option({"Dx": 1, "Dy": 1}) self.Dx = self.options.DicoOptions["Dx"] self.Dy = self.options.DicoOptions["Dy"] self.num_subX = 2 self.num_subY = 2 self.draw_border = False self.draw_horizontal_grid = True self.draw_vertical_grid = True self.main_horizontal = Segment(Point(0, 1), Point(1, 1)) self.main_horizontal.parameters.color = "gray" self.main_horizontal.parameters.style = "solid" self.main_vertical = Segment(Point(0, 1), Point(1, 1)) self.main_vertical.parameters.color = "gray" self.main_vertical.parameters.style = "solid" self.sub_vertical = Segment(Point(0, 1), Point(1, 1)) self.sub_vertical.parameters.color = "gray" self.sub_vertical.parameters.style = "dotted" self.sub_horizontal = Segment(Point(0, 1), Point(1, 1)) self.sub_horizontal.parameters.color = "gray" self.sub_horizontal.parameters.style = "dotted" self.border = Segment(Point(0, 1), Point(1, 1)) self.border.parameters.color = "gray" self.border.parameters.style = "dotted"
def __init__(self, curve1, curve2): """ Give the graph of the surface between the two lines. The lines are needed to have a starting and ending point that will be joined by straight lines. """ from yanntricks.src.segment import Segment # By convention, the first line goes from left to right and the second one to right to left. ObjectGraph.__init__(self, self) if curve1.I.x > curve1.F.x: curve1 = curve1.reverse() if curve2.I.x > curve2.F.x: curve2 = curve2.reverse() self.curve1 = curve1 self.curve2 = curve2 self.I1 = curve1.I self.I2 = curve2.I self.F1 = curve1.F self.F2 = curve2.F self.Isegment = Segment(self.I1, self.I2) self.Fsegment = Segment(self.F1, self.F2)
def __init__(self, O, A, B): ObjectGraph.__init__(self, self) self.O = O self.A = A self.B = B self.angleI = 0 self.angleF = 2 * pi
def __init__(self, op, P, a, b, c): from yanntricks.src.segment import Segment from yanntricks.src.point import Point ObjectGraph.__init__(self, self) self.op = op self.P = P self.Px = P[0] self.Py = P[1] self.a = a self.b = b self.c = c self.transparent = True self.A = [ Point(self.Px, self.Py + b), Point(self.Px + a, self.Py + b), Point(self.Px + a, self.Py), Point(self.Px, self.Py) ] # The points on the first and second rectangle self.c1 = [self.op.point(P.x, P.y, 0) for P in self.A] self.c2 = [self.op.point(P.x, P.y, self.c) for P in self.A] self.A = self.c1[0] self.B = self.c1[1] self.C = self.c1[2] self.D = self.c1[3] self.E = self.c2[0] self.F = self.c2[1] self.G = self.c2[2] self.H = self.c2[3] for P in self.c1: P.parameters.symbol = "" for P in self.c2: P.parameters.symbol = "" # The edges. self.segP = [ Segment(self.c1[i], self.c2[i]) for i in range(0, len(self.c1)) ] self.segc1 = [ Segment(self.c1[i], self.c1[(i + 1) % len(self.c1)]) for i in range(0, len(self.c1)) ] self.segc2 = [ Segment(self.c2[i], self.c2[(i + 1) % len(self.c2)]) for i in range(0, len(self.c2)) ] if op.alpha < 90: self.segP[3].parameters.style = "dashed" self.segc2[2].parameters.style = "dashed" self.segc2[3].parameters.style = "dashed" else: self.segP[2].parameters.style = "dashed" self.segc2[2].parameters.style = "dashed" self.segc2[1].parameters.style = "dashed"
def __init__(self, A, B=None, vector=None): if vector: B = A.translate(vector) self.I = A self.F = B self._advised_mark_angle = None ObjectGraph.__init__(self, self) self.measure = None self.coefs = None
def __init__(self, minimum, Q1, M, Q3, maximum, h, delta_y=0): ObjectGraph.__init__(self, self) self.Q1 = Q1 self.Q3 = Q3 self.M = M self.h = h self.delta_y = delta_y self.minimum = minimum self.maximum = maximum
def __init__(self, implicit_curve, xrange, yrange, plot_points=300): ObjectGraph.__init__(self, implicit_curve) GeometricImplicitCurve.__init__(self, implicit_curve.f) self.implicit_curve = implicit_curve self.implicit_plot = implicit_plot(self.f, xrange, yrange) self.xrange = xrange self.yrange = yrange self.plot_points = plot_points self.paths = get_paths_from_implicit_plot(self.implicit_plot) self.parameters.color = "blue"
def __init__(self, points_list, context_object=None, mode=None): ObjectGraph.__init__(self, self) self.parameters.color = "brown" self.points_list = points_list self.I = self.points_list[0] self.F = self.points_list[-1] self.context_object = context_object if self.context_object is None: self.contex_object = self self.mode = mode self._minmax_data = None
def __init__(self, a, b, n, histo): """ It is given by the initial value, the final value and the "surrounding" histogram """ ObjectGraph.__init__(self, self) self.d_xmin = a self.d_xmax = b self.n = n self.histo = histo self.size = self.d_xmax - self.d_xmin self.th_height = self.n / self.size self.length = None self.height = None
def __init__(self, P, text, hide=True): from yanntricks.src.Constructors import Mark from yanntricks.src.Constructors import Rectangle ObjectGraph.__init__(self, self) self.P = P self.text = text self.mark = Mark(self, 0, 0, self.text) self.hide = hide # This is fake; just to have an object to act on. self.rectangle = Rectangle(Point(0, 0), Point(1, 1)) self.rectangle.parameters.filled() self.rectangle.parameters.fill.color = "white" self.rectangle.parameters.style = "none"
def __init__(self, fun, mx=None, Mx=None): ObjectGraph.__init__(self, fun) self.mx = mx self.Mx = Mx self.fun = fun self.parameters.plotpoints = 100 # Will be used in order to simulate a lazy_attribute in self.get_minmax_data self.old_mx = None self.old_Mx = None self.minmax_result = None if self.mx is not None and self.Mx is not None: self.drawpoints = linspace( self.mx, self.Mx, self.parameters.plotpoints, endpoint=True) self.parameters.color = "blue"
def __init__(self, f1, f2, mx, Mx): ObjectGraph.__init__(self, self) self.f1 = f1 self.f2 = f2 self.mx = mx self.Mx = Mx self.I = self.get_point(mx) self.F = self.get_point(Mx) self.parameters.plotpoints = 100 from numpy import linspace if self.mx is not None and self.Mx is not None: self.drawpoints = linspace( self.mx, self.Mx, self.parameters.plotpoints, endpoint=True)
def __init__(self, values, h, delta_y=0): ObjectGraph.__init__(self, self) import numpy from scipy.stats.mstats import mquantiles ms = mquantiles(values) self.average = numpy.mean(values) self.q1 = ms[0] self.median = ms[1] self.q3 = ms[2] self.minimum = min(values) self.maximum = max(values) self.h = h self.delta_y = delta_y
def __init__(self, f, mx, Mx): ObjectGraph.__init__(self, self) self.f = f self.mx = mx self.Mx = Mx self.I = self.get_point(mx) self.F = self.get_point(Mx) self.parameters.plotpoints = 100 from numpy import linspace if self.mx is not None and self.Mx is not None: self.drawpoints = linspace(numerical_approx(self.mx), numerical_approx( self.Mx), self.parameters.plotpoints, endpoint=True) self._curve = None self.mode = None
def __init__(self,X,Y): ObjectGraph.__init__(self,self) self.X=X self.Y=Y self.linewidth=1 # width of the lines (in centimetrs) self.numbering=True self.numbering_decimals=2 # Definition of the default bars to be drawn. self.lines_list=[] for i,x in enumerate(self.X): y=self.Y[i] l=Segment(Point(x,0),Point(x,y) ) l.parameters.color="blue" l.parameters.add_option("linewidth","{}cm".format(self.linewidth)) self.lines_list.append(l)
def __init__(self, center, radius, a, b): """ The pie diagram for the fraction 'a/b' inside the circle of given center and radius. 2/4 and 1/2 are not treated in the same way because 2/4 divides the pie into 4 parts (and fills 2) while 1/2 divides into 2 parts (and fills 1). """ from yanntricks.src.Constructors import Circle ObjectGraph.__init__(self, self) self.center = center self.radius = radius self.numerator = a self.denominator = b if a > b: raise ValueError("Numerator is larger than denominator") self.circle = Circle(self.center, self.radius) self._circular_sector = None
def __init__(self, C, bb, pspict=None): # if a pspicture is passed, these axes will be considered as the # default axes system of `pspict`. This has an influence in the # computation of the bounding box. from yanntricks.src.Constructors import Vector ObjectGraph.__init__(self, self) self.take_math_BB = False self.C = C self.BB = bb.copy() self.pspict = pspict self.options = Options() self.Dx = 1 self.Dy = 1 self.arrows = "->" self.separator_name = "AXES" self.graduation = True self.numbering = True # Since the size of the axe is given in multiple of self.base, # one cannot give mx=-1000 as "minimal value". self.single_axeX = SingleAxe(self.C, Vector(1, 0), 0, 0, pspict=self.pspict) self.single_axeX.mark_origin = False self.single_axeX.axes_unit = AxesUnit(1, "") self.draw_single_axeX = True self.single_axeY = SingleAxe(self.C, Vector(0, 1), 0, 0, pspict=self.pspict) self.single_axeY.mark_origin = False self.single_axeY.axes_unit = AxesUnit(1, "") self.single_axeY.mark_angle = 180 self.draw_single_axeY = True self.single_axeX.Dx = self.Dx self.single_axeY.Dx = self.Dy self.already_enlarged = False self.enlarge_size = 0.5 self.do_enlarge = True self.do_mx_enlarge = True self.do_my_enlarge = True self.do_Mx_enlarge = True self.do_My_enlarge = True
def __init__(self, a, b): self.x = SR(a) self.y = SR(b) ObjectGraph.__init__(self, self) self.point = self.obj self.add_option("PointSymbol=*") self._advised_mark_angle = None try: ax = abs(numerical_approx(self.x)) if ax < 0.00001 and ax > 0: self.x = 0 ay = abs(numerical_approx(self.y)) if ay < 0.00001 and ay > 0: self.y = 0 except TypeError: pass
def __init__(self, f1, f2, llamI, llamF): """ Use the constructor :func:`ParametricCurve`. INPUT: - ``f1,f2`` - two functions. - ``llamI,llamF`` - initial and final values of the parameter. ATTRIBUTES: - ``plotpoints`` - (default=50) number of points to be computed. If the function seems wrong, increase that number. It can happen with functions like sin(1/x) close to zero: such a function have too fast oscillations. """ if isinstance(f1, ParametricCurveGraph): print( "You cannot creare a parametric curve by giving a parametric curve" ) raise TypeError ObjectGraph.__init__(self, self) GenericCurve.__init__(self, llamI, llamF) self._derivative_dict = {0: self} self.f1 = f1 self.f2 = f2 self.curve = self.obj self.llamI = llamI self.llamF = llamF self.mx = llamI self.Mx = llamF self.parameters.color = "blue" self.plotstyle = "curve" self.record_arrows = [] # TODO: if I remove the protection "if self.llamI", sometimes it # tries to make self.get_point(self.llamI) with self.llamI==None # In that case the crash is interesting since it is a segfault instead of an exception. if self.llamI != None: self.I = self.get_point(self.llamI, advised=False) self.F = self.get_point(self.llamF, advised=False)
def __init__(self, fun, mx, Mx): ObjectGraph.__init__(self, fun) GenericCurve.__init__(self, mx, Mx) self.sage = fun x, y = var('x,y') self.sage = fun try: self.sageFast = self.sage._fast_float_(x) except (NotImplementedError, TypeError, ValueError, AttributeError): # Happens when the derivative of the function is # not implemented in Sage # Also happens when there is a free variable, # as an example # F=VectorFieldGraph(x,y) # Also when something non analytic is given # like a distribution. self.sageFast = self.sage self.string = repr(self.sage) self.fx = self.string.replace("x |--> ", "") # self.pstricks = SubstitutionMathPsTricks(self.fx) # self.tikz is suppressed on October 16, 2019 # self.tikz = SubstitutionMathTikz(self.fx) self.ListeSurface = [] self.listeTests = [] self.TesteDX = 0 self.listeExtrema = [] self.listeExtrema_analytique = [] self.equation = y == self.sage self.f = self.obj self.mx = mx self.Mx = Mx self.do_cut_y = False self.cut_ymin = None self.cut_ymax = None self.pieces = [] # Modification with respect to the attribute in ObjectGraph self.parameters.color = "blue" self.nul_function = None self._derivative = None self._parametric_curve = None
def __init__(self, curve1, curve2, interval1=None, interval2=None, reverse1=False, reverse2=True): from yanntricks.src.segment import Segment # TODO: I think that the parameters reverse1 and reverse2 are no more useful # since I enforce the condition curve1 : left -> right by hand. ObjectGraph.__init__(self, self) self.curve1 = curve1 self.curve2 = curve2 #self.f1=self.curve1 # TODO: Soon or later, one will have to fusion these two #self.f2=self.curve2 self.mx1 = interval1[0] self.mx2 = interval1[1] self.Mx1 = interval2[0] self.Mx2 = interval2[1] for attr in [self.mx1, self.mx2, self.Mx1, self.Mx2]: if attr == None: raise TypeError( "At this point, initial and final values have to be already chosen" ) self.curve1.llamI = self.mx1 self.curve1.llamF = self.Mx1 self.curve2.llamI = self.mx2 self.curve2.llamF = self.Mx2 self.draw_Isegment = True self.draw_Fsegment = True self.Isegment = Segment(self.curve2.get_point(self.mx2, advised=False), self.curve1.get_point(self.mx1, advised=False)) self.Fsegment = Segment(self.curve1.get_point(self.Mx1, advised=False), self.curve2.get_point(self.Mx2, advised=False)) self.add_option("fillstyle=vlines") self.parameters.color = None
def __init__(self, A, O, B, r=None): from yanntricks.src.affine_vector import AffineVector self.A = A self.O = O self.B = B if r == None: # Does not depend on the radius because we are giving a 'visual' length. r = 0.5 self.r = r self.angleA = AffineVector(O, A).angle() self.angleB = AffineVector(O, B).angle() # I think that one does not have to check and fix what angle is first here # because the angles are re-computed in self.circle. self.angleI = self.angleA self.angleF = self.angleB ObjectGraph.__init__(self, self) self._mark_angle = None
def __init__(self, tuple_box_list, legende=None): ObjectGraph.__init__(self, self) self.tuple_box_list = tuple_box_list self.box_list = [] for t in self.tuple_box_list: self.box_list.append(HistogramBox(t[0], t[1], t[2], self)) #self.n=sum( [b.n for b in self.box_list] ) # New iterator trick http://python3porting.com/improving.html self.n = sum(b.n for b in self.box_list) self.length = 12 # Visual length (in centimeter) of the histogram self.height = 6 # Visual height (in centimeter) of the histogram self.d_xmin = min([b.d_xmin for b in self.box_list]) # min and max of the data self.d_xmax = max([b.d_xmax for b in self.box_list]) # max of the data ordinate. self.d_ymax = max([b.n for b in self.box_list]) self.xsize = self.d_xmax - self.d_xmin self.ysize = self.d_ymax # d_ymin is zero (implicitly) self.legende = legende # TODO : For sure one can sort it easier. # The problem is that if several differences # x.th_height-y.th_height are small, # int(...) always returns 1 (or -1), so that the sorting # gets wrong. self.xscale = self.length / self.xsize classement = self.box_list[:] facteur = 10 for x in classement: for y in classement: try: facteur = max(facteur, 10 / (x.th_height - y.th_height)) except ZeroDivisionError: pass classement.sort(key=lambda x: int(x.th_height * facteur)) self.yscale = self.height / classement[-1].th_height self.height / self.ysize
def __init__(self, op, O, A, B, angleI=0, angleF=0): """ The circle passing trough A and B with center O. `A`, `B` and `O` are tuples of numbers """ from yanntricks.src.Constructors import Vector3D ObjectGraph.__init__(self, self) self.op = op self.O = O self.A = A self.B = B self.center = Vector3D(O[0], O[1], O[2]) self.u = Vector3D(A[0] - O[0], A[1] - O[1], A[2] - O[2]) self.v = Vector3D(B[0] - O[0], B[1] - O[1], B[2] - O[2]) self.radius_u = sqrt(sum(k**2 for k in self.u)) self.radius_v = sqrt(sum(k**2 for k in self.v)) self.parameters.plotpoints = 10 * max(self.radius_u, self.radius_v) self.angleI = angleI self.angleF = angleF self.divide = False self.linear_plotpoints = CIRCLE3D_LINEAR_PLOTPOINTS
def __init__(self, d1, d2, r, n1, n2): """ two lines and a distance. n1 and n2 are 0 or 1 and indicating which sector has to be marked. 'n1' if for the intersection with d1. If 'n1=0' then we choose the intersection nearest to d1.I Similarly for n2 """ ObjectGraph.__init__(self, self) self.d1 = d1 self.d2 = d2 # If the intersection point is one of the initial or final point of d1 or d2, then the sorting # in 'action_on_pspict' does not work. # This happens in RightAngle( Segment(D,E),Segment(D,F),l=0.2, n1=1,n2=1 ) because the same point 'D' is given # for both d1 and d2. # We need d1.I, d1.F, d2.I and d2.F to be four distinct points. if self.d1.I.is_almost_equal(self.d2.I) or self.d1.I.is_almost_equal( self.d2.F) or self.d1.F.is_almost_equal( self.d2.I) or self.d1.F.is_almost_equal(self.d2.F): self.d1 = d1.dilatation(1.5) self.d2 = d2.dilatation(1.5) self.r = r self.n1 = n1 self.n2 = n2 self.intersection = Intersection(d1, d2)[0] # If the intersection point is one of the given points, # there will be troubles. # For then angle between AB and CD at point I, we need A,B,C,D # and I to be five different points. if self.intersection.is_almost_equal( self.d1.I) or self.intersection.is_almost_equal(self.d1.F): self.d1 = d1.dilatation(1.5) if self.intersection.is_almost_equal( self.d2.I) or self.intersection.is_almost_equal(self.d2.F): self.d2 = d2.dilatation(1.5)
def __init__(self, nlines, ncolumns): ObjectGraph.__init__(self, self) self.nlines = nlines self.ncolumns = ncolumns self._computed_central_points = False self.elements = {} self._lines = {} self._columns = {} self.matrix_environment = "pmatrix" for i in range(1, nlines + 1): for j in range(1, ncolumns + 1): self.elements[i, j] = MatrixElement(line=i, column=j) # Line constructions for i in range(1, nlines + 1): self._lines[i] = MatrixLineColumn(i, self) for j in range(1, ncolumns + 1): self.getLine(i).elements[j] = self.getElement(i, j) # Column constructions for j in range(1, ncolumns + 1): self._columns[j] = MatrixLineColumn(j, self) for i in range(1, nlines + 1): self.getColumn(j).elements[i] = self.getElement(i, j)
def __init__(self, C, base, mx, Mx, pspict=None): ObjectGraph.__init__(self, self) self.C = C self.base = base self.mx = mx self.Mx = Mx self.pspict = pspict self.options = Options() self.IsLabel = False self.axes_unit = AxesUnit(self.base.length, "") self.Dx = 1 self.arrows = "->" self.graduation = True self.numbering = True self.imposed_graduation = [] self.mark_origin = True self.mark = None self.mark_angle = degree(base.angle().radian-pi/2) self.enlarge_size = 0.5 # The `conclude` method performs the last computations before # to be drawn. The graduation bars are added there. self._already_concluded = False
def __init__(self, center, radius, angleI=0, angleF=360, visual=False, pspict=None): from yanntricks.src.AngleMeasure import AngleMeasure from yanntricks.src.Defaults import CIRCLE_LINEAR_PLOTPOINTS GenericCurve.__init__(self, pI=angleI, pF=angleF) self.linear_plotpoints = CIRCLE_LINEAR_PLOTPOINTS self.center = center self.radius = radius ObjectGraph.__init__(self, self) self.diameter = 2 * self.radius self._parametric_curve = None self.angleI = AngleMeasure(value_degree=angleI, keep_negative=True) self.angleF = AngleMeasure(value_degree=angleF, keep_negative=True) a = numerical_approx(self.angleI.degree) b = numerical_approx(self.angleF.degree) self.visual = visual self.pspict = pspict self._equation = None self._numerical_equation = None
def __init__(self, points_list): ObjectGraph.__init__(self, self) self.edges = [] self.vertices = points_list self.points_list = self.vertices for i in range(0, len(self.points_list)): segment = Segment( self.points_list[i], self.points_list[(i + 1) % len(self.points_list)]) self.edges.append(segment) self.draw_edges = True self.independent_edge = False self.parameters = None from yanntricks.src.parameters.Parameters import Parameters from yanntricks.src.parameters.HatchParameters import HatchParameters from yanntricks.src.parameters.FillParameters import FillParameters self.edges_parameters = Parameters(self) self.hatch_parameters = HatchParameters() self.fill_parameters = FillParameters() self._hatched = False self._filled = False
def __init__(self, question, length=1): ObjectGraph.__init__(self, self) self.question = sudoku_substitution(question) self.length = length # length of a cell