请选择 进入手机版 | 继续访问电脑版

[python] Python中使用 matplotlib绘制mqtt数据及时 图像功能

[复制链接]
查看97 | 回复14 | 2021-9-13 11:23:56 | 显示全部楼层 |阅读模式
目次

效果 图

请添加图片形貌

mqtt发布

本代码中

  1. publish
复制代码
是一个死循环,数据不停 往外发送。

  1. import random
  2. import time
  3. from paho.mqtt import client as mqtt_client
  4. import json
  5. from datetime import datetime
  6. broker = 'broker.emqx.io'
  7. port = 1883
  8. topic = "/python/mqtt/li"
  9. client_id = f'python-mqtt-{random.randint(0, 1000)}' # 随机生成客户端id
  10. def connect_mqtt():
  11. def on_connect(client, userdata, flags, rc):
  12. if rc == 0:
  13. print("Connected to MQTT Broker!")
  14. else:
  15. print("Failed to connect, return code %d\n", rc)
  16. client = mqtt_client.Client(client_id)
  17. client.on_connect = on_connect
  18. client.connect(broker, port)
  19. return client
  20. def publish(client):
  21. while True:
  22. time.sleep(0.01)
  23. msg = json.dumps({"MAC": "0123456789",
  24. "samplerate": 12,
  25. "sampletime": str(datetime.utcnow().strftime('%Y/%m/%d-%H:%M:%S.%f')[:-3]),
  26. "battery": 0.5,
  27. "acc": [
  28. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  29. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  30. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  31. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  32. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  33. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  34. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  35. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  36. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  37. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  38. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  39. [random.randint(200, 350), -random.randint(200, 350), -random.randint(200, 350), random.randint(200, 350), random.randint(200, 350), random.randint(200, 350)],
  40. ]})
  41. result = client.publish(topic, msg)
  42. status = result[0]
  43. if status == 0:
  44. print(f"Send `{msg}` to topic `{topic}`")
  45. else:
  46. print(f"Failed to send message to topic {topic}")
  47. def run():
  48. client = connect_mqtt()
  49. client.loop_start()
  50. publish(client)
  51. if __name__ == '__main__':
  52. run()
复制代码

mqtt订阅

  1. from paho.mqtt import client as mqtt_client
  2. import time
  3. import os
  4. broker = 'broker.emqx.io'
  5. port = 1883
  6. topic = "/python/mqtt/li"
  7. def connect_mqtt(client_id):
  8. """ MQTT 连接函数。 """
  9. def on_connect(client, userdata, flags, rc):
  10. """
  11. 连接回调函数
  12. 在客户端连接后被调用,在该函数中可以依据 rc 来判断客户端是否连接成功。
  13. """
  14. if rc == 0:
  15. print("Connected to MQTT Broker! return code %d" % rc)
  16. else:
  17. print("Failed to connect, return code %d\n", rc)
  18. client = mqtt_client.Client(client_id)
  19. # client.username_pw_set('uname', 'upwd') # 链接mqtt所需的用户名和密码,没有可不写
  20. client.on_connect = on_connect
  21. client.connect(broker , port)
  22. return client
  23. def subscribe(client: mqtt_client, a_topic):
  24. """ 订阅消息 """
  25. def on_message(client, userdata, msg):
  26. """
  27. 消息回调函数
  28. 在客户端从 MQTT Broker 收到消息后被调用,在该函数中我们将打印出订阅的 topic 名称以及接收到的消息内容。
  29. * 这里可添加自定义数据处理程序
  30. """
  31. print('From topic : %s\n\tmsg : %s' % (msg.topic, msg.payload.decode()))
  32. client.subscribe(topic)
  33. client.on_message = on_message
  34. def run(client_id, topic):
  35. client = connect_mqtt(client_id)
  36. subscribe(client, topic)
  37. client.loop_forever()
  38. if __name__ == '__main__':
  39. run('test_eartag-003-python-li', 'zk100/gw/#')
复制代码

