Julia PyPlot control parameters in multiple plot

Hello,
I am creating some plot in Julia using PyPlot. How can I how can I combine plots with PyPlot?
For instance, I would like one line in solid red the other in dotted green:

julia> x = range(0; stop=2*pi, length=1000)
0.0:0.006289474781961547:6.283185307179586

julia> y1 = sin.(3 * x + 4 * cos.(2 * x))
1000-element Array{Float64,1}:
 -0.7568024953079282
 -0.7687979429150046
 -0.7801330261327849
 -0.790830536475742
 -0.800913192079596
 -0.8104035427077365
  ⋮
 -0.6861303352619349
 -0.7017645466519309
 -0.7166271329853839
 -0.7307395907784272
 -0.7441239200875579
 -0.7568024953079278

julia> y2 = sin.(2 * x + 5 * cos.(3 * x))
1000-element Array{Float64,1}:
 -0.9589242746631385
 -0.9555431333512879
 -0.9525745225417045
 -0.9500689261982551
 -0.9480672919504057
 -0.9466011427015437
  ⋮
 -0.9795705265038878
 -0.975224815064202
 -0.9708927507542918
 -0.9666738797537784
 -0.9626578163088578
 -0.9589242746631386
julia> myPlot = plot(x, y1, x, y2, linewidth=2.0, color="green", "red", linestyle = "-", ".")
3-element Array{PyCall.PyObject,1}:
 PyObject <matplotlib.lines.Line2D object at 0x7f9b5feadbe0>
 PyObject <matplotlib.lines.Line2D object at 0x7f9b5fe7af98>
 PyObject <matplotlib.lines.Line2D object at 0x7f9b5fdc5240>
julia> xlabel("X-values")
PyObject Text(0.5, 23.52222222222222, 'X-values')
julia> ylabel("sin(x)")
PyObject Text(44.222222222222214, 0.5, 'sin(x)')
julia> title("simulation")
PyObject Text(0.5, 1.0, 'simulation')
julia> savefig("./plot.png", dpi = 100, format = "png", transparent = false)

But the graph is not really as I wanted:
plot
This compared to:

julia> myPlot = plot(x, y1, x, y2, linewidth=2.0)
2-element Array{PyCall.PyObject,1}:
 PyObject <matplotlib.lines.Line2D object at 0x7f9b5ffffb70>
 PyObject <matplotlib.lines.Line2D object at 0x7f9b5fde9d68>
julia> xlabel("X-values")
PyObject Text(0.5, 23.52222222222222, 'X-values')
julia> ylabel("sin(x)")
PyObject Text(60.347222222222214, 0.5, 'sin(x)')
julia> title("simulation")
PyObject Text(0.5, 1.0, 'simulation')
julia> savefig("./plot2.png", dpi = 100, format = "png", transparent = false)

plot2
I also tried to provide arrays but it was not good:

julia> myPlot = plot(x, y1, x, y2, linewidth=2.0, color=["green", "red"], linestyle = ["-", "."])
ERROR: PyError ($(Expr(:escape, :(ccall(#= /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError("Unrecognized linestyle: ['-', '.']",)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 2813, in plot
    is not None else {}), **kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/__init__.py", line 1810, in inner
    return func(ax, *args, **kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 1611, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 393, in _grab_next_args
    yield from self._plot_args(this, kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 383, in _plot_args
    seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 288, in _makeline
    seg = mlines.Line2D(x, y, **kw)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/lines.py", line 381, in __init__
    self.set_linestyle(linestyle)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/lines.py", line 1101, in set_linestyle
    self._us_dashOffset, self._us_dashSeq = _get_dash_pattern(ls)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/lines.py", line 47, in _get_dash_pattern
    raise ValueError('Unrecognized linestyle: %s' % str(style))

Stacktrace:
 [1] pyerr_check at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:60 [inlined]
 [2] pyerr_check at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:64 [inlined]
 [3] macro expansion at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:84 [inlined]
 [4] __pycall!(::PyCall.PyObject, ::Ptr{PyCall.PyObject_struct}, ::PyCall.PyObject, ::PyCall.PyObject) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44
 [5] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}, ::Int64, ::PyCall.PyObject) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:29
 [6] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}, ::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,Array{String,1},Array{String,1}}}}) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:11
 [7] #pycall#110(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,Array{String,1},Array{String,1}}}}, ::Function, ::PyCall.PyObject, ::Type{PyCall.PyAny}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:86
 [8] (::getfield(PyCall, Symbol("#kw##pycall")))(::NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,Array{String,1},Array{String,1}}}, ::typeof(PyCall.pycall), ::PyCall.PyObject, ::Type{PyCall.PyAny}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at ./none:0
 [9] #plot#85(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,Array{String,1},Array{String,1}}}}, ::Function, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at /home/gigiux/.julia/packages/PyPlot/cdCMF/src/PyPlot.jl:177
 [10] (::getfield(PyPlot, Symbol("#kw##plot")))(::NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,Array{String,1},Array{String,1}}}, ::typeof(plot), ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at ./none:0
 [11] top-level scope at none:0

