0

I have below script which only plots case1.hdf5 file.

  • I want to plot another case2.hdf5 file in same script such that I get two overlapping plots.

Additionally, I want to use

  1. Times New Roman fonts for labels and titles.
  2. Insert Legends for both the plots.
  3. Multiply Y-axis data with some constant number.
  4. This script gives bottom three lines in a same colour but I want all three in different solid colours for case1.hdf5 and with same colour and dashed for another case2.hdf5 file.

My script is here

import h5py
import matplotlib.pyplot as plt 
import warnings
import matplotlib

warnings.filterwarnings("ignore") # Ignore all warnings


ticklabels=[r'$\Gamma$','F','Q','Z',r'$\Gamma$']

params = {
'mathtext.default': 'regular',
'axes.linewidth': 1.2,
'axes.edgecolor': 'Black',
}

plt.rcParams.update(params)
fig, ax = plt.subplots() 

f = h5py.File('band.hdf5',  'r')
#print ('datasets are:')
print(list(f.keys()))

dist=f[u'distance']
freq=f[u'frequency']
kpt=f[u'path']

# Iterate over each segment
for i in range(len(dist)):
# Iteraton over each band
    for nbnd in range(len(freq[i][0])):
        x=[]
        y=[]

        for j in range(len(dist[i])):
            x.append(dist[i][j])
            y.append(freq[i][j][nbnd])
# First 3 bands are red
        if (nbnd<3):
            color='red'
        else:
            color='black'

        ax.plot(x, y, c=color, lw=2.0, alpha=0.8)

# Labels and axis limit and ticks
ax.set_ylabel(r'Frequency (THz)', fontsize=12)
ax.set_xlabel(r'Wave Vector (q)', fontsize=12)
ax.set_xlim([dist[0][0],dist[len(dist)-1][-1]])
xticks=[dist[i][0] for i in range(len(dist))]
xticks.append(dist[len(dist)-1][-1])
ax.set_xticks(xticks)
ax.set_xticklabels(ticklabels)
# Plot grid
ax.grid(which='major', axis='x', c='green', lw=2.5, linestyle='--', alpha=0.8)
# Save to pdf
plt.savefig('plots.pdf', bbox_inches='tight')

You see, there is

First 3 bands are red

    if (nbnd<3):
        color='red'

and instead of red I want all of these three in solid different colours and for case2.hdf5 in dashed lines with same colours.

Community
  • 1
  • 1
astha
  • 593
  • 5
  • 15
  • I'm not behind a keyboard rn. But as for the other file, it seams like you want to alternate between black and red lines. In that case I would use the modulo operator (%) within the outer most loop (i think, could be inner loop tbh) to set the color of the line. Something like 'ax.plot(..., color="r" if i % 2 else "k")'...notice you can use shorthand 'r' for 'red' and 'k' for 'black' – Andrew Micallef Jun 01 '20 at 02:36

1 Answers1

2

1. Colours

It sounds like in the first instance you want to map different colours to the first there bands of your data.

One way you might do this is to setup a colourmap and then apply it to those first three bands. Here I have just picked the default matplotlib colormap, but there are loads to choose from, so if the default doesn't work for you I would suggest checking out the post about choosing a colormap. In most use cases you should try to stick to a perceptually constant map.

2. Legend

This should just be a matter of calling ax.legend(). Although be wary when setting the position of the legend to be outside the bounds of the plot as you need to do some extra finicking when saving to pdf, as detailed here..

However you first need to add some labels to your plot, which in your case you would do inside your ax.plot() calls. I'm not sure what you are plotting, so can't tell you what labels would be sensible, but you may want something like: ax.plot(... label=f'band {nbnd}' if nbnd < 4 else None).

Notice the inline if. You are likely going to have a whole bunch of black bands that you don't want to label individually, so you likely want to only label the first and let the rest have label = None which means no bloated legend.

3. Scale Y

If you change the way you iterate through your data you should be able to capture the h5 dataset as something that behaves much like a numpy array. What I mean by that is you really only need two loops to index the data you want. freq[i, :, nbnd] should be a 1-d array that you want to set to y. You can multiply that 1-d array by some scale value

4.

import h5py
import matplotlib.pyplot as plt 
import warnings
import matplotlib

warnings.filterwarnings("ignore") # Ignore all warnings

cmap = matplotlib.cm.get_cmap('jet', 4)

ticklabels=['A','B','C','D','E']

params = {
'mathtext.default': 'regular',
'axes.linewidth': 1.2,
'axes.edgecolor': 'Black',
'font.family' : 'serif'
}


#get the viridis cmap with a resolution of 3

#apply a scale to the y axis. I'm just picking an arbritrary number here
scale = 10
offset = 0 #set this to a non-zero value if you want to have your lines offset in a waterfall style effect


plt.rcParams.update(params)
fig, ax = plt.subplots() 

f = h5py.File('band.hdf5',  'r')
#print ('datasets are:')
print(list(f.keys()))

dist=f[u'distance']
freq=f[u'frequency']
kpt=f[u'path']

lbl = {0:'AB', 1:'BC', 2:'CD', 3:'fourth'}

for i, section in enumerate(dist):
    for nbnd, _ in enumerate(freq[i][0]):
        x = section # to_list() you may need to convert sample to list.
        y = (freq[i, :, nbnd] + offset*nbnd) * scale

        if (nbnd<3):
            color=f'C{nbnd}'
        else:
            color='black'

        ax.plot(x, y, c=color, lw=2.0, alpha=0.8, label = lbl[nbnd] if nbnd < 3 and i == 0 else None)


ax.legend()

# Labels and axis limit and ticks
ax.set_ylabel(r'Frequency (THz)', fontsize=12)
ax.set_xlabel(r'Wave Vector (q)', fontsize=12)
ax.set_xlim([dist[0][0],dist[len(dist)-1][-1]])
xticks=[dist[i][0] for i in range(len(dist))]
xticks.append(dist[len(dist)-1][-1])
ax.set_xticks(xticks)
ax.set_xticklabels(ticklabels)
# Plot grid
ax.grid(which='major', axis='x', c='green', lw=2.5, linestyle='--', alpha=0.8)
# Save to pdf
plt.savefig('plots.pdf', bbox_inches='tight')

This script gives me the following image with the data you supplied ![enter image description here

Andrew Micallef
  • 360
  • 1
  • 10
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/215060/discussion-on-answer-by-andrew-micallef-how-to-plot-two-case1-hdf5-and-case2-hdf). – Samuel Liew Jun 01 '20 at 03:49