matplotlib绘制动态图

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. count = 100 # 图中最多数据量
  4. ax = list(range(count)) # 保存图1数据
  5. ay = [0] * 100
  6. bx = list(range(count)) # 保存图2数据
  7. by = [0] * 100
  8. num = count # 计数
  9. plt.ion() # 开启一个画图的窗口进入交互模式,用于实时更新数据
  10. plt.rcParams['figure.figsize'] = (10, 10) # 图像显示大小
  11. plt.rcParams['font.sans-serif'] = ['SimHei'] # 防止中文标签乱码,还有通过导入字体文件的方法
  12. plt.rcParams['axes.unicode_minus'] = False
  13. plt.rcParams['lines.linewidth'] = 0.5 # 设置曲线线条宽度
  14. plt.tight_layout()
  15. while True:
  16. plt.clf() # 清除刷新前的图表,防止数据量过大消耗内存
  17. plt.suptitle("总标题", fontsize=30) # 添加总标题,并设置文字大小
  18. g1 = np.random.random() # 生成随机数画图
  19. # 图表1
  20. ax.append(num) # 追加x坐标值
  21. ay.append(g1) # 追加y坐标值
  22. agraphic = plt.subplot(2, 1, 1)
  23. agraphic.set_title('子图表标题1') # 添加子标题
  24. agraphic.set_xlabel('x轴', fontsize=10) # 添加轴标签
  25. agraphic.set_ylabel('y轴', fontsize=20)
  26. plt.plot(ax[-count:], ay[-count:], 'g-') # 等于agraghic.plot(ax,ay,'g-')
  27. # 图表2
  28. bx.append(num)
  29. by.append(g1)
  30. bgraghic = plt.subplot(2, 1, 2)
  31. bgraghic.set_title('子图表标题2')
  32. bgraghic.plot(bx[-count:], by[-count:], 'r^')
  33. plt.pause(0.001) # 设置暂停时间,太快图表无法正常显示
  34. num = num + 1
复制代码

matplotlib绘制mqtt数据及时 图像

  • 单线程

先启动mqtt订阅服务
mqtt订阅中有壅闭 ,更新数据后因订阅服务没有竣事 ,导致绘图程序无法绘图
先启动绘图程序
绘图程序本身也是个循环,拿不到mqtt的及时 数据,图像无法更新

  • 两个服务加入协程,也不行。详细 缘故原由 还不知道,容后补充。
  • mqtt作为线程启动,可办理 上述标题
  1. import json
  2. import random
  3. from paho.mqtt import client as mqtt_client
  4. import time
  5. import datetime
  6. from math import ceil, floor
  7. import matplotlib.pyplot as plt
  8. import _thread
  9. # 公共变量
  10. broker = 'broker.emqx.io'
  11. topic = "/python/mqtt/li"
  12. port = 1883
  13. client_id = f'python-mqtt-li-{random.randint(0, 100)}'
  14. show_num = 300
  15. x_num = [-1] # 计数
  16. acc1 = []
  17. acc2 = []
  18. acc3 = []
  19. acc4 = []
  20. acc5 = []
  21. acc6 = []
  22. stime = []
  23. """mqtt subscribe topic"""
  24. def str_microsecond_datetime2int_13timestamp(str_microsecond_datetime):
  25. """将字符串型【毫秒级】格式化时间 转为 【13位】整型时间戳"""
  26. datetime_obj = datetime.datetime.strptime(str_microsecond_datetime, "%Y/%m/%d-%H:%M:%S.%f")
  27. obj_stamp = int(time.mktime(datetime_obj.timetuple()) * 1000.0 + datetime_obj.microsecond / 1000.0) / 1000.0
  28. return obj_stamp
  29. def int2datetime(int_float_timestamp):
  30. """
  31. 有小数点:分离小数点,整数转为格式化时间,小数点直接跟在后面
  32. 无小数点:从第10位进行分离,
  33. 所以本函数只适用于时间戳整数位数大于9且小于11.
  34. """
  35. if '.' in str(int_float_timestamp):
  36. int_float = str(int_float_timestamp).split('.')
  37. date = time.localtime(int(int_float[0]))
  38. tempDate = time.strftime("%Y/%m/%d-%H:%M:%S", date)
  39. secondafter = '.' + str(int_float[1])
  40. return str(tempDate) + secondafter
  41. def parse_mqttmsg(msg):
  42. """解析mqt头数据 MAC samplerate sampletime battery acc"""
  43. content = json.loads(msg.payload.decode())
  44. span = 1000 / content['samplerate'] * 10
  45. time_span = [ceil(span) / 10 / 1000, floor(span) / 10 / 1000]
  46. sampletime = content['sampletime']
  47. sampletime_int = str_microsecond_datetime2int_13timestamp(sampletime)
  48. acc = content['acc']
  49. for i in range(len(acc)):
  50. x_num.append(x_num[-1] + 1)
  51. acc1.append(acc[i][0])
  52. acc2.append(acc[i][1])
  53. acc3.append(acc[i][2])
  54. acc4.append(acc[i][3])
  55. acc5.append(acc[i][4])
  56. acc6.append(acc[i][5])
  57. if i != 0:
  58. sampletime_int += time_span[i % 2]
  59. stime.append(int2datetime(round(sampletime_int * 1000, 0) / 1000))
  60. else:
  61. stime.append(sampletime)
  62. print(x_num[-1], stime[-1], acc1[-1], acc2[-1], acc3[-1], acc4[-1], acc5[-1], acc6[-1])
  63. def connect_mqtt():
  64. def on_connect(client, userdata, flags, rc):
  65. if rc == 0:
  66. print("Connected to MQTT Broker!")
  67. else:
  68. print("Failed to connect, return code %d\n", rc)
  69. pass
  70. client = mqtt_client.Client(client_id)
  71. client.on_connect = on_connect
  72. client.connect(broker, port)
  73. return client
  74. def subscribe(client: mqtt_client):
  75. def on_message(client, userdata, msg):
  76. # print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
  77. parse_mqttmsg(msg)
  78. client.subscribe(topic)
  79. client.on_message = on_message
  80. def run():
  81. client = connect_mqtt()
  82. subscribe(client)
  83. client.loop_forever()
  84. """ draw figures """
  85. def draw_figure():
  86. plt.ion() # 开启一个画图的窗口进入交互模式,用于实时更新数据
  87. plt.rcParams['figure.figsize'] = (10, 10) # 图像显示大小
  88. plt.rcParams['font.sans-serif'] = ['SimHei'] # 防止中文标签乱码,还有通过导入字体文件的方法
  89. plt.rcParams['axes.unicode_minus'] = False
  90. plt.rcParams['lines.linewidth'] = 0.5 # 设置曲线线条宽度
  91. count = 0
  92. while True:
  93. plt.clf() # 清除刷新前的图表,防止数据量过大消耗内存
  94. plt.suptitle("总标题", fontsize=30) # 添加总标题,并设置文字大小
  95. plt.tight_layout()
  96. # 图表1
  97. agraphic = plt.subplot(2, 1, 1)
  98. agraphic.set_title('子图表标题1') # 添加子标题
  99. agraphic.set_xlabel('x轴', fontsize=10) # 添加轴标签
  100. agraphic.set_ylabel('y轴', fontsize=20)
  101. plt.plot(x_num[1:][-show_num:], acc1[-show_num:], 'g-')
  102. try:
  103. xtricks = list(range(len(acc1) - show_num, len(acc1), 10)) # **1**
  104. xlabels = [stime[i] for i in xtricks] # **2**
  105. plt.xticks(xtricks, xlabels, rotation=15)
  106. except:
  107. pass
  108. # 图表2
  109. bgraghic = plt.subplot(2, 1, 2)
  110. bgraghic.set_title('子图表标题2')
  111. bgraghic.set_xlabel('x轴', fontsize=10) # 添加轴标签
  112. bgraghic.set_ylabel('y轴', fontsize=20)
  113. bgraghic.plot(x_num[1:][-show_num:], acc2[-show_num:], 'r^')
  114. plt.pause(0.001) # 设置暂停时间,太快图表无法正常显示
  115. count = count + 1
  116. if __name__ == '__main__':
  117. # 多线程
  118. _thread.start_new_thread(run, ())
  119. draw_figure()
