6

What application do you use for creating plots?

Years ago, I was using gnuplot and then matplotlib (which is just Python library). But none of those were perfect. For example, I was unable to create Smith chart in gnuplot or two Y axes in one plot. And matplotlib is too unfriendly, everything takes hours of reading documentation (but result is very nice and professional).

So is there any other good application for electronic engineers? GUI or CLI.

Note: I am using Mac/Linux and I do not have Matlab license.

vasco
  • 957
  • 2
  • 15
  • 25
  • I use matplotlib a fair bit, and I find that it's only really confusing at the outset. Go through the docs, and spend a bit of time tinkering, and everything begins to make sense. There *is* an internal structure and language, it's just not very well documented. – Connor Wolf Nov 29 '12 at 10:57
  • 1
    More critically, *go through the **examples***. They're much more useful and educational then the docs. – Connor Wolf Nov 29 '12 at 10:58
  • There are a lot of matlab or mathematica like tools. E.g. octave. Just browse through the filtered package list of your favourite distribution. – Ariser Apr 26 '20 at 05:17

4 Answers4

5

My favourite free maths software is Scilab - it's numerical and matrix based like Matlab, so if you know Matlab you should have little trouble getting started with it. It has a thing called Xcos which is like Simulink, and various modules you can add on.

The downside is the documentation is pretty rubbish, but there are plenty of tutorials out there if you do some Googling. Plotting is done with Gnuplot plus another option I can't remember the name of. It supports Latex, and can convert (Matlab) M files to Scilab scripts.

Smith chart in scilab (very basic version)

Scilab smith chart

More examples of plotting in Scilab (vector, contour, bode, 3d, etc)

On the CAS side, I love Maxima (the wxMaxima version), it's great to use side by side with Scilab (or Matlab) Even though you can do symbolic stuff in Matlab/Scilab, it's so much faster in Maxima, and all the output is in Latex/Mathjax format, so stuff looks nice. It's workbook format, so you can add titles, section headers, and embed your plots (or other images) into the workbook too.

Example of ODE direction field plot in Maxima, with slider so you can adjust the amount of drag (the plot is of a free falling object m=10kg, drag = 2kg/s)

Maxima DF plot

Euler is worth looking at too, and if you are on linux there is Sage, which is gathering quite a reputation (I'm on windows so it's too much of a pain to use a VM, although I tried it and liked the look of it, but I have all I need with the above mentioned tools)

Oli Glaser
  • 54,990
  • 3
  • 76
  • 147
  • You are right. Documentation is pretty bad. But on the other hand, it can work with complex numbers, plots can be exported into vector graphics, it is possible to import CSV... the smith chart is very complicated, but it is possible to make it. – vasco Dec 09 '12 at 21:04
2

I've used Octave professionally after having used Matlab. Octave is very compatible with Matlab and it's very easy to use. Here is some info on Smith Charts in Octave:

http://rf.helpingcreate.com/cgi-bin/octave.pl
Gustavo Litovsky
  • 7,619
  • 3
  • 25
  • 44
  • I used Octave, but it uses gnuplot for plots. So polar (smith) charts are almost impossible. And for Mac OS, I cannot compile it from source. – vasco Dec 09 '12 at 21:05
  • The link I provided is about a package of software to specifically create smith charts. It is possible (even if it not always natively supported). – Gustavo Litovsky Dec 10 '12 at 16:04
  • Sorry, I did not see your link. Those scripts are very usefull! The Smith chart can be done by running `scCreate;`. There is even script for microstrip width. Thank you. – vasco Dec 16 '12 at 13:26
1

I wrote a gnuplot script that generates Smith Charts. The circles are a little sparse, but you can add more if needed. If you want to get really wild and crazy, there are even routines to draw circular arcs along constant X or constant R circles so you add more gridlines on part of the chart, or make the "grid circles" less dense in places. I also included some funcitons for annotating impedance (and admittance) on the charts. Here is the script...

# Smith Chart Plotting Tools
# Written By: Jess Stuart  4/21/2020
# Tested with gnuplot 5.2 patchlevel 6

reset
# Control Variables
chartType = 1  # 0=blank, 1=impedance, 2=admittance, 3=immitance
ZAxisLabels = 1  # controls if axis labels are printed or not. 1=true, 0=false.
YAxisLabels = 1  # controls if axis labels are printed or not. 1=true, 0=false.

set clip points
set parametric # t is gnuplot's default single parametric variable
set samples 500 # affects circle smoothness
unset key
set style increment default
set size ratio 1 1,1
set style data lines 
unset border
set trange [0:pi/2] noreverse nowriteback  # tan(t) goes from 0 to +inf
set xrange [-1.1:1.1] noreverse nowriteback
set yrange [-1.1:1.1] noreverse nowriteback
unset xtics
unset ytics