How to a fine control the parameters in PyPlot?

Have a look at the examples at either
Plot Examples
or
the Julia Plots Gallery.

1 Like

The easiest thing is just to call plot multiple times. The lines will be added to the same plot, but then you can control their properties individually.

plot(x, y1, linewidth=2.0, color="green", linestyle = "-")
plot(x, y2, linewidth=2.0, color="red", linestyle = ":")

But I got:

julia> myPlot = plot(x, y1, linewidth=2.0, color="green", linestyle = "-")
1-element Array{PyCall.PyObject,1}:
 PyObject <matplotlib.lines.Line2D object at 0x7f910db93cf8>

julia> myPlot = plot(x, y2, linewidth=2.0, color="red", linestyle = ".")
ERROR: PyError ($(Expr(:escape, :(ccall(#= /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError("Invalid linestyle '.'; see docs of Line2D.set_linestyle for valid values",)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 2813, in plot
    is not None else {}), **kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/__init__.py", line 1810, in inner
    return func(ax, *args, **kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 1611, in plot
    for line in self._get_lines(*args, **kwargs):
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 393, in _grab_next_args
    yield from self._plot_args(this, kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 383, in _plot_args
    seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 288, in _makeline
    seg = mlines.Line2D(x, y, **kw)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/lines.py", line 381, in __init__
    self.set_linestyle(linestyle)
  File "/home/gigiux/.local/lib/python3.6/site-packages/matplotlib/lines.py", line 1095, in set_linestyle
    .format(ls))

Stacktrace:
 [1] pyerr_check at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:60 [inlined]
 [2] pyerr_check at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:64 [inlined]
 [3] macro expansion at /home/gigiux/.julia/packages/PyCall/ttONZ/src/exception.jl:84 [inlined]
 [4] __pycall!(::PyCall.PyObject, ::Ptr{PyCall.PyObject_struct}, ::PyCall.PyObject, ::PyCall.PyObject) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44
 [5] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}, ::Int64, ::PyCall.PyObject) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:29
 [6] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}, ::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,String,String}}}) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:11
 [7] #pycall#110(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,String,String}}}, ::Function, ::PyCall.PyObject, ::Type{PyCall.PyAny}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at /home/gigiux/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:86
 [8] (::getfield(PyCall, Symbol("#kw##pycall")))(::NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,String,String}}, ::typeof(PyCall.pycall), ::PyCall.PyObject, ::Type{PyCall.PyAny}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at ./none:0
 [9] #plot#85(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,String,String}}}, ::Function, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at /home/gigiux/.julia/packages/PyPlot/cdCMF/src/PyPlot.jl:177
 [10] (::getfield(PyPlot, Symbol("#kw##plot")))(::NamedTuple{(:linewidth, :color, :linestyle),Tuple{Float64,String,String}}, ::typeof(plot), ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N) at ./none:0
 [11] top-level scope at none:0

julia> myPlot = plot!(x, y2, linewidth=2.0, color="red", linestyle = ".")
ERROR: UndefVarError: plot! not defined
Stacktrace:
 [1] top-level scope at none:0

julia>

Did you read the error message? It says exactly what your problem is: '.' is an invalid linestyle. If you want a dotted line, you can use linestyle=":". As the message says, the valid linestyles are listed in the Line2D.set_linestyle documentation, which you can easily google.

2 Likes

You were right, sorry. I got the linestyle = “.” probably from another plot function’s help. It worked.
plot