Okay, I'm going to wait for more feedback.  An hour of design can be worth
ten hours of implementation :)

On Fri, May 15, 2015 at 11:11 AM, Thomas Caswell <tcasw...@gmail.com> wrote:

> 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

Reply via email to