Compare commits

...

41 Commits

Author SHA1 Message Date
Daniel Schwabeneder f11b976574 Merge pull request #2128 from daschw/release
prepare release
2019-08-07 09:29:23 +02:00
Daniel Schwabeneder 59da5d5deb prepare release 2019-08-07 09:27:05 +02:00
Daniel Schwabeneder 0deb7038e6 Merge pull request #2124 from daschw/chars
handle chars
2019-08-07 09:19:53 +02:00
Daniel Schwabeneder 2ef692c690 Merge pull request #2125 from daschw/plotly-html
Fix saving to html and IJulia show for plotly (fix #1985)
2019-08-07 09:11:36 +02:00
Daniel Schwabeneder 9228c0b9ec improve plotly html formatting 2019-08-06 16:08:49 +02:00
Daniel Schwabeneder 89d02b1d67 allow plotly plotting in ijulia 2019-08-06 15:02:04 +02:00
Daniel Schwabeneder a63a9248d6 handle chars 2019-08-06 14:05:35 +02:00
Jack Devine 79777adc07 Merge pull request #2122 from JackDevine/expand_path
Expand paths beginning with ~ on unix systems.
2019-08-06 21:30:49 +12:00
JackDevine 5619feb6c0 Expand paths beginning with ~ on unix systems. 2019-08-06 20:40:09 +12:00
Daniel Schwabeneder f15a721db6 Merge pull request #2119 from daschw/palette
don't split color_palette into groups (fix #2104)
2019-08-02 15:50:57 +02:00
Daniel Schwabeneder d6b3b68cd9 don't split color_palette into groups 2019-08-02 14:54:32 +02:00
Yuval 78785fa8fe Merge pull request #2110 from yha/convertToAny
convertToAnyVector cleanup. Adds missing support in heatmap/volume.
2019-07-31 00:33:39 +03:00
yha 74c69f575f Fix general vec method 2019-07-25 18:51:04 +03:00
yha 12e34bb24f Fix comment, move all3D method 2019-07-25 18:29:49 +03:00
yha 4ac5484b4f convertToAnyVector cleanup. Adds missing support in heatmap/volume. 2019-07-25 18:08:37 +03:00
Daniel Schwabeneder 8306619faf Merge pull request #2109 from yha/datetime-fix
Restore Date, DateTime and Time recipes
2019-07-25 15:49:14 +02:00
yha 5673477428 Restore Date, DateTime and Time recipes 2019-07-25 16:05:08 +03:00
Daniel Schwabeneder 84c5b67574 Merge pull request #2035 from wfrgra/date_period_recipes
add recipes for time periods
2019-07-18 11:37:15 +02:00
Daniel Schwabeneder e71a15d46e Merge pull request #2102 from daschw/release
release
2019-07-16 13:55:16 +02:00
Daniel Schwabeneder daf9556bed up version 2019-07-16 13:53:20 +02:00
Daniel Schwabeneder b6a7c1036c update NEWS.md 2019-07-16 13:52:52 +02:00
Anshul Singhvi 8c2a66b00c Use FFMPEG.jl for video encoding (#2099)
* add FFMPEG as a project dependency

* run(`ffmpeg ...`) -> ffmpeg_exe(`...`)

Add FFMPEG.jl to Project.toml too.
2019-07-13 17:58:28 +05:30
Anshul Singhvi a1182e0ebe JuliaPlot -> JuliaPlots in README 2019-07-13 11:02:01 +05:30
Daniel Schwabeneder 750492f9e3 Merge pull request #2093 from daschw/abstractstring
convertToAnyVector method for AbstractString
2019-07-06 15:28:54 +02:00
Daniel Schwabeneder c6893f6cb5 convertToAnyVector method for AbstractString 2019-07-06 14:44:48 +02:00
Daniel Schwabeneder 64e035c53c Merge pull request #2090 from daschw/areaplot
add areaplot recipe (close #1423)
2019-07-04 13:45:52 +02:00
Daniel Schwabeneder adbe515af7 up version 2019-07-04 12:55:02 +02:00
Daniel Schwabeneder f0dac1630f fewer lines 2019-07-04 12:53:01 +02:00
Daniel Schwabeneder ddaa69bce2 move areaplot doc from shorthands to recipes 2019-07-04 12:48:47 +02:00
Daniel Schwabeneder bb7c2fd660 Merge pull request #2089 from daschw/zcolor-missing
allow missing in line_z, fill_z and marker_z (fix #2083)
2019-07-04 11:36:08 +02:00
Daniel Schwabeneder 8dfca61769 add areaplot recipe 2019-07-04 11:31:00 +02:00
Daniel Schwabeneder bb3c54cb27 allow missing in line_z, fill_z and marker_z 2019-07-04 10:39:31 +02:00
Daniel Schwabeneder 2816b1128f Merge pull request #2081 from oschulz/loghist-zerobins-fix
Fix representation of zero-valued bins on step-histograms with log-y axis
2019-07-02 08:01:50 +02:00
Daniel Schwabeneder cf0cf972e3 Merge pull request #2080 from daschw/gr-linealpha
fix gr linealpha (fix #2078)
2019-07-02 08:01:23 +02:00
Daniel Schwabeneder bb0e783c02 Merge pull request #2082 from yha/point-recipe-fix
Support arbitrary element type (esp. missing) in tuple/Point recipes
2019-07-01 22:02:52 +02:00
yha a7b7c5ba81 Support any element type (incl. missing) and length in tuple/Point recipes 2019-07-01 01:39:05 +03:00
Oliver Schulz 7214b8b1b1 Improve type stability of _stepbins_path 2019-06-30 17:42:25 +02:00
Oliver Schulz db1e25252a Fix zero and NaN weighted bins in stephist for log-yscale
Bins with weight NaN and zero (which the Plots engine seems to
turn into into NaN automatically for log-yscale) should
not be draws in log-yscale.
2019-06-30 17:42:25 +02:00
Daniel Schwabeneder 7a248331e7 fix gr linealpha 2019-06-30 13:15:04 +02:00
Will Grant 068523fac1 neaten change by implementing with a for loop 2019-06-17 17:44:24 +10:00
Will Grant 6d6d4f14b5 add recipes for time periods 2019-05-24 11:27:09 +10:00
13 changed files with 214 additions and 187 deletions
+30
View File
@@ -11,6 +11,36 @@
---
## (current master)
## 0.26.1
- handle `Char`s as input data
- fix html saving for Plotly
- expand ~ in paths on UNIX systems
- convertToAnyVector clean-up
- fix color_palette grouping issue
## 0.26.0
- use FFMPEG.jl
- add missing method for convertToAnyVector
## 0.25.3
- add areaplot
- allow missing in z_color arguments
- more general tuple recipe
- stephist logscale improvements
## 0.25.2
- improvements to handle missings
- pyplot: allow setting the color gradient for z values
- document :colorbar_entry
- limit number of automatic bins
- fix ENV['PLOTS_DEFAULT_BACKEND']
- don't let aspect_ratio impact subplot size
- implement arrowstyle for GR
- fix bug in plotly_convert_to_datetime
- improve missing support
- gr: polar heatmaps
- make sure show returns nothing
## 0.25.1
- fix gr_display
+2 -1
View File
@@ -1,12 +1,13 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "0.25.2"
version = "0.26.1"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Contour = "d38c429a-6771-53c6-b99e-75d170b6e991"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
FFMPEG = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
+1 -1
View File
@@ -11,7 +11,7 @@
#### Created by Tom Breloff (@tbreloff)
#### Maintained by the [JuliaPlot members](https://github.com/orgs/JuliaPlots/people)
#### Maintained by the [JuliaPlots members](https://github.com/orgs/JuliaPlots/people)
Plots is a plotting API and toolset. My goals with the package are:
+3 -1
View File
@@ -1,6 +1,6 @@
module Plots
_current_plots_version = v"0.25.0"
_current_plots_version = v"0.26.1"
using Reexport
@@ -8,6 +8,8 @@ import GeometryTypes
using Dates, Printf, Statistics, Base64, LinearAlgebra, Random
import SparseArrays: findnz
using FFMPEG
@reexport using RecipesBase
import RecipesBase: plot, plot!, animate
using Base.Meta
+5 -5
View File
@@ -70,21 +70,21 @@ function buildanimation(animdir::AbstractString, fn::AbstractString,
fps::Integer = 20, loop::Integer = 0,
variable_palette::Bool=false,
show_msg::Bool=true)
fn = abspath(fn)
fn = abspath(expanduser(fn))
if is_animated_gif
if variable_palette
# generate a colorpalette for each frame for highest quality, but larger filesize
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
ffmpeg_exe(`-v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
else
# generate a colorpalette first so ffmpeg does not have to guess it
run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
ffmpeg_exe(`-v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
# then apply the palette to get better results
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
ffmpeg_exe(` -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
end
else
run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
ffmpeg_exe(`-v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
+1 -1
View File
@@ -1280,10 +1280,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
for (i, rng) in enumerate(segments)
lc = get_linecolor(series, clims, i)
gr_set_line(get_linewidth(series, i), get_linestyle(series, i), lc) #, series[:linealpha])
gr_set_transparency(lc, get_linealpha(series, i))
arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none
arrowstyle = isa(series[:arrow], Arrow) ? series[:arrow].style : :simple
gr_set_fillcolor(lc)
gr_set_transparency(lc, get_linealpha(series, i))
gr_polyline(x[rng], y[rng]; arrowside = arrowside, arrowstyle = arrowstyle)
end
end
+7 -4
View File
@@ -347,7 +347,7 @@ function plotly_layout(plt::Plot)
end
function plotly_layout_json(plt::Plot)
JSON.json(plotly_layout(plt))
JSON.json(plotly_layout(plt), 4)
end
@@ -800,7 +800,7 @@ function plotly_series(plt::Plot)
end
# get json string for a list of dictionaries, each representing the series params
plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt))
plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt), 4)
# ----------------------------------------------------------------
@@ -822,8 +822,6 @@ function html_head(plt::Plot{PlotlyBackend})
""")
ijulia_initialized[] = true
end
# IJulia just needs one initialization
isijulia() && return ""
return "<script src=$(repr(plotly))></script>"
end
@@ -863,6 +861,11 @@ function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{Plotly
end
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
write(io, standalone_html(plt))
end
function _display(plt::Plot{PlotlyBackend})
standalone_html_window(plt)
end
+1 -1
View File
@@ -103,7 +103,7 @@ type is inferred from the file extension. All backends support png and pdf
file types, some also support svg, ps, eps, html and tex.
"""
function savefig(plt::Plot, fn::AbstractString)
fn = abspath(expanduser(fn))
# get the extension
local ext
try
+30 -3
View File
@@ -538,13 +538,15 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
w, it_state_w = it_tuple_w
if (log_scale_x && a 0)
a = b/_logScaleBases[xscale]^3
a = oftype(a, b/_logScaleBases[xscale]^3)
end
if isnan(w)
if !isnan(last_w)
push!(x, a)
push!(y, baseline)
push!(x, NaN)
push!(y, NaN)
end
else
if isnan(last_w)
@@ -557,8 +559,8 @@ function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::S
push!(y, w)
end
a = b
last_w = w
a = oftype(a, b)
last_w = oftype(last_w, w)
it_tuple_e = iterate(edge, it_state_e)
it_tuple_w = iterate(weights, it_state_w)
@@ -1097,6 +1099,7 @@ timeformatter(t) = string(Dates.Time(Dates.Nanosecond(t)))
@recipe f(::Type{Date}, dt::Date) = (dt -> Dates.value(dt), dateformatter)
@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> Dates.value(dt), datetimeformatter)
@recipe f(::Type{Dates.Time}, t::Dates.Time) = (t -> Dates.value(t), timeformatter)
@recipe f(::Type{P}, t::P) where P <: Dates.Period = (t -> Dates.value(t), t -> string(P(t)))
# -------------------------------------------------
# Complex Numbers
@@ -1181,3 +1184,27 @@ end
@series Plots.isvertical(plotattributes) ? (sx, sy) : (sy, sx)
end
end
"""
areaplot([x,] y)
areaplot!([x,] y)
Draw a stacked area plot of the matrix y.
# Examples
```julia-repl
julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], fillalpha = [0.2 0.3 0.4])
```
"""
@userplot AreaPlot
@recipe function f(a::AreaPlot)
data = cumsum(a.args[end], dims=2)
x = length(a.args) == 1 ? (1:size(data, 1)) : a.args[1]
seriestype := :line
for i in 1:size(data, 2)
@series begin
fillrange := i > 1 ? data[:,i-1] : 0
x, data[:,i]
end
end
end
+40 -87
View File
@@ -7,67 +7,36 @@
# note: returns meta information... mainly for use with automatic labeling from DataFrames for now
const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}}
const DataPoint = Union{Number, AbstractString, AbstractChar, Missing}
const SeriesData = Union{AVec{<:DataPoint}, Function, Surface, Volume}
all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(plotattributes, :seriestype, :none))
# unknown
convertToAnyVector(x, plotattributes::KW) = error("No user recipe defined for $(typeof(x))")
# missing
convertToAnyVector(v::Nothing, plotattributes::KW) = Any[nothing], nothing
# fixed number of blank series
convertToAnyVector(n::Integer, plotattributes::KW) = Any[zeros(0) for i in 1:n], nothing
# numeric/string vector
convertToAnyVector(v::AVec{T}, plotattributes::KW) where {T<:Union{Number,String,Missing}} = Any[handlemissings(v)], nothing
function convertToAnyVector(v::AMat, plotattributes::KW)
v = handlemissings(v)
if all3D(plotattributes)
Any[Surface(v)]
else
Any[v[:,i] for i in 1:size(v,2)]
end, nothing
end
prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting")
prepareSeriesData(::Nothing) = nothing
prepareSeriesData(s::SeriesData) = handlemissings(handlechars(s))
handlemissings(v) = v
handlemissings(v::AbstractArray{Union{T,Missing}}) where T <: Number = replace(v, missing => NaN)
handlemissings(v::AbstractArray{Union{T,Missing}}) where T <: String = replace(v, missing => "")
handlemissings(v::AbstractArray{Union{T,Missing}}) where T <: AbstractString = replace(v, missing => "")
handlemissings(s::Surface) = Surface(handlemissings(s.surf))
handlemissings(v::Volume) = Volume(handlemissings(v.v), v.x_extents, v.y_extents, v.z_extents)
# function
convertToAnyVector(f::Function, plotattributes::KW) = Any[f], nothing
handlechars(x) = x
handlechars(c::AVec{<:AbstractChar}) = string.(c)
# surface
convertToAnyVector(s::Surface, plotattributes::KW) = Any[s], nothing
# default: assume x represents a single series
convertToAnyVector(x) = Any[prepareSeriesData(x)]
# volume
convertToAnyVector(v::Volume, plotattributes::KW) = Any[v], nothing
# fixed number of blank series
convertToAnyVector(n::Integer) = Any[zeros(0) for i in 1:n]
# # vector of OHLC
# convertToAnyVector(v::AVec{OHLC}, plotattributes::KW) = Any[v], nothing
# # dates
convertToAnyVector(dts::AVec{D}, plotattributes::KW) where {D<:Union{Date,DateTime}} = Any[dts], nothing
# vector of data points is a single series
convertToAnyVector(v::AVec{<:DataPoint}) = Any[prepareSeriesData(v)]
# list of things (maybe other vectors, functions, or something else)
function convertToAnyVector(v::AVec, plotattributes::KW)
if all(x -> typeof(x) <: Number, v)
# all real numbers wrap the whole vector as one item
Any[convert(Vector{Float64}, v)], nothing
else
# something else... treat each element as an item
vcat(Any[convertToAnyVector(vi, plotattributes)[1] for vi in v]...), nothing
# Any[vi for vi in v], nothing
end
end
convertToAnyVector(v::AVec) = vcat((convertToAnyVector(vi) for vi in v)...)
convertToAnyVector(t::Tuple, plotattributes::KW) = Any[t], nothing
function convertToAnyVector(args...)
error("In convertToAnyVector, could not handle the argument types: $(map(typeof, args[1:end-1]))")
end
# Matrix is split into columns
convertToAnyVector(v::AMat{<:DataPoint}) = Any[prepareSeriesData(v[:,i]) for i in 1:size(v,2)]
# --------------------------------------------------------------------
@@ -130,23 +99,24 @@ struct SliceIt end
z = z.data
end
xs, _ = convertToAnyVector(x, plotattributes)
ys, _ = convertToAnyVector(y, plotattributes)
zs, _ = convertToAnyVector(z, plotattributes)
xs = convertToAnyVector(x)
ys = convertToAnyVector(y)
zs = convertToAnyVector(z)
fr = pop!(plotattributes, :fillrange, nothing)
fillranges, _ = if typeof(fr) <: Number
([fr],nothing)
fillranges = if typeof(fr) <: Number
[fr]
else
convertToAnyVector(fr, plotattributes)
convertToAnyVector(fr)
end
mf = length(fillranges)
rib = pop!(plotattributes, :ribbon, nothing)
ribbons, _ = if typeof(rib) <: Number
([fr],nothing)
ribbons = if typeof(rib) <: Number
[rib]
else
convertToAnyVector(rib, plotattributes)
convertToAnyVector(rib)
end
mr = length(ribbons)
@@ -288,8 +258,10 @@ end
@recipe f(n::Integer) = is3d(get(plotattributes,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(plotattributes, :seriestype, :none))
# return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat}
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat,Missing}
if all3D(plotattributes)
n,m = size(mat)
wrap_surfaces(plotattributes)
@@ -312,7 +284,7 @@ end
end
# assume this is a Volume, so construct one
@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Number
@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Union{Number,Missing}
seriestype := :volume
SliceIt, nothing, Volume(vol, args...), nothing
end
@@ -553,33 +525,14 @@ end
# # Lists of tuples and GeometryTypes.Points
# # --------------------------------------------------------------------
#
# # if we get an unhandled tuple, just splat it in
@recipe f(tup::Tuple) = tup
#
# # (x,y) tuples
@recipe f(xy::AVec{Tuple{R1,R2}}) where {R1<:Number,R2<:Number} = unzip(xy)
@recipe f(xy::Tuple{R1,R2}) where {R1<:Number,R2<:Number} = [xy[1]], [xy[2]]
@recipe f(v::AVec{<:Tuple}) = unzip(v)
@recipe f(v::AVec{<:GeometryTypes.Point}) = unzip(v)
@recipe f(tup::Tuple) = [tup]
@recipe f(p::GeometryTypes.Point) = [p]
#
# # (x,y,z) tuples
@recipe f(xyz::AVec{Tuple{R1,R2,R3}}) where {R1<:Number,R2<:Number,R3<:Number} = unzip(xyz)
@recipe f(xyz::Tuple{R1,R2,R3}) where {R1<:Number,R2<:Number,R3<:Number} = [xyz[1]], [xyz[2]], [xyz[3]]
# these might be points+velocity, or OHLC or something else
@recipe f(xyuv::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
@recipe f(xyuv::Tuple{R1,R2,R3,R4}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]]
#
# # 2D Points
@recipe f(xy::AVec{GeometryTypes.Point{2,T}}) where {T<:Number} = unzip(xy)
@recipe f(xy::GeometryTypes.Point{2,T}) where {T<:Number} = [xy[1]], [xy[2]]
#
# # 3D Points
@recipe f(xyz::AVec{GeometryTypes.Point{3,T}}) where {T<:Number} = unzip(xyz)
@recipe f(xyz::GeometryTypes.Point{3,T}) where {T<:Number} = [xyz[1]], [xyz[2]], [xyz[3]]
# Special case for 4-tuples in :ohlc series
@recipe f(xyuv::AVec{<:Tuple{R1,R2,R3,R4}}) where {R1,R2,R3,R4} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv)
#
# # --------------------------------------------------------------------
@@ -600,7 +553,7 @@ end
# end
splittable_kw(key, val, lengthGroup) = false
splittable_kw(key, val::AbstractArray, lengthGroup) = (key != :group) && size(val,1) == lengthGroup
splittable_kw(key, val::AbstractArray, lengthGroup) = !(key in (:group, :color_palette)) && size(val,1) == lengthGroup
splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup))
splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup)
+69 -69
View File
@@ -2,10 +2,10 @@
scatter(x,y)
scatter!(x,y)
Make a scatter plot of y vs x.
Make a scatter plot of y vs x.
# Examples
```julia-repl
```julia-repl
julia> scatter([1,2,3],[4,5,6],markersize=[3,4,5],markercolor=[:red,:green,:blue])
julia> scatter([(1,4),(2,5),(3,6)])
```
@@ -16,9 +16,9 @@ julia> scatter([(1,4),(2,5),(3,6)])
bar(x,y)
bar!(x,y)
Make a bar plot of y vs x.
Make a bar plot of y vs x.
# Arguments
# Arguments
- $(_document_argument("bar_position"))
- $(_document_argument("bar_width"))
@@ -26,7 +26,7 @@ Make a bar plot of y vs x.
- $(_document_argument("orientation"))
# Examples
```julia-repl
```julia-repl
julia> bar([1,2,3],[4,5,6],fillcolor=[:red,:green,:blue],fillalpha=[0.2,0.4,0.6])
julia> bar([(1,4),(2,5),(3,6)])
```
@@ -41,7 +41,7 @@ julia> bar([(1,4),(2,5),(3,6)])
Plot a histogram.
# Arguments
# Arguments
- `x`: AbstractVector of values to be binned
- $(_document_argument("bins"))
@@ -53,7 +53,7 @@ Plot a histogram.
- $(_document_argument("orientation"))
# Example
```julia-repl
```julia-repl
julia> histogram([1,2,1,1,4,3,8],bins=0:8)
```
"""
@@ -63,7 +63,7 @@ julia> histogram([1,2,1,1,4,3,8],bins=0:8)
barhist(x)
barhist!(x)
Make a histogram bar plot. See `histogram`.
Make a histogram bar plot. See `histogram`.
"""
@shorthands barhist
@@ -72,7 +72,7 @@ Make a histogram bar plot. See `histogram`.
stephist(x)
Make a histogram step plot (bin counts are represented using horizontal lines
instead of bars). See `histogram`.
instead of bars). See `histogram`.
"""
@shorthands stephist
@@ -80,8 +80,8 @@ instead of bars). See `histogram`.
scatterhist(x)
scatterhist!(x)
Make a histogram scatter plot (bin counts are represented using points
instead of bars). See `histogram`.
Make a histogram scatter plot (bin counts are represented using points
instead of bars). See `histogram`.
"""
@shorthands scatterhist
@@ -91,14 +91,14 @@ instead of bars). See `histogram`.
Plot a two-dimensional histogram.
# Arguments
# Arguments
- `bins`: Number of bins (if an `Integer`) or bin edges (if an `AbtractVector`)
- `weights`: Vector of weights for the values in `x`. Each entry of x contributes
its weight to the height of its bin.
- `bins`: Number of bins (if an `Integer`) or bin edges (if an `AbtractVector`)
- `weights`: Vector of weights for the values in `x`. Each entry of x contributes
its weight to the height of its bin.
# Example
```julia-repl
```julia-repl
julia> histogram2d(randn(10_000),randn(10_000))
```
"""
@@ -108,14 +108,14 @@ julia> histogram2d(randn(10_000),randn(10_000))
density(x)
density!(x)
Make a line plot of a kernel density estimate of x.
Make a line plot of a kernel density estimate of x.
# Arguments
- `x`: AbstractVector of samples for probability density estimation
- `x`: AbstractVector of samples for probability density estimation
# Example
```julia-repl
```julia-repl
julia> using StatsPlots
julia> density(randn(100_000))
```
@@ -126,10 +126,10 @@ julia> density(randn(100_000))
heatmap(x,y,z)
heatmap!(x,y,z)
Plot a heatmap of the rectangular array `z`.
Plot a heatmap of the rectangular array `z`.
# Example
```julia-repl
```julia-repl
julia> heatmap(randn(10,10))
```
"""
@@ -140,7 +140,7 @@ julia> heatmap(randn(10,10))
hexbin(x,y)
hexbin!(x,y)
Make a hexagonal binning plot (a histogram of the observations `(x[i],y[i])`
Make a hexagonal binning plot (a histogram of the observations `(x[i],y[i])`
with hexagonal bins)
# Example
@@ -154,11 +154,11 @@ julia> hexbin(randn(10_000), randn(10_000))
sticks(x,y)
sticks!(x,y)
Draw a stick plot of y vs x.
Draw a stick plot of y vs x.
# Example
```julia-repl
julia> sticks(1:10)
julia> sticks(1:10)
```
"""
@shorthands sticks
@@ -167,11 +167,11 @@ julia> sticks(1:10)
hline(y)
hline!(y)
Draw horizontal lines at positions specified by the values in
Draw horizontal lines at positions specified by the values in
the AbstractVector `y`
# Example
```julia-repl
```julia-repl
julia> hline([-1,0,2])
```
"""
@@ -181,11 +181,11 @@ julia> hline([-1,0,2])
vline(x)
vline!(x)
Draw vertical lines at positions specified by the values in
Draw vertical lines at positions specified by the values in
the AbstractVector `x`
# Example
```julia-repl
```julia-repl
julia> vline([-1,0,2])
```
"""
@@ -194,13 +194,13 @@ julia> vline([-1,0,2])
"""
hspan(y)
Draw a rectangle between the horizontal line at position `y[1]`
and the horizontal line at position `y[2]`. If `length(y) ≥ 4`,
then further rectangles are drawn between `y[3]` and `y[4]`,
`y[5]` and `y[6]`, and so on. If `length(y)` is odd, then the
last entry of `y` is ignored.
Draw a rectangle between the horizontal line at position `y[1]`
and the horizontal line at position `y[2]`. If `length(y) ≥ 4`,
then further rectangles are drawn between `y[3]` and `y[4]`,
`y[5]` and `y[6]`, and so on. If `length(y)` is odd, then the
last entry of `y` is ignored.
# Example
```julia-repl
```julia-repl
julia> hspan(1:6)
```
"""
@@ -209,13 +209,13 @@ julia> hspan(1:6)
"""
vspan(x)
Draw a rectangle between the vertical line at position `x[1]`
and the vertical line at position `x[2]`. If `length(x) ≥ 4`,
then further rectangles are drawn between `x[3]` and `x[4]`,
`x[5]` and `x[6]`, and so on. If `length(x)` is odd, then the
last entry of `x` is ignored.
Draw a rectangle between the vertical line at position `x[1]`
and the vertical line at position `x[2]`. If `length(x) ≥ 4`,
then further rectangles are drawn between `x[3]` and `x[4]`,
`x[5]` and `x[6]`, and so on. If `length(x)` is odd, then the
last entry of `x` is ignored.
# Example
```julia-repl
```julia-repl
julia> vspan(1:6)
```
"""
@@ -225,9 +225,9 @@ julia> vspan(1:6)
ohlc(x,y::Vector{OHLC})
ohlc!(x,y::Vector{OHLC})
Make open-high-low-close plot. Each entry of y is represented by a vertical
segment extending from the low value to the high value, with short horizontal
segments on the left and right indicating the open and close values, respectively.
Make open-high-low-close plot. Each entry of y is represented by a vertical
segment extending from the low value to the high value, with short horizontal
segments on the left and right indicating the open and close values, respectively.
# Example
```julia-repl
@@ -240,16 +240,16 @@ julia> ohlc(y)
"""
contour(x,y,z)
contour!(x,y,z)
contour(x,y,z)
contour!(x,y,z)
Draw contour lines of the `Surface` z.
Draw contour lines of the `Surface` z.
# Arguments
- `levels`: Contour levels (if `AbstractVector`) or number of levels (if `Integer`)
- `fill`: Bool. Fill area between contours or draw contours only (false by default)
# Example
# Example
```julia-repl
julia> x = y = range(-20, 20, length = 100)
julia> contour(x, y, (x, y) -> x^2 + y^2)
@@ -267,10 +267,10 @@ julia> contour(x, y, (x, y) -> x^2 + y^2)
surface(x,y,z)
surface!(x,y,z)
Draw a 3D surface plot.
Draw a 3D surface plot.
# Example
```julia-repl
```julia-repl
julia> x = y = range(-3, 3, length = 100)
julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
```
@@ -281,10 +281,10 @@ julia> surface(x, y, (x, y) -> sinc(norm([x, y])))
wireframe(x,y,z)
wireframe!(x,y,z)
Draw a 3D wireframe plot.
Draw a 3D wireframe plot.
# Example
```julia-repl
```julia-repl
julia> wireframe(1:10,1:10,randn(10,10))
```
"""
@@ -295,10 +295,10 @@ julia> wireframe(1:10,1:10,randn(10,10))
path3d!(x,y,z)
Plot a 3D path from `(x[1],y[1],z[1])` to `(x[2],y[2],z[2])`,
..., to `(x[end],y[end],z[end])`.
..., to `(x[end],y[end],z[end])`.
# Example
```julia-repl
```julia-repl
julia> path3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
```
"""
@@ -308,10 +308,10 @@ julia> path3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
scatter3d(x,y,z)
scatter3d!(x,y,z)
Make a 3D scatter plot.
Make a 3D scatter plot.
# Example
```julia-repl
```julia-repl
julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
```
"""
@@ -321,17 +321,17 @@ julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
boxplot(x, y)
boxplot!(x, y)
Make a box and whisker plot.
Make a box and whisker plot.
# Keyword arguments
- `notch`: Bool. Notch the box plot? (false)
- `range`: Real. Values more than range*IQR below the first quartile
or above the third quartile are shown as outliers (1.5)
- `outliers`: Bool. Show outliers? (true)
- `whisker_width`: Real or Symbol. Length of whiskers (:match)
or above the third quartile are shown as outliers (1.5)
- `outliers`: Bool. Show outliers? (true)
- `whisker_width`: Real or Symbol. Length of whiskers (:match)
# Example
```julia-repl
```julia-repl
julia> using StatsPlots
julia> boxplot(repeat([1,2,3],outer=100),randn(300))
```
@@ -342,10 +342,10 @@ julia> boxplot(repeat([1,2,3],outer=100),randn(300))
violin(x,y,z)
violin!(x,y,z)
Make a violin plot.
Make a violin plot.
# Example
```julia-repl
```julia-repl
julia> violin(repeat([1,2,3],outer=100),randn(300))
```
"""
@@ -355,11 +355,11 @@ julia> violin(repeat([1,2,3],outer=100),randn(300))
quiver(x,y,quiver=(u,v))
quiver!(x,y,quiver=(u,v))
Make a quiver (vector field) plot. The `i`th vector extends
from `(x[i],y[i])` to `(x[i] + u[i], y[i] + v[i])`.
Make a quiver (vector field) plot. The `i`th vector extends
from `(x[i],y[i])` to `(x[i] + u[i], y[i] + v[i])`.
# Example
```julia-repl
```julia-repl
julia> quiver([1,2,3],[3,2,1],quiver=([1,1,1],[1,2,3]))
```
"""
@@ -369,11 +369,11 @@ julia> quiver([1,2,3],[3,2,1],quiver=([1,1,1],[1,2,3]))
curves(x,y)
curves!(x,y)
Draw a Bezier curve from `(x[1],y[1])` to `(x[end],y[end])`
Draw a Bezier curve from `(x[1],y[1])` to `(x[end],y[end])`
with control points `(x[2],y[2]), ..., (x[end-1],y[end]-1)`
# Example
```julia-repl
```julia-repl
julia> curves([1,2,3,4],[1,1,2,4])
```
"""
@@ -424,9 +424,9 @@ ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} =
"""
annotate!(anns...)
Add annotations to an existing plot.
Add annotations to an existing plot.
# Arguments
# Arguments
- `anns`: An `AbstractVector` of tuples of the form (x,y,text). The text object
can be an String or PlotText
+13 -14
View File
@@ -271,18 +271,17 @@ maketuple(x::Tuple{T,S}) where {T,S} = x
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
mapFuncOrFuncs(fs::AVec{F}, u::AVec) where {F<:Function} = [map(f, u) for f in fs]
unzip(xy::AVec{Tuple{X,Y}}) where {X,Y} = [t[1] for t in xy], [t[2] for t in xy]
unzip(xyz::AVec{Tuple{X,Y,Z}}) where {X,Y,Z} = [t[1] for t in xyz], [t[2] for t in xyz], [t[3] for t in xyz]
unzip(xyuv::AVec{Tuple{X,Y,U,V}}) where {X,Y,U,V} = [t[1] for t in xyuv], [t[2] for t in xyuv], [t[3] for t in xyuv], [t[4] for t in xyuv]
for i in 2:4
@eval begin
unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}},
AVec{<:GeometryTypes.Point{$i}}}) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...))
end
end
unzip(xy::AVec{GeometryTypes.Point{2,T}}) where {T} = T[t[1] for t in xy], T[t[2] for t in xy]
unzip(xy::GeometryTypes.Point{2,T}) where {T} = T[xy[1]], T[xy[2]]
unzip(xyz::AVec{GeometryTypes.Point{3,T}}) where {T} = T[t[1] for t in xyz], T[t[2] for t in xyz], T[t[3] for t in xyz]
unzip(xyz::GeometryTypes.Point{3,T}) where {T} = T[xyz[1]], T[xyz[2]], T[xyz[3]]
unzip(xyuv::AVec{GeometryTypes.Point{4,T}}) where {T} = T[t[1] for t in xyuv], T[t[2] for t in xyuv], T[t[3] for t in xyuv], T[t[4] for t in xyuv]
unzip(xyuv::GeometryTypes.Point{4,T}) where {T} = T[xyuv[1]], T[xyuv[2]], T[xyuv[3]], T[xyuv[4]]
unzip(v::Union{AVec{<:GeometryTypes.Point{N}},
AVec{<:Tuple{Vararg{T,N} where T}}}) where N = error("$N-dimensional unzip not implemented.")
unzip(v::Union{AVec{<:GeometryTypes.Point},
AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.")
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
function _expand_limits(lims, x)
@@ -528,9 +527,9 @@ function get_clims(sp::Subplot)
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
for series in series_list(sp)
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real)
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
elseif (vals != nothing) && (eltype(vals) <: Real)
elseif (vals != nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
end
end
@@ -655,7 +654,7 @@ function has_attribute_segments(series::Series)
end
series[:seriestype] == :shape && return false
# ... else we check relevant attributes if they have multiple inputs
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z, :marker_z))
return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray for attr in (:line_z, :fill_z, :marker_z))
end
# ---------------------------------------------------------------
+12
View File
@@ -4,6 +4,7 @@ using Random
using BinaryProvider
using Test
using FileIO
using GeometryTypes
include("imgcomp.jl")
# don't actually show the plots
@@ -81,3 +82,14 @@ end
@test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10]
@test segments([nan10; 1:15], [1:15; nan10]) == [11:15]
end
@testset "Utils" begin
zipped = ([(1,2)], [("a","b")], [(1,"a"),(2,"b")],
[(1,2),(3,4)], [(1,2,3),(3,4,5)], [(1,2,3,4),(3,4,5,6)],
[(1,2.0),(missing,missing)], [(1,missing),(missing,"a")],
[(missing,missing)], [(missing,missing,missing),("a","b","c")])
for z in zipped
@test isequal(collect(zip(Plots.unzip(z)...)), z)
@test isequal(collect(zip(Plots.unzip(Point.(z))...)), z)
end
end