JuliaPlots / Plots.jl

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

Proposal: user-friendly DPI setting. #742

Open ma-laforge opened 7 years ago

ma-laforge commented 7 years ago

Currently, Plots.jl specifies (mostly) all of its dimenensions in pixels. For example, line widths & plot size are specified in pixels.

This solution is perfect for rending images on screen, because the user can really visualize how things will end up looking on their screen.

The problem is when people want to generate high-resolution "bitmap" images (typically .png).

Solution:

  1. Assume all dimensions are in typography "points" (1/72")- instead of pixels.
  2. Anything that gets rendered to screen somehow gets rendered using a "dpi" value of 72 - irrespective of the DPI value assigned to the plot. This way, users gets what they expect on screen - no surprises. A width of 1 shows up as 1 pixel wide on the screen!
  3. When the user saves to a bitmap format, that's when they actually get to apply the dpi value in a way that is useful:
    png("MyHighResPicture.png", dpi=4*72) #4*4=16x more pixels than on screen!

EDIT: Maybe screen "dpi" should be machine dependent or user-configurable (.juliarc.jl?). 1 pixel lines & small text apparently become very difficult to see/read when pixels are physically very small (see issue with retina displays https://github.com/JuliaPlots/Plots.jl/issues/739).

I am not too keen on using the os-supplied "dpi" value though - because Microsoft's supposed "96dpi screens" would end up with fractional line widths & result in strange pixel counts.

Comments:

ma-laforge commented 7 years ago

Edited

Implication when user designs with screen in mind

The solution proposed above implies that the user is using a "virtual DPI" value when he/she thinks in terms of pixels (ex: on screen):

I believe this "virtual DPI" method is much closer to what most users want/expect when sizing for optimal on-screen results.

Implication when user designs with physical dimensions in mind

The interpretation when a user describes the plot using physical dimensions in mind is much more straightforward:

In this case, the DPI value behaves exactly like it should: It describes the number of dots per inch to use to describe a plot of the specified dimensions.

spaceLem commented 7 years ago

It's handy to be able to specify the dpi or size even when outputting as an svg, because you might need to know the size of the final figure and need a specific font size (probably 12pt).

ma-laforge commented 7 years ago

@spaceLem: [...] you might need to know the size of the final figure and need a specific font size (probably 12pt).

Agreed with this part of your statement.

What I am saying in this thread is that we should use the "point" as the base unit for all dimensions in the plot image:

At this point, DPI has no meaning to an SVG file. SVGs simply describe how one would draw an image with objects (circles, arcs, lines, ...) of user-specified lengths, etc.

Intrinsically, SVG has no concept of "a pixel" - so DPI is not relevant.

The DPI value only comes into play when we render the SVG image onto a pixel-based canvas (like a PNG file, for example). It is at that rendering step that DPI becomes relevant.

ma-laforge commented 7 years ago

@spaceLem: I noticed my previous comments might have been a bit confusing, so I revised the second entry.

spaceLem commented 7 years ago

@ma-laforge Thanks. Mixing DPI and SVG was me being overly loose with my terms, I really just meant it's handy to be able to tie font sizes and line weights to the image dimensions, so you don't need to manually resize everything afterwards in Inkscape.

The SVG files I was making with Plots didn't seem to like me fiddling with any of the text, and it was easier to just resize the image, delete all the text and create new text boxes... which I suspect was unnecessary (unless the text was being saved as paths or something?)

mkborregaard commented 7 years ago

I agree with @spaceLem that the dpi could be equally useful in vector-based contexts in the same way that the size argument is used with vector formats - the dpi sets the relationship between the image size and the size of image elements.

ma-laforge commented 7 years ago

Thanks for clarifying that @mkborregaard. I thought @spaceLem was simply indicating that the plot backend being used did not respond to font.pointsize property.

So, in response to that, I opened a new issue: https://github.com/JuliaPlots/Plots.jl/issues/891.