[svg_plot] Progress of SVG_Plot

All, I have uploaded the newest version of SVG_Plot to the Boost Vault, and am looking for feedback. This library allows you to make 1 and 2 dimensional plots from STL containers, hopefully with minimal hassle :), and outputs the images as SVG files. The package contains 9 example files in project-root/libs/svg_plot/example that give a reasonable demonstration of what the library is capable of currently. The link to the library in the Vault is here: http://tinyurl.com/2mqvba And a link to online documentation is here: http://www.tcnj.edu/~voytko2/html/ It has been tested on Visual Studio 2005 and GCC 4.1.2. I'm looking for what you like about the library/documentation, and what you don't like (but please check the To Do list first to see if I'm aware of it!) The only extra issue is that because of some last minute trouble, I currently can't make 2D plots from 1D STL containers (vector, etc), but that will hopefully be fixed within the week. Thank you for your time, Jake P.S. If you need a program to look at the .SVG files, try either Firefox, IE with Adobe SVG plugin, or Inkscape.

Jake Voytko wrote:
All,
I have uploaded the newest version of SVG_Plot to the Boost Vault, and am looking for feedback.
Hey, I will try to look at the code when I have time, I looked at the docs though, and the output looks very nice! I spend a *lot* of time creating plots in IDL, and this looks to be quite a bit easier to use. A couple things about the docs, it wasn't clear to me what exactly I would be able to pass to the plot() function for a 2D plot. You say "any object that can return an iterator with begin() and end()", but I assume it needs to have a value type of std::pair<X,Y>, is that right? I think in the vast majority of use cases, people would just have two std::vectors and they would want to just pass them instead of having to make a zip_iterator or whatever. Is that what you meant when you said you were having problems gettind 2D plots with 1D containers? It seems like it would be easy enough to just make a zip iterator wrapper yourself to handle that, if you don't want to change the other code. Also, I don't like how all the parameters start with a leading underscore. I think it always feels like you are doing something "wrong" when you use an interface starting with a _... Anyway I will try out the library sometime later this week, it looks nice so far! Also, is SVG going to be the only output format? Postscript would be a nice option. -Lewis

On 7/31/07, Lewis Hyatt <lhyatt@princeton.edu> wrote:
Jake Voytko wrote:
All,
I have uploaded the newest version of SVG_Plot to the Boost Vault, and am looking for feedback.
Hey, I will try to look at the code when I have time, I looked at the docs though, and the output looks very nice! I spend a *lot* of time creating plots in IDL, and this looks to be quite a bit easier to use. A couple things about the docs, it wasn't clear to me what exactly I would be able to pass to the plot() function for a 2D plot. You say "any object that can return an iterator with begin() and end()", but I assume it needs to have a value type of std::pair<X,Y>, is that right? I think in the vast majority of use cases, people would just have two std::vectors and they would want to just pass them instead of having to make a zip_iterator or whatever. Is that what you meant when you said you were having problems gettind 2D plots with 1D containers? It seems like it would be easy enough to just make a zip iterator wrapper yourself to handle that, if you don't want to change the other code.
This is what I meant when I said that I was having problems. It currently accepts maps, and I didn't change the language in the documentation clear enough. My view on the 1D containers (vector, etc) is that a user will have a single container, and want to plot it in two dimensions, with the index of the data being the X coordinate, and the value stored being the Y value, and the behavior will be changed to reflect that. I will look into your suggestions and see how that affects my program. I'm a little fuzzy on C++ concepts, and I didn't see a way to say that the containers hold pair<,>s.
Also, I don't like how all the parameters start with a leading underscore. I think it always feels like you are doing something "wrong" when you use an interface starting with a _...
I agree. I generated the plot options using the macros in Boost.Parameter, which causes the underscores to appear in front of the variable names. This will be changed.
Anyway I will try out the library sometime later this week, it looks nice so far!
Also, is SVG going to be the only output format? Postscript would be a nice option.
For now, SVG is the only output format. This project is currently for Google Summer of Code, and afterwards, one of my planned tasks is to allow users to define custom image formats. Ostensibly, it's an easy task, but it becomes more and more complicated as you realize that SVG is rare in that it is a tree-based format. So, your concern will be addressed, just not in the near future.
-Lewis
Thank you for your time, Jake

