Matplotlib数据可视化实战-2绘制折线图(2)

2.11营业额可视化

已知某学校附近一个烧烤店2022年每个月的营业额如下图所示。编写程序绘制折线图对该烧烤店全年营业额进行可视化,使用红色点画线连接每个月的数据,并在每个月的数据处使用三角形进行标记。

烧烤店营业额
月份123456789101112
营业额/万元5.22.75.85.77.39.218.715.620.518.01.86.9

运行结果如下:

import matplotlib.pyplot as plt

# 月份和每月营业额
month = range(1, 13)
money = [5.2, 2.7, 5.8, 5.7, 7.3, 9.2, 18.7, 15.6, 20.5, 18.0, 7.8, 6.9]

plt.plot(month, money, 'r-.v', mfc='b', mec='y')
plt.xlabel('月份', fontproperties='simhei', fontsize=14)
plt.ylabel('营业额(万元)', fontproperties='simhei', fontsize=14)
plt.title('烧烤店2022年营业额变化趋势图', fontproperties='simhei', fontsize=18)
# 紧缩四周空白,扩大绘图区域可用面积
plt.tight_layout()

plt.show()

参数mfc(marker face color)用来设置散点符号内部颜色

参数mec(marker edge color)设置散点符号边线颜色 

 

2.12绘制折线图模拟连续信号与数字信号

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0, 6*np.pi, 0.05)
# 连续信号与数字信号的函数值
t_sin = np.sin(t)
t_digital1 = np.piecewise(t_sin, [t_sin>0, t_sin<0], [1,-1])
t_digital2 = np.round_(t_sin)

plt.plot(t, t_sin, label='$sin(x)$', color='red', lw=1)
plt.plot(t, t_digital1, 'b--', label='digital1')
plt.plot(t, t_digital2, 'g-.', label='digital2')
plt.ylim(-2.0, 2.0)
plt.legend()

plt.show()

 

2.13在第一象限中,任意反比例函数xy=k与任意矩形OABC的两个交点的连线始终与矩形的对角线平行,请编写程序验证这一点。

import numpy as np
import matplotlib.pyplot as plt

k = 1                                          # 反比例函数xy=k的常数k
m, n = 6, 3                                    # 矩形右上角坐标(m,n)
x = np.arange(0.1, m+0.5, 0.02)                # 第一象限中反比例函数曲线上顶点的x坐标
y = k / x                                      # 根据反比例函数xy=k计算顶点y坐标
plt.plot(x, y, 'b')                            # 绘制第一象限指定区间内的反比例函数图像

plt.plot([0,m,m,0,0], [0,0,n,n,0], 'r')        # 绘制矩形,从左下角出发,向右、上、左、下
plt.plot([0,m], [n,0], 'g')                    # 矩形对角线
plt.plot([k/n,m], [n,k/m], 'g')                # 矩形与反比例函数的交点连线

for x, y, ch in zip([0,m,m,0,k/n,m], [0,0,n,n,n,k/m], 'OABCDE'):
    plt.text(x, y+0.02, ch)                    # 绘制顶点与交点的符号
plt.xlim(-0.1, m+1)                            # 设置坐标轴跨度
plt.ylim(-0.1, n+1)
plt.title(f'k={k},m={m},{n=}', fontsize=20)   # 设置图形标题
plt.gca().set_aspect(True)                     # 设置图形纵横比相等

plt.show()                                     # 显示图形

2.14绘制函数曲线,计算并标记极值 

import numpy as np
import matplotlib.pyplot as plt

# 函数自变量取值范围区间
start, end = 0, 10
# 计算所有采样点的x坐标、y坐标,绘制折线图
x = np.arange(start, end, 0.01)
y = 3*np.sin(x) + 5*np.cos(3*x)
s, = plt.plot(x, y, 'r-')
# 设置子区间长度,在每个子区间(不包含端点)内寻找极值
# 调整区间大小时会影响极值数量,应使得每个子区间内都包含波峰和波谷
span = 66

