【头歌-Python】9.2 能带曲线绘制(project) 第1~3关

参考教程:B站视频讲解——https://space.bilibili.com/3546616042621301

第1关:能带曲线绘制一

任务描述

本关任务:使用matplotlib绘制图形。

相关知识

为了完成本关任务,你需要掌握:

  1. 使用 matplotlib 绘制图形
  2. python 读取文件

python 读取文件
python读取文件可以用以下函数实现:

# 读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中
def read_file(file):
    """
    @参数 file:文件名,字符串
    读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。
    返回值为二维列表,其中数据是浮点数类型。
    """
    with open(file, 'r', encoding='utf-8') as file:
        data_list = [list(map(float, line.strip().split('\t'))) for line in file]
    return data_list 

编程要求

  • 数据下载:
    band.txt
  • 根据提示,在右侧编辑器补充代码,绘制图形,具体要求如下:
  1. 绘制能带曲线图,线条颜色、粗细由系统默认,均为实线。
  2. 文件中的能带曲线数据有 2 列,分别代表坐标的(x, y)值。整个文件中的数据分为多组,每组数据 x 值范围从 0 增加到 1.0,每组数据可以绘制一条能带曲线。
  3. 重复读取各组数据,便可以绘制全部的能带曲线了。
  4. 绘制结果写入到文件"result/result.jpg"中

测试说明

平台会对你编写的代码进行测试:
在这里插入图片描述

参考代码

import matplotlib.pyplot as plt

def read_file(file):
    """参数文件名读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。  
    返回值为二维列表。 """
    with open(file, 'r', encoding='utf-8') as f:
    	res = []
        for line in f.readlines():
            res.append(line.strip().split('\t'))
    	return res

def plot_band(band_data):
    """参数数据是二维列表,x值从0-1的变化数据为一组,分组读取数据并绘制全部曲线"""
    x, y = [], []
    for data in band_data:
        x.append(eval(data[0]))
        y.append(eval(data[1]))
        if data[0] == '1':
            plt.plot(x, y)
            x, y = [], []
            
if __name__ == '__main__':
    filename = 'band.txt'
    data = read_file(filename)        # 读文件到二维列表
    plot_band(data)                 # 调用函数绘制曲线
    plt.savefig("result/result.jpg")  # 保存成图片
    plt.show()  

第2关:能带曲线绘制二

任务描述

本关任务:使用matplotlib绘制图形。

相关知识

为了完成本关任务,你需要掌握:

  1. 显示中文;
  2. python 读取文件
  3. 使用 matplotlib 绘制图形;
    显示中文
    设置中文字体和负号显示问题如下:
plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False

python 读取文件
python读取文件可以用以下函数实现:

# 读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中
def read_file(file):
    """读文件file,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。
    返回值为二维列表,其中数据是浮点数类型。
    """
    with open(file, 'r', encoding='utf-8') as file:
        data_list = [list(map(float, line.strip().split('\t'))) for line in file]
    return data_list 

或先以字符串形式加入列表,使用再转为数值:

def read_file(file):
    """读文件file,根据制表符'\t'将每行数据切分为列表再加入到列表中。返回值为二维列表,其中数据是字符串类型。 """
    with open(file, 'r', encoding='utf-8') as file:
        data_list = [line.strip().split('\t') for line in file]
    return data_list 

编程要求

根据提示,在右侧编辑器 Begin-End 区间中补充代码,绘制图形,具体要求如下:

  1. 一般来说,费米面附近的能带对性质影响最大,所以科学家只关心纵坐标为0的直线附近的能带曲线,用户输入用空格分隔的两个浮点数,用于确定一个纵坐标为 0 附近的区间,绘制纵坐标这个区间之间的能带曲线,

  2. 加图名“能带曲线图谱”,字体为’SimSun’,横坐标标签“k”,纵坐标标签“E(ev)”,在 y=0 处绘制一条直线,线型为虚线,红色。例如用户输入-5.0 5.0,绘制如下图形,相当于将处于这个区间的图形纵向拉伸放大,使曲线的弯曲程度更明显。

测试说明

平台会对你编写的代码进行测试:

  • 输入示例:
-5.0 5.0
  • 输出示例:
    在这里插入图片描述

参考代码

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False

def read_file(file):
    """参数文件名读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。  
    返回值为二维列表。 """
    with open(file, 'r', encoding='utf-8') as f:
    	res = []
        for line in f.readlines():
            res.append(line.strip().split('\t'))
    	return res

def plot_band(band_data, m, n):
    """参数数据是二维列表,x值从0-1的变化数据为一组,分组读取数据并绘制全部曲线"""
    x, y = [], []
    for data in band_data:
        x.append(eval(data[0]))
        y.append(eval(data[1]))
        if data[0] == '1':
            if len([i for i in y if not m<=i<=n])==0:
            	plt.plot(x, y)
            x, y = [], []
            
def plot_label():
    """绘制坐标标签、图名与x轴"""
    plt.axhline(0, linestyle='--', color='r')
    plt.title('能带曲线图谱')
    plt.xlabel('k')
    plt.ylabel('E(ev)')

