Search code examples
pythonnumpymatplotlibplot

How to hide a specific range in matplotlib?


I want to plot a graph of electronic structure data which looks like:

    0.0000  -79.9447
    0.0179  -79.9447
    0.0357  -79.9447
    0.0536  -79.9447
    0.0714  -79.9446
    0.0893  -79.9446
    0.1071  -79.9445
    0.1250  -79.9444
    0.1429  -79.9443
    0.1607  -79.9443
    0.1786  -79.9441
    0.1964  -79.9440
.....

Every 216 rows, there is an empty row, hence I wrote code like this:

import matplotlib.pyplot as plt
import numpy as np

with open('Mn3PtN_bands.dat.gnu', 'r') as f:
    lines = f.readlines()
    
k_points = []
bands = []
current_band = []
for line in lines:
    if line.strip():  
        data = line.split()
        k_point = float(data[0])
        energy = float(data[1])-17.8059 #Fermi energy level
        
        # K_point space between X &R high symmetry 
        if k_point > 3.2801:
            k_point += 0.2
        
        current_band.append((k_point, energy))
    else: 
        if current_band:
            k_points.append([point[0] for point in current_band])
            bands.append([point[1] for point in current_band])
            current_band = []


plt.figure(figsize=(8, 6))
for i in range(len(bands)):
    plt.plot(k_points[i], bands[i], label=f'Band {i+1}',color='k')
plt.xlabel('k-points')
plt.ylabel('Energy (eV)')
plt.title('Electronic Band Structure')
plt.axis([0, 3.7802, -2, 2]) 
#  high symmetry points
plt.axvline(0.5000, linewidth=0.75,linestyle=(0, (5, 5)), color='r', alpha=0.75)
plt.axvline(1.0000, linewidth=0.75,linestyle=(0, (5, 5)),color='r', alpha=0.75)
plt.axvline(1.7071, linewidth=0.75,linestyle=(0, (5, 5)),color='r', alpha=0.75)
plt.axvline(2.5731, linewidth=0.75,linestyle=(0, (5, 5)),color='r', alpha=0.75)
plt.axvline(3.2802, linewidth=0.75,linestyle=(0, (5, 5)),color='r', alpha=0.75)
plt.axvline(3.4802, linewidth=0.75,linestyle=(0, (5, 5)),color='r', alpha=0.75)
plt.xticks(ticks= [0, 0.5,1.0000, 1.7071, 2.5731, 3.2802, 3.4802,3.9802],\
           labels=['$\Gamma$', 'X','M','$\Gamma$','R','X','R','M'])
#Fermi level
plt.axhline(0.0, linestyle=(0, (5, 5)), linewidth=0.75, color='r', alpha=0.75)
plt.show()

with open('bands_output.dat', 'w') as output_file:
    for i in range(len(bands)):
        for j in range(len(k_points[i])):
            output_file.write('{:.5f} {:.5f}\n'.format(k_points[i][j],bands[i][j]))
        output_file.write('\n')

The obtained figure looks like this:

enter image description here

As you can see, even though it isn't, it looks like there is some data between X and R points.

I want a space between two specific x points at a range inside of a plot. How can I do that?


Solution

  • I think you are trying to plot functions that has discontinuities. Since you didn't provide dataset let's create some toy data that represents a step function.

    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    
    # Create data
    x=np.linspace(0,5,10001)    
    y=np.zeros(len(x))
    y[x>2.5] = 1
    
    # Plot step function
    plt.figure(figsize=(8, 6))
    
    plt.plot(x, y, color='k')
    
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('Step Function with Range')    
    plt.show()
    

    enter image description here

    You can deal with discontinuities by defining a range and filling with nan values in that range.

    # Specifying the range within which to introduce NaN values
    x1, x2 = 2.45, 2.55  # Example range to avoid plotting
    
    # introduce NaN values for specified x range
    y[((x >= x1) & (x <= x2))] = np.nan
    
    
    plt.figure(figsize=(8, 6))
    
    plt.plot(x, y, color='k')
    
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('Step Function with Excluded Range')
    plt.show()
    

    enter image description here

    You should then apply it to your case for each function you are showing.