for start in range(0, len(y), span):
    # 每个子区间的自变量与函数值
    sectionY = y[start:start+span]
    sectionX = x[start:start+span]
    # 局部最大值和局部最小值
    localMax = sectionY.max()
    localMin = sectionY.min()

    # 方案一:
    # 按值大小升序排序的索引
    argsort_result = sectionY.argsort()
    # 区间内所有最大值的索引和所有最小值的索引
    args_max = argsort_result[-len(sectionY[sectionY==localMax]):]
    args_min = argsort_result[:len(sectionY[sectionY==localMin])]
    # 去除子区间端点
    args_max = list(set(args_max)-{0,span-1})
    if args_max:
        s1 = plt.scatter(sectionX[args_max], sectionY[args_max], marker='*', c='b')
    
    args_min = list(set(args_min)-{0,span-1})
    if args_min:
        s2 = plt.scatter(sectionX[args_min], sectionY[args_min], marker='*', c='g')

    # 方案二:
##    for index, yy in enumerate(sectionY):
##        if yy==localMax and index not in (0, span-1):
##            # 在极大值处绘制一个蓝色五角星
##            s1 = plt.scatter(sectionX[index], yy, marker='*', c='b')
##        elif yy==localMin and index not in (0, span-1):
##            # 在极小值处绘制一个绿色五角星
##            s2 = plt.scatter(sectionX[index], yy, marker='*', c='g')

# 创建图例
plt.legend([s,s1,s2], ['curve','local max','local min'])
#显示绘制的结果
plt.show()

2.15使用折线图可视化角谷猜想

角谷猜想,也被称为“冰雹猜想”或“3n+1猜想”,是一个数学上的未解问题。这个猜想的内容是,对于任意一个正整数,如果是奇数,则乘3再加1,如果是偶数,则除以2,这样得到的结果再按照上述规则重复处理,最终总能够得到1。

角谷猜想的名称来源于其在不同地方的流传历史。它首先在美国流传开来,然后传播到欧洲。后来,一位名叫角谷的日本人将其带到亚洲,因此得名“角谷猜想”。而“冰雹猜想”的名称则来源于这个猜想处理数字时数字上上下下的变化过程,就像冰雹在高空中形成并落下的过程一样。

尽管角谷猜想自提出以来已经经过了许多数学家的研究,但至今仍然没有找到证明或反证。这个猜想在数学界引起了广泛的关注,甚至有一些数学家悬赏求解。

from random import choice, seed
import matplotlib.pyplot as plt

def check(num):
    times = 0         # 变为1所需要的次数
    numbers = [num]   # 变为1的过程中的所有数字
    while True:
        times = times + 1
        if num%2 == 0:
            num = num // 2
        else:
            num = num*3 + 1
        numbers.append(num)
        if num == 1:
            # 变为1时结束循环
            break
    return range(times+1), numbers

seed(20220702)
for _ in range(6):
    num = choice(range(1, 9999))
    plt.plot(*check(num), label=str(num))
    
plt.legend()
plt.show()

 2.16角谷猜想中正整数最终变为1所需要的计算次数

 

from random import randrange, seed
import matplotlib.pyplot as plt

def check(num):
    times = 0
    while True:
        times = times + 1
        if num%2 == 0:
            num = num // 2
        else:
            num = num*3 + 1
        if num == 1:
            break
    return times

ticks = []
seed(20220702)
for _ in range(6):
    num = randrange(1, 9999)
    tick = check(num)
    ticks.append(tick)
    # 第一个参数表示y坐标,表示每个柱的位置,对应变为1所需要的次数
    # 第二个参数表示长度,对应要变为1的数字
    plt.barh(tick, num, label=str(num))
# 在每个柱对应的位置显示刻度
plt.yticks(ticks)
plt.legend()

plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Pythoner研习社

整理不易,感谢金主!

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

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

打赏作者

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

抵扣说明:

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

余额充值