I would advocate for calling yours something different. path.Path is
really a container for a Bezier curve and is probably best left as simple
as possible. There is probably an interesting discussion about right is-a
and has-a relations between Path, FancyPath (don't use that name!), and
FancyArrow (which I do not have a clear view of yet).
Tom
On Fri, May 15, 2015 at 11:04 AM Neil Girdhar <mistersh...@gmail.com> wrote:
> On Fri, May 15, 2015 at 10:53 AM, Thomas Caswell <tcasw...@gmail.com>
> wrote:
>
>> A few very quick comments (just skimmed the docstrings)
>>
>> We already have a mpl.path.Path class, please don't shadow that.
>>
>
> I read the Path class and based mine on that. The problem is that I want
> to be able to place nodes along the path (like labels) and so I need to ask
> it questions. Maybe we should just extend the existing Path class? Or
> else we should call my Path something different?
>
>
>> Is your `Path` going to be an `Artist` that is responsible for drawing
>> it's self or does in serve a role like the existing `Path` in that it is
>> used by other artists as part of their `draw`?
>>
>> This feels very similar to the `FancyArrow` (with classes being passed in
>> to control how the arrow is styled), would this make sense as an extension
>> to that code? This does seem more general, maybe it makes sense to start
>> from scratch and implement `FancyArrow` in terms of this code.
>>
>
> Yes! Didn't know about that. I think modifying and extending that code
> might be a good way forward.
>
>
>
>>
>> Tom
>>
>> On Fri, May 15, 2015 at 10:40 AM Neil Girdhar <mistersh...@gmail.com>
>> wrote:
>>
>>> I have a draft proposal of the long term goal for what an interface
>>> could look like for drawing arrows between coordinates or nodes. I based
>>> the design on the tikz manual (http://pgf.sourceforge.net/pgf_CVS.pdf),
>>> so it might help to flip through that to get an idea for the basis of this
>>> design. I tried to separate the creating of Path objects with the drawing
>>> of paths since it's often really useful when compositing layouts to be able
>>> to do math with with the positions of things before drawing anything. For
>>> example, when automatically positioning nodes.
>>>
>>> I'm not committed to this design; it's just an outline to get feedback.
>>>
>>> Best,
>>>
>>> Neil
>>>
>>> class Axes_(_AxesBase):
>>> def path(self, path, draw=True, fill=False):
>>> """
>>> If draw is not falsy, draws along the path using the draw
>>> specification.
>>> If fill is not falsy, fills the closed path using the fill
>>> specification.
>>>
>>> Parameters
>>> ----------
>>> path is a Path object or path commands with which to create one.
>>>
>>> draw is a draw specification:
>>> either the value True, which indicates some defaults, or else
>>> False, or else a dictionary with the following keys:
>>> color
>>> opacity
>>> line_width
>>> line_join
>>> begin_tip is a Tip object
>>> tip or end_tip is a Tip object
>>> dashed is a dash specification
>>>
>>> a dash specification
>>> either dictionary containing:
>>> dash_pattern
>>> an iterable of numbers specifying the length of the
>>> dashes
>>> and gaps in points. E.g., [2, 3, 4, 3] means on for
>>> 2
>>> points, off for 3, on for 4, off for 3, i.e.,
>>> dash-dotted.
>>> dash_phase
>>> Shifts the start of the dash pattern by dash_phase
>>> points.
>>> or a string, one of:
>>> 'solid'
>>> 'dotted', 'densely dotted', 'loosely dotted'
>>> 'dashed', 'densely dashed', 'loosely dashed'
>>> 'dash dot', 'densely dash dot', 'loosely dash dot'
>>> 'dash dot dot', 'densely dash dot dot', 'loosely dash
>>> dot dot'
>>>
>>> fill is a fill specification:
>>> TODO
>>> """
>>>
>>> class Path:
>>> def __init__(self, path_commands):
>>> """
>>> path_commands is either
>>> a coordinate (representing a move to in the first position,
>>> or a
>>> line to in any other position)
>>> MoveTo(coordinate)
>>> LineTo(coordinate_or_node, draw=None)
>>> CurveTo(coordinate_or_node, control_points, draw=None)
>>> ClosePolygon()
>>>
>>> optional draw commands override the draw specification of
>>> the whole
>>> path within that edge.
>>>
>>> a coordinate is either an (x, y) pair, or a Coordinate
>>> object.
>>> a node is a Node object.
>>> """
>>>
>>> def at_position(self, fraction=0.5):
>>> """
>>> Returns a coordinate fraction of the way along the line.
>>> fraction can be one of 'at end', 'very near end', 'near end',
>>> 'midway', 'near start', 'very near start', 'at start'
>>> """
>>>
>>> def node_at(node, fraction=0.5, location, ...)
>>> """
>>> Sets the node's position so that it sits flush to the path.
>>>
>>> Parameters
>>> ----------
>>> location :
>>> Could be 'above', 'below', 'on', or a number, which is the
>>> number
>>> of points away from the path to place the node.
>>> """
>>>
>>> def pin_node(node, pin_distance, draw=draw_specification):
>>> pass
>>>
>>>
>>> class Coordinate:
>>> @property
>>> def coordinate(self):
>>> return (self.x, self.y)
>>>
>>> def node_at(self, node, angle):
>>> """
>>> Places the node so that it is in the direction angle from the
>>> coordinate. E.g.,
>>> angle=pi/2, or angle='above' places the node so that the
>>> coordinate is
>>> touching the center-bottom of the node.
>>> angle could be 'above', 'below', 'left', 'right', 'above left',
>>> etc.
>>> """
>>>
>>> class Node:
>>> """
>>> Available Node objects:
>>> Rectangle, Circle
>>> """
>>> @property
>>> def center(self):
>>> return (self.x, self.y)
>>>
>>> def node_at(self, node, angle):
>>> """
>>> Places the node so that it is in the direction angle from the
>>> coordinate. The node could be an arrowhead for example.
>>> """
>>>
>>> def convex_hulls(self):
>>> """
>>> Returns a list of convex hulls. The convex hulls are used when
>>> position one node or arrowhead flush with another using the
>>> separating axis algorithm.
>>> """
>>>
>>> class Tip:
>>> """
>>> Available Tip objects:
>>> ButtCap (no tip, the default)
>>> RectangleCap, TriangleCap, RoundCap
>>> ArcBarb, Bar, Bracket, Hooks, Parenthesis,
>>> StraightBarb, TeeBarb
>>> Circle, Diamond, Ellipse, Kite, Arrow,
>>> Rectangle, Square, Stealth, Triangle,
>>> TurnedSquare
>>> TipCombination (accepts multiple tips and merges them)
>>> """
>>> def __init__(self, draw=None, fill=True, reversed_=False):
>>> pass
>>>
>>> def convex_hulls(self, line_width):
>>> """
>>> Returns a list of convex hulls for use with placement
>>> whereby the arrow faces right starting at the origin.
>>> """
>>>
>>> def transmute(self, line_width):
>>> """
>>> Returns a pair of lists (draw_path, fill_path).
>>> """
>>>
>>> @property
>>> def draw_specification(self):
>>> """
>>> is a draw specification, or None to use the parent line's
>>> """
>>> def fill_specification(self):
>>> """
>>> Is a fill specification, or True to use defaults based
>>> on the parent line's draw color, or False to use an open fill.
>>> """
>>>
>>> -----
>>>
>>> Usage:
>>>
>>> # draw an arrow from point to point.
>>> ax.path([(x, y), (x2, y2)], draw={'tip': Arrow()})
>>>
>>> # Create a path.
>>> p = Path([(x, y), (x2, y2)])
>>>
>>> # Create a node along the path.
>>> n = p.node_at(Label("some label"))
>>>
>>> # Draw the path using an arrow, and the node.
>>> ax.path(p, draw={'tip': Arrow()})
>>> ax.node(n)
>>>
>>>
>>> On Wed, May 13, 2015 at 11:27 PM, Thomas Caswell <tcasw...@gmail.com>
>>> wrote:
>>>
>>>> Sorry, I may have been being a bit dramatic
>>>>
>>>> In mpl.patches: Arrow, FancyArrow, YAArrow, FancyArrowPatch,
>>>> ConnectionPatch + annotation related artists + some classes in axisartist
>>>> which now that I look at them are not really general purpose arrow tools.
>>>> I had not been counting quiver (or barbs) or sankey.
>>>>
>>>> Neil: Those are all great questions! Much of the arrow related code
>>>> was written by Joe-Joon Lee who (by having read a good deal of his code)
>>>> has a habit of writing very power but very opaque python.
>>>>
>>>> I believe that the line join style is controlled by `joinstyle` on the
>>>> graphics context and it is up to the backends to implement that correctly.
>>>>
>>>> Tom
>>>>
>>> On Wed, May 13, 2015 at 10:58 PM Neil Girdhar <mistersh...@gmail.com>
>>>> wrote:
>>>>
>>> Okay, I'm looking at this in more detail and there may be some design
>>>>> concerns:
>>>>>
>>>>> The arrow placement is decided without asking the arrow any questions,
>>>>> such as its bounding box. Instead, the arrow should return a bounding box
>>>>> and then the line should retreat until the bounding box no longer
>>>>> intersects the target node. Then the arrow should be placed. This
>>>>> doesn't
>>>>> matter so much when you have a simple arrow like this: ---->, but it's a
>>>>> big deal when you have an arrow like ----| . In this case, the sides of
>>>>> the arrow risk intersecting with the target node.
>>>>>
>>>>> I'm not keen on implementing every arrow three times: <-, ->, <->.
>>>>> This really should be handled by the code placing the arrows for many
>>>>> reasons:
>>>>> 1. It should also be possible to have a different arrowhead at either
>>>>> end of the line.
>>>>> 2. It should be possible to stack the arrows, for example having two
>>>>> heads one after another (to represent two kinds of relationships). This
>>>>> is
>>>>> another reason to be able to ask the arrowhead its length and so on.
>>>>>
>>>>> I don't understand the "monolithic" keyword. How can the arrow draw
>>>>> the line as well when it doesn't know the line style, color and so on?
>>>>>
>>>>> I think I like the design of the transmute function. I'm curious:
>>>>> ultimately, where does the mutation_size come from? Is it a global scale
>>>>> applied to the figure, or is it based on the linewidth, or?
>>>>>
>>>>> When you emit a set of lines, how are they joined? If I draw a line
>>>>> having linewidth 0.1 from the origin to (1, 0), and back to (0, 0.5), what
>>>>> happens at the tip? Are two rectangles drawn (each having width 0.1, but
>>>>> oriented differently)? Is a bevel created? A miter? Or is the tip
>>>>> rounded? Can this be controlled? See page 166 of the manual I sent
>>>>> earlier (search for tikz/line join).
>>>>>
>>>>> Best,
>>>>>
>>>>> Neil
>>>>>
>>>> On Wed, May 13, 2015 at 10:14 PM, Neil Girdhar <mistersh...@gmail.com>
>>>>> wrote:
>>>>>
>>>> Thanks, it works!
>>>>>>
>>>>>> I needed to add:
>>>>>>
>>>>>> import matplotlib.patches
>>>>>>
>>>>>> to one file and
>>>>>>
>>>>>> plt.show()
>>>>>>
>>>>>> to the other.
>>>>>>
>>>>>> Any word on the locations in the code of the seven arrow drawing
>>>>>> methods?
>>>>>>
>>>>>> I've located the arrow drawing code in tikz, and so I can start
>>>>>> porting it over. I'm curious, do we know the linewidth of the edge being
>>>>>> decorated by the arrow? To make arrows scale nicely, most of the arrow
>>>>>> dimensions are given in two pieces: an absolute value (in points for
>>>>>> example) and a line width factor. The dimension is the absolute value
>>>>>> plus
>>>>>> the line width factor times the line width. The TikZ manual explains:
>>>>>> "This makes it easy to vary the size of an arrow tip in accordance with
>>>>>> the
>>>>>> line width – usually a very good idea since thicker lines will need
>>>>>> thicker
>>>>>> arrow tips."
>>>>>>
>>>>>> Best,
>>>>>>
>>>>>> Neil
>>>>>>
>>>>> On Wed, May 13, 2015 at 10:07 PM, Benjamin Reedlunn <
>>>>>> breed...@gmail.com> wrote:
>>>>>>
>>>>> Neil,
>>>>>>>
>>>>>>> I have attached code to draw the arrowhead.
>>>>>>>
>>>>>>> -Ben
>>>>>>>
>>>>>>>
>>>>>>> On May 13, 2015, at 7:44 PM, Neil Girdhar <mistersh...@gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>> Do you have the code that you used to draw the arrowhead? I'm up to
>>>>>>> date now on the development workflow (
>>>>>>> http://matplotlib.org/devel/gitwash/development_workflow.html), so
>>>>>>> I'm ready to start working.
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> Neil
>>>>>>>
>>>>>>> On Wed, May 13, 2015 at 9:10 PM, Benjamin Reedlunn <
>>>>>>> breed...@gmail.com> wrote:
>>>>>>>
>>>>>>> Yes, I fully agree that we need to unify the many different ways to
>>>>>>>> draw arrows.
>>>>>>>>
>>>>>>>> Neil, in case an example would be helpful for you, I have attached
>>>>>>>> a module that includes a custom arrowhead class. The arrowhead class
>>>>>>>> works
>>>>>>>> with the with the ax.annotate() method. (I like the annotate method
>>>>>>>> because it allows me to easily mix and match coordinate systems for
>>>>>>>> arrow
>>>>>>>> placement.) As you can see in the attached pdf, the custom arrowhead
>>>>>>>> doesn't include fancy Bezier curves, but that could be added.
>>>>>>>>
>>>>>>>> -Ben
>>>>>>>>
>>>>>>>>
>>>>>>>> On May 13, 2015, at 2:54 PM, Thomas Caswell <tcasw...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> The other thing that should be done is to unify the (I think 7?!?)
>>>>>>>> unique ways to draw arrows in mpl.
>>>>>>>>
>>>>>>>> On Wed, May 13, 2015 at 4:52 PM Neil Girdhar <mistersh...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> Yes, I just noticed that as well. That's how the tikz pgf code
>>>>>>>>> looks (a sequence of line_to and curve_to commands and so on) so it
>>>>>>>>> should
>>>>>>>>> be easy to port over the various shapes.
>>>>>>>>>
>>>>>>>>> On Wed, May 13, 2015 at 4:49 PM, Eric Firing <efir...@hawaii.edu>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> On 2015/05/13 10:12 AM, Neil Girdhar wrote:
>>>>>>>>>>
>>>>>>>>>>> If you want to make arrowheads look at all decent, they really
>>>>>>>>>>> need to
>>>>>>>>>>> be enclosed in Bezier curves. See the diagram here:
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Mpl paths support Bezier curves.
>>>>>>>>>> http://matplotlib.org/api/path_api.html?highlight=bezier
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> http://tex.stackexchange.com/questions/150289/how-do-you-accomplish-stealth-with-the-new-arrows-meta/230965#230965
>>>>>>>>>>>
>>>>>>>>>>> The first two look like garbage. The last one is the only one
>>>>>>>>>>> that
>>>>>>>>>>> looks good imho.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> That depends on the application, and the observer.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Sure, but I may as well port them all of the tikz arrowheads over
>>>>>>>>> since most of the work would be figuring out how to do it.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Eric
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> Best,
>>>>>>>>>>>
>>>>>>>>>>> Neil
>>>>>>>>>>>
>>>>>>>>>>> On Wed, May 13, 2015 at 4:09 PM, Eric Firing <efir...@hawaii.edu
>>>>>>>>>>> <mailto:efir...@hawaii.edu>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> On 2015/05/13 9:36 AM, Neil Girdhar wrote:
>>>>>>>>>>>
>>>>>>>>>>> I don't know matplotlib well enough (yet) to know what
>>>>>>>>>>> the
>>>>>>>>>>> change would
>>>>>>>>>>> consist of.
>>>>>>>>>>>
>>>>>>>>>>> I suggest you take a look at the beautiful tikz manual:
>>>>>>>>>>> http://pgf.sourceforge.net/pgf_CVS.pdf
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Very helpful, thank you.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> The arrows.meta on page 201–212 are really well-designed
>>>>>>>>>>> and
>>>>>>>>>>> beautiful.
>>>>>>>>>>>
>>>>>>>>>>> Compare this with matplotlib's custom arrows:
>>>>>>>>>>>
>>>>>>>>>>> http://stackoverflow.com/questions/16968007/custom-arrow-style-for-matplotlib-pyplot-annotate
>>>>>>>>>>>
>>>>>>>>>>> How do I make tikz's arrowheads available for all
>>>>>>>>>>> backends?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> My guess offhand is that this is a matter of using the mpl
>>>>>>>>>>> API. I
>>>>>>>>>>> don't think we would want to add all of these types and
>>>>>>>>>>> options to
>>>>>>>>>>> the mpl core; but a toolkit might be ideal for this. The
>>>>>>>>>>> mpl API,
>>>>>>>>>>> which generates the same results for all backends, is quite
>>>>>>>>>>> complete
>>>>>>>>>>> and flexible. Things like arrowheads are Patch objects, and
>>>>>>>>>>> you can
>>>>>>>>>>> specify any path you want. The main trick is figuring out
>>>>>>>>>>> how to
>>>>>>>>>>> handle transforms--what kind of coordinates should the path
>>>>>>>>>>> be
>>>>>>>>>>> specifying? How should things scale as a figure is reshaped
>>>>>>>>>>> and
>>>>>>>>>>> resized?
>>>>>>>>>>>
>>>>>>>>>>> For many of these types you could also use mpl Line2D
>>>>>>>>>>> objects, for
>>>>>>>>>>> which several properties including cap style can be
>>>>>>>>>>> specified. Not
>>>>>>>>>>> all of the TikZ options would be available, but perhaps
>>>>>>>>>>> enough.
>>>>>>>>>>>
>>>>>>>>>>> Eric
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>>> One dashboard for servers and applications across
>>>>>>>>> Physical-Virtual-Cloud
>>>>>>>>> Widest out-of-the-box monitoring support with 50+ applications
>>>>>>>>> Performance metrics, stats and reports that give you Actionable
>>>>>>>>> Insights
>>>>>>>>> Deep dive visibility with transaction tracing using APM Insight.
>>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>>> Matplotlib-devel mailing list
>>>>>>>>> Matplotlib-devel@lists.sourceforge.net
>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>>>>>>>>>
>>>>>>>>
>>>>>>>> ------------------------------------------------------------------------------
>>>>>>>> One dashboard for servers and applications across
>>>>>>>> Physical-Virtual-Cloud
>>>>>>>> Widest out-of-the-box monitoring support with 50+ applications
>>>>>>>> Performance metrics, stats and reports that give you Actionable
>>>>>>>> Insights
>>>>>>>> Deep dive visibility with transaction tracing using APM Insight.
>>>>>>>>
>>>>>>>> Matplotlib-devel mailing list
>>>>>>>> Matplotlib-devel@lists.sourceforge.net
>>>>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>
>>
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel