You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用plt.plot绘制Rigol万用表实时数据仅显散点无连线的问题排查

问题:Matplotlib plt.plot()仅显示散点不连线,plt.scatter()正常工作

我编写了一段从Rigol万用表获取数据并实时更新图表的代码,遇到一个问题:使用plt.plot()时无法显示连线,仅能看到散点(电压变化时数据会同步更新),但换成plt.scatter()就能正常工作。请帮忙排查问题。

代码如下:

import pyvisa as visa
import os
import numpy as np
import time
import matplotlib.pyplot as plt
import datetime 
from time import sleep

rm = visa.ResourceManager()
print('Connected VISA resources:')
rm.list_resources()
print(rm.list_resources())


figure, ax = plt.subplots(figsize=(10, 8))


dmm = rm.open_resource('USB0::0x1AB1::0x09C4::DM3R251100732::INSTR')
print('Instrument ID (IDN:) = ', dmm.query('*IDN?'))
print("Volts DC   = ", dmm.query(":MEASure:VOLTage:DC?"))
print("DC Current = ", dmm.query(":MEASure:CURRent:DC?"))

f = open('iLog.txt','w')
fStr = "Time, DC Current, Raw\n"
f.write(fStr)

print("Poll rate = 500mS. Will run for 24 hours collecting 172,800 readings")
print("output file = iLog.csv\n\n")
print(" Seconds Count    ", "DC Current", "Raw Meter Response", sep="\t|\t")
print("----------------------------------------------------------------------------------")

for x in range(0, 100):
    rawStr = dmm.query(":MEASure:VOLTage:DC?")
    iStr = rawStr
    rawStr = rawStr.replace ("\n", "") 
    iStr = iStr.replace("\n", "")
    iStr = iStr.replace("#9000000015", "")

    iFlt = round(float(iStr),2)
    now = datetime.datetime.now()
    print(now, iFlt ,rawStr, sep="\t|\t")
    fStr = str(now) + "," + str(iFlt) + "," + rawStr + "\n"
    f.write(fStr)

    plt.plot(now,iFlt) # plt.scatter works but not plot
    plt.gcf().autofmt_xdate()

    # figure.canvas.draw()
    # figure.canvas.flush_events()

   
  
    plt.pause(0.05)
    sleep(1)


f.close()
plt.show()

原因分析

plt.plot()默认用于绘制连续折线,但你每次循环只传入单个点的x和y值,它只会在当前坐标绘制一个独立的标记(默认显示为线条端点,但单个点没有可连接的线段),所以看起来和散点一样。而plt.scatter()本身就是专门绘制散点的API,单个点能正常显示。

另外,你直接用datetime.datetime.now()作为x轴数据,每次循环生成的都是独立的时间对象,Matplotlib无法将这些离散的单次调用自动关联成一条连续的线——因为每次调用plt.plot()都是在添加新的独立线条,而非在同一条线上追加数据。


解决方法

  1. 提前初始化两个列表,存储所有时间和电压数据
  2. 每次循环将新采集的时间、电压值追加到列表中
  3. 清空当前坐标轴内容,用完整的数据列表调用plt.plot()绘制连续折线
  4. 保留autofmt_xdate()优化时间轴的显示格式

修改后的代码

import pyvisa as visa
import numpy as np
import matplotlib.pyplot as plt
import datetime 
from time import sleep

rm = visa.ResourceManager()
print('Connected VISA resources:')
print(rm.list_resources())

figure, ax = plt.subplots(figsize=(10, 8))
# 初始化存储数据的列表
times = []
voltages = []

dmm = rm.open_resource('USB0::0x1AB1::0x09C4::DM3R251100732::INSTR')
print('Instrument ID (IDN:) = ', dmm.query('*IDN?'))
print("Volts DC   = ", dmm.query(":MEASure:VOLTage:DC?"))
print("DC Current = ", dmm.query(":MEASure:CURRent:DC?"))

f = open('iLog.txt','w')
fStr = "Time, DC Current, Raw\n"
f.write(fStr)

print("Poll rate = 500mS. Will run for 24 hours collecting 172,800 readings")
print("output file = iLog.csv\n\n")
print(" Seconds Count    ", "DC Current", "Raw Meter Response", sep="\t|\t")
print("----------------------------------------------------------------------------------")

for x in range(0, 100):
    rawStr = dmm.query(":MEASure:VOLTage:DC?")
    iStr = rawStr.replace("\n", "").replace("#9000000015", "")
    rawStr = rawStr.replace("\n", "")

    iFlt = round(float(iStr),2)
    now = datetime.datetime.now()
    print(now, iFlt ,rawStr, sep="\t|\t")
    fStr = str(now) + "," + str(iFlt) + "," + rawStr + "\n"
    f.write(fStr)

    # 将新数据追加到列表
    times.append(now)
    voltages.append(iFlt)

    # 清空轴内容,重新绘制完整折线
    ax.clear()
    ax.plot(times, voltages)
    plt.gcf().autofmt_xdate()

    plt.pause(0.05)
    sleep(1)

f.close()
plt.show()

额外优化建议

  • 可以添加ax.set_xlabel('时间')、ax.set_ylabel('直流电压(V)')、ax.set_title('Rigol万用表实时电压监测')来完善图表标注
  • 如果担心频繁clear()和重绘的性能,可以改用更新线条数据的方式,避免清空整个坐标轴:
    # 初始化时创建线条对象
    line, = ax.plot([], [], '-')
    # 循环内更新数据
    line.set_data(times, voltages)
    ax.relim()
    ax.autoscale_view()
    

这种方式效率更高,适合长时间的实时监测场景。

内容的提问来源于stack exchange,提问作者Shahreza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:43:12