## Re: [PyX-user] xgridpath etc

 Re: [PyX-user] xgridpath etc From: Alan G Isaac - 2008-07-19 16:34:48 ```OK, here is a first pass at adding what I consider to be needed documentation of the example. However you will find six questions (marked as Q\d) interspersed. Cheers, Alan ############################################################ """ Next use the command ``g.plot`` to return a "plot-object" ``d``, which contains some information on the plotted data, including the title and the path which is plotted. We want access to the path ``p``, which comprises 100 short lines (concatenated to look like a curve). Comment: the path is just a path instance, completely independent of the graph. (This allows us, if we wish, to stroke the same path on a completely different canvas.) However, we cannot access this path until we do the graph layout. """ #plot some data on the graph d = g.plot(graph.data.function("y(x)=(x-3)*(x-5)*(x-7)")) #the path is not accessible until the layout is done g.finish() #Q1: would dolayout() be adequate here? # now we have access to the path, so get a handle to it p = d.path """ Next we want to create a path bounding the shaded area. Eventually we will do this by joining gridpath lines to part of the function plot path. Note: ``xgridpath`` is a graph method that returns a path along a line of constant 'x' within the plot area of the graph. As an alternative, we could have asked for the position of the values a and b and then created the path ourselves. E.g., :: x = g.pos(a, 0.0)[0] pa = path.line(0, x, 10, x) However this requires that we know something about the y-range (0.0 has to be a reasonable value) and that we know something about the position and size of the graph (0 should be below the x-axis, and 10 above the graph of the function). Instead, ``xgridpath`` does all that automatically for us. Q2: How do we know the "direction" of this path? From lesser to higher values? """ #get path for left boundary of the shaded area pa = g.xgridpath(a) #get path for right boundary of the shaded area pb = g.xgridpath(b) """ Next we generate an intersection between ``p`` and ``pa``. Note that ``intersect`` is a path method that returns a *2-tuple* containing two lists characterizing the points of intersection of the path with its argument (the other path). The two lists are of equal length. Each list contains parameter values corresponding to intersection points: the first list has the values for the intersecting path (``p``), and the secon list has the values for the intersected path (``pa``), A "parameter value" is a ``normpathparam`` object, which is a normalized way of characterizing a point along the path. Q3: Am I saying this correctly? Comment: Here we know that ``p`` and ``pa`` have a single intersection. Therefore, the two lists have length 1. In general, there may be many intersection points, and the following command would fail if there were more than one. :see: http://pyx.sourceforge.net/manual/module-path.html """ (splita,), (splitpa,) = p.intersect(pa) # Determine the top right conrner in the same fashion. (splitb,), (splitpb,) = p.intersect(pb) """ Like a path, a normpath can be split into pieces if we provide to the ``split`` mathod a list of parameter values at which to split. We now use this split method to produce pieces of the path around the shaded area. Remember, we always have to provide a *list* of parameters, and correspondingly we receive a list of pieces of the original path. We have to choose the correct piece. (E.g., here we specify the index [0] or [1]). Q4: Again we need to know the direction of the path ``pa``. How? :see: http://pyx.sourceforge.net/manual/node12.html """ #create a normpath as the part of ``pa`` from axis to intersection # (note: we split the path in two, and we want the first piece) leftbound = pa.split([splitpa])[0] #create a normpath as the part of ``p`` from left intersection to right intersection topbound = p.split([splita, splitb])[1] #create a normpath as the part of ``pb`` from intersection to axis # (note that we need to reverse the direction of ``rightbound``) rightbound = pb.split([splitpb])[0].reversed() """ We will us the ``<<`` operator to "glue" the path pieces together. Comment: The ``<<`` operator throws away any ``path.moveto`` at the beginning of the pieces. (Contrast with adding the paths together with the ``+`` operator, which keeps any ``moveto``.) Q5: is the << operator for *normpath* documented somewhere?? (Ex post, I understand you could say this is just another method.) """ #use the ``<<`` operator to join the three boundary paths into a single path area = (leftbound << topbound << rightbound) #an *open* path #Finally, close up the path. # Q6: Wouldn't area.append(closepath()) be more natural? # Is this different? If so, how? # Oh ... I think I see, ``area`` contains a *normpath* ... # I'll make some changes above to reflect this ... # # But ... is it needed? The fill will close automatically, right? # And restroking the axis is really not necessary. area[-1].close() ############################################################ ```