""" Holds all data needed for a documentation example... header, description, and plotting expression (Expr) """ mutable struct PlotExample header::AbstractString desc::AbstractString exprs::Vector{Expr} end # the _examples we'll run for each backend const _examples = PlotExample[ PlotExample( # 1 "Lines", "A simple line plot of the columns.", [:( begin plot(Plots.fakedata(50, 5), w = 3) end )], ), PlotExample( # 2 "Functions, adding data, and animations", """ Plot multiple functions. You can also put the function first, or use the form `plot(f, xmin, xmax)` where f is a Function or AbstractVector{Function}.\n\nGet series data: `x, y = plt[i]`. Set series data: `plt[i] = (x,y)`. Add to the series with `push!`/`append!`.\n\nEasily build animations. (`convert` or `ffmpeg` must be available to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the animation. """, [:( begin p = plot([sin, cos], zeros(0), leg = false, xlims = (0, 2π), ylims = (-1, 1)) anim = Animation() for x in range(0, stop = 2π, length = 20) push!(p, x, Float64[sin(x), cos(x)]) frame(anim) end end )], ), PlotExample( # 3 "Parametric plots", "Plot function pair (x(u), y(u)).", [ :( begin plot( sin, x -> sin(2x), 0, 2π, line = 4, leg = false, fill = (0, :orange), ) end ), ], ), PlotExample( # 4 "Colors", """ Access predefined palettes (or build your own with the `colorscheme` method). Line/marker colors are auto-generated from the plot's palette, unless overridden. Set the `z` argument to turn on series gradients. """, [ :( begin y = rand(100) plot( 0:10:100, rand(11, 4), lab = "lines", w = 3, palette = cgrad(:grays), fill = 0, α = 0.6, ) scatter!( y, zcolor = abs.(y .- 0.5), m = (:heat, 0.8, Plots.stroke(1, :green)), ms = 10 * abs.(y .- 0.5) .+ 4, lab = "grad", ) end ), ], ), PlotExample( # 5 "Global", """ Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow you to pass a tuple or value which will be mapped to the relevant args automatically. The `xaxis` below will be replaced with `xlabel` and `xlims` args automatically during the preprocessing step. You can also use shorthand functions: `title!`, `xaxis!`, `yaxis!`, `xlabel!`, `ylabel!`, `xlims!`, `ylims!`, `xticks!`, `yticks!` """, [ :( begin using Statistics y = rand(20, 3) plot( y, xaxis = ("XLABEL", (-5, 30), 0:2:20, :flip), background_color = RGB(0.2, 0.2, 0.2), leg = false, ) hline!( mean(y, dims = 1) + rand(1, 3), line = (4, :dash, 0.6, [:lightgreen :green :darkgreen]), ) vline!([5, 10]) title!("TITLE") yaxis!("YLABEL", :log10, minorgrid = true) end ), ], ), PlotExample( # 6 "Images", "Plot an image. y-axis is set to flipped", [ :( begin import FileIO path = download("http://juliaplots.org/PlotReferenceImages.jl/Plots/pyplot/0.7.0/ref1.png") img = FileIO.load(path) plot(img) end ), ], ), PlotExample( # 7 "Arguments", """ Plot multiple series with different numbers of points. Mix arguments that apply to all series (marker/markersize) with arguments unique to each series (colors). Special arguments `line`, `marker`, and `fill` will automatically figure out what arguments to set (for example, we are setting the `linestyle`, `linewidth`, and `color` arguments with `line`.) Note that we pass a matrix of colors, and this applies the colors to each series. """, [ :( begin ys = Vector[rand(10), rand(20)] plot( ys, color = [:black :orange], line = (:dot, 4), marker = ([:hex :d], 12, 0.8, Plots.stroke(3, :gray)), ) end ), ], ), PlotExample( # 8 "Build plot in pieces", "Start with a base plot...", [:( begin plot(rand(100) / 3, reg = true, fill = (0, :green)) end )], ), PlotExample( # 9 "", "and add to it later.", [:( begin scatter!(rand(100), markersize = 6, c = :orange) end )], ), PlotExample( # 10 "Histogram2D", "", [:( begin histogram2d(randn(10000), randn(10000), nbins = 20) end )], ), PlotExample( # 11 "Line types", "", [ :( begin linetypes = [:path :steppre :steppost :sticks :scatter] n = length(linetypes) x = Vector[sort(rand(20)) for i = 1:n] y = rand(20, n) plot( x, y, line = (linetypes, 3), lab = map(string, linetypes), ms = 15, ) end ), ], ), PlotExample( # 12 "Line styles", "", [ :( begin styles = filter( s -> s in Plots.supported_styles(), [:solid, :dash, :dot, :dashdot, :dashdotdot], ) styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors n = length(styles) y = cumsum(randn(20, n), dims = 1) plot( y, line = (5, styles), label = map(string, styles), legendtitle = "linestyle", ) end ), ], ), PlotExample( # 13 "Marker types", "", [ :( begin markers = filter( m -> m in Plots.supported_markers(), Plots._shape_keys, ) markers = permutedims(markers) n = length(markers) x = range(0, stop = 10, length = n + 2)[2:(end - 1)] y = repeat(reshape(reverse(x), 1, :), n, 1) scatter( x, y, m = markers, markersize = 8, lab = map(string, markers), bg = :linen, xlim = (0, 10), ylim = (0, 10), ) end ), ], ), PlotExample( # 14 "Bar", "`x` is the midpoint of the bar. (todo: allow passing of edges instead of midpoints)", [:( begin bar(randn(99)) end )], ), PlotExample( # 15 "Histogram", "", [ :( begin histogram( randn(1000), bins = :scott, weights = repeat(1:5, outer = 200), ) end ), ], ), PlotExample( # 16 "Subplots", """ Use the `layout` keyword, and optionally the convenient `@layout` macro to generate arbitrarily complex subplot layouts. """, [ :( begin l = @layout([a{0.1h}; b [c; d e]]) plot( randn(100, 5), layout = l, t = [:line :histogram :scatter :steppre :bar], leg = false, ticks = nothing, border = :none, ) end ), ], ), PlotExample( # 17 "Adding to subplots", """ Note here the automatic grid layout, as well as the order in which new series are added to the plots. """, [ :( begin plot( Plots.fakedata(100, 10), layout = 4, palette = cgrad.([:grays :blues :heat :lightrainbow]), bg_inside = [:orange :pink :darkblue :black], ) end ), ], ), PlotExample( # 18 "", "", [ :( begin using Random Random.seed!(111) plot!(Plots.fakedata(100, 10)) end ) ] ), PlotExample( # 19 "Open/High/Low/Close", """ Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y` argument. This uses recipes to first convert the tuples to OHLC objects, and subsequently create a :path series with the appropriate line segments. """, [ :( begin n = 20 hgt = rand(n) .+ 1 bot = randn(n) openpct = rand(n) closepct = rand(n) y = OHLC[ ( openpct[i] * hgt[i] + bot[i], bot[i] + hgt[i], bot[i], closepct[i] * hgt[i] + bot[i], ) for i = 1:n ] ohlc(y) end ), ], ), PlotExample( # 20 "Annotations", """ The `annotations` keyword is used for text annotations in data-coordinates. Pass in a tuple `(x, y, text)`, or a vector of annotations, each of which is a tuple of `x`, `y` and `text`. `text` may be a simple `String`, or a `PlotText` object, which can be built with the method `text(string, attrs...)`. This wraps font and color attributes and allows you to set text styling. `text` may also be a tuple `(string, attrs...)` of arguments which are passed to `Plots.text`. `annotate!(ann)` is shorthand for `plot!(; annotation=ann)`. Series annotations are used for annotating individual data points. They require only the annotation; x/y values are computed. Series annotations require either plain `String`s or `PlotText` objects. """, [ :( begin y = rand(10) plot( y, annotations = (3, y[3], Plots.text("this is #3", :left)), leg = false, ) annotate!([ (5, y[5], ("this is #5", 16, :red, :center)), ( 10, y[10], ("this is #10", :right, 20, "courier"), ), ]) scatter!( range(2, stop = 8, length = 6), rand(6), marker = (50, 0.2, :orange), series_annotations = [ "series", "annotations", "map", "to", "series", Plots.text("data", :green), ], ) end ), ], ), PlotExample( # 21 "Custom Markers", """A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and the size is expected to be rougly the area of the unit circle. """, [ :( begin verts = [ (-1.0, 1.0), (-1.28, 0.6), (-0.2, -1.4), (0.2, -1.4), (1.28, 0.6), (1.0, 1.0), (-1.0, 1.0), (-0.2, -0.6), (0.0, -0.2), (-0.4, 0.6), (1.28, 0.6), (0.2, -1.4), (-0.2, -1.4), (0.6, 0.2), (-0.2, 0.2), (0.0, -0.2), (0.2, 0.2), (-0.2, -0.6), ] x = 0.1:0.2:0.9 y = 0.7 * rand(5) .+ 0.15 plot( x, y, line = (3, :dash, :lightblue), marker = (Shape(verts), 30, RGBA(0, 0, 0, 0.2)), bg = :pink, fg = :darkblue, xlim = (0, 1), ylim = (0, 1), leg = false, ) end ), ], ), PlotExample( # 22 "Contours", """ Any value for fill works here. We first build a filled contour from a function, then an unfilled contour from a matrix. """, [:( begin x = 1:0.5:20 y = 1:0.5:10 f(x, y) = (3x + y^2) * abs(sin(x) + cos(y)) X = repeat(reshape(x, 1, :), length(y), 1) Y = repeat(y, 1, length(x)) Z = map(f, X, Y) p1 = contour(x, y, f, fill = true) p2 = contour(x, y, Z) plot(p1, p2) end )], ), PlotExample( # 23 "Pie", "", [:( begin x = ["Nerds", "Hackers", "Scientists"] y = [0.4, 0.35, 0.25] pie(x, y, title = "The Julia Community", l = 0.5) end )], ), PlotExample( # 24 "3D", "", [ :( begin n = 100 ts = range(0, stop = 8π, length = n) x = ts .* map(cos, ts) y = 0.1ts .* map(sin, ts) z = 1:n plot( x, y, z, zcolor = reverse(z), m = (10, 0.8, :blues, Plots.stroke(0)), leg = false, cbar = true, w = 5, ) plot!(zeros(n), zeros(n), 1:n, w = 10) end ), ], ), PlotExample( # 25 "DataFrames", "Plot using DataFrame column symbols.", [ :(using StatsPlots), # can't be inside begin block because @df gets expanded first :( begin import RDatasets iris = RDatasets.dataset("datasets", "iris") @df iris scatter( :SepalLength, :SepalWidth, group = :Species, title = "My awesome plot", xlabel = "Length", ylabel = "Width", marker = (0.5, [:cross :hex :star7], 12), bg = RGB(0.2, 0.2, 0.2), ) end ), ], ), PlotExample( # 26 "Groups and Subplots", "", [ :( begin group = rand(map(i -> "group $i", 1:4), 100) plot( rand(100), layout = @layout([a b; c]), group = group, linetype = [:bar :scatter :steppre], linecolor = :match, ) end ), ], ), PlotExample( # 27 "Polar Plots", "", [:( begin Θ = range(0, stop = 1.5π, length = 100) r = abs.(0.1 * randn(100) + sin.(3Θ)) plot(Θ, r, proj = :polar, m = 2) end )], ), PlotExample( # 28 "Heatmap, categorical axes, and aspect_ratio", "", [:( begin xs = [string("x", i) for i = 1:10] ys = [string("y", i) for i = 1:4] z = float((1:4) * reshape(1:10, 1, :)) heatmap(xs, ys, z, aspect_ratio = 1) end )], ), PlotExample( # 29 "Layouts, margins, label rotation, title location", "", [ :( begin using Plots.PlotMeasures # for Measures, e.g. mm and px plot( rand(100, 6), layout = @layout([a b; c]), title = ["A" "B" "C"], titlelocation = :left, left_margin = [20mm 0mm], bottom_margin = 10px, xrotation = 60, ) end ), ], ), PlotExample( # 30 "Boxplot and Violin series recipes", "", [ :(using StatsPlots), # can't be inside begin block because @df gets expanded first :( begin import RDatasets singers = RDatasets.dataset("lattice", "singer") @df singers violin( :VoicePart, :Height, line = 0, fill = (0.2, :blue), ) @df singers boxplot!( :VoicePart, :Height, line = (2, :black), fill = (0.3, :orange), ) end ), ], ), PlotExample( # 31 "Animation with subplots", "The `layout` macro can be used to create an animation with subplots.", [ :( begin l = @layout([[a; b] c]) p = plot( plot([sin, cos], 1, ylims = (-1, 1), leg = false), scatter([atan, cos], 1, ylims = (-1, 1.5), leg = false), plot(log, 1, ylims = (0, 2), leg = false), layout = l, xlims = (1, 2π), ) anim = Animation() for x in range(1, stop = 2π, length = 20) plot(push!( p, x, Float64[sin(x), cos(x), atan(x), cos(x), log(x)], )) frame(anim) end end ), ], ), PlotExample( # 32 "Spy", """ For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. """, [ :( begin using SparseArrays a = spdiagm( 0 => ones(50), 1 => ones(49), -1 => ones(49), 10 => ones(40), -10 => ones(40), ) b = spdiagm( 0 => 1:50, 1 => 1:49, -1 => 1:49, 10 => 1:40, -10 => 1:40, ) plot( spy(a), spy(b), title = ["Unique nonzeros" "Different nonzeros"], ) end ), ], ), PlotExample( # 33 "Magic grid argument", """ The grid lines can be modified individually for each axis with the magic `grid` argument. """, [ :( begin x = rand(10) p1 = plot(x, title = "Default looks") p2 = plot( x, grid = (:y, :olivedrab, :dot, 1, 0.9), title = "Modified y grid", ) p3 = plot(deepcopy(p2), title = "Add x grid") xgrid!(p3, :on, :cadetblue, 2, :dashdot, 0.4) plot( p1, p2, p3, layout = (1, 3), label = "", fillrange = 0, fillalpha = 0.3, ) end ), ], ), PlotExample( # 34 "Framestyle", """ The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`. """, [ :( begin scatter( fill(randn(10), 6), fill(randn(10), 6), framestyle = [:box :semi :origin :zerolines :grid :none], title = [":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], color = permutedims(1:6), layout = 6, label = "", markerstrokewidth = 0, ticks = -2:2, ) end ), ], ), PlotExample( # 35 "Lines and markers with varying colors", """ You can use the `line_z` and `marker_z` properties to associate a color with each line segment or marker in the plot. """, [ :( begin t = range(0, stop = 1, length = 100) θ = 6π .* t x = t .* cos.(θ) y = t .* sin.(θ) p1 = plot(x, y, line_z = t, linewidth = 3, legend = false) p2 = scatter( x, y, marker_z = +, color = :bluesreds, legend = false, ) plot(p1, p2) end ), ], ), PlotExample( # 36 "Portfolio Composition maps", """ see: http://stackoverflow.com/a/37732384/5075246 """, [ :( begin using Random Random.seed!(111) tickers = ["IBM", "Google", "Apple", "Intel"] N = 10 D = length(tickers) weights = rand(N, D) weights ./= sum(weights, dims = 2) returns = sort!((1:N) + D * randn(N)) portfoliocomposition( weights, returns, labels = permutedims(tickers), ) end ), ], ), PlotExample( # 37 "Ribbons", """ Ribbons can be added to lines via the `ribbon` keyword; you can pass a tuple of arrays (upper and lower bounds), a single Array (for symmetric ribbons), a Function, or a number. """, [ :( begin plot( plot( 0:10; ribbon = (LinRange(0, 2, 11), LinRange(0, 1, 11)), ), plot(0:10; ribbon = 0:0.5:5), plot(0:10; ribbon = sqrt), plot(0:10; ribbon = 1), ) end ), ], ), PlotExample( # 38 "Histogram2D (complex values)", "", [ :( begin n = 10_000 x = exp.(0.1 * randn(n) .+ randn(n) .* (im)) histogram2d( x, nbins = (20, 40), show_empty_bins = true, normed = true, aspect_ratio = 1, ) end ), ], ), PlotExample( # 39 "Unconnected lines using `missing` or `NaN`", """ Missing values and non-finite values, including `NaN`, are not plotted. Instead, lines are separated into segments at these values. """, [ :( begin x, y = [1, 2, 2, 1, 1], [1, 2, 1, 2, 1] plot( plot([rand(5); NaN; rand(5); NaN; rand(5)]), plot([1, missing, 2, 3], marker = true), plot([x; NaN; x .+ 2], [y; NaN; y .+ 1], arrow = 2), plot( [1, 2 + 3im, Inf, 4im, 3, -Inf * im, 0, 3 + 3im], marker = true, ), legend = false, ) end ), ], ), PlotExample( # 40 "Lens", "A lens lets you easily magnify a region of a plot. x and y coordinates refer to the to be magnified region and the via the `inset` keyword the subplot index and the bounding box (in relative coordinates) of the inset plot with the magnified plot can be specified. Additional attributes count for the inset plot.", [ quote begin plot( [(0, 0), (0, 0.9), (1, 0.9), (2, 1), (3, 0.9), (80, 0)], legend = :outertopright, ) plot!([(0, 0), (0, 0.9), (2, 0.9), (3, 1), (4, 0.9), (80, 0)]) plot!([(0, 0), (0, 0.9), (3, 0.9), (4, 1), (5, 0.9), (80, 0)]) plot!([(0, 0), (0, 0.9), (4, 0.9), (5, 1), (6, 0.9), (80, 0)]) lens!( [1, 6], [0.9, 1.1], inset = (1, bbox(0.5, 0.0, 0.4, 0.4)), ) end end, ], ), PlotExample( # 41 "Array Types", "Plots supports different `Array` types that follow the `AbstractArray` interface, like `StaticArrays` and `OffsetArrays.`", [ quote begin using StaticArrays, OffsetArrays sv = SVector{10}(rand(10)) ov = OffsetVector(rand(10), -2) plot([sv, ov], label = ["StaticArray" "OffsetArray"]) plot!(3ov, ribbon=ov, label="OffsetArray ribbon") end end, ], ), PlotExample( # 42 "Setting defaults and font arguments", "", [ quote begin using Plots default( titlefont = (20, "times"), legendfontsize = 18, guidefont = (18, :darkgreen), tickfont = (12, :orange), guide = "x", framestyle = :zerolines, yminorgrid = true ) plot( [sin, cos], -2π, 2π, label = ["sin(θ)" "cos(θ)"], title = "Trigonometric Functions", xlabel = "θ", linewidth = 2, legend = :outertopleft, ) end end, ], ), PlotExample( # 43 "Heatmap with DateTime axis", "", [ quote begin using Dates z = rand(5, 5) x = DateTime.(2016:2020) y = 1:5 heatmap(x, y, z) end end, ], ), PlotExample( # 44 "Linked axes", "", [ quote begin x = -5:0.1:5 plot(plot(x, x->x^2), plot(x, x->sin(x)), layout = 2, link = :y) end end, ], ), PlotExample( # 45 "Error bars and array type recipes", "", [ quote begin struct Measurement <: Number val::Float64 err::Float64 end value(m::Measurement) = m.val uncertainty(m::Measurement) = m.err @recipe function f(::Type{T}, m::T) where T <: AbstractArray{<:Measurement} if !(get(plotattributes, :seriestype, :path) in [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image]) error_sym = Symbol(plotattributes[:letter], :error) plotattributes[error_sym] = uncertainty.(m) end value.(m) end x = Measurement.(10sort(rand(10)), rand(10)) y = Measurement.(10sort(rand(10)), rand(10)) z = Measurement.(10sort(rand(10)), rand(10)) surf = Measurement.((1:10) .* (1:10)', rand(10,10)) plot( scatter(x, [x y]), scatter(x, y, z), heatmap(x, y, surf), wireframe(x, y, surf), legend = :topleft ) end end, ], ), PlotExample( # 46 "Tuples and `Point`s as data", "", [quote using GeometryBasics using Distributions d = MvNormal([1.0 0.75; 0.75 2.0]) plot([(1,2),(3,2),(2,1),(2,3)]) scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25) end] ), PlotExample( # 47 "Mesh3d", """ Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically. You can also specify the connections using the connections keyword. The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle, such that elements at the same position of these vectors form a triangle. """, [ :( begin # specify the vertices x=[0, 1, 2, 0] y=[0, 0, 1, 2] z=[0, 2, 0, 1] # specify the triangles # every column is one triangle, # where the values denote the indices of the vertices of the triangle i=[0, 0, 0, 1] j=[1, 2, 3, 2] k=[2, 3, 1, 3] # the four triangles gives above give a tetrahedron mesh3d( x, y, z; connections=(i, j, k), title="triangles", xlabel="x", ylabel="y", zlabel="z", legend=:none, margin=2Plots.mm ) end ), ], ), PlotExample( # 48 "Vectors of markershapes and segments", "", [quote using Base.Iterators: cycle, take yv = ones(9) ys = [1; 1; NaN; ones(6)] y = 5 .- [yv 2ys 3yv 4ys] plt_color_rows = plot( y, seriestype = [:path :path :scatter :scatter], markershape = collect(take(cycle((:utriangle, :rect)), 9)), markersize = 8, color = collect(take(cycle((:red, :black)), 9)) ) plt_z_cols = plot( y, markershape = [:utriangle :x :circle :square], markersize = [5 10 10 5], marker_z = [5 4 3 2], line_z = [1 3 3 1], linewidth = [1 10 5 1] ) plot(plt_color_rows, plt_z_cols) end] ), PlotExample( # 49 "Polar heatmaps", "", [quote x = range(0, 2π, length=9) y = 0:4 z = (1:4) .+ (1:8)' heatmap(x, y, z, projection = :polar) end] ), PlotExample( # 50 "3D surface with axis guides", "", [quote f(x,a) = 1/x + a*x^2 xs = collect(0.1:0.05:2.0); as = collect(0.2:0.1:2.0); x_grid = [x for x in xs for y in as]; a_grid = [y for x in xs for y in as]; plot(x_grid, a_grid, f.(x_grid,a_grid), st = :surface, xlabel = "longer xlabel", ylabel = "longer ylabel", zlabel = "longer zlabel", ) end] ), PlotExample( # 51 "Images with custom axes", "", [quote using Plots using TestImages img = testimage("lighthouse") # plot the image reversing the first dimension and setting yflip = false plot([-π, π], [-1, 1], reverse(img, dims=1), yflip=false, aspect_ratio=:none) # plot other data plot!(sin, -π, π, lw=3, color=:red) end] ), PlotExample( "3d quiver", "", [quote using Plots ϕs = range(-π, π, length=50) θs = range(0, π, length=25) θqs = range(1, π-1, length=25) x = vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)]) y = vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θs)]) z = vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θs)]) u = 0.1 * vec([sin(θ) * cos(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)]) v = 0.1 * vec([sin(θ) * sin(ϕ) for (ϕ, θ) in Iterators.product(ϕs, θqs)]) w = 0.1 * vec([cos(θ) for (ϕ, θ) in Iterators.product(ϕs, θqs)]) quiver(x,y,z, quiver=(u,v,w)) end] ), PlotExample( # 53 "Step Types", "A comparison of the various step-like `seriestype`s", [ :( begin x = 1:5 y = [1, 2, 3, 2, 1] default(shape=:circle) plot( plot(x, y, markershape=:circle, seriestype=:steppre, label="steppre"), plot(x, y, markershape=:circle, seriestype=:stepmid, label="stepmid"), plot(x, y, markershape=:circle, seriestype=:steppost, label="steppost"), layout=(3,1) ) end ), ], ), PlotExample( # 54 "Guide positions and alignment", "", [ :( begin plot( rand(10, 4), layout=4, xguide="x guide", yguide="y guide", xguidefonthalign=[:left :right :right :left], yguidefontvalign=[:top :bottom :bottom :top], xguideposition=:top, yguideposition=[:right :left :right :left], ymirror=[false true true false], xmirror=[false false true true], legend=false, seriestype=[:bar :scatter :path :stepmid] ) end ), ], ), PlotExample( # 55 "3D axis flip / mirror", "", [ :( begin using LinearAlgebra scalefontsizes(.4) x, y = collect(-6:0.5:10), collect(-8:0.5:8) args = x, y, (x, y) -> sinc(norm([x, y]) / π) kwargs = Dict(:xlabel=>"x", :ylabel=>"y", :zlabel=>"z", :grid=>true, :minorgrid=>true) plots = [wireframe(args..., title = "wire"; kwargs...)] for ax ∈ (:x, :y, :z) push!(plots, wireframe( args..., title = "wire-flip-$ax", xflip = ax == :x, yflip = ax == :y, zflip = ax == :z; kwargs..., )) end for ax ∈ (:x, :y, :z) push!(plots, wireframe( args..., title = "wire-mirror-$ax", xmirror = ax == :x, ymirror = ax == :y, zmirror = ax == :z; kwargs..., )) end plt = plot(plots..., layout=(@layout [_ ° _; ° ° °; ° ° °]), margin=0Plots.px) resetfontsizes() plt end ), ], ), ] # Some constants for PlotDocs and PlotReferenceImages _animation_examples = [2, 31] _backend_skips = Dict( :gr => [25, 30], :pyplot => [2, 25, 30, 31, 47, 49, 55], :plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55], :plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55], :pgfplotsx => [ 2, # animation 6, # images 16, # pgfplots thinks the upper panel is too small 30, # @df 31, # animation 32, # spy 49, # polar heatmap 51, # image with custom axes ], :inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55], :unicodeplots => [6, 10, 22, 24, 28, 38, 43, 45, 47, 49, 50, 51, 55], :gaston => [ 2, # animations 31, # animations 47, # TODO: support mesh3d 49, # TODO: support polar 50, # TODO: 1D data not supported for pm3d ], ) # --------------------------------------------------------------------------------- # make and display one plot function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true) Plots._debugMode.on = debug @info("Testing plot: $pkgname:$idx:$(_examples[idx].header)") backend(pkgname) backend() # prevent leaking variables (esp. functions) directly into Plots namespace m = Module(:PlotExampleModule) Base.eval(m, :(using Plots)) map(exprs -> Base.eval(m, exprs), _examples[idx].exprs) plt = current() if disp gui(plt) end plt end # generate all plots and create a dict mapping idx --> plt """ test_examples(pkgname[, idx]; debug = false, disp = true, sleep = nothing, skip = [], only = nothing Run the `idx` test example for a given backend, or all examples if `idx` is not specified. """ function test_examples( pkgname::Symbol; debug = false, disp = true, sleep = nothing, skip = [], only = nothing, ) Plots._debugMode.on = debug plts = Dict() for i in eachindex(_examples) only !== nothing && !(i in only) && continue i in skip && continue try plt = test_examples(pkgname, i, debug = debug, disp = disp) plts[i] = plt catch ex # TODO: put error info into markdown? @warn("Example $pkgname:$i:$(_examples[i].header) failed with: $ex") end if sleep !== nothing Base.sleep(sleep) end end plts end