In some plotting applications I have, it is quite useful to be able to reuse the X values, i.e. std::vector<double> x; // few million data points std::vector<double> y1; std::vector<double> p2; ... plotXY( x, y1 ); plotXY( x, y2 ); So this type of interface may be nice to provide too, in addition to plotting maps.

This is what I meant when I said that I was having problems. It currently accepts maps, and I didn't change the language in the documentation clear enough. My view on the 1D containers (vector, etc) is that a user will have a single container, and want to plot it in two dimensions, with the index of the data being the X coordinate, and the value stored being the Y value, and the behavior will be changed to reflect that. I will look into your suggestions and see how that affects my program. I'm a little fuzzy on C++ concepts, and I didn't see a way to say that the containers hold pair<,>s.
OK, well I think what you want to do is set up the interface so that, instead of expecting a container which provides begin() and end(), you expect anything conforming to Boost.Range. (This should not be a major change, just some minor syntax adjustments). The other use cases, such as passing in a separate vector<> for x and y, or passing in only y and having x be auto-generated, are easily adapted to this interface using boost::zip_iterator and boost::counting_iterator. You might choose to support that directly by providing alternate overloads which do the adaptation for the user. I think what seems most natural to me is that you can provide two overloads of plot(x), where x can be: -a Boost.Range with a value_type of std::pair<T,U> (what you have now) -a Boost.Range with a value_type of T, in which case you will provide an adaptor which auto-generates the x axis from the data indices Additionally, there could be another overload accepting two ranges, plot(x,y), where x and y are each a Boost.Range with value_type T. Basically, since you've already implemented the first interface, you could quickly support the other two just by using the boost iterator adaptors zip_iterator and counting_iterator. -Lewis

On 7/31/07, Lewis Hyatt <lhyatt@princeton.edu> wrote:
This is what I meant when I said that I was having problems. It currently accepts maps, and I didn't change the language in the documentation clear enough. My view on the 1D containers (vector, etc) is that a user will have a single container, and want to plot it in two dimensions, with the index of the data being the X coordinate, and the value stored being the Y value, and the behavior will be changed to reflect that. I will look into your suggestions and see how that affects my program. I'm a little fuzzy on C++ concepts, and I didn't see a way to say that the containers hold pair<,>s.
OK, well I think what you want to do is set up the interface so that, instead of expecting a container which provides begin() and end(), you expect anything conforming to Boost.Range. (This should not be a major change, just some minor syntax adjustments). The other use cases, such as passing in a separate vector<> for x and y, or passing in only y and having x be auto-generated, are easily adapted to this interface using boost::zip_iterator and boost::counting_iterator. You might choose to support that directly by providing alternate overloads which do the adaptation for the user.
That's a good idea. I'll have to play around with that and see what I can get out of it.
I think what seems most natural to me is that you can provide two overloads of plot(x), where x can be:
-a Boost.Range with a value_type of std::pair<T,U> (what you have now) -a Boost.Range with a value_type of T, in which case you will provide an adaptor which auto-generates the x axis from the data indices
This was my original goal. I ran into some last-minute trouble providing the second interface, but that was certainly the intent. I had not considered using boost::counting_iterator and boost::zip_iterator, but I think they'll certainly help. Thanks, Jake

