Michael H.
Michael H.

Reputation: 3483

Matplotlib: different color for every point of line plot

I'm trying to make a plot like in the following figure (source of image):figure I'm talking about the plot in the right panel even though there is some correlation between the two panels: the colorbar.

Just so you know what this is about: For every value of V, I find all N eigenvalues and eigenvectors of a NxN matrix that depends on V. The eigenvalue (this is an energy) is labeled E and is plotted in the right panel as a function of V. The value on the colorbar (let's call it IPR) is calculated from the eigenvectors and defines the color of the points in the right panel. So you see that the color and the value E are correlated which is why such a plot is pretty nice. For the physicists among you, this is a band structure as a function of some potential strength V and the IPR says something about the degree of localization of the corresponding eigenstate of the Hamiltonian.

Now my question is how I can produce such a plot in matplotlib/pyplot in a nice/efficient way. Of course one could think of a "non-pythonian" way (first calculate the data for all V, find min/max of the IPR to define the bijection between IPR and color, then go through two loops (one for all values of V, one for all N eigenvalues/-vectors at fixed V) and use some matplotlib method to get a color for every point of the plot (I assume there is such a method, even though I couldn't find one using Google)). If you take a close look you could guess that this is exactly what was done in the image. If this is the only way one of you could think of, I would be happy if anyone would let me know what said matplotlib method is. The best solution (for my purposes) would be if instead of making points, one could make N lines and still lie a color scale over it so you could still identify the bands in the plot (in the image you see vertical lines of dots but I'd rather like "vertical" lines like in a usual line plot) but I understand that this is probably not possible.

Thanks in advance!

Upvotes: 0

Views: 3391

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339230

If I understand correctly after the calculation you end up with the data in a table like this

Eig.Val.Nr|  V    |  E      |  IPR   |
----------+-------+---------+--------+
0.000     | 0.000 |  -1.000 |  0.000 |
0.000     | 0.092 |  -1.010 |  0.075 |
0.000     | 0.184 |  -1.021 |  0.075 |
0.000     | 0.276 |  -1.031 |  0.075 |
.....     | ..... |  ...... |  ..... |

The plot could then be reproduced by plotting an image of the reshaped IPR values and a scatter of column V and E, where IPR is set as color.

import matplotlib.pyplot as plt
import numpy as np

eig, v, e, ipr = np.loadtxt("output.txt", unpack=True)
IPR = ipr.reshape(500,50)

fig, axes = plt.subplots(ncols=2)
im = axes[0].imshow(IPR , cmap="magma", origin="lower")
axes[0].set_aspect("auto")
plt.colorbar(im, ax=axes[0])

axes[1].scatter(v, e, c=ipr,s = 0.06, marker=".", cmap="magma", )

plt.show()

enter image description here

Upvotes: 1

Diziet Asahi
Diziet Asahi

Reputation: 40697

Assuming you have your values of V, E and IPR already calculated, you can generate your plot simply by plotting E vs V using IPR as a color.

See this very nicely-detailed answer to a previous question: https://stackoverflow.com/a/17682382/1356000

Upvotes: 1

Related Questions