# Linear Map t to something else
LM(t,S,E)=2*(E-S)*t/pi + S  # t goes from 0 to pi/2
# Pertibation Function (causes parametric plot to draw a point without using a         "point"; useful for debugging)
e(t)= t*{0.002,0.002}
# Evaluate String Expressions!!!
# usage:
# 1. store value to t. (Ex. t=0.5)
# 2. eval(wrapper(strExp)) assigns outVal the value of the string expression     evaluated at t.
# 3. use outVal in whatever calculation you wanted (Ex. setting label text)
wrapper(strExp)=sprintf("outVal=%s",strExp)

# Simplify parametric plotting on the complex plane. Must use eval() on returned string.
plot_complex(s,a) = sprintf("plot real(%s),imag(%s) %s",s,s,a)
replot_complex(s,a)= sprintf("replot real(%s),imag(%s) %s",s,s,a)

#constant value circle plotting
conValCirs(i,Start,End,s,a) = sprintf("replot for [%s=%d:%d] real(%s),imag(%s) %s",i,Start,End,s,s,a)

# Complex Parametric Circle Function 
CIRCLE(t,r,xc,yc)=r*(cos(t)+{0,1}*sin(t)) + xc + {0,1}*yc

#"set angles degrees" will mess up tan(t) used to draw the constant R, constant X circles
# Use these functions to convert from degrees to radians or plot polar data that uses
# angles in degrees.
DEG2RAD(d)= d*pi/180
POL2X(r,d)=r*cos(d*pi/180)
POL2Y(r,d)=r*sin(d*pi/180)

# Complex Reflection Coefficient Functions
Z2RC(z)=((z)-1)/((z)+1) #impedance to reflection coefficient
Y2RC(y)=(1-(y))/((y)+1) #admittance to reflection coefficient
sZ2RC(z)=sprintf("((%s)-1)/((%s)+1)",z,z) # string version
sY2RC(y)=sprintf("(1-(%s))/((%s)+1)",y,y) # string version

# Constant Resistance or Reactance Circular Arc Functions
RARC(t,R,X1,X2,a)=sprintf("replot real(Z2RC(t*(%s)/t+{0,1}*LM(t,%s,%s))),imag(Z2RC(t*(%s)/t+{0,1}*LM(t,%s,%s))) %s",R,X1,X2,R,X1,X2,a)
XARC(t,X,R1,R2,a)=sprintf("replot real(Z2RC(LM(t,%s,%s)+{0,1}*t*(%s)/t)),imag(Z2RC(LM(t,%s,%s)+{0,1}*t*(%s)/t)) %s",R1,R2,X,R1,R2,X,a)
GARC(t,G,B1,B2,a)=sprintf("replot real(Y2RC(t*(%s)/t+{0,1}*LM(t,%s,%s))),imag(Y2RC(t*(%s)/t+{0,1}*LM(t,%s,%s))) %s",G,B1,B2,G,B1,B2,a)
BARC(t,B,G1,G2,a)=sprintf("replot real(Y2RC(LM(t,%s,%s)+{0,1}*t*(%s)/t)),imag(Y2RC(LM(t,%s,%s)+{0,1}*t*(%s)/t)) %s",G1,G2,B,G1,G2,B,a)

# Combine an impedance(admittance) with a parallel(series) admittance(impedance).      Returns a calculation string for impedance(admittance).
INVADDINV(A,B)=sprintf("1/(1/(%s)+(%s))",A,B)  

# convert impedance(admittance) to admittance(impedance)    
FLIP(U)=sprintf("t*1.0/((%s)*t)",U)

# Calculate radius of a SWR circle
SWR2RADIUS(swr)=(swr-1)/(swr+1)

# Constant Circle Values: Array length must match indexing variable range in plot statements

# Impedance Chart
array Xvals[17] = [-10.0,-5.0,-2.5,-1.5,-1.0,-0.7,-0.4,-0.2,\
                     0.0,\
                    10.0, 5.0, 2.5, 1.5, 1.0, 0.7, 0.4, 0.2,]
array Rvals[7] = [0.0,0.2,0.5,1.0,2.0,4.0,10.0] 
# Admittance Chart
array Bvals[17] = [-10.0,-5.0,-2.5,-1.5,-1.0,-0.7,-0.4,-0.2,\
                     0.0,\
                    10.0, 5.0, 2.5, 1.5, 1.0, 0.7, 0.4, 0.2,]
array Gvals[7] = [0.0,0.2,0.5,1.0,2.0,4.0,10.0]