Hi Jake, I gave a look to the doc, I find the interface of your library clear and intuitive, moreover the library lets the user perform a fine tuning of the plot properties. The documentation is really readable, maybe some more example in the tutorial would be nice, but I understand that it's only at a preliminary stage.Finally, I have only some minor observation/hint for you: (1) If I understood what you mean, I think you'd replace the sentence: "Any object that can return an iterator with begin() and end()" with a more formal one like this: "Any data type that models the Range concept" where the word Range should appear as a link to the Boost.Range doc (http://www.boost.org/libs/range/doc/range.html) (2) You define default for the x,y range as [-10, 10]. Shouldn't the default be guessed by the data values ? (3) Instead of x_external_style_on you could use x_axis_alignment( alignment_type alignment ) where alignment is one from {center, top, bottom}, the default case would be alignment==center, while the bottom alignment would produce the same effect of x_external_style_on(true), and the top alignment would put the x axis ticks and values on the top of the window; similiarly for the y axis you could make use of a method y_axis_alignment( alignment_type alignment ) with possible alignment values center, left and right. Regards Marco On Tue, 31 Jul 2007 07:48:13 +0200, Jake Voytko <jakevoytko@gmail.com> wrote:
All,
I have uploaded the newest version of SVG_Plot to the Boost Vault, and am looking for feedback. This library allows you to make 1 and 2 dimensional plots from STL containers, hopefully with minimal hassle :), and outputs the images as SVG files. The package contains 9 example files in project-root/libs/svg_plot/example that give a reasonable demonstration of what the library is capable of currently.
The link to the library in the Vault is here: http://tinyurl.com/2mqvba
And a link to online documentation is here: http://www.tcnj.edu/~voytko2/html/
It has been tested on Visual Studio 2005 and GCC 4.1.2.
I'm looking for what you like about the library/documentation, and what you don't like (but please check the To Do list first to see if I'm aware of it!) The only extra issue is that because of some last minute trouble, I currently can't make 2D plots from 1D STL containers (vector, etc), but that will hopefully be fixed within the week.
Thank you for your time, Jake
P.S. If you need a program to look at the .SVG files, try either Firefox, IE with Adobe SVG plugin, or Inkscape. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

On 7/31/07, Marco <mrcekets@gmail.com> wrote:
(2) You define default for the x,y range as [-10, 10]. Shouldn't the default be guessed by the data values ?
Yes, but I'm finding that it's harder than it seems to pull this off right. Picking a range that contains all / a majority of the axis is relatively easy (scale axis to n standard deviations), but making the ticks fall on "nice" numbers is a little harder. This is a goal for this project, but is not my primary one for the time being. Also, the user may want to have good control over the plot window, so I'm not sure just how much guessing the header should do without being told to do so. My philosophy has been to leave the lowest-common-denominator as a default, and this would be something the user would specify my_plot.auto_scale_x(true).y_range(-1, 15);
(3) Instead of x_external_style_on you could use x_axis_alignment( alignment_type alignment ) where alignment is one from {center, top, bottom}, the default case would be alignment==center, while the bottom alignment would produce the same effect of x_external_style_on(true), and the top alignment would put the x axis ticks and values on the top of the window; similiarly for the y axis you could make use of a method y_axis_alignment( alignment_type alignment ) with possible alignment values center, left and right.
That's a great idea! This will also allow me to easily change the alignment of the axes for when the alignment is "center", but the axis is not drawn within the plot window. The solution I've been sketching out in my head was more of a brute-force attack, but it seems this more elegantly solves the problem. Thank you, Jake

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Jake Voytko Sent: 31 July 2007 19:31 To: boost@lists.boost.org Subject: Re: [boost] [svg_plot] Progress of SVG_Plot
On 7/31/07, Marco <mrcekets@gmail.com> wrote:
(2) You define default for the x,y range as [-10, 10]. Shouldn't the default be guessed by the data values ?
Yes, but I'm finding that it's harder than it seems to pull this off right. Picking a range that contains all / a majority of the axis is relatively easy (scale axis to n standard deviations), but making the ticks fall on "nice" numbers is a little harder. This is a goal for this project, but is not my primary one for the time being.
Having slightly explored this choice of axis limits and ticks, I concur that it is more tricky to choose the nicest than you might imagine. There are lots of published algorithms, but (like Microsoft Excel for example), the results are not so pretty. But Jake is right - the algorithm(s) for this can be refined later. Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

On 7/30/07, Jake Voytko <jakevoytko@gmail.com> wrote:
All,
I have uploaded the newest version of SVG_Plot to the Boost Vault, and am looking for feedback. This library allows you to make 1 and 2
Hi Jake, I finally got around to taking a look at your lib (although I used the code and docs from the sandbox - hopefully that's OK). First impressions - this functionality is extremely useful. Being able to make an .svg straight out of code makes creating plots so much easier, and the functionality you already have available allows for a lot of customization. And the potential for future growth of the lib is also exciting. In exploring your lib, I first read the docs front to back. I may have skimmed through parts of it :-) Here are some comments (a lot of them are very nit-picky, or they are just regarding things that weren't perfectly clear). * From the intro: "The first task when dealing with numerical data is to plot it." Ehm... Very motivational, but likely untrue? :-) I agree that plotting data is extremely useful and important, but I don't think it is necessarily always "the first task", or even a necessary task at all. * From the Colors docs: "The list contains one extra color element, blank, used when you need to pass a color, but would not like it to show up. This comes in handy for defining defaults for functions, for example." I don't understand this. What do you mean by "would not like it to show up?" The element whose color you are specifying should not show up? * From the x and y axis documentation: "For an alternate way to display a regular axis, you can use an external style:" What is an external style? * About customizing the plot It first struck me as odd that some drawing parameters are specified through the plot object, and some at plotting time (.plot method). Then I realized that it is because there are common "plot" elements - axis, title, background, etc., and then there are elements that are common to each range "plot" - area fill, bezier, line color... First thing - how can we disambiguate between "plot" as "the whole shabang" / with options describing common supporting elements (axis, title, ...), and "plot" as what is visualizing a single range (drawn via .plot())? Second - specifying the line / area fill characteristics (only) at .plot() invocation seems to have a drawback. Suppose that I want to create a large number of .SVGs, out of the same data but all in different styles. So I create the plot in the first style, and output it to a file. Now I want to change the style for the second file. For the background elements, i can just change them by invoking the appropriate methods. But for the .plots? There seems to be no mechanism for me to go in and change the style of a plot drawn with .plot(). So, I have to recreate each plot from scratch. Maybe an avenue for this will be added when you allow for the use of external stylesheets? Or maybe you will cover it as a part of "avoiding having to redraw the entire plot each time". * The defaults tables docs The two tables have a huge overlap - could they be condensed into one table? There could be two columns, describing the setting for each scenario (1d/2d). if something has the same default value for both, it can span both columns, otherwise you can list different values in each column or say "N/A" in one of the columns. Also, it would be nice to cross-reference this with the functions that change the values. * In the documentation of svg_2d_plot (and mostly in svg_1d_plot): The reference for .plot(), _x_functor parameter: "You will not have to worry about this, unless you are trying to accomplish stuff like plotting a vector of humans" This is fun sounding but confusing - "what do you mean, a vector of humans?" - can you be more specific like "when you need to plot a vector of values not convertible to double"? Also, in the example you have humans as the subject, but then title the plot "Lions" - this is a minor detail, but it made me think that there is some human-lion conversion going on. In the example you have: class my_functor { typdef pair<double, double> result_type; pair<double, double> operator()(const human& _hum) const { return pair<double, double>(i, _hum.age()); } } - what is this "i"? ----- At this point I looked at the code a bit and decided to try solving a task - creating an .svg in which the text is wrapped in \tex{} so that I can load it with Inkscape, save it as a .eps, and then use it in a LaTeX document via psfrag (the purpose of using psfrag is to make the fonts and their sizes match the text). Looking ahead, since I can specify all the text verbatim there should be no problem putting everything in \tex{}. The only exception are tick labels, and that will be solved when you add custom axis lables support (about that - you should disambiguate between axis labels and axis tick labels). Another thought - if you are planning on tackling another format next, I vote for PS/EPS :-) I first ran into problems trying out your examples - for one, there is no Jamfile in the example directory (but this not be a problem with the version in the vault). I added my own, but then found out that the rest of your build configuration files seem to be set as if your lib was located in boost-root. So I ended up replacing all of them by the time I got to bjam the examples successfully. And then - a lot of warnings and a few errors (GCC 4.0.1/darwin). Most of the warnings were regarding the order of initialization of members in the constructors. Then, some of the errors were (nothing built successfully for me): 1d_full_layout.cpp:82: instantiated from here ../../../boost/svg_plot/svg_1d_plot.hpp:127: error: 'is_limit' was not declared in this scope 2d_simple: ../../../boost/svg_plot/detail/numeric_limits_handling.hpp: In function 'bool boost::svg::detail::limit_NaN(double)': ../../../boost/svg_plot/detail/numeric_limits_handling.hpp:35: error: '_isnan' was not declared in this scope I didn't look into the reasons for the errors much. Simple fix? Itsy-bitsy comment correction from glancing at a little bit of the source: svg_1d_plot.hpp // sorting them into the correcet std::veector - correcet -> correct? - veector -> vector Well, that's it for now :-) I can go further after I get past the errors. Cheers, Stjepan

