Merge pull request #2644 from daschw/pie
Implement pie as series recipe
This commit is contained in:
commit
8976fc4ae4
12
src/axes.jl
12
src/axes.jl
@ -576,18 +576,6 @@ end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
function pie_labels(sp::Subplot, series::Series)
|
||||
plotattributes = series.plotattributes
|
||||
if haskey(plotattributes,:x_discrete_indices)
|
||||
dvals = sp.attr[:xaxis].plotattributes[:discrete_values]
|
||||
[dvals[idx] for idx in plotattributes[:x_discrete_indices]]
|
||||
else
|
||||
plotattributes[:x]
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# compute the line segments which should be drawn for this axis
|
||||
function axis_drawing_info(sp::Subplot)
|
||||
xaxis, yaxis = sp[:xaxis], sp[:yaxis]
|
||||
|
||||
@ -341,10 +341,18 @@ const _gr_attr = merge_with_base_supported([
|
||||
:contour_labels,
|
||||
])
|
||||
const _gr_seriestype = [
|
||||
:path, :scatter, :straightline,
|
||||
:heatmap, :pie, :image,
|
||||
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
|
||||
:shape
|
||||
:path,
|
||||
:scatter,
|
||||
:straightline,
|
||||
:heatmap,
|
||||
:image,
|
||||
:contour,
|
||||
:path3d,
|
||||
:scatter3d,
|
||||
:surface,
|
||||
:wireframe,
|
||||
:volume,
|
||||
:shape,
|
||||
]
|
||||
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||
const _gr_marker = _allMarkers
|
||||
@ -408,9 +416,17 @@ const _plotly_attr = merge_with_base_supported([
|
||||
])
|
||||
|
||||
const _plotly_seriestype = [
|
||||
:path, :scatter, :pie, :heatmap,
|
||||
:contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl,
|
||||
:straightline
|
||||
:path,
|
||||
:scatter,
|
||||
:heatmap,
|
||||
:contour,
|
||||
:surface,
|
||||
:wireframe,
|
||||
:path3d,
|
||||
:scatter3d,
|
||||
:shape,
|
||||
:scattergl,
|
||||
:straightline,
|
||||
]
|
||||
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
const _plotly_marker = [
|
||||
@ -533,12 +549,22 @@ const _pyplot_attr = merge_with_base_supported([
|
||||
:contour_labels,
|
||||
])
|
||||
const _pyplot_seriestype = [
|
||||
:path, :steppre, :steppost, :shape, :straightline,
|
||||
:scatter, :hexbin, #:histogram2d, :histogram,
|
||||
# :bar,
|
||||
:heatmap, :pie, :image,
|
||||
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
|
||||
]
|
||||
:path,
|
||||
:steppre,
|
||||
:steppost,
|
||||
:shape,
|
||||
:straightline,
|
||||
:scatter,
|
||||
:hexbin,
|
||||
:heatmap,
|
||||
:image,
|
||||
:contour,
|
||||
:contour3d,
|
||||
:path3d,
|
||||
:scatter3d,
|
||||
:surface,
|
||||
:wireframe,
|
||||
]
|
||||
const _pyplot_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
const _pyplot_marker = vcat(_allMarkers, :pixel)
|
||||
const _pyplot_scale = [:identity, :ln, :log2, :log10]
|
||||
@ -605,12 +631,22 @@ const _hdf5_attr = merge_with_base_supported([
|
||||
:colorbar_title,
|
||||
])
|
||||
const _hdf5_seriestype = [
|
||||
:path, :steppre, :steppost, :shape, :straightline,
|
||||
:scatter, :hexbin, #:histogram2d, :histogram,
|
||||
# :bar,
|
||||
:heatmap, :pie, :image,
|
||||
:contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe
|
||||
]
|
||||
:path,
|
||||
:steppre,
|
||||
:steppost,
|
||||
:shape,
|
||||
:straightline,
|
||||
:scatter,
|
||||
:hexbin,
|
||||
:heatmap,
|
||||
:image,
|
||||
:contour,
|
||||
:contour3d,
|
||||
:path3d,
|
||||
:scatter3d,
|
||||
:surface,
|
||||
:wireframe,
|
||||
]
|
||||
const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
const _hdf5_marker = vcat(_allMarkers, :pixel)
|
||||
const _hdf5_scale = [:identity, :ln, :log2, :log10]
|
||||
|
||||
@ -1048,9 +1048,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
# axes_2d = true
|
||||
for series in series_list(sp)
|
||||
st = series[:seriestype]
|
||||
if st == :pie
|
||||
draw_axes = false
|
||||
end
|
||||
if st in (:heatmap, :image)
|
||||
outside_ticks = true
|
||||
x, y = heatmap_edges(series[:x], sp[:xaxis][:scale], series[:y], sp[:yaxis][:scale], size(series[:z]))
|
||||
@ -1704,54 +1701,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
gr_draw_markers(series, x2, y2, clims)
|
||||
end
|
||||
|
||||
# TODO: replace with pie recipe
|
||||
elseif st == :pie
|
||||
GR.selntran(0)
|
||||
GR.setfillintstyle(GR.INTSTYLE_SOLID)
|
||||
xmin, xmax, ymin, ymax = viewport_plotarea
|
||||
ymax -= 0.1 * (xmax - xmin)
|
||||
xcenter = 0.5 * (xmin + xmax)
|
||||
ycenter = 0.5 * (ymin + ymax)
|
||||
if xmax - xmin > ymax - ymin
|
||||
r = 0.5 * (ymax - ymin)
|
||||
xmin, xmax = xcenter - r, xcenter + r
|
||||
else
|
||||
r = 0.5 * (xmax - xmin)
|
||||
ymin, ymax = ycenter - r, ycenter + r
|
||||
end
|
||||
labels = pie_labels(sp, series)
|
||||
slices = series[:y]
|
||||
numslices = length(slices)
|
||||
total = sum(slices)
|
||||
a1 = 0
|
||||
x = zeros(3)
|
||||
y = zeros(3)
|
||||
for i in 1:numslices
|
||||
a2 = round(Int, a1 + (slices[i] / total) * 360.0)
|
||||
GR.setfillcolorind(980 + (i-1) % 20)
|
||||
GR.fillarc(xmin, xmax, ymin, ymax, a1, a2)
|
||||
α = 0.5 * (a1 + a2)
|
||||
cosf = r * cos(α * pi / 180)
|
||||
sinf = r * sin(α * pi / 180)
|
||||
x[1] = xcenter + cosf
|
||||
y[1] = ycenter + sinf
|
||||
x[2] = x[1] + 0.1 * cosf
|
||||
y[2] = y[1] + 0.1 * sinf
|
||||
y[3] = y[2]
|
||||
if 90 <= α < 270
|
||||
x[3] = x[2] - 0.05
|
||||
GR.settextalign(GR.TEXT_HALIGN_RIGHT, GR.TEXT_VALIGN_HALF)
|
||||
gr_text(x[3] - 0.01, y[3], string(labels[i]))
|
||||
else
|
||||
x[3] = x[2] + 0.05
|
||||
GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF)
|
||||
gr_text(x[3] + 0.01, y[3], string(labels[i]))
|
||||
end
|
||||
gr_polyline(x, y)
|
||||
a1 = a2
|
||||
end
|
||||
GR.selntran(1)
|
||||
|
||||
elseif st == :shape
|
||||
x, y = shape_data(series)
|
||||
for (i,rng) in enumerate(iter_segments(x, y))
|
||||
|
||||
@ -757,7 +757,6 @@ function pgfx_should_add_to_legend(series::Series)
|
||||
:contourf,
|
||||
:contour3d,
|
||||
:heatmap,
|
||||
:pie,
|
||||
:image,
|
||||
)
|
||||
)
|
||||
|
||||
@ -543,12 +543,6 @@ function plotly_series(plt::Plot, series::Series)
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
end
|
||||
|
||||
elseif st == :pie
|
||||
plotattributes_out[:type] = "pie"
|
||||
plotattributes_out[:labels] = pie_labels(sp, series)
|
||||
plotattributes_out[:values] = y
|
||||
plotattributes_out[:hoverinfo] = "label+percent+name"
|
||||
|
||||
else
|
||||
@warn("Plotly: seriestype $st isn't supported.")
|
||||
return KW()
|
||||
|
||||
@ -784,21 +784,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
||||
push!(handles, handle)
|
||||
end
|
||||
|
||||
if st == :pie
|
||||
handle = ax."pie"(y;
|
||||
# colors = # a vector of colors?
|
||||
labels = pie_labels(sp, series)
|
||||
)[1]
|
||||
push!(handles, handle)
|
||||
|
||||
# # expand extrema... get list of Wedge objects
|
||||
# for wedge in handle
|
||||
# path = wedge[:get_path]()
|
||||
# for
|
||||
lim = 1.1
|
||||
expand_extrema!(sp, -lim, lim, -lim, lim)
|
||||
end
|
||||
|
||||
series[:serieshandle] = handles
|
||||
|
||||
# # smoothing
|
||||
|
||||
@ -999,7 +999,6 @@ _backend_skips = Dict(
|
||||
10, # histogram2d
|
||||
16, # pgfplots thinks the upper panel is too small
|
||||
22, # contourf
|
||||
23, # pie
|
||||
25, # @df
|
||||
30, # @df
|
||||
31, # animation
|
||||
|
||||
@ -330,7 +330,7 @@ function _expand_subplot_extrema(sp::Subplot, plotattributes::AKW, st::Symbol)
|
||||
ymin, ymax = ignorenan_extrema(plotattributes[:y])
|
||||
expand_extrema!(sp[:xaxis], (xmin, xmax))
|
||||
expand_extrema!(sp[:yaxis], (ymin, ymax))
|
||||
elseif !(st in (:pie, :histogram, :bins2d, :histogram2d))
|
||||
elseif !(st in (:histogram, :bins2d, :histogram2d))
|
||||
expand_extrema!(sp, plotattributes)
|
||||
end
|
||||
# expand for zerolines (axes through origin)
|
||||
|
||||
@ -9,7 +9,6 @@ function _precompile_()
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:formatter,), Tuple{typeof(RecipesPipeline.datetimeformatter)}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims), Tuple{Bool, Tuple{Int64, Int64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :lims, :flip), Tuple{Bool, Tuple{Int64, Int64}, Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid, :ticks), Tuple{Bool, Nothing}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:grid,), Tuple{Bool}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:gridlinewidth, :grid, :gridalpha, :gridstyle, :foreground_color_grid), Tuple{Int64, Bool, Float64, Symbol, ColorTypes.RGBA{Float64}}}, typeof(Plots.attr!), Plots.Axis})
|
||||
isdefined(Plots, Symbol("#attr!##kw")) && precompile(Tuple{getfield(Plots, Symbol("#attr!##kw")), NamedTuple{(:guide,), Tuple{String}}, typeof(Plots.attr!), Plots.Axis})
|
||||
@ -523,8 +522,8 @@ function _precompile_()
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Base.UnitRange{Int64}})
|
||||
precompile(Tuple{typeof(Plots.optimal_ticks_and_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Axis, Nothing})
|
||||
precompile(Tuple{typeof(Plots.parse_axis_kw), Symbol})
|
||||
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.GRBackend}, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.pie_labels), Plots.Subplot{Plots.PlotlyBackend}, Plots.Series})
|
||||
precompile(Tuple{typeof(Plots.partialcircle), Float64, Float64, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.partialcircle), Int64, Float64, Int64, Int64})
|
||||
precompile(Tuple{typeof(Plots.plotarea!), Plots.GridLayout, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.GRBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
precompile(Tuple{typeof(Plots.plotarea!), Plots.Subplot{Plots.PlotlyBackend}, Measures.BoundingBox{Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}, Tuple{Measures.Length{:mm, Float64}, Measures.Length{:mm, Float64}}}})
|
||||
@ -539,10 +538,8 @@ function _precompile_()
|
||||
precompile(Tuple{typeof(Plots.plotly_colorscale), PlotUtils.ContinuousColorGradient, Nothing})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Array{String, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Array{String, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.plotly_data), Plots.Series, Symbol, Base.StepRange{Int64, Int64}})
|
||||
@ -562,7 +559,6 @@ function _precompile_()
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Float64, 2}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{Int64, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Array{String, 1}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.OneTo{Int64}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}})
|
||||
precompile(Tuple{typeof(Plots.plotly_native_data), Plots.Axis, Base.StepRange{Int64, Int64}})
|
||||
|
||||
@ -885,6 +885,28 @@ end
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# pie
|
||||
@recipe function f(::Type{Val{:pie}}, x, y, z)
|
||||
framestyle --> :none
|
||||
aspect_ratio --> true
|
||||
s = sum(y)
|
||||
θ = 0
|
||||
for i in eachindex(y)
|
||||
θ_new = θ + 2π * y[i] / s
|
||||
coords = [(0.0, 0.0); partialcircle(θ, θ_new, 50)]
|
||||
@series begin
|
||||
seriestype := :shape
|
||||
label --> string(x[i])
|
||||
x := first.(coords)
|
||||
y := last.(coords)
|
||||
end
|
||||
θ = θ_new
|
||||
end
|
||||
end
|
||||
@deps pie shape
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# scatter 3d
|
||||
|
||||
|
||||
@ -381,8 +381,7 @@ julia> curves([1,2,3,4],[1,1,2,4])
|
||||
@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)
|
||||
@shorthands pie
|
||||
|
||||
"Plot with seriestype :path3d"
|
||||
plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d)
|
||||
|
||||
@ -42,12 +42,24 @@ get_subplot_index(plt::Plot, sp::Subplot) = findfirst(x -> x === sp, plt.subplot
|
||||
series_list(sp::Subplot) = sp.series_list # filter(series -> series.plotattributes[:subplot] === sp, sp.plt.series_list)
|
||||
|
||||
function should_add_to_legend(series::Series)
|
||||
series.plotattributes[:primary] && series.plotattributes[:label] != "" &&
|
||||
!(series.plotattributes[:seriestype] in (
|
||||
:hexbin,:bins2d,:histogram2d,:hline,:vline,
|
||||
:contour,:contourf,:contour3d,:surface,:wireframe,
|
||||
:heatmap, :pie, :image
|
||||
))
|
||||
series.plotattributes[:primary] &&
|
||||
series.plotattributes[:label] != "" &&
|
||||
!(
|
||||
series.plotattributes[:seriestype] in (
|
||||
:hexbin,
|
||||
:bins2d,
|
||||
:histogram2d,
|
||||
:hline,
|
||||
:vline,
|
||||
:contour,
|
||||
:contourf,
|
||||
:contour3d,
|
||||
:surface,
|
||||
:wireframe,
|
||||
:heatmap,
|
||||
:image,
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user