复制代码

到此这篇关于Python中利用 matplotlib绘制mqtt数据及时 图像的文章就先容 到这了,更多干系 matplotlib绘制mqtt数据及时 图像内容请搜刮 脚本之家从前 的文章或继续欣赏 下面的干系 文章渴望 大家以后多多支持脚本之家!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 工兵班长纬 | 2021-9-25 06:50:22 | 显示全部楼层
我和我的小伙伴都惊呆了!
回复

使用道具 举报

avatar 小珍248 | 2021-9-28 18:58:28 | 显示全部楼层
顶顶更健康!
回复

使用道具 举报

avatar 阿豆学长长ov | 2021-9-29 22:26:57 | 显示全部楼层
今天过得很不爽!
回复

使用道具 举报

avatar HY107 | 2021-10-2 03:35:48 | 显示全部楼层
内容很有深度!
回复

使用道具 举报

avatar Harry192 | 2021-10-7 20:01:13 | 显示全部楼层
信admin楼主,考试不挂科!
回复

使用道具 举报

avatar 湘军 | 2021-10-9 07:17:23 | 显示全部楼层
听admin楼主一席话,省我十本书!
回复

使用道具 举报

avatar 天使798 | 2021-10-9 21:56:13 | 显示全部楼层
以后要跟admin楼主好好学习学习!
回复

使用道具 举报

avatar 败明急总 | 2021-10-11 15:19:38 | 显示全部楼层
很多天不上线,一上线就看到这么给力的帖子!
回复

使用道具 举报

avatar 囝囝刚 | 2021-10-11 15:22:43 | 显示全部楼层
admin楼主该去看心理医生了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则