JuliaPlots / Plots.jl

Powerful convenience for Julia visualizations and data analysis
https://docs.juliaplots.org
Other
1.84k stars 356 forks source link

Match plot and image aspect ratios #1238

Open ttparker opened 7 years ago

ttparker commented 7 years ago

The aspect_ratio setting appears to only change the aspect ratio of the plot itself, not the image. This means that there is typically a lot of extra whitespace/margins on the sides or top/bottom of the image when using a non-default aspect_ratio. Is there a way to automatically minimally crop the image to get rid of the extra whitespace? (You can sort of do this manually by setting size to have the same aspect ratio as your plot, but in addition to being a pain to do repeatedly, it isn't ideal because axis labels, color bars, etc. mean that the minimal rectangle containing everything won't necessarily have exactly the same aspect ratio as the plot itself.)

mkborregaard commented 7 years ago

This is partly a duplicate of #484 I understand the argument - I find the current behaviour to be the best for aspect ratio, though. If there was another keyword for plot_aspect_ratio, how would you think it should interact with size?

ttparker commented 7 years ago

I think the simplest solution would be to add a Boolean keyword argument crop instead of a new keyword for plot_aspect_ratio. The plot would first be drawn normally according to size, but then if crop is set to true, the final plot would be automatically resized down to the smallest rectangle that contains all the drawn elements. This wouldn't solve issue #484 because the color bar would still be too far to the right (i.e. it would eliminate extra outer whitespace, but not extra whitespace inside the plot), but this keyword seems like it might not be too difficult to add in, and would greatly improve the problem.

mkborregaard commented 7 years ago

OK, I've marked this as discussion so others can chime in.

yakir12 commented 6 years ago

Found this issue looking for a solution to my woes with @layout and aspect_ratio. I'm trying to plot this: screenshot_2017-12-03_11 36 10 I want the aspect ratio of that image to be equal (as is common with images -> maybe this should be a default), so I set it and I get this: screenshot_2017-12-03_11 42 28 The layout is specified like this: @layout([a{1w}; [b{0.5w} c{0.5w}]]) Hope all of this is related.

Evizero commented 6 years ago

Sorry to derail this conversation, but may I ask what your image is showing @yakir12. I am just curious

yakir12 commented 6 years ago

Sure, these are time lapse images of roots of plants that have been genetically modified. These roots emit tiny amounts of light when they grow and when you take an image with a long enough exposure time, you can actually register the light. I automatically track their progress, extract their length and light intensity. I then produce a gif to see what the results were. Here's the gif: anim_fps15

Evizero commented 6 years ago

That is fascinating. Thanks for sharing

yakir12 commented 6 years ago

Sure, my pleasure! So I guess the only solution right now is to use size somehow..?

Evizero commented 6 years ago

One thing that strikes me as strange (which just means I have not seen it before), is that the "past" keeps changing as time moves forward (in your bottom right plot). Is this because your estimate of the true value of the past gets more accurate?

yakir12 commented 6 years ago

Awesome, thank you for noticing that.. So the problem you've spotted (this is really derailing this issue) is that the time plot is the same as the rot-length plot except that the x-axis is temporal. It's totally wrong. Fixing it now..

(replied via a PM to keep this channel clean)

mkborregaard commented 6 years ago

@yakir12 how would you like the plot to look? And why don't you like using 'size'?

yakir12 commented 6 years ago

Well, ideally, there would be a lot less space between the y-label Y (mm) and the y-axis. Like, imagine that the image subplot would be nice and square with no extraneous air, and the two subplots below it would be half as wide (and probably half as tall) so that their total width would be equal to that of the image. Here's a mock version I made in gimp (ignore all the wrong sized fonts, lines, placement, etc): 000101

Nothing at all against using size, but I imagine that the intension is that this would "just work", which it does now, but with extra much space between the y-label and the y-axis. I'd just like to point that if we don't have any y labels it looks identical to how it looks like now, which is still not exactly what I'd want.

Evizero commented 6 years ago

without testing it myself (and with the risk of a syntax error since I don't quite know the macro very well), you could try something like @layout [a{0.7h}; b{0.5w} c{0.5w}], i.e. assign the top plot a larger height manually. Its similar to the layout you use but instead of a{1w} which looks like a NoOp, you could assign it a large fraction of the height a{0.7h}

yakir12 commented 6 years ago

Sounded like a good idea, but the distance between the axis and the y label is still large:

img = rand(Gray, 10, 10)
h1 = plot(img, aspect_ratio=1, ylabel="y")
h2 = plot(rand(5))
h3 = plot(rand(5))
l = @layout [a{0.9h}; b{0.5w} c{0.5w}]
plot(h1, h2, h3, layout=l)

tmp2

daschw commented 6 years ago

Does this ylabel distance issue happen on all backends?

yakir12 commented 6 years ago

I'd more than gladly test it but I have issues with other backends due to some system-wide issue. This is with GR.

kleinschmidt commented 6 years ago

FWIW this happens with just a single plot (no layout) on GR as well: screenshot from 2018-07-19 13-44-50

Wouldn't it make sense to position the axis labels relative to the position of the axes, not the edge of the subplot?

daschw commented 6 years ago

Yes, I agree. That would make more sense.