MakieOrg / Makie.jl

Interactive data visualizations and plotting in Julia
https://docs.makie.org/stable
MIT License
2.41k stars 311 forks source link

Projections of the earth in the examples on the front page #137

Closed jaakkor2 closed 6 years ago

jaakkor2 commented 6 years ago

Looking at the examples on https://github.com/JuliaPlots/Makie.jl ,

First earth example from https://gist.github.com/SimonDanisch/8f5489cffaf6b89c9a3712ba3eb12a84 simplified and with lighting adjusted (current documentation does not say too much about the light attribute :) )

using Makie, FileIO, Colors
earth = load(download("https://svs.gsfc.nasa.gov/vis/a000000/a002900/a002915/bluemarble-2048.png"));
scene = Scene(resolution = (500, 500), color = :black)
m = GLNormalUVMesh(Sphere(Point3f0(0), 1f0), 60)
light = Vec{3,Float32}[[1.0, 1.0, 1.0], [0.1, 0.1, 0.1], [0.9, 0.9, 0.9], [0.0, -20.0, 0.0]]
Makie.mesh(m, color = earth, light = light)

Antarctica looks big antarctica1

Antarctica should look like this (takes from Wikipedia) image https://upload.wikimedia.org/wikipedia/commons/thumb/f/f2/Antarctica_%28orthographic_projection%29.svg/250px-Antarctica_%28orthographic_projection%29.svg.png

This example is a nice one https://gist.github.com/SimonDanisch/58cb1050581658859f7a5df51fa1e5a1#file-earth-jl but it has two problems 1) Projection of the tempeture map has the same projection error as above. 2) The precipitation is not matching the temperature map, but is 90 deg rotated and scaling is distorted earth

These are low priority, but since these are on the front page, I thought to file an issue.

Also, gists as far as I know do not accept PRs to update them to Julia v1.0.

mkborregaard commented 6 years ago

I think this is because of https://github.com/JuliaPlots/Makie.jl/issues/205 . So the precipitation bars might actually be correct, but the heatmap is wrapped the wrong way around the globe. EDIT: No this idea was incorrect.

mkborregaard commented 6 years ago

No, now I agree it's unrelated. But the color does seem to wrap around weirdly. Check the code here (temperature[10] is a matrix)

m = GLNormalUVMesh(Sphere(Point3f0(0), 1f0), 200)
p = decompose(Point3f0, m)
scene = Makie.mesh(m, color = temperature[10], shading = true)
scatter!(scene, p, markersize = 0.1)
skaermbillede 2018-11-01 kl 23 14 50

The decomposition shows that the sphere's vertices align with centers of a lat/long grid (conveniently). But the heatmap seems to have wrapped around "from the side", so that North on the heatmap is now facing to the right, in a different orientation in that revealed by the points.

AshtonSBradley commented 6 years ago

trying another equirectangular projection test:

using Makie, FileIO, Colors, GeometryTypes
scene = Scene(resolution = (500, 500), color = :black)
m = GLNormalUVMesh(Sphere(Point3f0(0), 1f0), 60)
moon = load(download("https://svs.gsfc.nasa.gov/vis/a000000/a004600/a004675/phases.0001_print.jpg"))
mesh(m, color = moon)

there is quite a lot of polar distortion in the image. Craters are elliptical:

screen shot 2018-11-04 at 11 28 55 am

(not sure if I am using this correctly though!)

AshtonSBradley commented 6 years ago

ok, needed correct coordinate spacing. I if I adapt the image on a sphere example, everything works:

using Makie, FileIO, Colors, GeometryTypes

n = 512
θ = LinRange(0,pi,n)
φ = LinRange(0,2*pi,2*n)
x = [cos(φ)*sin(θ) for θ in θ, φ in φ]
y = [sin(φ)*sin(θ) for θ in θ, φ in φ]
z = [cos(θ) for θ in θ, φ in φ]
pts = vec(Point3f0.(x, y, z))
moon = load(download("https://svs.gsfc.nasa.gov/vis/a000000/a004600/a004675/phases.0001_print.jpg"));
surface(x, y, z, color = moon)

screen shot 2018-11-04 at 11 47 09 am

AshtonSBradley commented 6 years ago

@SimonDanisch the distortion seems to be traceable to the way the sphere points are sampled by HyperSphere. Does this function generate an equirectangular coordinate grid for the 3-sphere? Should it be doing something like the image on a surface example adapted above?

