I do not understand what I am doing wrong plotting a 2D function. The resulted heatmap is rotated 90 deg.
using Plots
rosenbrock(x, y; a=1, b=100) = (a - x)^2 + b*(y - x^2)^2
# Define the range for x and y
x = -2:0.01:2
y = -1:0.01:3
# Create a grid of (x, y) points
z = [rosenbrock(xi, yi) for xi in x, yi in y];
# Plot the function with contour lines and log scale heatmap using Plots.jl
heatmap(x, y, log10.(z), xlabel="x", ylabel="y", title="Rosenbrock Function (Log Scale)", color=:viridis)
âwhich is wrongâ - based on what?
Makie and Plots simply have two different ways of defining the default transposition of a heatmat.
Makie uses the idea that a heatmap is a matrix, so uses the default way of displaying matrices with the first dimension being rows going down.
Plots uses the idea that any plot always plots x values on the x axis, y values on the y axis, with values rising upwards and towards the left.
None of these concepts are inherently more correct. And in fact plotting packages in many languages all do this differently. The Plots way has the advantage of intuitively adding e.g. x,y scatter points on top of a heatmap in the correct location.
You can always transpose the matrix and possibly set yflip = true to get the other behaviour.
I actually hate plotting interfaces for heatmaps, pcolor, contours etc where the coordinates can be specified by vectors for exactly that reason: there is no commonly accepted standard and particularly if you have the same vector length (and a square matrix) you will not even see if your interpretation is wrong in a lot of cases. I would really have preferred (even if that costs some memory) that plotting tools accept only coordinates x, and y which are also matrices and of the same size as the matrix to plot. Then you are sure that any discrete point [i,j] will be at position x[i,j],y[i,j] with value z[i,j]. And it also very naturally opens the way for curvilinear plots etc.
If you look at the axes in the plots you see that the x-axis has âincreasing while going leftâ, y is âincurring while going upâ. We usually would put these coordinates as (x,y)
But if you consider a matrix (which contains the pixels/ samples for your contour map colors)
the first index is the rows, but that is the vertical one (previously y)
the second one is the horizontal one
the vertical axis is the opposite direction as the y above, it is âincreasing while going downâ
So, we have to (1) transport the matrix, which switches the roles of the indeces, so that the first one is the horizontal one, the second the vertical, and âflipâ the vertical one.
Sorry, I must have misremembered the discussion then. I just quoted it from memory, which was not careful enough. I can also read in the issue I linked that I actually changed my mind on this after thinking about it, and suggested changing Plotsâ behaviour to match Makieâs.
Apparently 6 years is enough to forget something I felt strongly about at the timeâŚ
No problem, many people are actually confused when they plot images with Makie because they expect the right orientation by default, but itâs tricky as explained above and I think the current default makes the most sense overall. Maybe in the future thereâll be an alternative for easier image plotting
On the other hand, if we include the function in the heatmap, this problem disappears (i.e. both x and y are respected, and there is no need to transpose):
heatmap(x, y, log10 â rosenbrock, xlabel="x", ylabel="y", color=:viridis)
The problem is that this is actually not a transpose, I discussed this with @ffreyer the other day. Itâs because the uvs of the underlying Rect are weird, probably chosen such that images are shown in correct orientation more easily.
Plus, even if it wasnât buggy, for most images you would still want to count pixels from top to bottom, so you canât really get around the yreversed = true.
To deal with this issue, the GMT.jl grid and image types have a layout field that describe the memory layout. Itâs a three (or four for images) chars string with T(op)|B(ot) R(ow)|C(ol) B(and)|P(ixel), like TRBm saying if the array is Top-Bot, Row or Column major, and Band or Pixel interleaved. This last makes sense only to images.