if __name__ == '__main__':
    filename = 'band.txt'
    data = read_file(filename)  # 读文件到二维列表
    min_value, max_value = map(float, input().split())  # 输入数据范围
    if min_value > max_value:
        min_value, max_value = max_value, min_value
    plot_band(data, min_value, max_value)  # 调用函数绘制曲线
    plot_label()
    plt.savefig("result/result.jpg")  # 保存成图片
    plt.show()

第3关:能带曲线绘制(拓展)

任务描述

本关任务:使用 matplotlib 绘制图形。

相关知识

为了完成本关任务,你需要掌握:

  1. 使用 matplotlib 绘制图形;
  2. python 读取文件。

python 读取文件
python读取文件可以用以下函数实现:

# 读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中
def read_file(file):
    """
    @参数 file:文件名,字符串
    读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。
    返回值为二维列表,其中数据是浮点数类型。
    """
    with open(file, 'r', encoding='utf-8') as file:
        data_list = [list(map(float, line.strip().split('\t'))) for line in file]
    return data_list 

编程要求

根据提示,在右侧补充代码,绘制图形,具体要求如下:

  1. 找出纵坐标大于0的曲线上的最低点A的坐标,标注该点为“bottom of conduction band”。

  2. 找出纵坐标小于0的曲线上、与A点相同横坐标的最高点B的坐标,标注该点为“top of valence band”。

  3. 计算并输出A、B之间的距离(A,B横坐标相同),用灰色虚线连接A,B两点。输出导带底坐标、价带顶坐标和带隙。

测试说明

平台会对你编写的代码进行测试:

  • 输入示例: -5.0 5.0

  • 输出示例:
    在这里插入图片描述

参考代码

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False

def read_file(file):
    """参数文件名读文件,根据制表符'\t'将每行数据切分为列表再加入到列表中将数据映射为浮点数类型。  
    返回值为二维列表。 """
    with open(file, 'r', encoding='utf-8') as f:
    	res = []
        for line in f.readlines():
            res.append(line.strip().split('\t'))
    	return res

def plot_band(band_data, m, n):
    """参数数据是二维列表,x值从0-1的变化数据为一组,分组读取数据并绘制全部曲线"""
    x, y = [], []
    for data in band_data:
        x.append(eval(data[0]))
        y.append(eval(data[1]))
        if data[0] == '1':
            if len([i for i in y if not m<=i<=n])==0:
            	plt.plot(x, y)
            x, y = [], []

def bottom_top_band(data_list):
    """参数是浮点数的二维列表,定位导价底和价带顶的坐标。导带底为纵坐标大于0的部曲线最低点,
    价带顶为纵坐标小于0 的曲线最高点,一般导带底与价带顶相对,即横坐标相同。以元组形式返回导带底坐标和价带顶坐标 """
    Min = (0, 1000)
    for data in data_list:
        d = eval(data[1])
        if 0<d<Min[1]:
            Min = (data[0], d)
            
    Max = max([eval(d[1]) for d in data_list if d[0]==Min[0] and eval(d[1])<0])
    return (eval(Min[0]), Min[1]), (eval(Min[0]), Max)

def gap_of_band(bottom, top):
    """bottom纵坐标大于0的部曲线最低点坐标;top纵坐标小于0 的曲线最高点坐标
    接收导带底和价带顶的数值,带隙为导带底和价带顶纵坐标之差,返回带隙值。 """
	return #该函数在本题中似乎没有用

def mark_peak(bottom_top):
    """绘制注释,在y值大于0的部分找到曲线最低点,标注'bottom of conduction band'
    在y值小于0的部分找到曲线最高点,标注'top of valence band'。 绘制导带底到价带顶连线,灰色破折线 """
    plt.plot([bottom_top[0][0], bottom_top[1][0]], [bottom_top[0][1], bottom_top[1][1]], linestyle='--', color='gray') 
    plt.annotate(r'bottom of conduction band', xy=bottom_top[0], xytext=(-200, -20),
                 textcoords='offset points', fontsize=12,
                 arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
    plt.annotate(r'top of valence band', xy=bottom_top[1], xytext=(0, 15),
                 textcoords='offset points', fontsize=12,
                 arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
            
def plot_label():
    """绘制坐标标签、图名与x轴"""
    plt.axhline(0, linestyle='--', color='r')
    plt.title('能带曲线图谱')
    plt.xlabel('k')
    plt.ylabel('E(ev)')
    
if __name__ == '__main__':
    filename = 'band.txt'
    data = read_file(filename)  # 读文件到二维列表
    min_value, max_value = map(float, input().split())  # 输入数据范围
    if min_value > max_value:
        min_value, max_value = max_value, min_value
    plot_band(data, min_value, max_value)  # 调用函数绘制曲线
    bottom_to_top = bottom_top_band(data)
    mark_peak(bottom_to_top)
    plot_label()
    bottom_top_band(data)
    plt.savefig("result/result.jpg")  # 保存成图片
    plt.show()
  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谛凌

本人水平有限,感谢您支持与指正

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值