5
$\begingroup$

The following code produces the 3D plot below (which is almost what I want).

ListPlot3D[myplotfcn,ViewPoint -> {-(N[Pi]/8.), -(N[Pi]/2.), 0.45},
AxesLabel -> {"Re[Z^*]", Rotate[BarLegend[{"Rainbow", {-50, 50}}], N[Pi]/2.3],"- Im[Z^*]"}]

enter image description here

myplotfcn is a list of triplets that produces any surface.

The 2nd item in the axeslabel list is where the "Rainbow" colourbar is included. I have rotated it by a close-enough angle that it is somewhat aligned with my y-axis (in the depth direction). Now, I need help with three things.

  1. How do I automatically rotate the colorbar so that it aligns with my y-axis irrespective of the view angle I choose ?
  2. How do I scale it to match the axis length ?
  3. How do I bring the colorbar physically closer to my y-axis ?

I am a novice in Mathematica, and any help with this is highly appreciated!


Updated Question: Need to automate the process suggested in the accepted answer

I am looking for a way to automate the process for the solution given in the accepted answer so far (which is a manual way of doing things). The reason I need to do this is because, I need to generate about 20 of these 3D plots and later assemble them into an animation. Hence, won't be able to fiddle around with these manual changes.

  1. Is there a way of programmatically getting the length of the top right of the bounding-box (into the depth, i.e. y-axis) for every view-angle, and

  2. Then apply this information to the rotation angle of the colorbar ?

$\endgroup$
2
$\begingroup$

I will use the following data for ListPlot3D

data = Table[Sin[j^2 + i], {i, 0, Pi, 0.1}, {j, 0, Pi, 0.1}];

Some initialization to be used later

{w, h} = {300, 300};
pt = Scaled[{0.5, 0.5}];
{{l, r}, {b, t}} = {{80, 40}, {60, 10}};

Now make the ViewPoint dynamic as shown here

vp = Options[Graphics3D, ViewPoint][[1, 2]];
p1 = ListPlot3D[data, ViewPoint -> Dynamic[vp]]

Note: You can now play around with the above output to set your preferred viewpoint for the final image.

Define the BarLegend separately with control over of its size and angle of rotation

 legend[size_, angle_] := 
  Rotate[BarLegend[{"Rainbow", {-50, 50}}, LegendMarkerSize -> size], 
   angle]

Finally we can Overlay the plot and legend together with Manipulate to control the position of the legend plus its size and angle.

Manipulate[
Overlay[{ListPlot3D[data, ViewPoint -> Dynamic[vp]], 
Graphics[{}, AspectRatio -> (h + b + t)/(w + l + r), 
 ImageSize -> {w + l + r, h + b + t}, 
 ImagePadding -> {{100, 10}, {100, 10}}, 
 Epilog -> {Dynamic[Locator[Dynamic[pt], legend[size, angle]]]}]}, All, 2,
Alignment -> Center], {size, 100, 500}, {angle, 0 Degree, 360 Degree}]

The legend position can be changed by dragging it around and Manipulate controls change the size and rotation angle. You can go back to the p1 output plot to change the Viewpoint. The final image can be saved by clicking the Paste Snapshot option in Manipulate. Below is a gif showing these controls in action.

enter image description here

$\endgroup$
  • $\begingroup$ Wow, @Hubble07, that's quite brilliant.....thanks a lot for your help ! $\endgroup$ – krishnakumar G Nov 26 '15 at 19:21
1
$\begingroup$

In my opinion the easiest approach is to use Polygon[] 3D graphics and and texture it with the BarLegend[]. The sample code is:

myplotfcn = RandomReal[{0, 1}, {10, 3}];
x = Max[myplotfcn[[All, 1]]];
y = Max[myplotfcn[[All, 2]]];
z = Max[myplotfcn[[All, 3]]];
Show[ListPlot3D[myplotfcn, 
  ViewPoint -> {-(N[Pi]/8.), -(N[Pi]/2.), 0.45}, 
  AxesLabel -> {"Re[Z^*]", "Y", "- Im[Z^*]"}], 
 Graphics3D[{Texture[BarLegend["Rainbow"]], 
   Polygon[{{0.8 x, 0, 0.8 z}, {x - 0.001, 0, z - 0.001}, {x - 0.001, 
      y, z - 0.001}, {0.8 x, y, 0.8 z}}, 
    VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}]]

It produces the following output

The output of the code above

However I am afraid this approach might require adjusting scaling manually. The easiest approach is to scale the polygon. If you want to have the bar outsde the box, then you should extend the PlotRange in the dmanded direction and disable the box. After that draw the box an axes manually.

EDIT: Dependently on what you need (a publication or a presentation for example), maybe it is even better to use external graphics software like Adobe Illustrator, Corel Draw, Inkscape (free one) etc to prepare your plot the way you want.

$\endgroup$
  • $\begingroup$ With respect to placing the polygon, have you seen Scaled? $\endgroup$ – Michael E2 Nov 26 '15 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.