# Styles used for plots
set style line 1 lw 1 lc rgb "black"  # Impedance (Z)
set style line 2 lw 1 lc rgb "red"  # Admittance (Y)
set style line 3 lw 1 lc rgb "#008000" # dark green  
set style line 4 lw 2 lc rgb "blue" #use for ploting frequency response
set style line 5 lw 2 lc rgb "magenta" # second frequency response 
set style line 6 lw 2 lc rgb "cyan" # third frequency response 

# Axis labels on Smith Chart
XCIR_LABEL(X,a)=sprintf("set label \"%.1f\" at %f,%f %s", X, 1.05*(X*X-1)/(X*X+1),1.05*2*X/(X*X+1),a )
RCIR_LABEL(R,a)=sprintf("set label \"%.1f\" at %f,%f %s", R, (R-1)/(R+1),0.05,a)
BCIR_LABEL(B,a)=sprintf("set label \"%.1f\" at %f,%f %s", B, -1.05*(B*B-1)/(B*B+1),-1.05*2*B/(B*B+1),a )
GCIR_LABEL(G,a)=sprintf("set label \"%.1f\" at %f,%f %s", G, -(G-1)/(G+1),0.05,a)

# Useful for Annotating Plots. 
Z_MARKER(indx,Z,str,a) = sprintf("set label %s \"z=%.2f%sj%.2f\ %s\" at %f,%f point ls 1 pt 5 offset 0.4,-0.4 tc ls 1 %s",\
                        indx, real(Z),((sgn(imag(Z))==1)?"+":"-"),abs(imag(Z)),\
                        str, real(((Z)-1)/((Z)+1)),imag(((Z)-1)/((Z)+1)),a)
Y_MARKER(indx,Y,str,a) = sprintf("set label %s \"y=%.2f%sj%.2f\ %s\" at %f,%f point ls 2 pt 5 offset 0.4,-0.4 tc ls 2 %s",\
                indx, real(Y),((sgn(imag(Y))==1)?"+":"-"),abs(imag(Y)),\
                str, real((1-(Y))/(1+(Y))),imag((1-(Y))/(1+(Y))),a)
RC_MARKER(indx,S,str,a)= sprintf("set label %s \"{/Symbol G}=%.2f%sj%.2f\ %s\" at %f,%f point ls 3 pt 5 offset 0.4,-0.4 tc ls 3 %s",\
                indx, real(S),((sgn(imag(S))==1)?"+":"-"),abs(imag(S)),\
                str, real(S),imag(S),a)
TEXT_LABEL(indx,S,str,a) = sprintf("set label %s \"%s\" at real(%s),imag(%s) %s",indx,str,S,S,a) # plot text on the complex-plane

if (chartType==0){
    set title "Blank Smith Chart" tc rgb "gray"
}
if (chartType==1){
set title "Normalized Impedance Smith Chart" tc ls 1
}
if (chartType==2){
    set title "Normalized Admittance Smith Chart" tc ls 2
}
if (chartType==3){
    set title "Normalized Immitance Smith Chart" black
}

plot 0,0 black  # create a plot to get started
# Blank (Useful for debugging plotting commands)
if (chartType==0) {
    eval(replot_complex("CIRCLE(4*t,1,0,0)","black"))
}
# Impedance Chart Part
if ((chartType==1) || (chartType==3)) {
    eval(conValCirs("i",1,|Rvals|,"Z2RC(Rvals[i]+{0,1}*tan(2*t))","ls 1"))     #tan(2t) => 0 to +inf to -inf to 0
    eval(conValCirs("i",1,|Xvals|,"Z2RC(tan(t)+{0,1}*Xvals[i])","ls 1"))
    # Labels
    if (ZAxisLabels!=0){
        do for [i=1:|Rvals|] {
         eval(RCIR_LABEL(Rvals[i],"center tc rgb \"black\""))
         }
        do for [i=1:|Xvals|] {
        eval(XCIR_LABEL(Xvals[i],"center tc rgb \"black\""))
        }
    }
}
# Admittance Chart Part
if ((chartType==2) || (chartType==3)) {
    eval(conValCirs("i",1,|Gvals|,"Y2RC(Gvals[i]+{0,1}*tan(2*t))","ls 2")) # tan(2t) 0 to +inf to -inf to 0
    eval(conValCirs("i",1,|Bvals|,"Y2RC(tan(t)+{0,1}*Bvals[i])","ls 2")) 
    # Labels
    if (YAxisLabels!=0){
        do for [i=1:|Gvals|] {
        eval(GCIR_LABEL(Gvals[i],"center tc rgb \"red\""))
        }
        do for [i=1:|Bvals|] {
        eval(BCIR_LABEL(Bvals[i],"center tc rgb \"red\""))
        }
    }
}
if ((chartType!=0) && (chartType!=1) && (chartType!=2) && (chartType!=3)) {
    print("Unknown chartType.")
 }
