SignalTables.SilentNoPlot.closeAllFigures
— FunctioncloseAllFigures()
Close all figures.
SignalTables.SilentNoPlot.closeFigure
— FunctioncloseFigure(figure)
Close figure
.
SignalTables.SilentNoPlot.plot
— Methodplot(signalTable, names;
heading = "", grid = true, xAxis = nothing,
figure = 1, prefix = "", reuse = false, maxLegend = 10,
minXaxisTickLabels = false,
MonteCarloAsArea = true)
Generate plots of selected signals of a signal table using the plot package defined with [@usePlotPackage
]@ref(xxx)
. Possible values for xxx
: "GLMakie", "WGLMakie", "CairoMakie", "PyPlot", "SilentNoPlot"
).
signalTable
is an instance of a type that supports the Abstract Signal Table Interface.
Argument names
defines the diagrams to be drawn and the signals to be included in the respective diagram:
If
names
is a String, generate one diagram with one time series of the variable with keynames
.If
names
is a Tuple of Strings, generate one diagram with the time series of the variables with the keys given in the tuple.If names is a Vector or a Matrix of Strings and/or Tuples, generate a vector or matrix of diagrams.
Note, the names (and their units, if available in the signals) are automatically used as legends in the respective diagram.
A signal variable identified by a String
key can be a scalar of type <:Number
or an array of element type <:Number
. A signal is defined by a vector of time values, a corresponding vector of signal values, and the signal type (continuous or clocked).
Note, before passing data to the plot package, it is converted to Float64. This allows to, for example, also plot rational numbers, even if not supported by the plot package. Measurements.Measurement{xxx}
and MonteCarloMeasurements
is specially handled.
Optional Arguments
heading::AbstractString
: Optional heading above the diagram.grid::Bool
: = true, to display a grid.xAxis::Union{AbstractString,Nothing}
: Name of x-axis. IfxAxis=nothing
, the independent variable of the signal table (usually"time"
is used as x-axis.figure::Int
: Integer identifier of the window in which the diagrams shall be drawn.prefix::AbstractString
: String that is appended in front of every legend label (useful especially ifreuse=true
).reuse::Bool
: If figure already exists and reuse=false, clear the figure before adding the plot. Otherwise, include the plot in the existing figure without removing the curves present in the figure.reuse = true
is ignored for"WGLMakie"
(because not supported).maxLegend::Int
: If the number of legend entries in one plot command> maxLegend
, the legend is suppressed. All curves have still their names as labels. In PyPlot, the curves can be inspected by their names by clicking in the toolbar of the plot on buttonEdit axis, curve ..
and then onCurves
.minXaxisTickLabels::Bool
: = true, if xaxis tick labels shall be removed in a vector or array of plots, if not the last row (useful when including plots in a document). = false, x axis tick labels are always shown (useful when interactively zooming into a plot).MonteCarloAsArea::Bool
: = true, if MonteCarloMeasurements values are shown with the mean value and the area between the minimum and the maximum value of all particles. = false, if all particles of MonteCarloMeasurements values are shown (e.g. if a value has 2000 particles, then 2000 curves are shown in the diagram).
Examples
using SignalTables
using Unitful
# Generate "using xxx" statement
# (where "xxx" is from a previous SignalTables.usePlotPackage("xxx"))
@usingPlotPackage
# Construct result data
t = range(0.0, stop=10.0, length=100);
result = Dict{String,Any}();
result["time"] = t*u"s";
result["phi"] = sin.(t)*u"rad";
result["w"] = cos.(t)*u"rad/s";
result["a"] = 1.2*sin.(t)*u"rad/s^2";
result["r"] = hcat(0.4 * cos.(t), 0.5 * sin.(t), 0.3*cos.(t))*u"m";
# 1 signal in one diagram (legend = "phi [rad]")
plot(result, "phi")
# 3 signals in one diagram
plot(result, ("phi", "w", "a"), figure=2)
# 3 diagrams in form of a vector (every diagram has one signal)
plot(result, ["phi", "w", "r"], figure=3)
# 4 diagrams in form of a matrix (every diagram has one signal)
plot(result, ["phi" "w";
"a" "r[2]" ], figure=4)
# 2 diagrams in form of a vector
plot(result, [ ("phi", "w"), ("a") ], figure=5)
# 4 diagrams in form of a matrix
plot(result, [ ("phi",) ("phi", "w");
("phi", "w", "a") ("r[2:3]",) ],figure=6)
# Plot w=f(phi) in one diagram
plot(result, "w", xAxis="phi", figure=7)
# Append signal of the next simulation run to figure=1
# (legend = "Sim 2: phi [rad]")
result["phi"] = 0.5*result["phi"];
plot(result, "phi", prefix="Sim 2: ", reuse=true)
Example of a matrix of plots:
SignalTables.SilentNoPlot.prepend!
— Methodprepend!(prefix, signalLegend)
Add prefix
string in front of every element of the signalLegend
string-Vector.
SignalTables.SilentNoPlot.saveFigure
— FunctionsaveFigure(figure, file; kwargs...)
Save figure on file. The file extension defines the image format (for example *.png
).
Plot package | Supported file extensions |
---|---|
GLMakie | png, jpg, bmp |
WGLMakie | png |
CairoMakie | png, pdf, svg, eps |
PyPlot | depends on backend (usually: png, pdf, jpg, tiff, svg, ps, eps) |
SilentNoPlot | Call is ignored |
Keyword arguments
- resolution: (width::Int, height::Int) of the scene in dimensionless units (equivalent to px for GLMakie and WGLMakie).
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
saveFigure(1, "plot.png") # save in png-format
saveFigure(2, "plot.svg") # save in svg-format
SignalTables.SilentNoPlot.showFigure
— FunctionshowFigure(figure)
Plot package | Effect |
---|---|
GLMakie | Show figure in the single window. |
WGLMakie | Show figure in the single window. |
CairoMakie | Call is ignored |
PyPlot | Call is ignored |
SilentNoPlot | Call is ignored |
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
plot(..., figure=3)
showFigure(2)
showFigure(1)
SignalTables.SignalTable
— TypesigTable = SignalTable(args...)
Returns a new SignalTable dictionary.
Arguments args...
are dictionary pairs where values
must be Var
(...) and/or Par
(...) and/or Map
(...). Example:
The first argument must define the independent signal, that is, Var(values=..., independent=true), ...
and values
must be an AbstractVector
. Further added signals with a :values
key, must have the same first dimension as the independent signal.
Most dictionary operations can be applied on sigTable
, as well as all functions of Overview of Functions.
Examples
using SignalTables
using Unitful
t = 0.0:0.1:0.5
sigTable = SignalTable(
"time" => Var(values= t, unit="s", independent=true),
"load.r" => Var(values= [sin.(t) cos.(t) sin.(t)], unit="m"),
"motor.angle" => Var(values= sin.(t), unit="rad", state=true, der="motor.w"),
"motor.w" => Var(values= cos.(t), unit="rad/s"),
"motor.w_ref" => Var(values= 0.9*[sin.(t) cos.(t)], unit = ["rad", "1/s"],
info="Reference angle and speed"),
"wm" => Var(alias = "motor.w"),
"ref.clock" => Var(values= [true, missing, missing, true, missing, missing],
variability="clock"),
"motor.w_c" => Var(values= [0.8, missing, missing, 1.5, missing, missing],
variability="clocked", clock="ref.clock"),
"motor.inertia"=> Par(value = 0.02f0, unit="kg*m/s^2"),
"motor.data" => Par(value = "resources/motorMap.json"),
"attributes" => Map(experiment=Map(stoptime=0.5, interval=0.01))
)
signalInfo(sigTable)
This results in the following output:
name unit size eltypeOrType kind attributes
─────────────────────────────────────────────────────────────────────────────────────────────────────────
time "s" [6] Float64 Var independent=true
load.r "m" [6,3] Float64 Var
motor.angle "rad" [6] Float64 Var state=true, der="motor.w"
motor.w "rad/s" [6] Float64 Var
motor.w_ref ["rad", "1/s"] [6,2] Float64 Var info="Reference angle and speed"
wm "rad/s" [6] Float64 Var alias="motor.w"
ref.clock [6] Union{Missing,Bool} Var variability="clock"
motor.w_c [6] Union{Missing,Float64} Var variability="clocked", clock="ref.clock"
motor.inertia "kg*m/s^2" Float32 Par
motor.data String Par
attributes Map experiment=Map(stoptime=0.5, interval=0.01)
The command show(IOContext(stdout, :compact => true), sigTable)
results in the following output:
SignalTable(
"time" => Var(values=0.0:0.1:0.5, unit="s", independent=true),
"load.r" => Var(values=[0.0 1.0 0.0; 0.0998334 0.995004 0.0998334; 0.198669 0.980067 0.198669; 0.29552 0.955336 0.29552; 0.389418 0.921061 0.389418; 0.479426 0.877583 0.479426], unit="m"),
"motor.angle" => Var(values=[0.0, 0.0998334, 0.198669, 0.29552, 0.389418, 0.479426], unit="rad", state=true. der="motor.w"),
"motor.w" => Var(values=[1.0, 0.995004, 0.980067, 0.955336, 0.921061, 0.877583], unit="rad/s"),
"motor.w_ref" => Var(values=[0.0 0.9; 0.0898501 0.895504; 0.178802 0.88206; 0.265968 0.859803; 0.350477 0.828955; 0.431483 0.789824], unit=["rad", "1/s"], info="Reference angle and speed"),
"wm" => Var(values=[1.0, 0.995004, 0.980067, 0.955336, 0.921061, 0.877583], unit="rad/s", alias="motor.w"),
"ref.clock" => Var(values=Union{Missing, Bool}[true, missing, missing, true, missing, missing], variability="clock"),
"ref.trigger" => Var(values=Union{Missing, Bool}[missing, missing, true, missing, true, true], variability="trigger"),
"motor.w_c" => Var(values=Union{Missing, Float64}[0.8, missing, missing, 1.5, missing, missing], variability="clocked", clock="ref.clock"),
"motor.inertia" => Par(value=0.02, unit="kg*m/s^2"),
"motor.data" => Par(value="resources/motorMap.json"),
"attributes" => Map(experiment=Map(stoptime=0.5, interval=0.01)),
)
SignalTables.StringDictType
— Typeconst StringDictType = OrderedDict{String,Any}
Predefined dictionary type used for the signal dictionary.
SignalTables.SymbolDictType
— Typeconst SymbolDictType = OrderedDict{Symbol,Any}
Predefined dictionary type used for attributes.
SignalTables.Map
— Methodsignal = Map(; kwargs...)::OrderedDict{Symbol,Any}
Returns a set of key/value pairs in form of a dictionary. A Map is used to associate a set of attributes to a Variable, Parameter or Signal Table.
The following keys are recognized (all are optional):
key | value |
---|---|
:info | Short description. |
Additionally, any other signal attributes can be stored in signal
with a desired key,
Example
using SignalTables
sigTable = SignalTable(
J = Par(value = 0.02),
attributes = Map(author = "xyz")
)
SignalTables.Par
— Methodsignal = Par(; kwargs...)::OrderedDict{Symbol,Any}
Returns a parameter signal definition in form of a dictionary. A parameter is a variable that is constant and is not a function of the independent variables. kwargs...
are key/value pairs of parameter attributes.
The value of a parameter variable is stored with key :value in signal
and is an instance of any Julia type (number, string, array, tuple, dictionary, ...).
The following keys are recognized (all are optional):
key | value (of type String, if not obvious from context) |
---|---|
:value | signal[:value] is a constant value that holds for all values of the independent signals. |
:unit | String: Unit of all signal elements (parseable with Unitful.uparse ), e.g., "kg*m*s^2" . Array{String,N}: signal[:unit][j1,j2,...] is unit of variable element [j1,j2,...] . |
:info | Short description of signal (= description of FMI 3.0 and of Modelica). |
:alias | String: signal[:value] is a reference to getSignal (signalTable, signal[:alias])[:value] . The reference is set and attributes are merged when the Par-signal is added to the signal table. |
Additionally, any other signal attributes can be stored in signal
with a desired key, such as Variable Types of FMI 3.0.
Example
using SignalTables
J = Par(value = 0.02, unit=u"kg*m/s^2", info="Motor inertia")
fileNames = Par(value = ["data1.json", "data2.json"])
J_alias = Par(alias = "J")
SignalTables.Var
— Methodsignal = Var(; kwargs...)::OrderedDict{Symbol,Any}
Returns a variable signal definition in form of a dictionary. kwargs...
are key/value pairs of variable attributes.
The :values key represents a signal array of any element type as function of the independent signal(s) (or is the k-th independent variable). A signal array has indices [i1,i2,...,j1,j2,...]
to hold variable elements [j1,j2,...]
at the [i1,i2,...]
independent signal(s). If an element of a signal array is not defined it has a value of missing. Furthermore, additional attributes can be stored.
The following keys are recognized (all are optional with exception of :values that must be either directly defined or via :alias):
key | value (of type String, if not obvious from context) |
---|---|
:values | Array{T,N}: signal[:values][i1,i2,...j1,j2,...] is value [j1,j2,...] at the [i1,i2,...] independent signal(s), or signal[:values][i_k] is value [i_k] of the k-th independent variable. |
:unit | String: Unit of all signal elements (parseable with Unitful.uparse ), e.g., "kg*m*s^2" . Array{String,N}: signal[:unit][j1,j2,...] is unit of variable element [j1,j2,...] . |
:info | Short description of signal (= description of FMI 3.0 and of Modelica). |
:independent | = true, if independent variable (k-th independent variable is k-th Var insignal table) |
:variability | "continuous", "clocked", "clock", "discrete", or "tunable" (parameter). |
:state | = true, if signal is a (continuous, clocked, or discrete) state. |
:der | String: getSignal (signalTable, signal[:der])[:values] is the derivative of signal[:values] . |
:clock | String: getSignal (signalTable, signal[:clock])[:values] is the clock associated with signal[:values] (is only defined at clock ticks and otherwise is missing). If Vector{String} , a set of clocks is associated with the signal. |
:alias | String: signal[:values] is a reference to getSignal (signalTable, signal[:alias])[:values] . The reference is set and attributes are merged when the Var-signal is added to the signal table. |
:interpolation | Interpolation of signal points ("linear", "none" ). If not provided, interpolation is deduced from :variability and otherwise interpolation is `"linear". |
:extrapolation | Extrapolation outside the values of the independent signal ("none" ). |
Additionally, any other signal attributes can be stored in signal
with a desired key, such as Variable Types of FMI 3.0.
Example
using SignalTables
t = (0.0:0.1:0.5)
t_sig = Var(values = t, unit=u"s", independent=true)
w_sig = Var(values = sin.(t), unit="rad/s", info="Motor angular velocity")
c_sig = Var(values = [1.0, missing, missing, 4.0, missing, missing],
variability="clocked")
b_sig = Var(values = [false, true, true, false, false, true])
a_sig = Var(alias = "w_sig")
SignalTables.closeAllFigures
— FunctioncloseAllFigures()
Close all figures.
SignalTables.closeFigure
— FunctioncloseFigure(figure)
Close figure
.
SignalTables.compactPaths
— MethodcompactPaths(str::String)
Returns a compacted string, where all paths with dots are reduced to their leaf name. Example: compactPaths("MonteCarloMeasurements.Particles") is reduced to "Particles".
SignalTables.currentPlotPackage
— MethodcurrentPlotPackage()
Return the name of the plot package as a string that was defined with usePlotPackage
. For example, the function may return "GLMakie", "PyPlot" or "NoPlot" or or "", if no PlotPackage is defined.
SignalTables.dictToString
— MethoddictToString(dict:AbstractDict)
SignalTables.eltypeOrType
— MethodeltypeOrType(obj)
Returns eltype(obj), if obj is an AbstractArray and otherwise returns typeof(obj).
SignalTables.encodeSignalTable
— MethodjsigDict = encodeSignalTable(signalTable; signalNames = nothing)
Encodes a SignalTable suitable to convert to JSON format.
If a keyword signalNames with a vector of strings is provided, then only the corresponding signals are encoded.
SignalTables.encodeSignalTableElement
— MethodjsigDict = encodeSignalTableElement(path, signalTableElement; log=false)
Encodes a signal table element suitable to convert to JSON format.
SignalTables.getDefaultHeading
— MethodgetDefaultHeading(signalTable, name::String)::String
Returns the default heading for a plot.
SignalTables.getFlattenedSignal
— Methodsignal = getFlattenedSignal(signalTable, name;
missingToNaN = true,
targetInt = Int,
targetFloat = Float64)
Returns a copy of a signal where the flattened and converted values (e.g.: missing -> NaN) are stored as signal[:flattenedValues]
and the legend as signal[:legend]
. A flattened signal can be, for example, used for traditional plot functions or for traditional tables.
signal[:flattenedValues]
is a reshape of values into a vector or a matrix with optionally the following transformations:
name
can be a signal name with or without array range indices (for examplename = "a.b.c[2,3:5]"
).- If
missingToNaN=true
, then missing values are replaced by NaN values. If NaN does not exist in the corresponding type, the values are first converted totargetFloat
. - If targetInt is not nothing, Int-types are converted to targetInt
- If targetFloat is not nothing, Float-types are converted to targetFloat
- collect(..) is performed on the result.
flattenedSignal[:legend]
is a vector of strings that provides a description for every array column (e.g. if "name=a.b.c[2,3:5]", unit="m/s"
, then legend = ["a.b.c[2,3] [m/s]", "a.b.c[2,3] [m/s]", "a.b.c[2,5] [m/s]"]
.
If the required transformation is not possible, a warning message is printed and nothing
is returned.
As a special case, if signal[:values] is a vector or signal[:value] is a scalar and an element of values or value is of type Measurements{targetFloat}
or MonteCarloMeasurements{targetFloat}
, then the signal is not transformed, so signal[:flattenedValues] = signal[:values].
SignalTables.getHeading
— MethodgetHeading(signalTable, heading)
Return heading
if no empty string. Otherwise, return defaultHeading(signalTable)
.
SignalTables.getIndependentSignalNames
— MethodgetIndependentSignalNames(signalTable)::Vector{String}
Returns the names of the independent signals (often: ["time"]) from signalTable.
SignalTables.getIndependentSignalsSize
— MethodgetIndependentSignalsSize(signalTable)::Dims
Returns the lengths of the independent signals as Dims. E.g. for one independent signal of length 5 return (5,), or for two independent signals of length 5 and 7 return (5,7).
SignalTables.getSignal
— MethodSignalTables.getSignalInfo
— MethodgetSignalInfo(signalTable, name::String)
Returns signal, but Var
or Par
) without :values or :value but instead with :eltypeOrType (eltype of the values if AbstractArray, otherwise typeof the values) and :size (if defined on the values)
If name
does not exist, an error is raised.
This function is useful if only the attributes of a signal are needed, but not their values (returning the attributes might be a cheap operation, whereas returning the values might be an expensive operation).
SignalTables.getSignalNames
— MethodgetSignalNames(signalTable; getVar=true, getPar=true, getMap=true)::Vector{String}
Returns a string vector of the signal names that are present in signalTable (including independent signal names).
- If getVar=true, Var(..) variables are included.
- If getPar=true, Par(..) variables are included.
- If getMap=true, Map(..) variables are included.
SignalTables.getSignalTableExample
— MethodgetSignalTableExample(signalTableName::String; logTitle=true, logShowInfo=true)
Return an example signal table.
SignalTables.getValue
— MethodgetValue(signalTable, name)
Returns the value of a Par
signal name from signalTable.
SignalTables.getValueWithUnit
— MethodgetValueWithUnit(signalTable, name)
Returns the value of a Par
signal name from signalTable including its unit.
SignalTables.getValues
— MethodgetValues(signalTable, name)
Returns the values of a Var
signal name from signalTable.
SignalTables.getValuesWithUnit
— MethodgetValuesWithUnit(signalTable, name)
Returns the values of a Var
signal name from signalTable including its unit.
SignalTables.hasSignal
— MethodhasSignal(signalTable, name::String)
Returns true
if signal name
is present in signalTable
.
SignalTables.isMap
— MethodisMap(signal)
Returns true, if signal is a Map
.
SignalTables.isPar
— MethodisPar(signal)
Returns true, if signal is a Par
.
SignalTables.isSignal
— MethodSignalTables.isSignalTable
— MethodisSignalTable(obj)::Bool
Returns true, if obj
is a signal table and supports the functions of the Abstract Signal Table Interface.
SignalTables.isVar
— MethodisVar(signal)
Returns true, if signal is a Var
.
SignalTables.new_signal_table
— Methodnew_signal_table(args...)::OrderedDict{String,Any}
Returns a new signal table, that is OrderedDict{String,Any}("_class" => :SignalTable, args...)
SignalTables.plot
— Methodplot(signalTable, names;
heading = "", grid = true, xAxis = nothing,
figure = 1, prefix = "", reuse = false, maxLegend = 10,
minXaxisTickLabels = false,
MonteCarloAsArea = true)
Generate plots of selected signals of a signal table using the plot package defined with [@usePlotPackage
]@ref(xxx)
. Possible values for xxx
: "GLMakie", "WGLMakie", "CairoMakie", "PyPlot", "SilentNoPlot"
).
signalTable
is an instance of a type that supports the Abstract Signal Table Interface.
Argument names
defines the diagrams to be drawn and the signals to be included in the respective diagram:
If
names
is a String, generate one diagram with one time series of the variable with keynames
.If
names
is a Tuple of Strings, generate one diagram with the time series of the variables with the keys given in the tuple.If names is a Vector or a Matrix of Strings and/or Tuples, generate a vector or matrix of diagrams.
Note, the names (and their units, if available in the signals) are automatically used as legends in the respective diagram.
A signal variable identified by a String
key can be a scalar of type <:Number
or an array of element type <:Number
. A signal is defined by a vector of time values, a corresponding vector of signal values, and the signal type (continuous or clocked).
Note, before passing data to the plot package, it is converted to Float64. This allows to, for example, also plot rational numbers, even if not supported by the plot package. Measurements.Measurement{xxx}
and MonteCarloMeasurements
is specially handled.
Optional Arguments
heading::AbstractString
: Optional heading above the diagram.grid::Bool
: = true, to display a grid.xAxis::Union{AbstractString,Nothing}
: Name of x-axis. IfxAxis=nothing
, the independent variable of the signal table (usually"time"
is used as x-axis.figure::Int
: Integer identifier of the window in which the diagrams shall be drawn.prefix::AbstractString
: String that is appended in front of every legend label (useful especially ifreuse=true
).reuse::Bool
: If figure already exists and reuse=false, clear the figure before adding the plot. Otherwise, include the plot in the existing figure without removing the curves present in the figure.reuse = true
is ignored for"WGLMakie"
(because not supported).maxLegend::Int
: If the number of legend entries in one plot command> maxLegend
, the legend is suppressed. All curves have still their names as labels. In PyPlot, the curves can be inspected by their names by clicking in the toolbar of the plot on buttonEdit axis, curve ..
and then onCurves
.minXaxisTickLabels::Bool
: = true, if xaxis tick labels shall be removed in a vector or array of plots, if not the last row (useful when including plots in a document). = false, x axis tick labels are always shown (useful when interactively zooming into a plot).MonteCarloAsArea::Bool
: = true, if MonteCarloMeasurements values are shown with the mean value and the area between the minimum and the maximum value of all particles. = false, if all particles of MonteCarloMeasurements values are shown (e.g. if a value has 2000 particles, then 2000 curves are shown in the diagram).
Examples
using SignalTables
using Unitful
# Generate "using xxx" statement
# (where "xxx" is from a previous SignalTables.usePlotPackage("xxx"))
@usingPlotPackage
# Construct result data
t = range(0.0, stop=10.0, length=100);
result = Dict{String,Any}();
result["time"] = t*u"s";
result["phi"] = sin.(t)*u"rad";
result["w"] = cos.(t)*u"rad/s";
result["a"] = 1.2*sin.(t)*u"rad/s^2";
result["r"] = hcat(0.4 * cos.(t), 0.5 * sin.(t), 0.3*cos.(t))*u"m";
# 1 signal in one diagram (legend = "phi [rad]")
plot(result, "phi")
# 3 signals in one diagram
plot(result, ("phi", "w", "a"), figure=2)
# 3 diagrams in form of a vector (every diagram has one signal)
plot(result, ["phi", "w", "r"], figure=3)
# 4 diagrams in form of a matrix (every diagram has one signal)
plot(result, ["phi" "w";
"a" "r[2]" ], figure=4)
# 2 diagrams in form of a vector
plot(result, [ ("phi", "w"), ("a") ], figure=5)
# 4 diagrams in form of a matrix
plot(result, [ ("phi",) ("phi", "w");
("phi", "w", "a") ("r[2:3]",) ],figure=6)
# Plot w=f(phi) in one diagram
plot(result, "w", xAxis="phi", figure=7)
# Append signal of the next simulation run to figure=1
# (legend = "Sim 2: phi [rad]")
result["phi"] = 0.5*result["phi"];
plot(result, "phi", prefix="Sim 2: ", reuse=true)
Example of a matrix of plots:
SignalTables.prepend!
— Methodprepend!(prefix, signalLegend)
Add prefix
string in front of every element of the signalLegend
string-Vector.
SignalTables.quantity
— MethodquantityType = quantity(numberType, numberUnit::Unitful.FreeUnits)
Returns Quantity from numberType and numberUnit, e.g. quantity(Float64,u"m/s")
Example
using SignalTables
using Unitful
mutable struct Data{FloatType <: AbstractFloat}
velocity::quantity(FloatType, u"m/s")
end
v = Data{Float64}(2.0u"mm/s")
@show v # v = Data{Float64}(0.002 m s^-1)
sig = Vector{Union{Missing,quantity(Float64,u"m/s")}}(missing,3)
append!(sig, [1.0, 2.0, 3.0]u"m/s")
append!(sig, fill(missing, 2))
@show sig # [missing, missing, missing, 1.0u"m/s", 2.0u"m/s", 3.0u"m/s", missing, missing]
SignalTables.saveFigure
— FunctionsaveFigure(figure, file; kwargs...)
Save figure on file. The file extension defines the image format (for example *.png
).
Plot package | Supported file extensions |
---|---|
GLMakie | png, jpg, bmp |
WGLMakie | png |
CairoMakie | png, pdf, svg, eps |
PyPlot | depends on backend (usually: png, pdf, jpg, tiff, svg, ps, eps) |
SilentNoPlot | Call is ignored |
Keyword arguments
- resolution: (width::Int, height::Int) of the scene in dimensionless units (equivalent to px for GLMakie and WGLMakie).
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
saveFigure(1, "plot.png") # save in png-format
saveFigure(2, "plot.svg") # save in svg-format
SignalTables.showFigure
— FunctionshowFigure(figure)
Plot package | Effect |
---|---|
GLMakie | Show figure in the single window. |
WGLMakie | Show figure in the single window. |
CairoMakie | Call is ignored |
PyPlot | Call is ignored |
SilentNoPlot | Call is ignored |
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
plot(..., figure=3)
showFigure(2)
showFigure(1)
SignalTables.showInfo
— MethodshowInfo([io::IO=stdout,] signalTable;
sorted=false, showVar=true, showPar=true, showMap=true, showAttributes=true)
Writes info about a signal table to the output stream. The keyword arguments define what information shall be printed or whether the names shall be sorted or presented in definition order.
Example
using SignalTables
using Unitful
t = 0.0:0.1:0.5
sigTable = SignalTable(
"time" => Var(values= t, unit="s", independent=true),
"load.r" => Var(values= [sin.(t) cos.(t) sin.(t)], unit="m"),
"motor.angle" => Var(values= sin.(t), unit="rad", state=true, der="motor.w"),
"motor.w" => Var(values= cos.(t), unit="rad/s"),
"motor.w_ref" => Var(values= 0.9*[sin.(t) cos.(t)], unit = ["rad", "1/s"],
info="Reference angle and speed"),
"wm" => Var(alias = "motor.w"),
"ref.clock" => Var(values= [true, missing, missing, true, missing, missing],
variability="clock"),
"motor.w_c" => Var(values= [0.8, missing, missing, 1.5, missing, missing],
variability="clocked", clock="ref.clock"),
"motor.inertia"=> Par(value = 0.02f0, unit="kg*m/s^2"),
"motor.data" => Par(value = "resources/motorMap.json"),
"attributes" => Map(experiment=Map(stoptime=0.5, interval=0.01))
)
signalInfo(sigTable)
results in the following output
name unit size eltypeOrType kind attributes
───────────────────────────────────────────────────────────────────────────────────────────────────────
time "s" [6] Float64 Var independent=true
load.r "m" [6,3] Float64 Var
motor.angle "rad" [6] Float64 Var state=true, der="motor.w"
motor.w "rad/s" [6] Float64 Var
motor.w_ref ["rad", "1/s"] [6,2] Float64 Var info="Reference angle and speed"
wm "rad/s" [6] Float64 Var alias="motor.w"
ref.clock [6] Union{Missing,Bool} Var variability="clock"
motor.w_c [6] Union{Missing,Float64} Var variability="clocked", clock="ref.clock"
motor.inertia "kg*m/s^2" Float32 Par
motor.data String Par
attributes Map experiment=Map(stoptime=0.5, interval=0.01)
SignalTables.showSignal
— MethodSignalTables.signalTableToDataFrame
— Methoddf = signalTableToDataFrame(signalTable)
Returns a signal table as DataFrame object.
SignalTables.signalTableToJSON
— Methodjson = signalTableToJSON(signalTable; signalNames = nothing)
Returns a JSON string representation of signalTable
If keyword signalNames with a Vector of strings is provided, then a signal table with the corresponding signals are returned as JSON string.
SignalTables.toSignalTable
— MethodtoSignalTable(signalTable)::SignalTable
Returns a signalTable as instance of SignalTable
.
SignalTables.unitAsParseableString
— Methodv_unit = unitAsParseableString(v::[Number|AbstractArray])::String
Returns the unit of v
as a string that can be parsed with Unitful.uparse
.
This allows, for example, to store a quantity with units into a JSON File and recover it when reading the file. This is not (easily) possible with current Unitful functionality, because string(unit(v))
returns a string that cannot be parse with uparse
. In Julia this is an unusual behavior because string(something)
typically returns a string representation of something that can be again parsed by Julia. For more details, see Unitful issue 412.
Most likely, unitAsParseableString(..)
cannot handle all occuring cases.
Examples
using SignalTables
using Unitful
s = 2.1u"m/s"
v = [1.0, 2.0, 3.0]u"m/s"
s_unit = unitAsParseableString(s) # ::String
v_unit = unitAsParseableString(v) # ::String
s_unit2 = uparse(s_unit) # :: Unitful.FreeUnits{(m, s^-1), ..., nothing}
v_unit2 = uparse(v_unit) # :: Unitful.FreeUnits{(m, s^-1), ..., nothing}
@show s_unit # = "m*s^-1"
@show v_unit # = "m*s^-1"
@show s_unit2 # = "m s^-1"
@show v_unit2 # = "m s^-1"
SignalTables.usePlotPackage
— MethodusePlotPackage(plotPackage::String)
Define the plot package that shall be used by command @usingPlotPackage
. If a PlotPackage package is already defined, save it on an internal stack (can be reactivated with usePreviousPlotPackage()
.
Possible values for plotPackage
:
"PyPlot"
"GLMakie"
"WGLMakie"
"CairoMakie"
"SilentNoPlot"
Example
using SignalTables
usePlotPackage("GLMakie")
module MyTest
using SignalTables
@usingPlotPackage
t = range(0.0, stop=10.0, length=100)
result = Dict{String,Any}("time" => t, "phi" => sin.(t))
plot(result, "phi") # use GLMakie for the rendering
end
SignalTables.usePreviousPlotPackage
— MethodusePreviousPlotPackage()
Pop the last saved PlotPackage package from an internal stack and call usePlotPackage(<popped PlotPackage package>)
.
SignalTables.writeSignalTable
— MethodwriteSignalTable(filename::String, signalTable; signalNames=nothing, indent=nothing, log=false)
Write signalTable in JSON format on file filename
.
If keyword signalNames with a Vector of strings is provided, then a signal table with the corresponding signals are stored on file.
If indent=<number> is given, then <number> indentation is used (otherwise, compact representation)
SignalTables.@usingPlotPackage
— Macro@usingPlotPackage()
Execute using XXX
, where XXX
is the Plot package that was activated with usePlotPackage(plotPackage)
.
SignalTables.NoPlot.closeAllFigures
— FunctioncloseAllFigures()
Close all figures.
SignalTables.NoPlot.closeFigure
— FunctioncloseFigure(figure)
Close figure
.
SignalTables.NoPlot.plot
— Methodplot(signalTable, names;
heading = "", grid = true, xAxis = nothing,
figure = 1, prefix = "", reuse = false, maxLegend = 10,
minXaxisTickLabels = false,
MonteCarloAsArea = true)
Generate plots of selected signals of a signal table using the plot package defined with [@usePlotPackage
]@ref(xxx)
. Possible values for xxx
: "GLMakie", "WGLMakie", "CairoMakie", "PyPlot", "SilentNoPlot"
).
signalTable
is an instance of a type that supports the Abstract Signal Table Interface.
Argument names
defines the diagrams to be drawn and the signals to be included in the respective diagram:
If
names
is a String, generate one diagram with one time series of the variable with keynames
.If
names
is a Tuple of Strings, generate one diagram with the time series of the variables with the keys given in the tuple.If names is a Vector or a Matrix of Strings and/or Tuples, generate a vector or matrix of diagrams.
Note, the names (and their units, if available in the signals) are automatically used as legends in the respective diagram.
A signal variable identified by a String
key can be a scalar of type <:Number
or an array of element type <:Number
. A signal is defined by a vector of time values, a corresponding vector of signal values, and the signal type (continuous or clocked).
Note, before passing data to the plot package, it is converted to Float64. This allows to, for example, also plot rational numbers, even if not supported by the plot package. Measurements.Measurement{xxx}
and MonteCarloMeasurements
is specially handled.
Optional Arguments
heading::AbstractString
: Optional heading above the diagram.grid::Bool
: = true, to display a grid.xAxis::Union{AbstractString,Nothing}
: Name of x-axis. IfxAxis=nothing
, the independent variable of the signal table (usually"time"
is used as x-axis.figure::Int
: Integer identifier of the window in which the diagrams shall be drawn.prefix::AbstractString
: String that is appended in front of every legend label (useful especially ifreuse=true
).reuse::Bool
: If figure already exists and reuse=false, clear the figure before adding the plot. Otherwise, include the plot in the existing figure without removing the curves present in the figure.reuse = true
is ignored for"WGLMakie"
(because not supported).maxLegend::Int
: If the number of legend entries in one plot command> maxLegend
, the legend is suppressed. All curves have still their names as labels. In PyPlot, the curves can be inspected by their names by clicking in the toolbar of the plot on buttonEdit axis, curve ..
and then onCurves
.minXaxisTickLabels::Bool
: = true, if xaxis tick labels shall be removed in a vector or array of plots, if not the last row (useful when including plots in a document). = false, x axis tick labels are always shown (useful when interactively zooming into a plot).MonteCarloAsArea::Bool
: = true, if MonteCarloMeasurements values are shown with the mean value and the area between the minimum and the maximum value of all particles. = false, if all particles of MonteCarloMeasurements values are shown (e.g. if a value has 2000 particles, then 2000 curves are shown in the diagram).
Examples
using SignalTables
using Unitful
# Generate "using xxx" statement
# (where "xxx" is from a previous SignalTables.usePlotPackage("xxx"))
@usingPlotPackage
# Construct result data
t = range(0.0, stop=10.0, length=100);
result = Dict{String,Any}();
result["time"] = t*u"s";
result["phi"] = sin.(t)*u"rad";
result["w"] = cos.(t)*u"rad/s";
result["a"] = 1.2*sin.(t)*u"rad/s^2";
result["r"] = hcat(0.4 * cos.(t), 0.5 * sin.(t), 0.3*cos.(t))*u"m";
# 1 signal in one diagram (legend = "phi [rad]")
plot(result, "phi")
# 3 signals in one diagram
plot(result, ("phi", "w", "a"), figure=2)
# 3 diagrams in form of a vector (every diagram has one signal)
plot(result, ["phi", "w", "r"], figure=3)
# 4 diagrams in form of a matrix (every diagram has one signal)
plot(result, ["phi" "w";
"a" "r[2]" ], figure=4)
# 2 diagrams in form of a vector
plot(result, [ ("phi", "w"), ("a") ], figure=5)
# 4 diagrams in form of a matrix
plot(result, [ ("phi",) ("phi", "w");
("phi", "w", "a") ("r[2:3]",) ],figure=6)
# Plot w=f(phi) in one diagram
plot(result, "w", xAxis="phi", figure=7)
# Append signal of the next simulation run to figure=1
# (legend = "Sim 2: phi [rad]")
result["phi"] = 0.5*result["phi"];
plot(result, "phi", prefix="Sim 2: ", reuse=true)
Example of a matrix of plots:
SignalTables.NoPlot.prepend!
— Methodprepend!(prefix, signalLegend)
Add prefix
string in front of every element of the signalLegend
string-Vector.
SignalTables.NoPlot.saveFigure
— FunctionsaveFigure(figure, file; kwargs...)
Save figure on file. The file extension defines the image format (for example *.png
).
Plot package | Supported file extensions |
---|---|
GLMakie | png, jpg, bmp |
WGLMakie | png |
CairoMakie | png, pdf, svg, eps |
PyPlot | depends on backend (usually: png, pdf, jpg, tiff, svg, ps, eps) |
SilentNoPlot | Call is ignored |
Keyword arguments
- resolution: (width::Int, height::Int) of the scene in dimensionless units (equivalent to px for GLMakie and WGLMakie).
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
saveFigure(1, "plot.png") # save in png-format
saveFigure(2, "plot.svg") # save in svg-format
SignalTables.NoPlot.showFigure
— FunctionshowFigure(figure)
Plot package | Effect |
---|---|
GLMakie | Show figure in the single window. |
WGLMakie | Show figure in the single window. |
CairoMakie | Call is ignored |
PyPlot | Call is ignored |
SilentNoPlot | Call is ignored |
Example
using SignalTables
@usingPlotPackage
...
plot(..., figure=1)
plot(..., figure=2)
plot(..., figure=3)
showFigure(2)
showFigure(1)