mkborregaard commented 6 years ago

So the error is in the code wrapping the color on a spherical mesh. Where is that function defined in Makie?

SimonDanisch commented 6 years ago

It's basically here: https://github.com/JuliaGeometry/GeometryTypes.jl/blob/master/src/decompose.jl#L367 And here: https://github.com/JuliaGeometry/GeometryTypes.jl/blob/master/src/decompose.jl#L381 (uv coordinates are in 0..1 mapping to the coordinates of the image)

mkborregaard commented 6 years ago

But decompose works, right? Look at my image above - the points are correctly placed but the underlying heatmap isn't (or is it the other way around)? The "North pole" convergence of the decompose points are at the points that correspond to longitude-latitude (0, 0), the South Pole at (180, 0) on the heatmap. But the correspondence should be at (_, 90) and (_, -90) (where _ corresponds to any value as the longitudes collapse in the poles).

SimonDanisch commented 6 years ago

The UV map seems pretty wrong (decompose(UV, Sphere(...)))

SimonDanisch commented 6 years ago

This works:

n = 512
θ = LinRange(0,pi,n)
φ = LinRange(0,2pi,n)
ux = LinRange(0, 1, n)
x = [cos(φ)*sin(θ) for θ in θ, φ in φ]
y = [sin(φ)*sin(θ) for θ in θ, φ in φ]
z = [cos(θ) for θ in θ, φ in φ]
pts = vec(Point3f0.(x, y, z))
uv = [UV{Float32}(φ, θ) for θ in ux, φ in ux]
f = decompose(Face{3, GLIndex}, SimpleRectangle(0, 0, 1, 1), (n, n))
m = GLNormalUVMesh(vertices = pts, faces = f, texturecoordinates = vec(uv))
scene = mesh(m, color = moon, shading = false)

Maybe that's how I should define the decompose for sphere

SimonDanisch commented 6 years ago

Although that's still inconsistent with surface:

image

SimonDanisch commented 6 years ago

Ah reverse ux for x fixes that. I put some time into making sure that surface works like the others, so I guess we should just follow surface here ;)

SimonDanisch commented 6 years ago

Thanks everyone, I think this is fixed now with https://github.com/JuliaGeometry/GeometryTypes.jl/pull/158

using Makie, FileIO, Colors
earth = load(download("https://svs.gsfc.nasa.gov/vis/a000000/a002900/a002915/bluemarble-2048.png"));
scene = Scene(resolution = (500, 500), color = :black)
m = GLNormalUVMesh(Sphere(Point3f0(0), 1f0), 60)
light = Vec{3,Float32}[[1.0, 1.0, 1.0], [0.1, 0.1, 0.1], [0.9, 0.9, 0.9], [0.0, -20.0, 0.0]]
Makie.mesh(m, color = earth, shading = false)

earth

mkborregaard commented 6 years ago

Awesome, you're a wizard!

mkborregaard commented 6 years ago

Note that this does not completely resolve the issue with the points decomposition: This is with GeometryTypes/sd-sphere checked out:

skaermbillede 2018-11-05 kl 12 48 00

Note the polar position of the points wrongly at (0,0) and the clearly misplaced rainy belt over Sahara. The bar heights could be something in the meshscatter function but at least the point decomposition is not consistent with that of a globe.

mkborregaard commented 6 years ago

For info, the world-clim precipitation layer is only defined over land, so the correct projection would put all the flat bars over the ocean.

SimonDanisch commented 6 years ago

Yeah the uv look up code needs to be adapted for sampling the precipitation: test

mkborregaard commented 6 years ago

Do you mean in the example or in GeometryTypes? That looks amazing btw.

SimonDanisch commented 6 years ago

The example needs an update ;)

mkborregaard commented 6 years ago

OK, so you just fixed the to_msize function? I wouldn't mind adding this unless you've essentially already done it for your plot above.

SimonDanisch commented 6 years ago

Yeah it's fixed ;) https://github.com/JuliaPlots/Makie.jl/blob/master/examples/bigdata.jl#L2 needed some julia 1.0 updates as well!

mkborregaard commented 6 years ago

Oh great. Yeah I'd fixed the other things locally because I wanted to update this example, that was how I fell over this to begin with.

mkborregaard commented 6 years ago

So, this can be closed I guess?