RE: inverting y axis in DensityPlot
- To: mathgroup at smc.vnet.net
- Subject: [mg27278] RE: [mg27271] inverting y axis in DensityPlot
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.de>
- Date: Sun, 18 Feb 2001 02:52:12 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
-----Original Message----- From: Matthias Hertel [mailto:wir95cgu at studserv.uni-leipzig.de] To: mathgroup at smc.vnet.net Subject: [mg27278] [mg27271] inverting y axis in DensityPlot Hello, I would like to display the design matrix of a medium-sized general least-squares problem as a bitmap. (It's too large for StandardForm or MatrixForm to be useful, yet its structure is simple enough that one can tell if something has gone really wrong just by looking at a DensityPlot.) ListDensityPlot[desmtx, Mesh->False] almost does what I want, but the matrix is displayed upside down (desmtx[[1,1]] is in the *bottom* left corner). ListDensityPlot[Reverse@desmtx, Mesh->False] is closer, but now the frame tick marks are wrong (don't correspond to the row index). It would be perfect if there was something like ListDensityPlot[desmtx, InvertY->True, Mesh->False] that's just like a normal ListDensityPlot but with the y axis flipped. But there isn't. So, how can I get a DensityPlot with (0, 0) in the top left corner and y increasing downwards? Thanks Matthias ----------------- Matthias, let's make up an example: In[1]:= t = Table[Sin[x^2 - x y], {y, 0., 6, 6/50}, {x, 0., 6, 6/50}]; In[2]:= g = ListDensityPlot[t, MeshRange -> {{-0.5, 50.5}, {-0.5, 50.5}}, Mesh -> False] We have 51 points in each direction, and we adjusted MeshRange a bit as to have the Tick marks point to the center of our raster "pixels" and not to their left lower corners. Now if we plot with the y-axes reversed In[4]:= gy = ListDensityPlot[Reverse@t, MeshRange -> {{-0.5, 50.5}, {-0.5, 50.5}}, Mesh -> False] we get (of course) the same tick marks, corresponding to the indices of the reversed matrix. But you want to have them correspond to the indices of the original matrix. You can do that by either specifying the FrameTicks explicitly or with a hand-crafted tick function, yet the better idea seems to be: just take the automatically generated tick marks of the graphics and manipulate their labels a bit such that they'll come out "right". Now we can't get at the FrameTicks of a DensityGraphics by FullOptions (which does next to nothing here) nor by FullGraphics (which here does exactly nothing). The trick is to convert the DensityGraphics to a Graphics first: In[5]:= rg = Graphics[gy] and then get at the FullOptions In[6]:= opts = FullOptions[rg]; Now we can do what we want, I did it this way: In[7]:= Block[{minlab = Infinity, maxlab = -Infinity}, Show[rg, opts /. (FrameTicks -> {bottom_, left_, up_, right_}) :> FrameTicks -> {bottom, left /. {y_, ylabel_?NumberQ, len_, style_} /; (If[ylabel > maxlab, maxlab = ylabel]; If[ylabel < minlab, minlab = ylabel]; True) :> {y, maxlab - ylabel + minlab, len, style}, up, right}]] This code deserves some explanation. As you see we manipulate the tick marks to the left. As generated by the automatic tick function the labels are numeric (not explicitly converted to strings) -- this is our luck. The intend of the conversion formula is clear, but how come the right values of maxlab and minlab (at the right time)? RuleDelayed does not evaluate it's rhs (it has the HoldRest attribute), but the lhs is evaluated and such is the condition on the pattern, which we just set to True, but misuse it as a hook to calculate the minimum and maximum for the labels on the fly. -- Hartmut