Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addtional 3D plot options #57

Closed
mars0i opened this issue Jul 4, 2017 · 3 comments
Closed

Addtional 3D plot options #57

mars0i opened this issue Jul 4, 2017 · 3 comments

Comments

@mars0i
Copy link
Contributor

mars0i commented Jul 4, 2017

There are variations on 3D plots that Owl doesn't currently provide but that would be useful for me. For example, this plot was created by using [PL_DRAW_LINEY] as the opt argument to plmesh:
foo.pdf
(The color variation in the plot is something I'll discuss in a different issue.)

I don't want to make Owl's plotting API overly complicated. Its simplicity is what makes it so nice to use. So I've thought about different ways to make mesh and surf more flexible. This is my current thinking:

Ideally it's good to give users as much flexibility as possible with mesh and surf.

(a) However, adding an optional argument for every option that can be passed (e.g. PL_DRAW_LINEY, etc. is confusing and would make the interface to mesh and surf a mess.

(b) The number of optional arguments could be reduced by adding only one optional argument that allows users to pass something like Plplot.([ PL_DRAW_LINEXY; PL_MAG_COLOR; PL_MESH ]). This is confusing, though, and interferes with the simplicity of the Owl interface.

(c) Another option is to define new 3D plot options that use different plplot option lists. However, it's also important to avoid writing many different plot functions with a lot of duplicate code. (On the other hand, I do think that a little bit of duplicated code can be easier to understand rather than abstracting out too much of the code into common functions.)

So there's no ideal solution, other just than (d) not allowing more flexibility in 3D plotting.

My inclination at this point is use option (b) to add an optional first argument to mesh and surf. This argument allows passing a list of plplot options for plmesh, plmeshc, or plsurf3d. It's not a nice interface, but then one can use this optional argument to define new 3D plotting functions as in (c).

For example, this is the definition of the function plots2d_in_3d that I used to generate the PDF linked above:

let plots2d_in_3d = mesh ~plplot_opt:Plplot.([PL_DRAW_LINEY])

(I couldn't think of a better name for this function.) The full revised code for mesh that I used (and surf, too) is here: https://github.com/mars0i/owl/blob/master/lib/owl_plot.ml#L877

What do you think? I didn't want to submit a PR before seeing what your thoughts about this were.

@ryanrhymes
Copy link
Member

ryanrhymes commented Jul 5, 2017

Thanks for pointing out this issue. I agree with you that keeping adding optional parameters is not a very scalable solution. [b] seems like the right direction, by using some type constructor imo.

As you mentioned, we need to find a good balance between flexibility and simplicity. I think this can be achieved actually in Owl. Ideally, every plot function should have:

  • one optional handle parameter pointing to where to plot;
  • one optional list of configurations;
  • one or multiple datasets depending on the type of plot.

By using a list of config parameters, we can increase the flexibility and also maintain the simplicity. It will also actually help in simplifying the current API. E.g., if we have a new type called config in Owl_plot

type config =
  | Color of int * int * int
  | Linestyle of int
  | Contour of bool
  | ....
``

Then current `plot` function will become 
```ocaml
val plot : ?h:handle -> ?config: config list -> dsmat -> dsmat -> unit

which is much nicer. This requires some re-wrapping of the config types in PLPLOT and also changes the existing plot functions. But since there are not many plotting functions at the moment in Plot module. I think this should be OK. I guess this design can also satisfy what you need now, right?

I am happy to accept your current solution, but in the long run, we need to change to the aforementioned design imo :)

@mars0i
Copy link
Contributor Author

mars0i commented Jul 5, 2017

Yes, I can see why this makes sense.

[b] seems like the right direction, by using some type constructor imo.

Do you mean creating an OCaml type in Owl.Plot that corresponds to PL_DRAW_LINEXY, etc.? Should the variants have the same names and capitalization?

Here are some "thinking out loud"-style thoughts about the general config type:

  • Should there be one type for all plot functions, even though some fields are only needed for certain functions?
  • Some of the fields in config would duplicate those in page as well as a few fields in legend_item and handle. What about e.g. passing something like a page structure to plotting functions? This would have slightly different function than page as its used now. It wouldn't need a plots field, for example. I'm not sure that fields would need to be mutable, either. Or would it make sense to replace the fields in page with a reference to a config structure?

@mars0i
Copy link
Contributor Author

mars0i commented Jul 6, 2017

... I guess this design can also satisfy what you need now, right?

I am happy to accept your current solution, but in the long run, we need to change to the aforementioned design imo :)

This all sounds good to me. If there's a clear path at the moment for using the new type strategy, I could implement it in mesh and surf, and the other functions could be converted later. If the new strategy needs more planning, I'll go ahead and use my current design as a temporary solution. If it's OK to submit a PR with both the color changes and the addition of the optional plplot option argument for mesh and surf, my fork has all of these changes in the same branch. If you'd rather have two separate PRs for the color argument changes and the plplot option argument changes, it wouldn't be difficult to reimplement the color changes on a fresh clone of your main branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants