diff --git a/src/Plots.jl b/src/Plots.jl index 48669c7d..fb93c45f 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -186,97 +186,7 @@ include("backends/plotly.jl") include("backends/gr.jl") include("backends/web.jl") -# --------------------------------------------------------- - -@shorthands scatter -@shorthands bar -@shorthands barh -@shorthands histogram -@shorthands barhist -@shorthands stephist -@shorthands scatterhist -@shorthands histogram2d -@shorthands density -@shorthands heatmap -@shorthands plots_heatmap -@shorthands hexbin -@shorthands sticks -@shorthands hline -@shorthands vline -@shorthands hspan -@shorthands vspan -@shorthands ohlc -@shorthands contour -@shorthands contourf -@shorthands contour3d -@shorthands surface -@shorthands wireframe -@shorthands path3d -@shorthands scatter3d -@shorthands boxplot -@shorthands violin -@shorthands quiver -@shorthands curves - -"Plot a pie diagram" -pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing) -pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing) - -"Plot with seriestype :path3d" -plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d) -plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d) - -"Add title to an existing plot" -title!(s::AbstractString; kw...) = plot!(; title = s, kw...) - -"Add xlabel to an existing plot" -xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...) - -"Add ylabel to an existing plot" -ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...) - -"Set xlims for an existing plot" -xlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; xlims = lims, kw...) - -"Set ylims for an existing plot" -ylims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; ylims = lims, kw...) - -"Set zlims for an existing plot" -zlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; zlims = lims, kw...) - -xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...) -ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...) -zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...) - - -"Set xticks for an existing plot" -xticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; xticks = v, kw...) - -"Set yticks for an existing plot" -yticks!(v::TicksArgs; kw...) where {T<:Real} = plot!(; yticks = v, kw...) - -xticks!( -ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...) -yticks!( -ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; yticks = (ticks,labels), kw...) - -"Add annotations to an existing plot" -annotate!(anns...; kw...) = plot!(; annotation = anns, kw...) -annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...) - -"Flip the current plots' x axis" -xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...) - -"Flip the current plots' y axis" -yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...) - -"Specify x axis attributes for an existing plot" -xaxis!(args...; kw...) = plot!(; xaxis = args, kw...) - -"Specify x axis attributes for an existing plot" -yaxis!(args...; kw...) = plot!(; yaxis = args, kw...) -xgrid!(args...; kw...) = plot!(; xgrid = args, kw...) -ygrid!(args...; kw...) = plot!(; ygrid = args, kw...) +include("shorthands.jl") let PlotOrSubplot = Union{Plot, Subplot} global title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 64ce5b93..6fe8f068 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -2,7 +2,7 @@ const _arg_desc = KW( # series args -:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.", +:label => "String type. The label for a series, which appears in a legend. If empty, no legend entry is added.", :seriescolor => "Color Type. The base color for this series. `:auto` (the default) will select a color from the subplot's `color_palette`, based on the order it was added to the subplot", :seriesalpha => "Number in [0,1]. The alpha/opacity override for the series. `nothing` (the default) means it will take the alpha value of the color.", :seriestype => "Symbol. This is the identifier of the type of visualization for this series. Choose from $(_allTypes) or any series recipes which are defined.", @@ -10,7 +10,7 @@ const _arg_desc = KW( :linewidth => "Number. Width of the line (in pixels)", :linecolor => "Color Type. Color of the line (for path and bar stroke). `:match` will take the value from `:seriescolor`, (though histogram/bar types use `:black` as a default).", :linealpha => "Number in [0,1]. The alpha/opacity override for the line. `nothing` (the default) means it will take the alpha value of linecolor.", -:fillrange => "Number or AbstractVector. Fills area from this to y for line-types, sets the base for bar/stick types, and similar for other types.", +:fillrange => "Number or AbstractVector. Fills area between fillrange and y for line-types, sets the base for bar/stick types, and similar for other types.", :fillcolor => "Color Type. Color of the filled area of path or bar types. `:match` will take the value from `:seriescolor`.", :fillalpha => "Number in [0,1]. The alpha/opacity override for the fill area. `nothing` (the default) means it will take the alpha value of fillcolor.", :markershape => "Symbol, Shape, or AbstractVector. Choose from $(_allMarkers).", @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(min(x), stop = extrema(x), length = 25)`", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `range(minimum(x), stop = maximum(x), length = 25)`", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", @@ -29,13 +29,13 @@ const _arg_desc = KW( :z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.", :marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.", :line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or Function `f(x,y) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).", -:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.", -:levels => "Integer, NTuple{2,Integer}. Number of levels (or x-levels/y-levels) for a contour type.", +:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.", +:levels => "Integer, NTuple{2,Integer}, or AbstractVector. Levels or number of levels (or x-levels/y-levels) for a contour type.", :orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).", :bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)", -:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).", -:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?", -:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)", +:bar_width => "nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when `orientation = :h`).", +:bar_edges => "Bool. Align bars to edges (true), or centers (the default)?", +:xerror => "AbstractVector or 2-Tuple of Vectors. x (horizontal) error relative to x-value. If 2-tuple of vectors, the first vector corresponds to the left error (and the second to the right)", :yerror => "AbstractVector or 2-Tuple of Vectors. y (vertical) error relative to y-value. If 2-tuple of vectors, the first vector corresponds to the bottom error (and the second to the top)", :ribbon => "Number or AbstractVector. Creates a fillrange around the data points.", :quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.", @@ -43,12 +43,12 @@ const _arg_desc = KW( :normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).", :weights => "AbstractVector. Used in histogram types for weighted counts.", :contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.", -:contour_labels => "Bool. Show labels at the contour lines?", +:contour_labels => "Bool. Show labels at the contour lines?", :match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.", :subplot => "Integer (subplot index) or Subplot object. The subplot that this series belongs to.", -:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", -:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.", -:hover => "nothing or vector of strings. Text to display when hovering over each data point.", +:series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", +:primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.", +:hover => "nothing or vector of strings. Text to display when hovering over each data point.", # plot args :plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)", @@ -63,11 +63,11 @@ const _arg_desc = KW( :link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).", :overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).", :html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.", -:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots", -:dpi => "Number. Dots Per Inch of output figures", +:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots", +:dpi => "Number. Dots Per Inch of output figures", :thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.", -:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.", -:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.", +:display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.", +:extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.", :fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides", # subplot args @@ -98,7 +98,7 @@ const _arg_desc = KW( :legendfont => "Font. Font of legend items.", :annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.", :projection => "Symbol or String. '3d' or 'polar'", -:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `apect_ratio` x-units.", +:aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `aspect_ratio` x-units.", :margin => "Measure (multiply by `mm`, `px`, etc). Base for individual margins... not directly used. Specifies the extra padding around subplots.", :left_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding to the left of the subplot.", :top_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the top of the subplot.", @@ -110,14 +110,14 @@ const _arg_desc = KW( :camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots", # axis args -:guide => "String. Axis guide (label).", +:guide => "String. Axis guide (label).", :guide_position => "Symbol. Position of axis guides: :top, :bottom, :left or :right", -:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]", -:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`", -:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`", -:rotation => "Number. Degrees rotation of tick labels.", -:flip => "Bool. Should we flip (reverse) the axis?", -:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.", +:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]", +:ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`", +:scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`", +:rotation => "Number. Degrees rotation of tick labels.", +:flip => "Bool. Should we flip (reverse) the axis?", +:formatter => "Function, :scientific, :plain or :auto. A method which converts a number to a string for tick labeling.", :tickfontfamily => "String or Symbol. Font family of tick labels.", :tickfontsize => "Integer. Font pointsize of tick labels.", :tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center", diff --git a/src/components.jl b/src/components.jl index f1f27dc4..f338432c 100644 --- a/src/components.jl +++ b/src/components.jl @@ -256,7 +256,25 @@ mutable struct Font color::Colorant end -"Create a Font from a list of unordered features" +""" + font(args...) + +Create a Font from an unordered list of features. + +# Arguments + +- `family`: AbstractString. "serif" or "sans-serif" or "monospace" +- `pointsize`: Integer. Size of font in points +- `halign`: Symbol. Horizontal alignment (:hcenter, :left, or :right) +- `valign`: Symbol. Vertical aligment (:vcenter, :top, or :bottom) +- `rotation`: Real. Angle of rotation for text in degrees (use a non-integer type) +- `color`: Colorant or Symbol + +# Examples +```julia-repl +julia> text("sans-serif",8,:hcenter,45.0,:blue) +``` +""" function font(args...) # defaults diff --git a/src/utils.jl b/src/utils.jl index e0d26c81..a0bad5a8 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1199,3 +1199,40 @@ end function construct_categorical_data(x::AbstractArray, axis::Axis) map(xi -> axis[:discrete_values][searchsortedfirst(axis[:continuous_values], xi)], x) end + +_fmt_paragraph(paragraph::AbstractString;kwargs...) = _fmt_paragraph(IOBuffer(),paragraph,0;kwargs...) + +function _fmt_paragraph(io::IOBuffer, + remaining_text::AbstractString, + column_count::Integer; + fillwidth=60, + leadingspaces=0) + + kwargs = (fillwidth = fillwidth, leadingspaces = leadingspaces) + + m = match(r"(.*?) (.*)",remaining_text) + if isa(m,Nothing) + if column_count + length(remaining_text) ≤ fillwidth + print(io,remaining_text) + String(take!(io)) + else + print(io,"\n"*" "^leadingspaces*remaining_text) + String(take!(io)) + end + else + if column_count + length(m[1]) ≤ fillwidth + print(io,"$(m[1]) ") + _fmt_paragraph(io,m[2],column_count + length(m[1]) + 1;kwargs...) + else + print(io,"\n"*" "^leadingspaces*"$(m[1]) ") + _fmt_paragraph(io,m[2],leadingspaces;kwargs...) + end + end +end + +function _document_argument(S::AbstractString) + _fmt_paragraph("`$S`: "*_arg_desc[Symbol(S)],leadingspaces = 6 + length(S)) +end + + +