While using both Interact and Gadfly packages in Julia, the sliders which are supposed to appear (coming from Interact) in the plots don't show up. Here's an example of code:
using Gadfly
using Interact
set_default_plot_size(15cm, 15cm)
f(x)= e^x
x =-10:0.001:10
#manipulate for a in 1:5, b in 4:9
plot(
layer(x=x, y=f.(x)*a, Geom.line),
layer(x=[-10; 10], y=[10000; 10000], Geom.line),
Coord.Cartesian(xmin=0,xmax=10)
)
end
I am running Julia on version 0.6.2.
Thanks.
Related
I am trying to obtain a corrplot of some three-dimensional data array using Julia. The StatsPlots documentation includes the following example of a corrplot:
M = randn(1000,4)
M[:,2] .+= 0.8sqrt.(abs.(M[:,1])) .- 0.5M[:,3] .+ 5
M[:,3] .-= 0.7M[:,1].^2 .+ 2
corrplot(M, label = ["x$i" for i=1:4])
However, when I try to run the same script, I obtain flat histograms (no color gradient):
I generated the previous figure with the following script:
using StatsPlots
gr()
M = randn(1000,4)
M[:,2] .+= 0.8sqrt.(abs.(M[:,1])) .- 0.5M[:,3] .+ 5
M[:,3] .-= 0.7M[:,1].^2 .+ 2
corrplot(M, label = ["x$i" for i=1:4])
savefig("corrplot_example.png")
I am not sure what I am doing differently. My Julia version is 1.3.1, and my StatsPlots version is 0.14.6.
I would like to create a stacked area chart, similar to this for example, in Julia using Plots.
I know / suppose that you can do this if you directly use the Gadfly or PyPlot backends in Julia, but I was wondering if there was a recipe for this. If not, how can you contribute to the Plots Recipes? Would be a useful addition.
There's a recipe for something similar in
https://docs.juliaplots.org/latest/examples/pgfplots/#portfolio-composition-maps
For some reason the thumbnail looks broken now though (but the code works).
The exact plot in the matlab example can be produced by
plot(cumsum(Y, dims = 2)[:,end:-1:1], fill = 0, lc = :black)
As a recipe that would look like
#userplot AreaChart
#recipe function f(a::AreaChart)
fillto --> 0
linecolor --> :black
seriestype --> :path
cumsum(a.args[1], dims = 2)[:,end:-1:1]
end
If you want to contribute a recipe to Plots you can open a pull request on Plots, or, eg. on StatsPlots - there's a good description of contributing here: https://docs.juliaplots.org/latest/contributing/
It's a bit of reading, but very generally useful as an introduction to contributing to Julia packages.
You can read this thread in the Julia discourse forum where the question is developed in deep.
One solution posted there using Plots is :
# a simple "recipe" for Plots.jl to get stacked area plots
# usage: stackedarea(xvector, datamatrix, plotsoptions)
#recipe function f(pc::StackedArea)
x, y = pc.args
n = length(x)
y = cumsum(y, dims=2)
seriestype := :shape
# create a filled polygon for each item
for c=1:size(y,2)
sx = vcat(x, reverse(x))
sy = vcat(y[:,c], c==1 ? zeros(n) : reverse(y[:,c-1]))
#series (sx, sy)
end
end
a = [1,1,1,1.5,2,3]
b = [0.5,0.6,0.4,0.3,0.3,0.2]
c = [2,1.8,2.2,3.3,2.5,1.8]
sNames = ["a","b","c"]
x = [2001,2002,2003,2004,2005,2006]
plotly()
stackedarea(x, [a b c], labels=reshape(sNames, (1,3)))
(by user NiclasMattsson)
Other ways presented there include using the VegaLite.jl package.
with Julia 1.0.3
following this tutorial for plotting with Gadfly (it's from 2015: it might a bit old)
I used the following code:
using RDatasets, Gadfly, Cairo, Plots
sleep = dataset("lme4", "sleepstudy");
plot(sleep, x = "Days", y = "Reaction", Geom.point, Geom.smooth)
and got the following output: Plot(...) instead of a plot. Why am I not seeing a real plot instead
Here is the output of the following command: typeof.(Base.Multimedia.displays):
3-element Array{DataType,1}:
TextDisplay
IJulia.InlineDisplay
Gadfly.GadflyDisplay
When solving differential equations and plotting the results, how can I increase the number of data points that are plotted? I have
using DifferentialEquations
using Plots
function lorenz(du,u,p,t)
du[1] = 10.0*(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
u0 = [5.0;0.0;0.0]
tspan = (0.0,100000.0)
prob = ODEProblem(lorenz,u0,tspan)
sol = solve(prob)
plot(sol, vars = 1, xlims = (10,100000),xscale =:log)
Specifically, when using something like PyPlots I can use:
x = linspace(0,100000,num=10000)
where I set num = 10000 which increases the number of samples and allows for a higher resolution of data points for longer integration timespans.
The obvious answer is to use PyPlots, but I'm not sure if I can even use PyPlots with the DifferentialEquations package. It would be nice to know how this is done for Plots. (As depending on the function, some plots come out very jagged).
Plots.jl is actually a wrapper around plotting backends like PyPlot.jl and GR.jl (which are also wrappers).
You can make Plots.jl use PyPlot by calling pyplot(), provided that you have PyPlot.jl installed.
using Plots
pyplot() # switch to PyPlot
plot(sol.t[2:end], sol[1,2:end], xlim =(10,100000), xscale=:log10)
Note that I started from the second index, because at the first index t is 0, which creates problem with log-scale (even if xlim is set). This uses every data point in the solution. If you are on the terminal this will open up PyPlot GUI, so you can zoom as you wish. If you are on Juno you can use gui(plot(...)) to open the window.
You can sample the system at arbitrary time points. (with the DifferentialEquations' interpolant sol(t))
t = range(10, stop = 100000, num=10000) # to reach t=100000 you need to adjust `maxiters` accordingly in your call to `solve`
samples = sol(t) # sample using interpolator
plot(samples.t, samples.u[1,:], xscale=:log10)
You could also use the recipe without log-scale and with plotdensity option.
plot(sol, vars=1, plotdensity=1000)
See here for more examples: http://diffeq.sciml.ai/stable/basics/plot.html
I would like to add a global title to a group of subplots using Plots.jl.
Ideally, I'd do something like:
using Plots
pyplot()
plot(rand(10,2), plot_title="Main title", title=["A" "B"], layout=2)
but, as per the Plots.jl documentation, the plot_title attribute is not yet implemented:
Title for the whole plot (not the subplots) (Note: Not currently implemented)
In the meanwhile, is there any way around it?
I'm currently using the pyplot backend, but I'm not especially tied to it.
This is a bit of a hack, but should be agnostic to the backend. Basically create a new plot where the only contents are the title you want, and then add it on top using layout. Here is an example using the GR backend:
# create a transparent scatter plot with an 'annotation' that will become title
y = ones(3)
title = Plots.scatter(y, marker=0,markeralpha=0, annotations=(2, y[2], Plots.text("This is title")),axis=false, grid=false, leg=false,size=(200,100))
# combine the 'title' plot with your real plots
Plots.plot(
title,
Plots.plot(rand(100,4), layout = 4),
layout=grid(2,1,heights=[0.1,0.9])
)
Produces:
More recent versions of Plots.jl support the plot_title attribute, which provides a title for the whole plot. This can be combined with individual titles of individual plots.
using Plots
layout = #layout [a{0.66w} b{0.33w}]
LHS = heatmap(rand(100, 100), title="Title for just the heatmap")
RHS = plot(1:100, 1:100, title="Only the line")
plot(LHS, RHS, plot_title="Overall title of the plot")
Alternatively, you can set the title for an existing plot directly.
p = plot(LHS, RHS)
p[:plot_title] = "Overall title of the plot"
plot(p)
When using the pyplot backend, you can use PyPlot commands to alter a Plots figure, cf. Accessing backend specific functionality with Julia Plots.
To set a title for the whole figure, you could do something like:
using Plots
p1 = plot(sin, title = "sin")
p2 = plot(cos, title = "cos")
p = plot(p1, p2, top_margin=1cm)
import PyPlot
PyPlot.suptitle("Trigonometric functions")
PyPlot.savefig("suptile_test.png")
One needs to explicitly call PyPlot.savefig to see the effect of the PyPlot functions.
Note that all changes made using the PyPlot interface will be overwritten when you use a Plots function.
subplots are fields of the Plot type, and each subplot has a field called :attr that you can modify and re-display() the plot. Try the following:
julia> l = #layout([a{0.1h} ;b [c; d e]])
Plots.GridLayout(2,1)
julia> p = plot(randn(100,5),layout=l,t=[:line :histogram :scatter :steppre :bar],leg=false,ticks=nothing,border=false)
julia> p.subplots
5-element Array{Plots.Subplot,1}:
Subplot{1}
Subplot{2}
Subplot{3}
Subplot{4}
Subplot{5}
julia> fieldnames(p.subplots[1])
8-element Array{Symbol,1}:
:parent
:series_list
:minpad
:bbox
:plotarea
:attr
:o
:plt
julia> for i in 1:length(p.subplots)
p.subplots[i].attr[:title] = "subtitle $i"
end
julia> display(p)
You should now see a title in each subplot