2
$\begingroup$

I have the following code from a textbook:

b = 4;(*set width of infinite square well *)
v[x_] := If[Abs[x - b/2] < 0.5, 0, 50]; (*define PE fn for finite well*)
nMax = 50; (*largest n value used throughout calc*)
basis[n_, x_] := Sqrt[2/b]*Sin[n*Pi*x/b]; (*define sine-wave basis fns, properly normalized*)
hMatrix = Table[(n^2 Pi^2/(2 b^2)) KroneckerDelta[m, n] + 
          NIntegrate[basis[m, x]*v[x]*basis[n, x], {x, 0, b}, 
          AccuracyGoal -> 8], {m, 1, nMax}, {n, 1, nMax}]; (*build H matrix*)

contrast = 0.01;
MatrixPlot[hMatrix*contrast + 0.5,ColorFunction -> Function[f, Blend[{Cyan, White,Red}, f]], 
ColorFunctionScaling -> False]

which gives me the following graphic:

enter image description here

But the text shows a much more insightful graphic that looks like this:

enter image description here

I would like to know how to make a graphic that looks like this so that when I recreate this using my own functions I can show a similar graphic.

$\endgroup$

1 Answer 1

3
$\begingroup$

Here's one way to do it: First, we create the two individual plots with the appropriate styling:

bigPlot = 
 MatrixPlot[hMatrix*contrast + 0.5, 
  ColorFunction -> Function[f, Blend[{Cyan, White, Red}, f]], 
  ColorFunctionScaling -> False, 
  FrameTicksStyle -> Directive[Transparent, FontSize -> 0], 
  PlotRangePadding -> None, FrameStyle -> Black]

insetPlot = 
 MatrixPlot[hMatrix[[;; 8, ;; 8]]*contrast + 0.5, 
  ColorFunction -> Function[f, Blend[{Cyan, White, Red}, f]], 
  ColorFunctionScaling -> False, 
  Epilog -> 
   MapIndexed[Text[Round[#, 0.01], #2 - 1/2] &, 
    Transpose@Reverse@hMatrix[[;; 8, ;; 8]], {2}], Frame -> None, 
  PlotRangePadding -> None]

enter image description here

Adding the numbers in the insetPlot is done following this answer. The FrameTicksStyle -> Directive[Transparent, FontSize -> 0] setting is used to get the black frame fully shown without having to touch ImagePadding (just setting FrameTicks->None tends to cut off parts of the frame). For the smaller plot we leave the frame away completely, this makes it easier to size everything properly in the next step.

We now combine the two plots by adding insetPlot as an Inset to the other plot:

zoomPos = {0, Length@hMatrix - 8};
zoomSize = {8, 8};
insetPos = {-0.875, 0.125};
insetSize = {0.75, 0.75};

Show[
 bigPlot,
 Graphics@{
   [email protected],
   Dashed,
   MapThread[Line@{#, Scaled@#2} &, 
    Tuples /@ 
     Transpose /@ {{zoomPos, zoomPos + zoomSize}, {insetPos, 
        insetPos + insetSize}}],
   Inset[insetPlot, Scaled@insetPos, ImageScaled@{0, 0}, 
    Scaled@insetSize],
   FaceForm@None,
   EdgeForm@{[email protected], Black},
   Rectangle[zoomPos, zoomPos + zoomSize],
   Rectangle[Scaled@insetPos, Scaled[insetPos + insetSize]]
   }
 ]

enter image description here

Some notes:

  • It is important that the size of the Inset is given in ImageScaled coordinates, otherwise the ImagePadding of the main plot is not automatically adjusted to include the inset.
  • The frame around the inset is added as a rectangle during this step. This allows us to use a ImagePadding->None and PlotRangePadding->None for the insetPlot, which makes sure that we have precise control over where the corners of the plot end up at.
  • Since we were a bit careful with the Inset (size given as ImageScaled, not inside Epilog, ...), the default setting ImagePadding->Automatic manages to properly leave room for the inset on the left of the plot (If we hadn't done this, we'd have to manually compute the appropriate ImagePadding)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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