Pylogix and Matplotlib

Taylor Turner

Member
Join Date
Sep 2020
Location
Midwest
Posts
78
I am not the best in python...
"What is a library?" Said structured text.


I am trying to make a simple plot by grabbing tag values from pylogix to y-axis data for pyplot.
I was hoping to store the tag values in an array in python and not the PLC by indexing a delayed for loop.


I have used excel and VB to DDERequest into incrementing rows but I don't trust the timing and it's not fast enough.


Here is some embarrassing python. The indirect addressing is incorrect and the data type for the plot must be a float() and not a "result." Initially I intended the plot being live but if more simple, defining a data set, then displaying the plot would be great too now that I'm thinking about it.


Code:
[COLOR=#d4d4d4][FONT=Consolas][COLOR=#569cd6]from[/COLOR][COLOR=#d4d4d4] pylogix [/COLOR][COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] PLC[/COLOR]
[COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] matplotlib.pyplot [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] plt[/COLOR]
[COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] numpy [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] np[/COLOR]

[COLOR=#d4d4d4]comm = PLC()[/COLOR]
[COLOR=#d4d4d4]comm.IPAddress = [/COLOR][COLOR=#ce9178]'255.255.255.255'[/COLOR]
[COLOR=#d4d4d4]comm.ProcessorSlot = [/COLOR][COLOR=#b5cea8]0[/COLOR]

[COLOR=#6a9955]#Read single tag[/COLOR]
[COLOR=#d4d4d4]rTag = comm.Read([/COLOR][COLOR=#ce9178]'rTag'[/COLOR][COLOR=#d4d4d4])[/COLOR]

[COLOR=#569cd6]for[/COLOR][COLOR=#d4d4d4] i [/COLOR][COLOR=#569cd6]in[/COLOR][COLOR=#d4d4d4] range([/COLOR][COLOR=#b5cea8]100[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]    xpoints = (i)[/COLOR]
[COLOR=#d4d4d4]    ypoints[i] = rTag[/COLOR]
[COLOR=#d4d4d4]    plt.plot(xpoints, ypoints[i])[/COLOR]
[COLOR=#d4d4d4]    plt.show()[/COLOR]
[COLOR=#d4d4d4]    plt.pause([/COLOR][COLOR=#b5cea8]0.1[/COLOR][COLOR=#d4d4d4])[/COLOR]
[/FONT][/COLOR]
 
That can't be your PLC's IP address. It looks to me like you read the tag once, then plot the same point 100 times. I've never used matplotlib, I'll kick the tires on it. Though there are probably people around here that have used it (drbitboy), they may chime in first.

Is the tag rTag in your PLC an array of data?
 
A library is a package of various modules that include different functions etc, depending on what you're wanting to do. For instance, numpy could be considered a library.
 
I think this does what you are asking Taylor:

Edit: This will read the tag 100 times with a 100ms delay between each read. After 100 reads, plot the data.

Code:
import time
from pylogix import PLC
import matplotlib.pyplot as plt
import numpy as np

iterations = 100
# generate our x points
xpoints = [i for i in range(iterations)]
# make an empty list for our y points
ypoints = []

# connect to the PLC, read 100 times
with PLC("192.168.1.9") as comm:
    for i in range(iterations):
        # read the tag
        ret = comm.Read("rTag")
        # add the result to our ypoints list
        ypoints.append(float(ret.Value))
        # pause
        time.sleep(0.1)

# plog our points
plt.plot(xpoints, ypoints)
plt.show()
 
Last edited:
dmroeder, thank you for the timely response!
That works like a charm. I tried .append at a point in time. Good to know how it was needing to be formatted.


I added a sample rate to give the x-axis more meaning.

Code:
[COLOR=#d4d4d4][FONT=Consolas][COLOR=#d4d4d4]sample = [/COLOR][COLOR=#b5cea8].005[/COLOR]
[COLOR=#6a9955]# generate our x points[/COLOR]
[COLOR=#d4d4d4]xpoints = [i*sample [/COLOR][COLOR=#569cd6]for[/COLOR][COLOR=#d4d4d4] i [/COLOR][COLOR=#569cd6]in[/COLOR][COLOR=#d4d4d4] range(iterations)][/COLOR]
[COLOR=#d4d4d4]
[/COLOR]
[COLOR=#d4d4d4][FONT=Consolas][COLOR=#6a9955]# pause[/COLOR]
[COLOR=#d4d4d4]        time.sleep(sample)[/COLOR]
[/FONT][/COLOR]
[COLOR=#d4d4d4][/COLOR]
[/FONT][/COLOR]


Next step, It'd be nice to constrain the y value in the GUI as ypoints at x.
 
Thanks Peter!
Small detail, but the dotted actual for the step response is slick.


Is there a py module that reads from the delta? Not that the plots can get much better in Tools. I have a job I'm about to walk out to that has a 151 and a 75 strapped to it. Customer didn't know what a 200 was and wanted their own stand alone 75 for an axis... I can only do so much.
 
Oh, I wasn't sure if the picture had attached properly.


Additionally, I am running into a runtime error on that x axis (t). The blue is actually a one second timer .ACC value coming from the plc. The x values need to be iterated in the same loop as the y values.


Code:
[COLOR=#d4d4d4][FONT=Consolas][COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] time[/COLOR]
[COLOR=#569cd6]from[/COLOR][COLOR=#d4d4d4] pylogix [/COLOR][COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] PLC[/COLOR]
[COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] matplotlib.widgets [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] widgets[/COLOR]
[COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] matplotlib.pyplot [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] plt[/COLOR]
[COLOR=#569cd6]import[/COLOR][COLOR=#d4d4d4] numpy [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] np[/COLOR]

[COLOR=#6a9955]#Init[/COLOR]
[COLOR=#d4d4d4]iterations = [/COLOR][COLOR=#b5cea8]200[/COLOR]
[COLOR=#d4d4d4]sample = [/COLOR][COLOR=#b5cea8].01[/COLOR]
[COLOR=#6a9955]# generate our x points[/COLOR]
[COLOR=#d4d4d4]xpoints = [i*sample [/COLOR][COLOR=#569cd6]for[/COLOR][COLOR=#d4d4d4] i [/COLOR][COLOR=#569cd6]in[/COLOR][COLOR=#d4d4d4] range(iterations)][/COLOR]
[COLOR=#6a9955]# make an empty list for our y points[/COLOR]
[COLOR=#d4d4d4]ypoints1 = [][/COLOR]
[COLOR=#d4d4d4]ypoints2 = [][/COLOR]

[COLOR=#6a9955]#PLC[/COLOR]
[COLOR=#569cd6]with[/COLOR][COLOR=#d4d4d4] PLC([/COLOR][COLOR=#ce9178]"255.255.255.255"[/COLOR][COLOR=#d4d4d4]) [/COLOR][COLOR=#569cd6]as[/COLOR][COLOR=#d4d4d4] comm:[/COLOR]
[COLOR=#569cd6]for[/COLOR][COLOR=#d4d4d4] i [/COLOR][COLOR=#569cd6]in[/COLOR][COLOR=#d4d4d4] range(iterations):[/COLOR]
[COLOR=#6a9955]# read the tag[/COLOR]
[COLOR=#d4d4d4]        ret1 = comm.Read([/COLOR][COLOR=#ce9178]"rsin"[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]        ret2 = comm.Read([/COLOR][COLOR=#ce9178]"iiTest"[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#6a9955]# add the result to our ypoints list[/COLOR]
[COLOR=#d4d4d4]        ypoints1.append(float(ret1.Value))[/COLOR]
[COLOR=#d4d4d4]        ypoints2.append(float(ret2.Value))[/COLOR]
[COLOR=#6a9955]# pause[/COLOR]
[COLOR=#d4d4d4]        time.sleep(sample)[/COLOR]

[COLOR=#6a9955]#Cursor[/COLOR]
[COLOR=#569cd6]class[/COLOR][COLOR=#d4d4d4] SnaptoCursor(object):[/COLOR]
[COLOR=#569cd6]def[/COLOR][COLOR=#d4d4d4] __init__(self, ax, x, y):[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].ax = ax[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].ly = ax.axvline(color=[/COLOR][COLOR=#ce9178]'k'[/COLOR][COLOR=#d4d4d4], alpha=[/COLOR][COLOR=#b5cea8]0.2[/COLOR][COLOR=#d4d4d4])  [/COLOR][COLOR=#6a9955]# the vert line[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].marker, = ax.plot([[/COLOR][COLOR=#b5cea8]0[/COLOR][COLOR=#d4d4d4]],[[/COLOR][COLOR=#b5cea8]0[/COLOR][COLOR=#d4d4d4]], marker=[/COLOR][COLOR=#ce9178]"."[/COLOR][COLOR=#d4d4d4], color=[/COLOR][COLOR=#ce9178]"crimson"[/COLOR][COLOR=#d4d4d4], zorder=[/COLOR][COLOR=#b5cea8]3[/COLOR][COLOR=#d4d4d4]) [/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].x = x[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].y = y[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].txt = ax.text([/COLOR][COLOR=#b5cea8]0.7[/COLOR][COLOR=#d4d4d4], [/COLOR][COLOR=#b5cea8]0.9[/COLOR][COLOR=#d4d4d4], [/COLOR][COLOR=#ce9178]''[/COLOR][COLOR=#d4d4d4])[/COLOR]

[COLOR=#569cd6]def[/COLOR][COLOR=#d4d4d4] mouse_move(self, event):[/COLOR]
[COLOR=#569cd6]if[/COLOR][COLOR=#569cd6]not[/COLOR][COLOR=#d4d4d4] event.inaxes: [/COLOR][COLOR=#569cd6]return[/COLOR]
[COLOR=#d4d4d4]        x, y = event.xdata, event.ydata[/COLOR]
[COLOR=#d4d4d4]        indx = np.searchsorted([/COLOR][COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].x, [x])[[/COLOR][COLOR=#b5cea8]0[/COLOR][COLOR=#d4d4d4]][/COLOR]
[COLOR=#d4d4d4]        x = [/COLOR][COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].x[indx][/COLOR]
[COLOR=#d4d4d4]        y = [/COLOR][COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].y[indx][/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].ly.set_xdata(x)[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].marker.set_data([x],[y])[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].txt.set_text([/COLOR][COLOR=#ce9178]' y=%1.4f,\n x=%1.4f'[/COLOR][COLOR=#d4d4d4] % (y, x))[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].txt.set_size([/COLOR][COLOR=#ce9178]'x-small'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].txt.set_position((x,y))[/COLOR]
[COLOR=#569cd6]self[/COLOR][COLOR=#d4d4d4].ax.figure.canvas.draw_idle()[/COLOR]

[COLOR=#d4d4d4]fig, ax = plt.subplots()[/COLOR]
[COLOR=#d4d4d4]cursor1 = SnaptoCursor(ax, xpoints, ypoints1)[/COLOR]
[COLOR=#d4d4d4]cid =  plt.connect([/COLOR][COLOR=#ce9178]'motion_notify_event'[/COLOR][COLOR=#d4d4d4], cursor1.mouse_move)[/COLOR]
[COLOR=#d4d4d4]cursor2 = SnaptoCursor(ax, xpoints, ypoints2)[/COLOR]
[COLOR=#d4d4d4]cid =  plt.connect([/COLOR][COLOR=#ce9178]'motion_notify_event'[/COLOR][COLOR=#d4d4d4], cursor2.mouse_move)[/COLOR]

[COLOR=#6a9955]#Plot[/COLOR]
[COLOR=#d4d4d4]plt.figure([/COLOR][COLOR=#b5cea8]1[/COLOR][COLOR=#d4d4d4],figsize=([/COLOR][COLOR=#b5cea8]10[/COLOR][COLOR=#d4d4d4],[/COLOR][COLOR=#b5cea8]4[/COLOR][COLOR=#d4d4d4]))            [/COLOR][COLOR=#6a9955]# x and y size[/COLOR]
[COLOR=#d4d4d4]plt.plot(xpoints, ypoints1, [/COLOR][COLOR=#ce9178]'c-'[/COLOR][COLOR=#d4d4d4], label=[/COLOR][COLOR=#ce9178]'target position'[/COLOR][COLOR=#d4d4d4] )[/COLOR]
[COLOR=#d4d4d4]plt.plot(xpoints, ypoints2 ,[/COLOR][COLOR=#ce9178]'r--'[/COLOR][COLOR=#d4d4d4], label=[/COLOR][COLOR=#ce9178]'actual position'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.title([/COLOR][COLOR=#ce9178]'Title'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.xlabel([/COLOR][COLOR=#ce9178]'time, s'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.ylabel([/COLOR][COLOR=#ce9178]'Position'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.legend(loc=[/COLOR][COLOR=#ce9178]'best'[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.legend(fontsize=[/COLOR][COLOR=#b5cea8]10[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.grid([/COLOR][COLOR=#569cd6]True[/COLOR][COLOR=#d4d4d4])[/COLOR]
[COLOR=#d4d4d4]plt.show()[/COLOR]
[/FONT][/COLOR]
 
Last edited:
Sometimes it's not because it's a good idea, but it's because we can ;)

import sys
from time import sleep
from pylogix import PLC
import matplotlib.pyplot as plt

### --argval= --argopt command-line argument parser
getarg = lambda default,prefix: (
[default]
+[type(default)(arg[len(prefix):])
for arg in sys.argv[2:]
if arg.startswith(prefix)
]
).pop()

### Parse command line
not_micro8xx = getarg(False,'--no-micro8xx=')
ip = getarg('192.168.1.160','--ip=')
step = getarg(0.628,'--step=')
samples = getarg(int(10),'--samples=')

### Generator method to sample data
def getpair(comm,step,count):
xpoint = 0.0
while count>-1:
yield xpoint,comm.Read("_IO_EM_AI_00").Value
sleep(step)
xpoint += step
count -= 1

### Sample, then plot, then show, the data
with PLC(ip) as comm:
comm.Micro800 = not not_micro8xx
plt.plot(*zip(*getpair(comm,step,samples)))
plt.show()


 

Similar Topics

Hey everyone, I am looking for a tool to parse PLC data and I believe pylogix may be the best approach. I am very new with python but can see its...
Replies
1
Views
813
Can I not access locally defined UDT data? Scope.. Task>Prog1>Parameters and Local Tags(Test1 = real)(UTD.Test2 = real) #To access the local...
Replies
10
Views
1,451
If anyone is interested, I have an experimental branch on github that adds an “adapter” module to pylogix, which will allow you to interface to a...
Replies
1
Views
1,132
I am trying to use pylogix to write to a string array ID_Data_Table_Name. In the array there are 200 possible entries. For...
Replies
13
Views
3,991
I'm currently working with pylogix and have no trouble reading and writing tags. My problem is, I would like to be able to read (and write) I/O...
Replies
5
Views
3,660
Back
Top Bottom