Stjepan, Thank you for taking the time to review this library! Let me know when yours is in a stable state, and I'll respond in kind.
Hi Jake,
I finally got around to taking a look at your lib (although I used the code and docs from the sandbox - hopefully that's OK). First impressions - this functionality is extremely useful. Being able to make an .svg straight out of code makes creating plots so much easier, and the functionality you already have available allows for a lot of customization. And the potential for future growth of the lib is also exciting.
In exploring your lib, I first read the docs front to back. I may have skimmed through parts of it :-) Here are some comments (a lot of them are very nit-picky, or they are just regarding things that weren't perfectly clear).
* From the intro:
"The first task when dealing with numerical data is to plot it."
Ehm... Very motivational, but likely untrue? :-) I agree that plotting data is extremely useful and important, but I don't think it is necessarily always "the first task", or even a necessary task at all.
This is a vestigial statement from my initial proposal. I've had a few teachers (statisticians and mathematicians both) over the years say this as a mantra, but I agree with you that it's not always as imperative as I make it out to be :)
* From the Colors docs:
"The list contains one extra color element, blank, used when you need to pass a color, but would not like it to show up. This comes in handy for defining defaults for functions, for example."
I don't understand this. What do you mean by "would not like it to show up?" The element whose color you are specifying should not show up?
SVG is cascading, in the CSS sense. If we have the following SVG fragment: <g fill="red"> <g> <rect x="5" y="50" width="490" height="295"/> </g> </g> the rectangle produced will have a red fill. If you would like the rectangle to simply be a frame, you can provide the color "blank", and be written as the following: <g fill="red"> <g> <rect x="5" y="50" width="490" height="295" fill="none"/> </g> </g> and it will appear as a rectangular frame. This will be made clearer in the documentation.
* From the x and y axis documentation:
"For an alternate way to display a regular axis, you can use an external style:"
What is an external style?
http://tinyurl.com/2vzp2o [tcnj.edu] I will provide an example in 2D as well.
* About customizing the plot
It first struck me as odd that some drawing parameters are specified through the plot object, and some at plotting time (.plot method). Then I realized that it is because there are common "plot" elements - axis, title, background, etc., and then there are elements that are common to each range "plot" - area fill, bezier, line color...
First thing - how can we disambiguate between "plot" as "the whole shabang" / with options describing common supporting elements (axis, title, ...), and "plot" as what is visualizing a single range (drawn via .plot())?
One of my ideas for post-GSoC was to try to group similar style methods using Boost.Parameter: my_plot.x_axis_style( width = 2, color = red, position = left) .legend_style( font_size = 15, background_color = lightgray); To me, this helps the user understand at a glance what is happening, as well as allowing for some clarity as to what sections are being affected. I wasn't sure that I was going to go this route, but the more I look at it, the better a solution it appears to be. My only concern is that this is very non-standard syntax, but OTOH it's already accepted into Boost, so on average, the community has accepted this. This should help a little with the first part of your concern. However, the definition of series styles should be done at the time the series is entered into the plot, IMO. Users are much less likely to define colors for the wrong series if they do it when they call plot(). Changing the name of the plot function to something like draw_series could help, but I also think that brief familiarity of the library (plus differentiating plot as a noun and plot as a verb) makes this a non-issue.
Second - specifying the line / area fill characteristics (only) at .plot() invocation seems to have a drawback. Suppose that I want to create a large number of .SVGs, out of the same data but all in different styles. So I create the plot in the first style, and output it to a file. Now I want to change the style for the second file. For the background elements, i can just change them by invoking the appropriate methods. But for the .plots? There seems to be no mechanism for me to go in and change the style of a plot drawn with .plot(). So, I have to recreate each plot from scratch. Maybe an avenue for this will be added when you allow for the use of external stylesheets? Or maybe you will cover it as a part of "avoiding having to redraw the entire plot each time".
You don't have to redo the *entire* graph from scratch, but yes, there is currently no way to modify the style of a series that is already stored. The stylesheet method could be a potential solution to this, if I allow the user to define class and ID names at .plot() invocation. Something like the following is also possible: my_plot.series(3).style().fill_color(black).stroke_color(white);
* The defaults tables docs
The two tables have a huge overlap - could they be condensed into one table? There could be two columns, describing the setting for each scenario (1d/2d). if something has the same default value for both, it can span both columns, otherwise you can list different values in each column or say "N/A" in one of the columns.
I will have to play around with it and see what looks better from the viewpoint of looking up information. IMO, the biggest use of a table like you mention is to do feature comparisons. When I use reference documents, it is purely a lookup function. If a user is looking for data on a 1D plot, they don't need to have information about 2D plots in front of them.. it's just extra noise, as far as the person is concerned. They are performing purely a lookup task. This gets even more difficult when differentiating between the 1D and 2D plot() features, as they both use Boost.Parameter, and to different ends. I would either have separate sections that still have redundant information, or I would have to try to take extra care to not confuse the user between options available in 1D and 2D (which is a concern I have, since named parameters are relatively unheard of outside of Boost).
Also, it would be nice to cross-reference this with the functions that change the values.
I don't understand what you mean.
In the example you have:
class my_functor { typdef pair<double, double> result_type;
pair<double, double> operator()(const human& _hum) const { return pair<double, double>(i, _hum.age()); } }
- what is this "i"?
A vestige of attempting to make functors that store state. This example will probably be replaced with a solution using counting_iterator<double>, but at the time of documentation, I ran into last-minute problems.
-----
At this point I looked at the code a bit and decided to try solving a task - creating an .svg in which the text is wrapped in \tex{} so that I can load it with Inkscape, save it as a .eps, and then use it in a LaTeX document via psfrag (the purpose of using psfrag is to make the fonts and their sizes match the text). Looking ahead, since I can specify all the text verbatim there should be no problem putting everything in \tex{}. The only exception are tick labels, and that will be solved when you add custom axis lables support (about that - you should disambiguate between axis labels and axis tick labels). Another thought - if you are planning on tackling another format next, I vote for PS/EPS :-)
When I do tackle formats, PS/EPS and .PNG are my two choices, but this won't happen until well after GSoC. PS/EPS is by far the most requested image format to implement.
I first ran into problems trying out your examples - for one, there is no Jamfile in the example directory (but this not be a problem with the version in the vault). I added my own, but then found out that the rest of your build configuration files seem to be set as if your lib was located in boost-root. So I ended up replacing all of them by the time I got to bjam the examples successfully.
My apologies. The examples were just that: example files that I've made as I wrote documentation, and that work upon invocation of gcc -I $BOOST_ROOT -I ../../.. example.cpp, and I didn't realize that I should provide a Jamfile to run them.
And then - a lot of warnings and a few errors (GCC 4.0.1/darwin). Most of the warnings were regarding the order of initialization of members in the constructors.
The warnings come up on GCC 4.1.2 as well, and I'm going to work on reducing them soon. I work primarily in MSVC with compatibility testing done with GCC, and MSVC (incorrectly) doesn't give warnings about this on the max error level, so this has been a problem for a long time.
Then, some of the errors were (nothing built successfully for me):
1d_full_layout.cpp:82: instantiated from here ../../../boost/svg_plot/svg_1d_plot.hpp:127: error: 'is_limit' was not declared in this scope
2d_simple: ../../../boost/svg_plot/detail/numeric_limits_handling.hpp: In function 'bool boost::svg::detail::limit_NaN(double)': ../../../boost/svg_plot/detail/numeric_limits_handling.hpp:35: error: '_isnan' was not declared in this scope
I didn't look into the reasons for the errors much. Simple fix?
So simple that they've already been fixed :). You must have downloaded the library at a bad time, because I think the errors were only in the SVN repository for 30 minutes or so.
Well, that's it for now :-) I can go further after I get past the errors.
Cheers,
Stjepan
Thank you for the comments! Jake

