因为本人做实验有画流程图需要,所以自己写个这个脚本。

采取的流程是:

  • 1.ai把图片里的数据写成py中数组形式

  • 2.把这其中# 示例数据换掉,作为纵坐标的值,横坐标,你可以另建一个数组也可以用下文中的

        voltages = np.arange(-75.0, 75.1, 5.0)
  • 类似这个自动生成从-75到75 间隔为5的点

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks
from scipy.interpolate import UnivariateSpline

# 设置全局字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

def plot_current_voltage_curve(currents):
    """
    绘制I_p-V_G2K曲线,并标注峰和谷的坐标值。
    
    参数:
    currents (list): 从10.0到82.0(每次增加0.5)对应的电流值列表
    """
    # 生成电压值
    voltages = np.arange(-75.0, 75.1, 5.0)
    print(voltages)  # 从10.0到82.0,每次增加0.5
    
    # 确保 currents 和 voltages 的长度一致
    if len(currents) != len(voltages):
        raise ValueError(f"currents 的长度 ({len(currents)}) 与 voltages 的长度 ({len(voltages)}) 不一致")
    
    # 转换为NumPy数组
    voltages = np.array(voltages)
    currents = np.array(currents)
    
    # 去除异常值(误差较大的点)
    mean_current = np.mean(currents)
    std_current = np.std(currents)
    mask = np.abs(currents - mean_current) <= 2 * std_current
    voltages = voltages[mask]
    currents = currents[mask]
    
    # 使用UnivariateSpline进行平滑拟合
    if len(voltages) < 4:  # 确保有足够的点进行拟合
        raise ValueError("数据点不足,无法进行平滑拟合")
    
    spline = UnivariateSpline(voltages, currents, s=1)
    voltages_smooth = np.linspace(voltages.min(), voltages.max(), 1000)
    currents_smooth = spline(voltages_smooth)
    
    # 创建图表
    plt.figure(figsize=(12, 7))
    
    # 绘制原始数据点
    plt.scatter(voltages, currents, marker='o', color='gray', label='原始数据点')
    
    # 绘制平滑曲线
    plt.plot(voltages_smooth, currents_smooth, color='b', label='平滑拟合曲线')
    
    # 标注峰和谷
    peaks, _ = find_peaks(currents_smooth)
    valleys, _ = find_peaks(-currents_smooth)
    
    for peak in peaks:
        plt.annotate(f'峰 ({voltages_smooth[peak]:.1f}, {currents_smooth[peak]:.1f})', 
                     (voltages_smooth[peak], currents_smooth[peak]), 
                     textcoords="offset points", 
                     xytext=(0,10), 
                     ha='center', 
                     arrowprops=dict(arrowstyle="->", color='r'))
    
    for valley in valleys:
        plt.annotate(f'谷 ({voltages_smooth[valley]:.1f}, {currents_smooth[valley]:.1f})', 
                     (voltages_smooth[valley], currents_smooth[valley]), 
                     textcoords="offset points", 
                     xytext=(0,-15), 
                     ha='center', 
                     arrowprops=dict(arrowstyle="->", color='g'))
    
    # 设置图表标题和坐标轴标签
    plt.title('对比度随角度变化曲线图')
    plt.xlabel('角度 (°)')
    plt.ylabel('透过率 (%)')
    
    # 设置坐标轴分度值
    plt.xticks(np.arange(min(voltages_smooth), max(voltages_smooth)+1, 5))
    plt.yticks(np.arange(min(currents_smooth), max(currents_smooth)+1, 1))
    
    # 添加图例
    plt.legend()
    
    # 显示网格
    plt.grid(True)
    
    # 显示图表
    plt.tight_layout()
    plt.show()

# 示例数据(你可以替换为自己的数据)
currents = [
 14.1,15.7,17.8,20.5,23.7,25.9,27.1,26.9,27.2,28.6,29.4,31.3,32.3,32.1,33.3,34.4,34.4,33.3,31.3,30.2,28.5,27.8,29.1,29.6,27.8,25.06,22.3,18.7,16,14,11.1
]
print(currents.count(0))

# 调用函数绘制图表
plot_current_voltage_curve(currents)

其中如果plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签没有效果可以用import zhplot方式感觉蛮好用的!