Winston.jl icon indicating copy to clipboard operation
Winston.jl copied to clipboard

Table: plot in mulitple rows

Open pfitzseb opened this issue 10 years ago • 10 comments

Not necessarily an issue, but more of an feature request (or, if it's already implemented: a request for a better documentation). How do you get a plot to span multiple cells in a Table environment? Or rather, is there any way to get to subplots that take different amounts of vertical space? Say two-thirds vs one-third? The naive way doesn't work:

t=Table(3,1)
p=plot(x,y)
t[1:2,1]=p ( or t[[1:2],1]=p )

So, am I missing something? Or is that feature not implemented/documented yet? Having sublplots that take multiple rows in a grid-layout is imho quite an important feature (especially for matlab-users like myself...).

pfitzseb avatar Feb 22 '14 20:02 pfitzseb

Currently you have to put tables inside table cells to achieve this kind of multiple column/row wide figures.

julia> t=Table(2,1)
julia> t[1,1]=plot(randn(100))
julia> t[2,1]=plot(rand(100))

julia> t2=Table(1,2)
julia> t2[1,1]=t
julia> t2[1,2]=plot([1:10])
julia> t2

example

As you can see this is kinda tedious task and I think we need some improvements to the current syntax. Maybe something along the matplotlibs gridspec where rowspan and colspan keywords can be specified to achieve similar plots.

Also the Table is currently tiling the figures based on their outer boundaries and not based on the drawn axis as it should be. This usually leads to rather ugly tables because the frames do not line up.

Third improvement could be to handle the figures dynamically based on the grid so that text size is also scaled accordingly. Currently the subplots are just squeezed to fit the table cells.

Based on this I think we would need some next generation Table or grid or something so that publication quality figures could be made.

natj avatar Apr 19 '14 10:04 natj

I come from IDL background where plot takes position keyword as an argument where you can specify how the plot spans the available space (i.e. position=[xmin, ymin, xmax, ymax], where these values are relative coordinates).

With this kind of option it would be rather easy to write new dynamic Table function and in addition you could use it to combine multiple figures however you like (see e.g. combination of scatter and histogram plots here). Just put default value of position=[0.1, 0.1, 0.95, 0.95] or similar to this so in general case it would not change anything but would add huge number of possibilities if you would want to adjust your plots more specifically.

natj avatar Apr 19 '14 10:04 natj

It would be a big, scary change, but...Gtk (and to a somewhat lesser extent, Tk) has really nice layout facilities that go way beyond the convenience of anything you can do in Matlab. I've long been of the opinion that a worthwhile experiment would be to explore creating one Canvas per "inner" axis, and use a separate Canvas for the "exterior" parts of the axis (the tick labels, etc). Using GtkGrid, one could then ensure alignment even in more complicated situations (like when you need a particular aspect ratio, alignment with respect to GUI elements like buttons and sliders, etc). I posted an example (still relatively simple) here; the features are (1) the image requires a fixed aspect ratio to look good, (2) the marginal distributions on either side of the scatter plot at the left have to be aligned to the scatter plot, and (3) the image should be aligned to the scatter plot top/bottom. In a more complex example one would integrate more substantive alignment of GUI elements.

An alternative would be to handle all layout in Julia. I even began a project to do that, but haven't had time to carry it farther forward.

If we could do the drawing updates from a separate thread, it would presumably be better to rely on the underlying toolkit for layout, because one would get smooth resizing without "bothering" the Julia process (which might be busy doing other things). But since we can't do that (at least currently)---resizing triggers a call to the Canvas draw function---I suspect that either one of these approaches might be viable.

timholy avatar Apr 19 '14 11:04 timholy

Woah! Looking good @timholy, I didn't know you were already this far experimenting with this!

natj avatar Apr 19 '14 14:04 natj

Well, the reality is that I'm not far long :smile:. In particular, I haven't touched it in about a year, and won't have time for the forseeable future. It would be great to hear from Mike what he thinks the right approach is.

timholy avatar Apr 19 '14 15:04 timholy

I remember seeing Winston in the GSoC-project list but did anybody apply for that? Maybe this would be a good project to do there. I was planning on applying myself too but my summer schedule got pretty crammed with summer schools and conferences, so no free time for me.

On a more broader scale, I think focusing and fixing problems like this becomes more and more important now that we have somewhat working interface (of course there is still work in that sector too, but still). Plotting needs to be easy and the figures need to look neat to attract a bigger audience.

natj avatar Apr 19 '14 15:04 natj

IIRC there's someone who applied to add support for OpenGL, and another person who applied to support better interaction via IJulia (which will help Gadfly). But I don't remember any other plotting-related applications.

timholy avatar Apr 19 '14 15:04 timholy

If this would not make installation more complicated I would also propose to use Gtk for layout stuff. When it comes to interactive plots Winston would also benefit from a toolkit like Gtk.

tknopp avatar Apr 20 '14 07:04 tknopp

Now that FramedArray is removed this issue and proposed fixes are even more relevant. Due to the nature of Table one can not really combine figures of different sizes. I know that currently the shrinking of lines and text is a feature, not a bug, but how hard would it be to make it preserve the line and symbol size? Also it is almost impossible to get figures of different sizes to line up nicely as that was originally the job of FramedArray.

What is your opinion about this issue @nolta ? Bring FramedArray back or go with the more radical changes?

natj avatar Jun 23 '14 19:06 natj

In the meanwhile, if somebody else needs to also make these kinds of figures, here is what I did (warning: this is horrible and dirty fix):

#Arrange figures p (main fig) and p2 (subfig) into a nice grid
##############

#fine-tuning parameters to make grids match
setattr(p2.frame, label_offset=0.01) #smaller fig offset
setattr(p.frame, label_offset=1.8) #larger fig offset
magnf = 1.5 #magnification for the smaller fig

#Default sizes
deflw = 1.5 #spine_style: linewidth 
deffs = 3.0 #ticklabels_style: fontsize
defts = 1.5 #ticks_size
defsb = 0.75 #subticks_size

#remove ticklabels from fig1
setattr(p.x1, ticklabels=[" ", " ", " "])

#magnify the smaller figure
setattr(p2.frame, :spine_style, (Symbol => Any)[:linewidth => deflw*magnf])
setattr(p2.frame, :ticklabels_style, (Symbol => Any)[:fontsize => deffs*magnf])
setattr(p2.frame, :label_style, (Symbol => Any)[:fontsize => deffs*magnf])
setattr(p2.frame, ticks_size=defts*magnf)
setattr(p2.frame, :ticks_style, (Symbol => Any)[:linewidth => deflw*magnf])
setattr(p2.frame, subticks_size=defsb*magnf)
setattr(p2.frame, :subticks_style, (Symbol => Any)[:linewidth => deflw*magnf])

#make table
t = Table(2,1)
setattr(t, cellspacing = -15.0)

t[1,1] = p
t[2,1] = p2

setattr(p, aspect_ratio=0.5)
setattr(p2, aspect_ratio=0.3)

file(t, "fig1.png")

fig_h

natj avatar Jun 24 '14 11:06 natj