You can subscribe to this list here.
2002 |
Jan
|
Feb
(13) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
(5) |
Jun
(15) |
Jul
(4) |
Aug
(4) |
Sep
(4) |
Oct
(41) |
Nov
(3) |
Dec
(19) |
2004 |
Jan
(7) |
Feb
(1) |
Mar
(6) |
Apr
(13) |
May
(26) |
Jun
(6) |
Jul
(66) |
Aug
(13) |
Sep
|
Oct
(21) |
Nov
(12) |
Dec
(24) |
2005 |
Jan
(7) |
Feb
(24) |
Mar
(9) |
Apr
(5) |
May
|
Jun
(8) |
Jul
(5) |
Aug
(22) |
Sep
(58) |
Oct
(6) |
Nov
|
Dec
(2) |
2006 |
Jan
(1) |
Feb
(11) |
Mar
(12) |
Apr
(8) |
May
(12) |
Jun
(30) |
Jul
(6) |
Aug
(2) |
Sep
(6) |
Oct
(1) |
Nov
(1) |
Dec
(1) |
2007 |
Jan
|
Feb
|
Mar
(1) |
Apr
(2) |
May
|
Jun
|
Jul
(8) |
Aug
(3) |
Sep
|
Oct
(1) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
(21) |
Apr
(6) |
May
(12) |
Jun
(13) |
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
(4) |
Dec
|
2010 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(6) |
Jul
(4) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
2011 |
Jan
|
Feb
|
Mar
|
Apr
(7) |
May
(26) |
Jun
(1) |
Jul
(40) |
Aug
|
Sep
|
Oct
(15) |
Nov
|
Dec
(2) |
2012 |
Jan
|
Feb
(14) |
Mar
|
Apr
|
May
(24) |
Jun
|
Jul
|
Aug
(2) |
Sep
|
Oct
(9) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
(12) |
Feb
(8) |
Mar
|
Apr
|
May
(3) |
Jun
|
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2014 |
Jan
(4) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
(2) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(4) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
(6) |
2016 |
Jan
(4) |
Feb
(10) |
Mar
(4) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(4) |
Oct
(2) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
|
From: André W. <wo...@us...> - 2012-10-26 10:11:39
|
Hi all, I just released PyX 0.12.1. It fixes some drawing bugs in the gradient style for the recently introduced key graph. Happy PyXing, André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: André W. <wo...@us...> - 2012-10-24 11:14:56
|
Hi, since there is a small visual defect in the key graphs introduced in PyX 0.12 recently, I will soon make an 0.12.1 release (by the end of the week or so). In case you observed any other misbehavior, I would gladly investigate your feedback. Best, André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: André W. <wo...@us...> - 2012-10-17 21:50:20
|
Hi all, We're proud to announce the release of PyX 0.12. This release features various improvements and bug fixes all over the place. The most prominent change is probably the addition of density plots by means of a density style, which uses bitmaps in the PostScript and PDF output. The color scale is managed by a separate axis, and can be displayed in a separate key graph. Another important addition with respect to the graph are the layers, which have been added as a generic feature to all canvases, and are used by graph instances to stack the output. PyX should now do a much better job in writing the graph output in an appropriate order (without tricks like calling do-methods early; this should not be necessary anymore!). Some other highlights are probably a decorator to put text along a path, a metapost like path creation (smooth paths from a series of points), and various fixes for the Windows platform, which hopefully resolves all the nasty little bugs reported by our users. Please find a full list of changes below. Thanks to everybody who contributed to this release. In case you're curious about Python 3, PyX is still Python 2 only software and we still support really old versions (to our best knowledge PyX should still run fine with Python 2.3 and all newer Python 2 releases). However, we plan to move to Python 3 in one of our next releases. As of now we do not intent to support Python 2 and 3 at the same time (except for maybe some kind of long term support for an older Python 2 release of PyX), but make a huge switch to require Python 3.3 or so as the minimal version. We recently upgraded the PyX project page to sourceforge's new Allura platform. In case you're using subversion checkouts, you're kindly asked to upgrade the repository root as stated on the project page. Happy PyXing, Jörg and André ---------------------------------------------------------------------- 0.12 (2012/10/17): - canvas module: - insert method now returns canvas wrapping item if attrs are given - insert method allows specification of position where item is inserted by before and after arguments - new layer method allows creation of separated drawing layers for grouping of drawing operations - writeXXXfile methods now use "page_" and "write_" prefixes for passing the keyword arguments to the page constructor and write method - pipeGS now returns a file handle instead of writing to a file or to stdout - the new method writeGSfile restores the previous pipeGS functionality - support rendering as png for use in IPython notebooks (as suggested by Nikolas Tezak) - document module: - writeXXXfile methods now support writing to stdout when filename is set to "-" - type 1 font modules: - allow font slanting for T1builtinfont instances - improve stripped font compatibility - remove UniqueID lookup from embedded fonts in PostScript output (fixes missing glyph issue with dvips and certain fonts) - allow Type1 font usage without TeX and without AFM font metric - add support for pfm font matrices - epsfile module: - fix race condition while generating bitmap for PDF inclusion - fix file opening for bbox reading when using filelocator (reported by Michael J Gruber) - filelocator module: - fix text mode line ending issue for MS Windows - text module: - fix subprocess call on MS Windows (closefds not functional not also not required at all) - fix pyxgraphics functionality because at least some versions of graphics and friends seem to expect the file extension .def for the driver files (thanks to Michael J Gruber) - deco module: - decorator to put text along a path; based on a patch by Michael J Gruber - dvifile module: - fix for MS Windows: open virtual font files in binary mode - graph modules: - graphs: - uses new canvas layers to stack graph components (fixing bug #1518414, reported by Dominic Ford) - add a flipped option to graphxy to exchange x and y coordinates - add a 1d graph "graphx" (use case: convert a value to a color) - add hiddenaxes layer to the 3d graph - add linkedaxes for the xy-plane in 3d like in 2d (works now properly due to the hiddenaxes feature) - graph styles: - add density style - add gradient style to convert a value to a color using a 1d graph - add a usenames dictionary to the pos style (like rangepos had it already) - graph data: - add a join data provide which adds concatenates several data sources - axis module: - divisor was not properly taken into account in tick handling (axis range extension and range rating) - added the metapost module: - create smooth paths from a series of points - bitmap module: - new fundamental constructor based on arbitrary affine transformations - add ASCIIHexDecode end marker - color module: - add rgbgradient and cmykgradient to force color space - mesh module: - add ASCIIHexDecode end marker - sourceforge.net: - upgrade PyX project page to the Allura platform -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: André W. <wo...@us...> - 2012-10-08 08:13:43
|
Michael, well, a \linebreak (*) is not what people want to express by "\\". See my enclosed example. I hope it goes through the list, we'll see. To my mind you should rethink your advice. People should use real paragraphs. This is what I would suggest in such situations most of the time. I'm aware this is sometimes difficult or impossible (think of the need for using \long\def for example), but we're really in a TeX discussion here. It's not that I want to quit this discussion as I think we can all learn from each other. I totally agree, that "\\" is often use wrongly. It harms the paragraph breaking algorithm of TeX and I constantly suggest to use paragraphs instead. While you then may need to fiddle with \parskip and \parindent, it is the only true solution to generate lines in LaTeX (to my knowledge). But in the end of the day if we want to give (and publish) a founded advice, we should probably ask a TeX guru (which I'm not). Best, André (*) at least when not in a raggedleft, raggedright or center-like mode, which happen to add some left and right horizontal material to each line at the beginning and end to suppress the inter-word glue blowup Am 08.10.2012 um 09:36 schrieb Michael J Gruber: > Hi there, > > I don't care personally, but '\linebreak' is the correct way to enforce > a linebreak in TeX. A new paragraph is something different. > > '\\' is used routinely (and mistakenly) by many people because it's > shorter, and most of the time it works. That patch was triggered by a > "bug report" on the users' list, and the intention was to preemptively > answer further reports. Anyway, it's "on google" now... > > Michael > > André Wobst venit, vidit, dixit 06.10.2012 18:39: >> Hi Michael, >> >> We just discussed this at a pyx dev weekend. Sorry for coming back to this email after such a long time of silence. While I totally agree with you in that "\\" to be considered harmful. However, I'm rather unsure whether \linebreak is the proper solution. I always suggest to use real paragraphs to generate breaks, as it creates separate vertical material in TeX. While I do understand your intention, I'm not sure whether we should document your solution. As it's a TeX problem, we may better not comment on that at all rather than proposing a wrong solution. >> >> Best, >> >> >> André >> >> >> Am 22.07.2011 um 14:26 schrieb Michael J Gruber: >> >>> The widespread use of \newline (in the incarnation \\) for enforcing >>> linebreaks causes many problems with the alignment of parboxes. >>> \linebreak is the correct way to force a line break without destroying >>> alignment. >>> --- >>> examples/text/halign.txt | 4 ++++ >>> 1 files changed, 4 insertions(+), 0 deletions(-) >>> >>> diff --git a/examples/text/halign.txt b/examples/text/halign.txt >>> index a9d15e3..b1453d0 100644 >>> --- a/examples/text/halign.txt >>> +++ b/examples/text/halign.txt >>> @@ -23,3 +23,7 @@ well, when you do not create a parbox. >>> !! Note that the alignment features are implemented in such a way, that they work >>> in both, TeX and LaTeX mode. Furthermore, you can always influence the >>> alignment of the box contents by appropriate TeX and LaTeX commands as well. >>> + >>> +!! If you want to enforce line breaks in a parbox use `\linebreak`, not `\newline` (which >>> +is equivalent to `\\`). `\linebreak` makes sure that horizontal alignment is preserved >>> +throughout the text box. >>> -- >>> 1.7.6.336.gdf067 >>> >>> >>> ------------------------------------------------------------------------------ >>> 10 Tips for Better Web Security >>> Learn 10 ways to better secure your business today. Topics covered include: >>> Web security, SSL, hacker attacks & Denial of Service (DoS), private keys, >>> security Microsoft Exchange, secure Instant Messaging, and much more. >>> http://www.accelacomm.com/jaw/sfnl/114/51426210/ >>> _______________________________________________ >>> PyX-devel mailing list >>> PyX...@li... >>> https://lists.sourceforge.net/lists/listinfo/pyx-devel >> > > ------------------------------------------------------------------------------ > Don't let slow site performance ruin your business. Deploy New Relic APM > Deploy New Relic app performance management and know exactly > what is happening inside your Ruby, Python, PHP, Java, and .NET app > Try New Relic at no cost today and get our sweet Data Nerd shirt too! > http://p.sf.net/sfu/newrelic-dev2dev > _______________________________________________ > PyX-devel mailing list > PyX...@li... > https://lists.sourceforge.net/lists/listinfo/pyx-devel -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Michael J G. <mic...@us...> - 2012-10-08 07:36:46
|
Hi there, I don't care personally, but '\linebreak' is the correct way to enforce a linebreak in TeX. A new paragraph is something different. '\\' is used routinely (and mistakenly) by many people because it's shorter, and most of the time it works. That patch was triggered by a "bug report" on the users' list, and the intention was to preemptively answer further reports. Anyway, it's "on google" now... Michael André Wobst venit, vidit, dixit 06.10.2012 18:39: > Hi Michael, > > We just discussed this at a pyx dev weekend. Sorry for coming back to this email after such a long time of silence. While I totally agree with you in that "\\" to be considered harmful. However, I'm rather unsure whether \linebreak is the proper solution. I always suggest to use real paragraphs to generate breaks, as it creates separate vertical material in TeX. While I do understand your intention, I'm not sure whether we should document your solution. As it's a TeX problem, we may better not comment on that at all rather than proposing a wrong solution. > > Best, > > > André > > > Am 22.07.2011 um 14:26 schrieb Michael J Gruber: > >> The widespread use of \newline (in the incarnation \\) for enforcing >> linebreaks causes many problems with the alignment of parboxes. >> \linebreak is the correct way to force a line break without destroying >> alignment. >> --- >> examples/text/halign.txt | 4 ++++ >> 1 files changed, 4 insertions(+), 0 deletions(-) >> >> diff --git a/examples/text/halign.txt b/examples/text/halign.txt >> index a9d15e3..b1453d0 100644 >> --- a/examples/text/halign.txt >> +++ b/examples/text/halign.txt >> @@ -23,3 +23,7 @@ well, when you do not create a parbox. >> !! Note that the alignment features are implemented in such a way, that they work >> in both, TeX and LaTeX mode. Furthermore, you can always influence the >> alignment of the box contents by appropriate TeX and LaTeX commands as well. >> + >> +!! If you want to enforce line breaks in a parbox use `\linebreak`, not `\newline` (which >> +is equivalent to `\\`). `\linebreak` makes sure that horizontal alignment is preserved >> +throughout the text box. >> -- >> 1.7.6.336.gdf067 >> >> >> ------------------------------------------------------------------------------ >> 10 Tips for Better Web Security >> Learn 10 ways to better secure your business today. Topics covered include: >> Web security, SSL, hacker attacks & Denial of Service (DoS), private keys, >> security Microsoft Exchange, secure Instant Messaging, and much more. >> http://www.accelacomm.com/jaw/sfnl/114/51426210/ >> _______________________________________________ >> PyX-devel mailing list >> PyX...@li... >> https://lists.sourceforge.net/lists/listinfo/pyx-devel > |
From: Joerg L. <jo...@us...> - 2012-10-06 19:09:20
|
Hi Nikolas, This has now been properly implemented in PyX as of revision 3269. Thanks for the idea, we enjoy it! Best, André and Jörg On 30.08.12, Nikolas Tezak wrote: > Hey guys, > > first of all thanks a lot for making PyX. It has been very useful to me for visualization purposes. Since our own software workflow makes heavy use of the new IPython notebook interface, I was wondering if you'd be interested in adding support for rendering canvasses automatically. The advantage would be that it allows a user to incrementally create a canvas object to his liking in a visual interface. > It can probably be written more elegantly, but it definitely works. > > Best, > > Nikolas > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > PyX-devel mailing list > PyX...@li... > https://lists.sourceforge.net/lists/listinfo/pyx-devel |
From: André W. <wo...@us...> - 2012-10-06 17:02:25
|
Hi Michael, We just discussed this at a pyx dev weekend. Sorry for coming back to this email after such a long time of silence. While I totally agree with you in that "\\" to be considered harmful. However, I'm rather unsure whether \linebreak is the proper solution. I always suggest to use real paragraphs to generate breaks, as it creates separate vertical material in TeX. While I do understand your intention, I'm not sure whether we should document your solution. As it's a TeX problem, we may better not comment on that at all rather than proposing a wrong solution. Best, André Am 22.07.2011 um 14:26 schrieb Michael J Gruber: > The widespread use of \newline (in the incarnation \\) for enforcing > linebreaks causes many problems with the alignment of parboxes. > \linebreak is the correct way to force a line break without destroying > alignment. > --- > examples/text/halign.txt | 4 ++++ > 1 files changed, 4 insertions(+), 0 deletions(-) > > diff --git a/examples/text/halign.txt b/examples/text/halign.txt > index a9d15e3..b1453d0 100644 > --- a/examples/text/halign.txt > +++ b/examples/text/halign.txt > @@ -23,3 +23,7 @@ well, when you do not create a parbox. > !! Note that the alignment features are implemented in such a way, that they work > in both, TeX and LaTeX mode. Furthermore, you can always influence the > alignment of the box contents by appropriate TeX and LaTeX commands as well. > + > +!! If you want to enforce line breaks in a parbox use `\linebreak`, not `\newline` (which > +is equivalent to `\\`). `\linebreak` makes sure that horizontal alignment is preserved > +throughout the text box. > -- > 1.7.6.336.gdf067 > > > ------------------------------------------------------------------------------ > 10 Tips for Better Web Security > Learn 10 ways to better secure your business today. Topics covered include: > Web security, SSL, hacker attacks & Denial of Service (DoS), private keys, > security Microsoft Exchange, secure Instant Messaging, and much more. > http://www.accelacomm.com/jaw/sfnl/114/51426210/ > _______________________________________________ > PyX-devel mailing list > PyX...@li... > https://lists.sourceforge.net/lists/listinfo/pyx-devel -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: SourceForge.net <no...@so...> - 2012-10-06 16:12:51
|
Patches item #1507349, was opened at 2006-06-16 07:59 Message generated for change (Comment added) made by joergl You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=442888&aid=1507349&group_id=45430 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Michael J Gruber (michaeljgruber) Assigned to: Jörg Lehmann (joergl) Summary: RFE: text along path Initial Comment: The attached diff implements typesetting of text along a path as a decorator (curvedtext). I put it in the bug tracker so that it doesn't get lost. It's a diff to r2824 (taking into account the reversal of trafos in canvas.py (r2728->r2730)). From the docstring: """a text decorator for curved text - text: is typeset along the path to which this decorator is applied - relarclenpos: position for the base point of the text (default: 0) - arlenfrombegin, arclenfromend: alternative ways of specifying the position of the base point; use of relarclenpos, arclenfrombegin and arclenfromend is mutually exclusive - textattrs, texrunner: standard text arguments (defaults: [] resp None) """ Files touched aside from deco.py: dvifile.__init__() in dvifile.py gets a new parameter singlecharmode which defaults to 0; dvifile.putchar() switches to single character mode if set to 1. texrunner.__init__(), texrunner.finishdvi(), texrunner.text() and texrunner.textboxes() in text.py get the same parameter so that it can be passed from the texrunner to dvifile. curvedtext switches to singlecharmode only while it is needed. Basic idea for curvedtext goes back to schindmi, I think. ---------------------------------------------------------------------- >Comment By: Jörg Lehmann (joergl) Date: 2012-10-06 09:12 Message: An implementation is available in SVN head. ---------------------------------------------------------------------- Comment By: Jörg Lehmann (joergl) Date: 2006-06-17 02:59 Message: Logged In: YES user_id=390410 Hello Michael, In principle I have nothing against this implementation. The only small things I noted are that our formating style is not followed everywhere (spaces are =), docstrings for the class in __init__, etc. And adding documentation would be nice too! Jörg PS: Not wanting to insist, but the idea and the implementation go back to me, although schindmi lost one afternoon of our precious worktime playing around with it, as well. ---------------------------------------------------------------------- Comment By: Michael J Gruber (michaeljgruber) Date: 2006-06-16 08:08 Message: Logged In: YES user_id=1454635 Attaching a simple example: It demonstrates how to achieve several orientations using text.halign.*, relarclenpos and path.reversed(); and how to set different stroke attributes on the text and the underlying path. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=442888&aid=1507349&group_id=45430 |
From: SourceForge.net <no...@so...> - 2012-10-06 15:53:15
|
Bugs item #1518414, was opened at 2006-07-06 14:42 Message generated for change (Comment added) made by joergl You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=442886&aid=1518414&group_id=45430 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Dominic Ford (dcf21) Assigned to: Nobody/Anonymous (nobody) Summary: gridlines overlay axis tics Initial Comment: The attached test script produces a blank plot, with faint grey gridlines. However, the left-most vertical gridline is drawn over the x1 axis, and both x1 and y1 axes lose their tick markings beneath the gridlines. I think the gridlines should be drawn at the back, behind all of the axes. Therefore, I think you need to draw all of the gridlines from all of the axes first, and then draw all of the axes and tick marks over the top? ---------------------------------------------------------------------- >Comment By: Jörg Lehmann (joergl) Date: 2012-10-06 08:53 Message: See changeset 3266. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=442886&aid=1518414&group_id=45430 |
From: Joerg L. <jo...@us...> - 2012-08-31 14:40:06
|
Hi Nikolas, On 30.08.12, Nikolas Tezak wrote: > first of all thanks a lot for making PyX. It has been very useful to > me for visualization purposes. Since our own software workflow makes > heavy use of the new IPython notebook interface, I was wondering if > you'd be interested in adding support for rendering canvasses > automatically. The advantage would be that it allows a user to > incrementally create a canvas object to his liking in a visual > interface. It can probably be written more elegantly, but it > definitely works. That's a very nice hack! For plotting, it could be made even more useful, if we would support calling the plot method even after the plot has been created. I'll keep this in mind for our next developer meeting. Best, Jörg |
From: Nikolas T. <nt...@st...> - 2012-08-30 23:49:59
|
Hey guys, first of all thanks a lot for making PyX. It has been very useful to me for visualization purposes. Since our own software workflow makes heavy use of the new IPython notebook interface, I was wondering if you'd be interested in adding support for rendering canvasses automatically. The advantage would be that it allows a user to incrementally create a canvas object to his liking in a visual interface. It can probably be written more elegantly, but it definitely works. Best, Nikolas |
From: Michael J G. <mic...@us...> - 2012-05-30 12:44:20
|
The pos argument of deco.arrow() maps the range [0,1] to the range of available positions such that the arrow head can be constructed from the path without extrapolation. This is useful especially for begin and end heads, but different from the positioning of other decorators such as deco.text(). Introduce additional position parameters relarclenpos, arclenfrombegin and arclendfromend which work exactly like for other decorators. They all default to None, which means that the pos argument is used and the behaviour of deco.arrow() is unchanged unless you specify a value for one of the new arguments. Also, introduce a new center argument which specifies the center of the arrow head (multiples of its size). It defaults to the center of mass of a solid triangular arrow head but is used only when any of the new position parameters is specified. Signed-off-by: Michael J Gruber <mic...@us...> --- pyx/deco.py | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/pyx/deco.py b/pyx/deco.py index e41e88e..58b9712 100644 --- a/pyx/deco.py +++ b/pyx/deco.py @@ -432,14 +432,19 @@ class arrow(deco, attr.attr): """arrow is a decorator which adds an arrow to either side of the path""" - def __init__(self, attrs=[], pos=1, reversed=0, size=_base, angle=45, constriction=0.8): + def __init__(self, attrs=[], pos=1, relarclenpos=None, arclenfrombegin=None, arclenfromend=None, + reversed=0, size=_base, angle=45, constriction=0.8, center=0.666667): self.attrs = attr.mergeattrs([style.linestyle.solid, filled] + attrs) attr.checkattrs(self.attrs, [deco, style.fillstyle, style.strokestyle]) self.pos = pos + self.relarclenpos = relarclenpos + self.arclenfrombegin = arclenfrombegin + self.arclenfromend = arclenfromend self.reversed = reversed self.size = size self.angle = angle self.constriction = constriction + self.center = center # calculate absolute arc length of constricition # Note that we have to correct this length because the arrowtemplates are rotated @@ -453,11 +458,18 @@ class arrow(deco, attr.attr): # need constrictionlen for cutting the path self.constrictionlen = self.size * 1 * math.cos(math.radians(self.angle/2.0)) - def __call__(self, attrs=None, pos=None, reversed=None, size=None, angle=None, constriction=_marker): + def __call__(self, attrs=None, pos=None, relarclenpos=None, arclenfrombegin=None, arclenfromend=None, + reversed=None, size=None, angle=None, constriction=_marker, center=None): if attrs is None: attrs = self.attrs if pos is None: pos = self.pos + if relarclenpos is None: + arelrclenpos = self.relarclenpos + if arclenfrombegin is None: + arclenfrombegin = self.arclenfrombegin + if arclenfromend is None: + arclenfromend = self.arclenfromend if reversed is None: reversed = self.reversed if size is None: @@ -466,14 +478,30 @@ class arrow(deco, attr.attr): angle = self.angle if constriction is _marker: constriction = self.constriction - return arrow(attrs=attrs, pos=pos, reversed=reversed, size=size, angle=angle, constriction=constriction) + if center is None: + center = self.center + return arrow(attrs=attrs, pos=pos, relarclenpos=relarclenpos, arclenfrombegin=arclenfrombegin, + arclenfromend=arclenfromend, reversed=reversed, size=size, angle=angle, constriction=constriction, center=center) def decorate(self, dp, texrunner): dp.ensurenormpath() anormpath = dp.path - arclenfrombegin = (1-self.reversed)*self.size + self.pos * (anormpath.arclen() - self.size) + pos = None + if self.arclenfrombegin is not None: + arclenfrombegin = self.arclenfrombegin + elif self.arclenfromend is not None: + arclenfrombegin = anormpath.end() - self.arclenfromend + elif self.relarclenpos is not None: + # relarcpos is used if neither arcfrombegin nor arcfromend is given + arclenfrombegin = self.relarclenpos * anormpath.arclen() + else: + # pos is used if neither of the above are given + pos = self.pos + arclenfrombegin = (1-self.reversed)*self.size + pos * (anormpath.arclen() - self.size) direction = self.reversed and -1 or 1 + if pos is None: + arclenfrombegin += direction * self.center * self.size arrowhead = _arrowhead(anormpath, arclenfrombegin, direction, self.size, self.angle, self.constriction is not None, self.constrictionlen) @@ -481,12 +509,12 @@ class arrow(deco, attr.attr): dp.ornaments.draw(arrowhead, self.attrs) # exlude part of the path from stroking when the arrow is strictly at the begin or the end - if self.pos == 0: + if pos == 0: if self.reversed: dp.excluderange(0, min(self.size, self.constrictionlen)) else: dp.excluderange(0, min(self.size, self.size - self.constrictionlen)) - elif self.pos == 1: + elif pos == 1: if self.reversed: dp.excluderange(anormpath.end() - min(self.size, self.size - self.constrictionlen), anormpath.end()) else: -- 1.7.11.rc0.281.g0a17a8c |
From: Michael J G. <mic...@us...> - 2012-05-29 14:32:24
|
The arrowhead needs a piece of size "size" of the path for its construction. Therefore, only (arclen-size) of the path is available as positions for a head without extending the path. So, change pos=0 to mean a position at arclenpos=size, and introduce the necessary additional path exclusions for begin/end arrows. --- Following up the pos/relarclen discussion, here's a patch within the current design which prevents the necessity of extrapolating the path. Also, in contrast to the other patches I sent a minute ago, I managed to set my author field again... Signed-off-by: Michael J Gruber <mic...@us...> --- pyx/deco.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pyx/deco.py b/pyx/deco.py index 193f566..e41e88e 100644 --- a/pyx/deco.py +++ b/pyx/deco.py @@ -472,7 +472,7 @@ class arrow(deco, attr.attr): dp.ensurenormpath() anormpath = dp.path - arclenfrombegin = (1-self.reversed)*self.constrictionlen + self.pos * (anormpath.arclen() - self.constrictionlen) + arclenfrombegin = (1-self.reversed)*self.size + self.pos * (anormpath.arclen() - self.size) direction = self.reversed and -1 or 1 arrowhead = _arrowhead(anormpath, arclenfrombegin, direction, self.size, self.angle, self.constriction is not None, self.constrictionlen) @@ -481,10 +481,16 @@ class arrow(deco, attr.attr): dp.ornaments.draw(arrowhead, self.attrs) # exlude part of the path from stroking when the arrow is strictly at the begin or the end - if self.pos == 0 and self.reversed: - dp.excluderange(0, min(self.size, self.constrictionlen)) - elif self.pos == 1 and not self.reversed: - dp.excluderange(anormpath.end() - min(self.size, self.constrictionlen), anormpath.end()) + if self.pos == 0: + if self.reversed: + dp.excluderange(0, min(self.size, self.constrictionlen)) + else: + dp.excluderange(0, min(self.size, self.size - self.constrictionlen)) + elif self.pos == 1: + if self.reversed: + dp.excluderange(anormpath.end() - min(self.size, self.size - self.constrictionlen), anormpath.end()) + else: + dp.excluderange(anormpath.end() - min(self.size, self.constrictionlen), anormpath.end()) arrow.clear = attr.clearclass(arrow) -- 1.7.11.rc0.265.g7c5e375 |
From: Michael J G. <mic...@us...> - 2012-05-29 14:25:43
|
From: Michael J Gruber <gr...@ma...> Signed-off-by: Michael J Gruber <mic...@us...> --- examples/drawing2/INDEX | 1 + examples/drawing2/canvasdeco.py | 17 +++++++++++++++++ examples/drawing2/canvasdeco.txt | 11 +++++++++++ 3 files changed, 29 insertions(+) create mode 100644 examples/drawing2/canvasdeco.py create mode 100644 examples/drawing2/canvasdeco.txt diff --git a/examples/drawing2/INDEX b/examples/drawing2/INDEX index e547b1b..f17d4f8 100644 --- a/examples/drawing2/INDEX +++ b/examples/drawing2/INDEX @@ -1,5 +1,6 @@ ellipse insert +canvasdeco smoothed parallel clipping diff --git a/examples/drawing2/canvasdeco.py b/examples/drawing2/canvasdeco.py new file mode 100644 index 0000000..3cc2bb4 --- /dev/null +++ b/examples/drawing2/canvasdeco.py @@ -0,0 +1,17 @@ +from pyx import * + +c = canvas.canvas() + +cd = canvas.canvas() + +cd.stroke(path.line(0,0,1,0), [deco.earrow]) +cd.stroke(path.line(0,0,0,1), [deco.earrow]) +cd.stroke(path.path(path.moveto(0.8,0), path.arc(0,0,0.6,0,90)), + [deco.earrow, style.linestyle.dotted]) + +c.insert(cd, [trafo.translate(0,1)]) +c.stroke(path.curve(2,2, 6,0, 0,0, 4,2), + [deco.insert(cd, [trafo.scale(0.6)], relarclenpos=p, relangle=0) for p in [0, 0.3, 0.5, 0.7, 1]]) + +c.writeEPSfile() +c.writePDFfile() diff --git a/examples/drawing2/canvasdeco.txt b/examples/drawing2/canvasdeco.txt new file mode 100644 index 0000000..d2873a0 --- /dev/null +++ b/examples/drawing2/canvasdeco.txt @@ -0,0 +1,11 @@ +Inserting a canvas as a path decoration + +In this example, a decoration is constructed using an arbitrary canvas (here +`cd`). This canvas decoration is then inserted, i.e. the path is decorated by +inserting the canvas at several positions. + +The canvas is inserted with its origin lined up with the point on the path, and +possibly rotated by a fixed angle or relative to the path tangent (as in the +example). + +For convenience, additional canvas attributes can be specified on the fly. -- 1.7.11.rc0.265.g7c5e375 |
From: Michael J G. <mic...@us...> - 2012-05-29 14:25:42
|
From: Michael J Gruber <gr...@ma...> deco.insert() inserts a canvas as a decoration. This allows arbitrary decorations which are constructed out of a fixed canvas which is then inserted (and, possibly, rotated absolutely or relatively) at the specified position on the path. --- As a next step one could reimplement deco.text() by using deco.insert(), but this is not necessary, of course. Signed-off-by: Michael J Gruber <mic...@us...> --- pyx/deco.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pyx/deco.py b/pyx/deco.py index 193f566..025ebe6 100644 --- a/pyx/deco.py +++ b/pyx/deco.py @@ -521,6 +521,41 @@ earrow.LARGe = earrow(size=_base*math.sqrt(32)) earrow.LARGE = earrow(size=_base*math.sqrt(64)) +class insert(deco, attr.attr): + """a decorator which inserts a canvas""" + + def __init__(self, decocanvas, attrs=[], angle=0, relangle=None, + relarclenpos=0.5, arclenfrombegin=None, arclenfromend=None): + if arclenfrombegin is not None and arclenfromend is not None: + raise ValueError("either set arclenfrombegin or arclenfromend") + self.decocanvas = decocanvas + self.attrs = attrs + self.angle = angle + self.relangle = relangle + self.relarclenpos = relarclenpos + self.arclenfrombegin = arclenfrombegin + self.arclenfromend = arclenfromend + + def decorate(self, dp, texrunner): + dp.ensurenormpath() + if self.arclenfrombegin is not None: + param = dp.path.begin() + self.arclenfrombegin + elif self.arclenfromend is not None: + param = dp.path.end() - self.arclenfromend + else: + # relarcpos is used, when neither arcfrombegin nor arcfromend is given + param = self.relarclenpos * dp.path.arclen() + x, y = dp.path.at(param) + + if self.relangle is not None: + a = dp.path.trafo(param).apply_pt(math.cos(self.relangle*math.pi/180), math.sin(self.relangle*math.pi/180)) + b = dp.path.trafo(param).apply_pt(0, 0) + angle = math.atan2(a[1] - b[1], a[0] - b[0]) + angle = angle*180/math.pi + else: + angle = self.angle + dp.ornaments.insert(self.decocanvas, self.attrs + [trafo.rotate(angle), trafo.translate(x, y)]) + class text(deco, attr.attr): """a simple text decorator""" -- 1.7.11.rc0.265.g7c5e375 |
From: Michael J G. <mic...@us...> - 2012-05-24 15:21:46
|
Dear André André Wobst venit, vidit, dixit 23.05.2012 21:19: > Dear Michael, > > I'm sorry, could we please rewind the whole discussion. And let us > not talk about code but about the way it should work. Sure, I should have marked the code as "RFD" ;) Let me point out that I think that pyx.deco is one of the gems of PyX, and that I only want to help polish it :) > To me, the current behavior is the correct (and only correct) one. > Let me explain again, why I think so. > > 1. The arrow should be "part" of the path, i.e. the tip and the > constriction point needs to be positioned on the path. Yes and no. The arrow head should be part of the path just like (the outline of) a stroke is part of the path. But the stroke extends transversally, of course, and also longitudinally (depending on linecap). > 2. For pos == 0 the arrow should be at the beginning, either in the > forward direction (reverse == 0) or backwards (reverse == 1). As it > is a common use-case, pos == 0 and reverse == 1 is available as > "barrow". > 3. For pos == 1 the arrow should be at the beginning. Again, it can > be reversed. pos == 1 and reverse == 0 is an "earrow". Yes and no: the begin and end case should be available as barrow and earrow. But one can really argue about what "at the beginning" and "at the end" mean. For the simple triangular arrow heads, one could also expect an end head to be attached to the end of a path (like a round linecap). This is difficult for PyX's path-shaped heads, of course. > 4. Between those limits the pos argument should interpolate > linearly. And yes, this means that for pos == 0.5 neighter the tip > nor the constriction point of the arrow is at 0.5*arclen(). > > Do you agree to this functionality? Not completely ;) For example, for a closed smooth curve it's quite reasonable to expect pos=0 and pos=1 to be equivalent since they are the same point with the same tangent! I think the main issue is that all other existing or conceivable decorations are "local" in the sense that they use a point and maybe the tangent at that point of the path; but arrow heads need to use a a whole segment of the path. This limits the available positions if one does not want to extend the path. Note that it is extended even now: _arrowhead() use a portion of the path of size "size", so the first allowed position should be at "size", not "constrictionlen": ---->%---- from pyx import * c = canvas.canvas() const = 0.5 c.stroke(path.circle(0,0,0.3), [deco.arrow(pos=0, constriction=const), deco.earrow(constriction=const)]) c.writePDFfile() ---->%---- See how the linear interpolation is used for pos=0 (i.e. arclenpos=constrictionlen)? So, following the existing reasoning pos from [0,1] should be mapped to an interval of length arclen-size. But that would require adding another exclusion range at the beginning! So, if we insist on avoiding path extrapolation, pos=0 would need to correspond to arclenpos=size (and analogous for reversed heads, of course). I don't think that's the look that we want even for pos=0! > I do understand, that you might wonder about my solution to split > the path to properly align the arrows. But this is a straight forward > and elegant solution to work around the intrinsic problem, that pos > interpolates on the range arclen-constrictionlen. It needs to be > that way. I'm glad you agree that this interpolation is the problem ;) Seriously: maybe we can, for a moment, _not_ take that range as given and see what could happen then: * Either by changing pos or introducing arclenpos, allow range 0 to arclen (or even more). * Make earrow put an arrow at arclenpos, barrow(reversed=true) at size and so on. * Either export size (like you did with constriction) or better introduce a poscorr (or shift) parameter which allows shifting the position by multiples of size. That way, the positioning would be analogous to other decorators, one could "center" the heads at will, and barrow/earrow results would be unchanged (except for a fix the size vs. constrictionlen problem). >> The difference between us is that you seem to care about begin and >> end arrows mainly, while I care about mid arrows (also). > > Well, to me an arrow is something like a text. It has some extend. Yes, exactly! > If you center it, the text starts before half of the path and ends > after half of the path. > Yes, exactly my thinking! And, just like for tick labels, there's no reason why the decoration should be clipped by the path. I've been meaning for a while now to code a deco.insert() which inserts a canvas as a decoration. deco.text() is just a special version of that. deco.arrow() is in some sense a special blend between a decorator and a deformer; but for a "uniformly shaped path", I would expect it to behave like the other decorators in the sense above: insert something at the path pos, where the insertion is centered/anchored at a natural reference point (which may be changed by options). Cheers Michael |
From: André W. <wo...@us...> - 2012-05-23 19:33:16
|
Hi Michael, there is one interesting point in here which I don't want to die. Am 23.05.2012 um 18:05 schrieb Michael J Gruber: > And no, splitting a path for every decoration that I put there is not a > solution. Just thing of annotating an integration path. Do you really > suggesting stroking it piecewise, or over and over again? The beauty of > the deco module in PyX is the fact that you have *one* path carrying > allow decorations (text labels, arrow heads and what not). For that you > have to be able to position them consistently (say, text label at pos > for arrow at pos). I agree. And I did see it already, but I don't have a proper solution yet. Sure, you want to stoke the path in a single operation. You can add multiple arrows and text. But how do you define their position? For text we have pos but also arclenfrombegin and arclenfromend. But you probably don't want to mess around with arclen either. Furthermore, for text you have halign.left, halign.center and halign.right. Maybe we need something like this for arrows too. Still I think using path.intersect() is a great and very PyX-like way of doing things. Now, how do you enter such a position into the decorators? Splitting the path and using "end of the path" is a solution, but it is not the nicest one I could envision. I don't have a solution so far. Best, André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: André W. <wo...@us...> - 2012-05-23 19:20:02
|
Dear Michael, I'm sorry, could we please rewind the whole discussion. And let us not talk about code but about the way it should work. To me, the current behavior is the correct (and only correct) one. Let me explain again, why I think so. 1. The arrow should be "part" of the path, i.e. the tip and the constriction point needs to be positioned on the path. 2. For pos == 0 the arrow should be at the beginning, either in the forward direction (reverse == 0) or backwards (reverse == 1). As it is a common use-case, pos == 0 and reverse == 1 is available as "barrow". 3. For pos == 1 the arrow should be at the beginning. Again, it can be reversed. pos == 1 and reverse == 0 is an "earrow". 4. Between those limits the pos argument should interpolate linearly. And yes, this means that for pos == 0.5 neighter the tip nor the constriction point of the arrow is at 0.5*arclen(). Do you agree to this functionality? I do understand, that you might wonder about my solution to split the path to properly align the arrows. But this is a straight forward and elegant solution to work around the intrinsic problem, that pos interpolates on the range arclen-constrictionlen. It needs to be that way. The interesting question is whether we can do what you want by adding another parameter or so. However, I don't see an obvious solution to it. Sure, we could add something like arclenfrombegin and arclenfromend like we did for the text decorators. But you don't really want that to position arrows at the circle. You know what? I really think, that my suggestion in splitting the path is the most elegant solution you can ever achieve. Consider the case, where you want to draw the arrow at the "x-axis", i.e. at zero degree. You can do so at the moment by using earrow to get the tip on the line or barrow(reverse=0) to get the constriction point on the line. This is very unsteady and will always be. I'll add some comment below, but don't mind. Best, André Am 23.05.2012 um 17:18 schrieb Michael J Gruber: > André Wobst venit, vidit, dixit 22.05.2012 10:10: >> Hi, >> >> Am 22.05.2012 um 09:18 schrieb Joerg Lehmann: >>>> We do try to position the arrow head based on the "inward tip" >>>> (constriction center) since r3151, which can be considered the >>>> "middle of the head". >>> >>> I am not sure if I understand you correctly, but I would say no. >> >> Jörg is right. We definitely don't do that. pos defines the position >> of the tip of the arrow. Originally before your patches. We really >> should stick at this simple rule. > > Well, then please tell me what r3079 was about: > > > diff --git a/pyx/deco.py b/pyx/deco.py > index 3206627..9f11211 100644 > --- a/pyx/deco.py > +++ b/pyx/deco.py > @@ -472,7 +472,7 @@ class arrow(deco, attr.attr): > constrictionlen = self.size * 1 * > math.cos(math.radians(self.angle/2.0)) > arrowheadconstrictionlen = None > > - arclenfrombegin = self.pos * anormpath.arclen() > + arclenfrombegin = constrictionlen + self.pos * > (anormpath.arclen() - constrictionlen) > direction = self.reversed and -1 or 1 > arrowhead = _arrowhead(anormpath, arclenfrombegin, direction, > self.size, self.angle, arrowheadconstrictionlen) > > > This shifts the head by constrictionlen to the right, and the later > r3151 made the direction of the shift depend on "reversed". The point is that the arrow should always be part of the path, not extending it. > I mean, I even uploaded those circular images where you can see it clearly. > >>>> It's the result of this principle: We calculate/restrict >>>> "admissible positions" so that 0 and 1 mean begin and end arrow, >>>> where an end arrow head has its tip lined up the end of the path, >>>> and a begin arrow has its constriction center lined up with the >>>> start of the path. That's why (1-0) has to mean >>>> (arclen-constrictionlen) which creates the other problems. >>> >>> Yes. >> >> Really, I don't see where this creates any problem. It's simple and >> it's the right thing to do. > > Again, please, look at the pictures again: There's currently no way to > position an arrow head visually in the middle of a path. And the > positions don't scale if you scale the path! What exactly is "in the middle of the path?" if you talk about it "visually"? To my mind it does not mean that the top nor the constriction point is at half of the arclen. It looks a little strange, as you change the size of the circle here. Please fix the size of the circle and change the size of the arrow. This is geometrically identical. But look at the result. Both, the tip and the constriction point will move. Isn't it right that it works that way? I don't see something wrong in it. >>>> Basically, I would love (1-0) to mean arclen (patch 2/2), i.e. >>>> everything relative to full arclen, then a beginhead would have >>>> pos=0, and an endhead would be at pos=1-constrictionlen/arclen. >>>> Consequently, a head at pos=1 would have its constriction center >>>> ("middle") at the end of the path. This would require additional >>>> adjustments to the way we cut the path, though. Which is why I >>>> did the min/max thingy. >> >> Sorry, IMHO this whole discussion will not result in anything useful. >> >> >>> We would need to extend the path, which is rather tricky. But doing >>> the min/max thing is not a solution, IMHO. >> >> >> Don't even think about extending the path. This is an absolute no-go. >> (I do understand that Michael did try to not do this. But he did so >> by using some very obscure min/max thing. Absolutely bizarre. No, no, >> no. Never.) > > I never suggested extending the path, and I never did it. You see, the > bizarre thing is that an arrow at pos=0 is not positioned in the same > way as an arrow at pos=1, *if* you agree that pos is supposed to be a > position relative to arclen. Calculating pos relative to > (arclen-constrictionlen) is what seems completely bizarre to me. And to me it is the other way around. "arclen-constrictionlen" clearly is the which is available for moving the arrow around. > Let me repeat: a head at pos=0 is positioned differently (with respect > to the start point of the path) comapred to how a head at pos=1 is > positioned (with respect to the end of the point). Sure, we position the arrow, not the tip of the arrow. We need to do so, as for pos=0 (and reverse=0) the constriction point is at the beginning of the path. What else should be it? > The difference between us is that you seem to care about begin and end > arrows mainly, while I care about mid arrows (also). Well, to me an arrow is something like a text. It has some extend. If you center it, the text starts before half of the path and ends after half of the path. -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Michael J G. <mic...@us...> - 2012-05-23 16:05:51
|
André Wobst venit, vidit, dixit 21.05.2012 22:59: > Hi Michael, > > sorry for being late in the discussion. > > Am 10.05.2012 um 10:28 schrieb Michael J Gruber: >> r3151 took into account the direction already but missed the fact that >> arrows are positioned wrt. the constriction center now. Make it so that >> a reversed arrow is positioned wrt. the constriction center also. > > > To my understanding this is not true. Everything is completely symmetric. For earrows, at pos=0, the "back" of the arrow starts at the starting point of the path and at pos=1 (the default for earrow) the tip is at the end. The same for barrow. At pos=1 the back is at the end of the path and at pos=0 (the default for barrow) the tip is at the beginning. Those limits are correct. In between we're just going linearly. > > I'm sorry, your circular example is much to complicated for me. Here's my attempt: > > from pyx import * > ···· > c = canvas.canvas() > c.stroke(path.line(0, 0, 10, 0)) > c.stroke(path.line(0, 0, 0, 2)) > c.stroke(path.line(0.1, 0, 0.1, 2)) > c.stroke(path.line(5, 0, 5, 2)) > c.stroke(path.line(9.9, 0, 9.9, 2)) > c.stroke(path.line(10, 0, 10, 2)) > c.stroke(path.line(0, 0.2, 10, 0.2), [deco.arrow(pos=1)]) # earrow > c.stroke(path.line(0, 0.4, 10, 0.4), [deco.arrow(pos=1, reversed=1)]) > c.stroke(path.line(0, 0.6, 10, 0.6), [deco.arrow(pos=0.99)]) > c.stroke(path.line(0, 0.8, 10, 0.8), [deco.arrow(pos=0.99, reversed=1)]) > c.stroke(path.line(0, 1.0, 10, 1.0), [deco.arrow(pos=0.5)]) > c.stroke(path.line(0, 1.2, 10, 1.2), [deco.arrow(pos=0.5, reversed=1)]) > c.stroke(path.line(0, 1.4, 10, 1.4), [deco.arrow(pos=0.01)]) > c.stroke(path.line(0, 1.6, 10, 1.6), [deco.arrow(pos=0.01, reversed=1)]) > c.stroke(path.line(0, 1.8, 10, 1.8), [deco.arrow(pos=0)]) > c.stroke(path.line(0, 2.0, 10, 2.0), [deco.arrow(pos=0, reversed=1)]) # barrow > c.writePDFfile() I think that's a perfect illustration of the current problems: The pos=1 arrow has its tip on the vertical comparison line, the one at 0.99 also. The one at pos=0.5 has "something" on that line (the line interesects the head between the tip and the constriction center). The one at pos=0 and pos=0.01 have their constriction centers on the respective lines. All positioned differently. Also note how the tips of the back of the arrow protrude beyond the vertical line, but the forward tip does not. Compare that to line drawing for accute angles: There, a stroked path will (due to the angle and linewidth) always protrude beyond the corner of the angle. In that sense, enforcing that an arrow tip does not protrude (as it is now) is artificial. But that's probably not going to change. I'm not saying that my patch solves all this - in fact, what you call "confusion" comes from the attempt to provide some backwards compatibility for pos=0 and 1. >From my point of view, pos should be relative to full arclength, and barrow and earrow should do whatever is needed so that they come out unchanged (say, earrow would have pos= (arclen-constricionlen/arclen)). Simply because that is the most natural, controllable and mathematically sane. But I see I'm facing an uphill battle. And no, splitting a path for every decoration that I put there is not a solution. Just thing of annotating an integration path. Do you really suggesting stroking it piecewise, or over and over again? The beauty of the deco module in PyX is the fact that you have *one* path carrying allow decorations (text labels, arrow heads and what not). For that you have to be able to position them consistently (say, text label at pos for arrow at pos). Michael |
From: Michael J G. <mic...@us...> - 2012-05-23 15:18:39
|
André Wobst venit, vidit, dixit 22.05.2012 10:10: > Hi, > > Am 22.05.2012 um 09:18 schrieb Joerg Lehmann: >>> We do try to position the arrow head based on the "inward tip" >>> (constriction center) since r3151, which can be considered the >>> "middle of the head". >> >> I am not sure if I understand you correctly, but I would say no. > > Jörg is right. We definitely don't do that. pos defines the position > of the tip of the arrow. Originally before your patches. We really > should stick at this simple rule. Well, then please tell me what r3079 was about: diff --git a/pyx/deco.py b/pyx/deco.py index 3206627..9f11211 100644 --- a/pyx/deco.py +++ b/pyx/deco.py @@ -472,7 +472,7 @@ class arrow(deco, attr.attr): constrictionlen = self.size * 1 * math.cos(math.radians(self.angle/2.0)) arrowheadconstrictionlen = None - arclenfrombegin = self.pos * anormpath.arclen() + arclenfrombegin = constrictionlen + self.pos * (anormpath.arclen() - constrictionlen) direction = self.reversed and -1 or 1 arrowhead = _arrowhead(anormpath, arclenfrombegin, direction, self.size, self.angle, arrowheadconstrictionlen) This shifts the head by constrictionlen to the right, and the later r3151 made the direction of the shift depend on "reversed". I mean, I even uploaded those circular images where you can see it clearly. >>> It's the result of this principle: We calculate/restrict >>> "admissible positions" so that 0 and 1 mean begin and end arrow, >>> where an end arrow head has its tip lined up the end of the path, >>> and a begin arrow has its constriction center lined up with the >>> start of the path. That's why (1-0) has to mean >>> (arclen-constrictionlen) which creates the other problems. >> >> Yes. > > Really, I don't see where this creates any problem. It's simple and > it's the right thing to do. Again, please, look at the pictures again: There's currently no way to position an arrow head visually in the middle of a path. And the positions don't scale if you scale the path! >>> Basically, I would love (1-0) to mean arclen (patch 2/2), i.e. >>> everything relative to full arclen, then a beginhead would have >>> pos=0, and an endhead would be at pos=1-constrictionlen/arclen. >>> Consequently, a head at pos=1 would have its constriction center >>> ("middle") at the end of the path. This would require additional >>> adjustments to the way we cut the path, though. Which is why I >>> did the min/max thingy. > > Sorry, IMHO this whole discussion will not result in anything useful. > > >> We would need to extend the path, which is rather tricky. But doing >> the min/max thing is not a solution, IMHO. > > > Don't even think about extending the path. This is an absolute no-go. > (I do understand that Michael did try to not do this. But he did so > by using some very obscure min/max thing. Absolutely bizarre. No, no, > no. Never.) I never suggested extending the path, and I never did it. You see, the bizarre thing is that an arrow at pos=0 is not positioned in the same way as an arrow at pos=1, *if* you agree that pos is supposed to be a position relative to arclen. Calculating pos relative to (arclen-constrictionlen) is what seems completely bizarre to me. Let me repeat: a head at pos=0 is positioned differently (with respect to the start point of the path) comapred to how a head at pos=1 is positioned (with respect to the end of the point). The difference between us is that you seem to care about begin and end arrows mainly, while I care about mid arrows (also). Michael |
From: André W. <wo...@us...> - 2012-05-22 08:10:49
|
Hi, Am 22.05.2012 um 09:18 schrieb Joerg Lehmann: >> We do try to position the arrow head based on the "inward tip" >> (constriction center) since r3151, which can be considered the "middle >> of the head". > > I am not sure if I understand you correctly, but I would say no. Jörg is right. We definitely don't do that. pos defines the position of the tip of the arrow. Originally before your patches. We really should stick at this simple rule. >> It's the result of this principle: >> We calculate/restrict "admissible positions" so that 0 and 1 mean begin >> and end arrow, where an end arrow head has its tip lined up the end of >> the path, and a begin arrow has its constriction center lined up with >> the start of the path. That's why (1-0) has to mean >> (arclen-constrictionlen) which creates the other problems. > > Yes. Really, I don't see where this creates any problem. It's simple and it's the right thing to do. >> Basically, I would love (1-0) to mean arclen (patch 2/2), i.e. >> everything relative to full arclen, then a beginhead would have pos=0, >> and an endhead would be at pos=1-constrictionlen/arclen. Consequently, a >> head at pos=1 would have its constriction center ("middle") at the end >> of the path. This would require additional adjustments to the way we cut >> the path, though. Which is why I did the min/max thingy. Sorry, IMHO this whole discussion will not result in anything useful. > We would need to extend the path, which is rather tricky. But doing the > min/max thing is not a solution, IMHO. Don't even think about extending the path. This is an absolute no-go. (I do understand that Michael did try to not do this. But he did so by using some very obscure min/max thing. Absolutely bizarre. No, no, no. Never.) André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Joerg L. <jo...@us...> - 2012-05-22 07:18:17
|
Hi Michael, sorry - too much traveling last week. On 14.05.12, Michael J Gruber wrote: > Joerg Lehmann venit, vidit, dixit 13.05.2012 17:20: > > Hi Michael, > > > > Thanks for the patch. I am not sure, however, whether it really improves > > the situation. In particular, I do not like the fact that varying the > > pos argument at the beginning and end of the path does not move the > > arrow at all. If I understand the intention of the change correctly, it > > means that the arrow is always positioned at the end of the > > constriction - as long as this is possible. Why is this desirable? > > That means I have not made myself clear enough. Let me try again: > > We do try to position the arrow head based on the "inward tip" > (constriction center) since r3151, which can be considered the "middle > of the head". I am not sure if I understand you correctly, but I would say no. > I don't propose changing that. PATCH 1/2 only makes sure > that the same positioning is applied to reversed heads, i.e. > non-reversed and reversed are mirror symmetric with respect to (an axis > through) the "middle of the head", i.e. the positioning center. > The problem I'm trying to address with PATCH 2/2 is: An arrow head > positioned with pos=0.5 ist not positioned at 0.5*arclen, e.g. a > semicircle. It is positioned at 0.5*(arclen-constrictionlen). But this patch changes the positioning of both heads again - so in fact your two patches do change this. > This becomes quite visible when you're trying to position arrow heads at > various intermediate positions, but also when you try to line up arrow > heads with other decorations (such as text) which are *really* > positioned at pos*arclen (or relarclenpos*arclen, there's no consistent > naming). The naming is another issue - we should fix that. > In the example which I provided, notice how the position of the ("middle > of the") arrow heads does not scale linearly with the radius of the > circle, even though the pos argument is always the same. I think, I see what you mean, but still the other solution also has it's drawbacks - in particular the one I pointed out previously, namely that it fixes the arrow position for a finite interval around pos<=1. > It's the result of this principle: > We calculate/restrict "admissible positions" so that 0 and 1 mean begin > and end arrow, where an end arrow head has its tip lined up the end of > the path, and a begin arrow has its constriction center lined up with > the start of the path. That's why (1-0) has to mean > (arclen-constrictionlen) which creates the other problems. Yes. > Basically, I would love (1-0) to mean arclen (patch 2/2), i.e. > everything relative to full arclen, then a beginhead would have pos=0, > and an endhead would be at pos=1-constrictionlen/arclen. Consequently, a > head at pos=1 would have its constriction center ("middle") at the end > of the path. This would require additional adjustments to the way we cut > the path, though. Which is why I did the min/max thingy. We would need to extend the path, which is rather tricky. But doing the min/max thing is not a solution, IMHO. Best, Jörg |
From: André W. <wo...@us...> - 2012-05-21 21:04:45
|
Hi, Am 14.05.2012 um 11:05 schrieb Michael J Gruber: > This becomes quite visible when you're trying to position arrow heads at > various intermediate positions, but also when you try to line up arrow > heads with other decorations (such as text) which are *really* > positioned at pos*arclen (or relarclenpos*arclen, there's no consistent > naming). I just wonder about this one. I didn't check myself, but it might be an error of the text decorator. Shouldn't it take into account "<arclen-of-the-path> - <length-of-the-text>" for positioning? Well, it might be, it might not. But the arrow does take into account "<arclen-of-the-path> - <constriction-length>". This is correct IMHO. Best, André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: André W. <wo...@us...> - 2012-05-21 21:00:26
|
Hi Michael, sorry for being late in the discussion. Am 10.05.2012 um 10:28 schrieb Michael J Gruber: > r3151 took into account the direction already but missed the fact that > arrows are positioned wrt. the constriction center now. Make it so that > a reversed arrow is positioned wrt. the constriction center also. To my understanding this is not true. Everything is completely symmetric. For earrows, at pos=0, the "back" of the arrow starts at the starting point of the path and at pos=1 (the default for earrow) the tip is at the end. The same for barrow. At pos=1 the back is at the end of the path and at pos=0 (the default for barrow) the tip is at the beginning. Those limits are correct. In between we're just going linearly. I'm sorry, your circular example is much to complicated for me. Here's my attempt: from pyx import * ···· c = canvas.canvas() c.stroke(path.line(0, 0, 10, 0)) c.stroke(path.line(0, 0, 0, 2)) c.stroke(path.line(0.1, 0, 0.1, 2)) c.stroke(path.line(5, 0, 5, 2)) c.stroke(path.line(9.9, 0, 9.9, 2)) c.stroke(path.line(10, 0, 10, 2)) c.stroke(path.line(0, 0.2, 10, 0.2), [deco.arrow(pos=1)]) # earrow c.stroke(path.line(0, 0.4, 10, 0.4), [deco.arrow(pos=1, reversed=1)]) c.stroke(path.line(0, 0.6, 10, 0.6), [deco.arrow(pos=0.99)]) c.stroke(path.line(0, 0.8, 10, 0.8), [deco.arrow(pos=0.99, reversed=1)]) c.stroke(path.line(0, 1.0, 10, 1.0), [deco.arrow(pos=0.5)]) c.stroke(path.line(0, 1.2, 10, 1.2), [deco.arrow(pos=0.5, reversed=1)]) c.stroke(path.line(0, 1.4, 10, 1.4), [deco.arrow(pos=0.01)]) c.stroke(path.line(0, 1.6, 10, 1.6), [deco.arrow(pos=0.01, reversed=1)]) c.stroke(path.line(0, 1.8, 10, 1.8), [deco.arrow(pos=0)]) c.stroke(path.line(0, 2.0, 10, 2.0), [deco.arrow(pos=0, reversed=1)]) # barrow c.writePDFfile() Now try your patches. It creates a lot of confusion. No way. I think the positioning of the arrows on the circle you're trying to get right should be done using path features. This is trivial: from pyx import * c = canvas.canvas() circ = path.circle(0, 0, 5) p = path.line(0, 0, 5, 5) c.stroke(circ.split(circ.intersect(p)[0][0])[0], [deco.arrow(size=1)]) c.stroke(p) c.writePDFfile() Now, the only problem is if you want to position the "back of the arrow" at the intersection point. I don't know whether it is that useful (technically) but I fully understand that it might be desirable from a visual point of view sometimes. You need to take into account the constriction length of the arrow in question. Unfortunately this was not accessible from the outside. I just checked in a simple patch (changeset 3247). Then it becomes a simple modification of what we had before: from pyx import * c = canvas.canvas() circ = path.circle(0, 0, 5) p = path.line(0, 0, 5, 5) a = deco.arrow(size=1) c.stroke(circ.split(circ.intersect(p)[0][0] + a.constrictionlen)[0], [a]) c.stroke(p) c.writePDFfile() Best, André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ |
From: Michael J G. <mic...@us...> - 2012-05-14 09:05:53
|
Joerg Lehmann venit, vidit, dixit 13.05.2012 17:20: > Hi Michael, > > Thanks for the patch. I am not sure, however, whether it really improves > the situation. In particular, I do not like the fact that varying the > pos argument at the beginning and end of the path does not move the > arrow at all. If I understand the intention of the change correctly, it > means that the arrow is always positioned at the end of the > constriction - as long as this is possible. Why is this desirable? That means I have not made myself clear enough. Let me try again: We do try to position the arrow head based on the "inward tip" (constriction center) since r3151, which can be considered the "middle of the head". I don't propose changing that. PATCH 1/2 only makes sure that the same positioning is applied to reversed heads, i.e. non-reversed and reversed are mirror symmetric with respect to (an axis through) the "middle of the head", i.e. the positioning center. The problem I'm trying to address with PATCH 2/2 is: An arrow head positioned with pos=0.5 ist not positioned at 0.5*arclen, e.g. a semicircle. It is positioned at 0.5*(arclen-constrictionlen). This becomes quite visible when you're trying to position arrow heads at various intermediate positions, but also when you try to line up arrow heads with other decorations (such as text) which are *really* positioned at pos*arclen (or relarclenpos*arclen, there's no consistent naming). In the example which I provided, notice how the position of the ("middle of the") arrow heads does not scale linearly with the radius of the circle, even though the pos argument is always the same. It's the result of this principle: We calculate/restrict "admissible positions" so that 0 and 1 mean begin and end arrow, where an end arrow head has its tip lined up the end of the path, and a begin arrow has its constriction center lined up with the start of the path. That's why (1-0) has to mean (arclen-constrictionlen) which creates the other problems. Basically, I would love (1-0) to mean arclen (patch 2/2), i.e. everything relative to full arclen, then a beginhead would have pos=0, and an endhead would be at pos=1-constrictionlen/arclen. Consequently, a head at pos=1 would have its constriction center ("middle") at the end of the path. This would require additional adjustments to the way we cut the path, though. Which is why I did the min/max thingy. Cheers, Michael |