On 8/9/07, Jake Voytko <jakevoytko@gmail.com> wrote:
Stjepan,
Thank you for taking the time to review this library! Let me know when yours is in a stable state, and I'll respond in kind.
Feel free to take a look anytime you like. I am currently churning the concepts in my head and it will take a while before I stabilize the next iteration of the code/docs :-) The last post with an update is: http://tinyurl.com/32la7r
* From the Colors docs:
"The list contains one extra color element, blank, used when you need to pass a color, but would not like it to show up. This comes in handy for defining defaults for functions, for example."
I don't understand this. What do you mean by "would not like it to show up?" The element whose color you are specifying should not show up?
SVG is cascading, in the CSS sense. If we have the following SVG fragment:
<g fill="red"> <g> <rect x="5" y="50" width="490" height="295"/> </g> </g>
the rectangle produced will have a red fill. If you would like the rectangle to simply be a frame, you can provide the color "blank", and be written as the following:
<g fill="red"> <g> <rect x="5" y="50" width="490" height="295" fill="none"/> </g> </g>
and it will appear as a rectangular frame. This will be made clearer in the documentation.
OK I see. If you wanted the color to be completely unspecified (as in the former snippet), is there an "inherit" element? (perhaps that is not needed for svg_plot though...)
* From the x and y axis documentation:
"For an alternate way to display a regular axis, you can use an external style:"
What is an external style?
http://tinyurl.com/2vzp2o [tcnj.edu]
I will provide an example in 2D as well.
Ahh!!! lol - It took me forever to notice that the difference is that the axis went to the bottom of the figure! I just thought they went missing, and didn't get what the point was :-) Saying something like "the external style will place the axis on the border of the figure" (or whatever the appropriate correct explanation is) might be helpful for other imperceptive individuals like me.
* About customizing the plot
It first struck me as odd that some drawing parameters are specified through the plot object, and some at plotting time (.plot method). Then I realized that it is because there are common "plot" elements - axis, title, background, etc., and then there are elements that are common to each range "plot" - area fill, bezier, line color...
First thing - how can we disambiguate between "plot" as "the whole shabang" / with options describing common supporting elements (axis, title, ...), and "plot" as what is visualizing a single range (drawn via .plot())?
One of my ideas for post-GSoC was to try to group similar style methods using Boost.Parameter:
my_plot.x_axis_style( width = 2, color = red, position = left) .legend_style( font_size = 15, background_color = lightgray);
To me, this helps the user understand at a glance what is happening, as well as allowing for some clarity as to what sections are being affected. I wasn't sure that I was going to go this route, but the more I look at it, the better a solution it appears to be. My only concern is that this is very non-standard syntax, but OTOH it's already accepted into Boost, so on average, the community has accepted this. This should help a little with the first part of your concern.
That is indeed very easy to understand. I like the fact that it nicely groups the related attributes.
However, the definition of series styles should be done at the time the series is entered into the plot, IMO. Users are much less likely to define colors for the wrong series if they do it when they call plot(). Changing the name of the plot function to something like draw_series could help, but I also think that brief familiarity of the library (plus differentiating plot as a noun and plot as a verb) makes this a non-issue.
You are right, it makes sense to specify the format while plotting the series. In fact, even specifying the data to be plotted can almost be regarded as an attribute of the plot, so a call to .plot is kind of like any other attribute setting member function (and that makes the syntax proposed above for specifying other elements very consistent with plotting, which is nice). As far as nomenclature goes, perhaps one big image where you clearly indicate the name of every element would be a good reference for a user that is learning the library. If you decide to change .plot, consider something like .add_series_plot or add_range_plot or whatever - "add" so it is clear that you are adding it, and "series" or "range" (or whatever) so it is clear what you are adding. That way, if you decide later that you want to provide support for plotting something else, you can also have, say, add_function_plot, or add_range_run_plot, or whatever...
Second - specifying the line / area fill characteristics (only) at .plot() invocation seems to have a drawback. Suppose that I want to create a large number of .SVGs, out of the same data but all in different styles. So I create the plot in the first style, and output it to a file. Now I want to change the style for the second file. For the background elements, i can just change them by invoking the appropriate methods. But for the .plots? There seems to be no mechanism for me to go in and change the style of a plot drawn with .plot(). So, I have to recreate each plot from scratch. Maybe an avenue for this will be added when you allow for the use of external stylesheets? Or maybe you will cover it as a part of "avoiding having to redraw the entire plot each time".
You don't have to redo the *entire* graph from scratch, but yes, there is currently no way to modify the style of a series that is already stored. The stylesheet method could be a potential solution to this, if I allow the user to define class and ID names at .plot() invocation.
Something like the following is also possible:
my_plot.series(3).style().fill_color(black).stroke_color(white);
That would do it.
* The defaults tables docs
The two tables have a huge overlap - could they be condensed into one table? There could be two columns, describing the setting for each scenario (1d/2d). if something has the same default value for both, it can span both columns, otherwise you can list different values in each column or say "N/A" in one of the columns.
I will have to play around with it and see what looks better from the viewpoint of looking up information. IMO, the biggest use of a table like you mention is to do feature comparisons. When I use reference documents, it is purely a lookup function. If a user is looking for data on a 1D plot, they don't need to have information about 2D plots in front of them.. it's just extra noise, as far as the person is concerned. They are performing purely a lookup task.
This gets even more difficult when differentiating between the 1D and 2D plot() features, as they both use Boost.Parameter, and to different ends. I would either have separate sections that still have redundant information, or I would have to try to take extra care to not confuse the user between options available in 1D and 2D (which is a concern I have, since named parameters are relatively unheard of outside of Boost).
Valid point.
Also, it would be nice to cross-reference this with the functions that change the values.
I don't understand what you mean.
When looking up a default value for an attribute, I might be immediately interested in what member function is used to change it, and vice versa. So, providing a conveniently located link to the member function from the default value, and vice versa, might be useful.
[snip]
I didn't look into the reasons for the errors much. Simple fix?
So simple that they've already been fixed :). You must have downloaded the library at a bad time, because I think the errors were only in the SVN repository for 30 minutes or so.
:-) It works now, thanks for the quick fix. I'll let you know how the psfrag thing goes! Best regards, Stjepan
participants (6)
-
Jake Voytko
-
Lewis Hyatt
-
Marco
-
Paul A Bristow
-
Schrom, Brian T
-
Stjepan Rajko