I have a bunch of $m \times m$ matrices with $m\geq 2$, which I would like to plot their eigenvalues as a function of a parameter. These eigenvalues are usually complex and wind together as a function of the parameter.

Here is an example to demonstrate the idea. A $2 \times 2$ Hamiltonian reads

A[x_] := {{1.2 I + 0.012 Cos[x] + 0.63 Cos[2 x] + 0.3 I Sin[2 x], 0.645}, {0.645, 0}}

I have plotted the real and imaginary parts of eigenvalues as a function of $x$ using

r1 = Table[{Re[Sort[Eigenvalues[A[x]]][[1]]], 
    Im[Sort[Eigenvalues[A[x]]][[1]]], x}, {x, 0.0, 7, 0.1}];
r2 = Table[{Re[Sort[Eigenvalues[A[x]]][[2]]], 
    Im[Sort[Eigenvalues[A[x]]][[2]]], x}, {x, 0.0, 7, 0.1}];

g1 = ListPointPlot3D[r1, PlotStyle -> Directive[Blue]];
g2 = ListPointPlot3D[r2, PlotStyle -> Directive[Red]];

Show[g1, g2, PlotRange -> All, AspectRatio -> 3, Frame -> True, 
 ImageSize -> 150]

The output is this imageenter image description here

I would like to ensure that each strand is only one color; currently, due to the Sort, they have mixed colors. If possible, I would also like to have these strands as tubes instead of points. It would be great if I could get the projection of these strands on the $(\Re[\lambda], \Im[\lambda])$ plane. I prefer not to use any analytical forms of eigenvalues, as attaining analytical eigenvalues is challenging for matrices with high ranks. Do you have suggestions for improving such plots?

  • $\begingroup$ ListLinePlot3D? $\endgroup$
    – cvgmt
    Commented Mar 12 at 9:13
  • $\begingroup$ Line plots won't do the job because of the mixing of eigenvalue order. $\endgroup$
    – Shasa
    Commented Mar 12 at 9:22
  • 1
    $\begingroup$ Maybe some of the answers here could help? $\endgroup$
    – Chris K
    Commented Mar 13 at 19:52
  • $\begingroup$ Thank you, @ChrisK, for sharing the link. I will check it out. $\endgroup$
    – Shasa
    Commented Mar 14 at 8:06

2 Answers 2


(* "14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023)" *)


A[x_] = {{1.2  I + 0.012  Cos[x] + 0.63  Cos[2  x] + 0.3  I  Sin[2  x], 
      0.645}, {0.645, 0}} // Rationalize // Simplify;

ev[x_] = Eigenvalues[A[x]] // Simplify;

ReImPlot[Evaluate@ev[x], {x, 0, 7},
 PlotLegends -> {"ev1", "ev2"}]

enter image description here

For 3D use ParametricPlot3D

  Flatten[{ReIm[#], x}] & /@ ev[x]],
 {x, 0, 7},
 BoxRatios -> {1, 1, 1/2},
 AxesLabel -> (Style[#, 14] & /@ {Re, Im, x}),
 PlotLegends -> {"ev1", "ev2"}]

enter image description here

EDIT: To color each strand separately

pp = ParametricPlot3D[
   Evaluate[Flatten[{ReIm[#], x}] & /@ ev[x]],
   {x, 0, 7}];

Extract all of the data points from the ParametricPlot3D

data = Join @@ Cases[pp, Line[pts_] :> pts, All];

Find the shortest tour and split into two segments

data2 = Split[Most@data[[FindShortestTour[data][[2]]]],
   Norm[#1 - #2] < 0.4 &];

 AxesLabel -> (Style[#, 14] & /@ {Re, Im, x}),
 PlotLegends -> {"ev1", "ev2"}]

enter image description here

EDIT 2: 2D projection of strands

data3 = data2 /. {x_, y_, z_} :> {x, y, -1};

ListLinePlot3D[Join[data2, data3], 
 AxesLabel -> (Style[#, 14] & /@ {Re, Im, x}),
 PlotStyle -> {ColorData[97][1], ColorData[97][2]}, 
 PlotLegends -> {"ev1", "ev2"},
 BoxRatios -> {1, 1, 3/4},
 PlotRange -> All]

enter image description here

  • $\begingroup$ Thank you for your answer. I want each strand to appear in one color. Currently, it is a mix of both colors. $\endgroup$
    – Shasa
    Commented Mar 13 at 7:35
  • $\begingroup$ See edit for update $\endgroup$
    – Bob Hanlon
    Commented Mar 13 at 16:08
  • $\begingroup$ (+1)This is great. Thank you very much. Could you also add a 2d projection of these strands on the Re-Im plane? This way all questions of my thread are addressed by your post. $\endgroup$
    – Shasa
    Commented Mar 14 at 7:44
  • $\begingroup$ Thanks a lot for the update. $\endgroup$
    – Shasa
    Commented Mar 15 at 7:11

There is a problem with sorting eigenvalues and eigenvectors. "Eigenvalues" sorts numerical eigenvalues according to their real parts. Therefore if we have eigenvalues that crosses for some value of the parameter, the eigenvalues do not change smoothly. Rather, what was the first eigenvalue before the crossing, becomes the second one. We can see this by:

Plot[Evaluate[Re[Eigenvalues[A[x]]]], {x, 0, 7}]
Plot[Evaluate[Im@Eigenvalues[A[x]]], {x, 0, 7}]

enter image description here

  • $\begingroup$ Yes, indeed, that is the issue, and for the same reason, LinePlots mix everything, and I cannot use them to greater my 3d figure. $\endgroup$
    – Shasa
    Commented Mar 12 at 9:21
  • $\begingroup$ There is no simple solution to this, but you may draw your plot piecewise. $\endgroup$ Commented Mar 12 at 9:38
  • $\begingroup$ Thank you for sharing your thoughts. I see. Is it possible that I keep both strands in one color but somehow add a direction of flow to the projection on the plane? $\endgroup$
    – Shasa
    Commented Mar 12 at 10:57
  • $\begingroup$ You may add an arrow by g3=Graphics3D[Arrow[{pt1,pt2}]] to the "Show" $\endgroup$ Commented Mar 12 at 11:11

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.