You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib中隐藏绘图的特定X轴区间?

问题

需要绘制电子结构能带图,数据格式为每216行后包含一个空行,示例数据如下:

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
.....

已编写如下Python代码处理数据并绘图,但生成的图像中X与R点之间看似存在数据(实际无数据),需要在特定X区间添加空白:

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')
解决方案

要在特定X区间添加空白,核心思路是拆分能带数据:在需要断开的位置,给原本连续的能带插入NaN值(matplotlib会自动跳过NaN值,形成空白)。

针对你的代码,具体修改如下:

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 = []
# 定义需要断开的区间:X点(3.2802)到R点(3.4802)
break_start = 3.2802
break_end = 3.4802

for line in lines:
    if line.strip():  
        data = line.split()
        k_point = float(data[0])
        energy = float(data[1]) - 17.8059  # Fermi energy level
        
        # 处理X到R之间的k点偏移
        if k_point > 3.2801:
            k_point += 0.2
        
        current_band.append((k_point, energy))
    else: 
        if current_band:
            # 拆分当前能带:在break_start位置插入NaN分隔
            band_k = []
            band_e = []
            for k, e in current_band:
                band_k.append(k)
                band_e.append(e)
                # 当k点接近break_start时,插入NaN断开
                if abs(k - break_start) < 1e-4:
                    band_k.append(np.nan)
                    band_e.append(np.nan)
            k_points.append(band_k)
            bands.append(band_e)
            current_band = []

plt.figure(figsize=(8, 6))
for i in range(len(bands)):
    plt.plot(k_points[i], bands[i], color='k')  # 去掉label避免图例混乱
plt.xlabel('k-points')
plt.ylabel('Energy (eV)')
plt.title('Electronic Band Structure')
plt.axis([0, 3.9802, -2, 2]) 
# 绘制高对称点竖线
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'])
# 绘制费米能级横线
plt.axhline(0.0, linestyle=(0, (5, 5)), linewidth=0.75, color='r', alpha=0.75)
plt.show()

# 输出处理后的数据(包含NaN分隔)
with open('bands_output.dat', 'w') as output_file:
    for i in range(len(bands)):
        for j in range(len(k_points[i])):
            k_val = k_points[i][j]
            e_val = bands[i][j]
            # 处理NaN值的输出
            if np.isnan(k_val):
                output_file.write('\n')
            else:
                output_file.write('{:.5f} {:.5f}\n'.format(k_val, e_val))
        output_file.write('\n')

关键改动说明

  • 在处理每个能带数据时,当遇到接近break_start(3.2802)的k点后,插入一对NaN值,matplotlib绘制时会自动跳过NaN,形成空白区间。
  • 调整了x轴范围到3.9802,确保所有高对称点都能完整显示。
  • 去掉了能带的label,避免能带数量过多时图例过于繁杂(如需保留可自行恢复)。
  • 输出文件时对NaN值做了处理,写入空行保持数据格式一致。

内容的提问来源于stack exchange,提问作者Hüseyin Yasin Uzunok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:22:04