#########################################
###### PLOT DATA HERE WITH REPLOT ######

# replot...
refresh #draw the labels
############################################
############################################
## Ex. Constant SWR Circle
#eval(replot_complex("CIRCLE(4*t,SWR2RADIUS(3.0),0,0)","ls 3")) 
#############################################
#############################################
##Ex. Parallel RLC circut impedance
#Z0=50 #Characteristic Impedance 
#f1=1e7
#w1=2*pi*f1
#f2=1e9
#w2=2*pi*f2
#R1(t)=t*40/t  # 32 ohm, "Vectorize" R by multiplying and dividing by parameter t.
#C1=3.3e-11 # 33 pF
#L1=1.8e-7 # 180 nH
#Y1(t)=Z0*(1/R1(t) + {0,1}*(LM(t,w1,w2)*C1 - 1/(LM(t,w1,w2)*L1) ) ) #Normalized    
#eval(replot_complex("Y2RC(Y1(t))","ls 4"))
#R2(t)=t*60/t  # 32 ohm, "Vectorize" R by multiplying and dividing by parameter t.
#C2=8.0e-11 # 80 pF
#L2=2.7e-7 # 180 nH
#Y2(t)=Z0*(1/R2(t) + {0,1}*(LM(t,w1,w2)*C2 - 1/(LM(t,w1,w2)*L2) ) ) #Normalized    
#eval(replot_complex("Y2RC(Y2(t))","ls 5"))
##############################################
##############################################
##Ex. Impedance Matching Network Smith-Chart Trajectories
#Cc=10e-12 # 10pF
#Ls=4.2e-9 #6nH
#Cp=4.7e-12 #4.7pF
##50 ohm characteristic impedance (adjust constants as necessary)
## helper functions with constants combined (needs parameter t)
## Build up Nested string expressions (to create a self-contained demo).
## Use a program to write columns to a datafile, then plot the
## data with gnuplot; Nested calculations inside gnuplot are cumbersome!
#Xc(f,C)=sprintf("t*{0,-0.00318310}/((%e)*(%e)*t)",f,C)  # -1/(2*pi*50)
#Xl(f,L)=sprintf("t*{0, 0.125664}*(%e)*(%e)/t",f,L) # 2*pi/50
#Bc(f,C)=sprintf("t*{0, 314.159}*(%e)*(%e)/t",f,C) # 2*pi*50
#Bl(f,L)=sprintf("t*{0,-7.95775}/(%e)*(%e)*t)",f,L) # -50/(2*pi)
#array freqs[3]=[1.70e9, 1.75e9, 1.80e9]
#do for[j=1:|freqs|] {
#    Yload=sprintf("t*50/(160*t)+(%s)",Bc(freqs[j],3e-12)) # load = (160ohm || 3pF)
#    Zload=FLIP(Yload)
#    Z1=sprintf("(%s)+(%s)", Zload, Xl(freqs[j],Ls)) #add series inductance
#    Y1=FLIP(Z1)  # used to plot constant conductance curve
#    Z2=INVADDINV(Z1,Bc(freqs[j],Cp)) # add shunt capacitance
#    Y2=FLIP(Z2)
#    Z3=sprintf("(%s)+(%s)", Z2, Xc(freqs[j],Cc)) # add series capitance   (coupling)
#    eval(RARC(t,"real(".Zload.")","imag(".Zload.")","imag(".Z1.")",sprintf("lw 3 lc %d",j)))
#    eval(GARC(t,"real(".Y1.")","imag(".Y1.")","imag(".Y2.")",sprintf("lw 3 lc %d",j)))
#    eval(RARC(t,"real(".Z2.")","imag(".Z2.")","imag(".Z3.")",sprintf("lw 3 lc %d",j)))
#    t=pi/2 #end value of sweep
#    eval(wrapper(Z3)) # evaluates at t, and assigns value to outVal.
#    eval(Z_MARKER("",outVal,"","")) 
# }  #loop
#refresh #draws last label
#######################################################
#######################################################
## label tests
#eval(Z_MARKER("",{0,0},"",""))
#eval(Y_MARKER("",{0,0},"",""))
#eval(RC_MARKER("",{0,0},"",""))
#eval(TEXT_LABEL("","{-0.24,0.77}","test","point ls 4 pt 5 offset 0.4,0.4 tc ls 4 "))
#refresh
#######################################################
0

I use LaTeX and tikz, there is nothing you can not do with it:

https://tex.stackexchange.com/questions/304026/adding-wavelength-co-ordinates-to-pgfplots-smith-chart/304032

The same library can be used for circuit diagrams, also.

Vesa Linja-aho
  • 271
  • 2
  • 7