如何用Matplotlib复刻素数计数阶跃函数并绘制反向曲线?
素数计数阶跃函数绘制问题解决
问题概述
需要复刻素数计数阶跃函数,现有代码存在以下问题:
- 非素数对应点的y值逻辑错误,无法正确呈现阶跃效果
- X轴刻度未对应1-30序列,点的x坐标偏移导致不在数字正上方
- 需添加示例中的反向红色对比曲线
原始代码
import sympy import matplotlib.pyplot as plt mylist = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] plt.gca().set_aspect("equal") plt.autoscale(False) plt.xlim(0, 31) plt.ylim(0, 15) y=0 for p in mylist: if sympy.isprime(p)==2: plt.plot(1,0) if sympy.isprime(p): x=p-1 y=y+1 plt.plot(x,y, marker='.') else: x=p-1 plt.plot(x,y, marker='.') plt.show()
修正后的代码
import sympy import matplotlib.pyplot as plt import numpy as np # 定义数字范围1-30 n_range = np.arange(1, 31) # 计算每个n对应的素数计数π(n):小于等于n的素数个数 pi_n = [sum(sympy.isprime(num) for num in range(1, n+1)) for n in n_range] plt.figure(figsize=(10, 6)) # 绘制每个n对应的点,位于数字正上方 plt.scatter(n_range, pi_n, color='black', marker='.', s=100) # 绘制阶跃线段:水平线段连接相邻点(非素数区间y值不变),垂直线段在素数处上升 for i in range(1, len(n_range)): # 水平线段:从n-1到n,y值保持π(n-1) plt.plot([n_range[i-1], n_range[i]], [pi_n[i-1], pi_n[i-1]], color='black') # 素数处绘制垂直线段:从π(n-1)到π(n) if pi_n[i] != pi_n[i-1]: plt.plot([n_range[i], n_range[i]], [pi_n[i-1], pi_n[i]], color='black') # 补充最左侧线段:从0到1,y值为0 plt.plot([0, n_range[0]], [0, pi_n[0]], color='black') # 设置X轴刻度为1-30,与点位置对应 plt.xticks(n_range) # 调整坐标轴范围 plt.xlim(0, 31) plt.ylim(0, max(pi_n)+1) # 移除等比例缩放,避免图形变形 # plt.gca().set_aspect("equal") # 绘制反向红色曲线:基于素数定理的n/ln(n),反向后呈现递减效果 x_curve = np.arange(2, 31) y_curve = x_curve / np.log(x_curve) # 通过y轴偏移实现反向,匹配示例图的红色曲线形态 plt.plot(x_curve, max(pi_n)+1 - y_curve, color='red', linestyle='--') # 添加坐标轴标签和标题 plt.xlabel('n') plt.ylabel('π(n)') plt.title('素数计数阶跃函数') plt.show()
关键修正说明
- 点位置与X轴刻度:将点的x坐标设为
n,并通过plt.xticks(n_range)设置X轴刻度为1-30,确保每个点精准对应数字正上方。 - 阶跃效果实现:通过计算每个n的素数计数
pi_n,循环绘制水平线段(非素数区间保持y值)和垂直线段(素数处y值上升),完美还原阶跃函数形态。 - 反向红色曲线:使用素数定理的近似公式
n/ln(n),通过max(pi_n)+1 - y_curve将曲线反向,实现示例图中从右上角到左下角的递减红色曲线。 - 视觉优化:关闭原代码的等比例缩放,避免X轴被压缩,提升图形可读性。
内容的提问来源于stack exchange,提问作者zeynel
相关产品推荐
相关产品推荐

