Compare commits

..
14 Commits
Author SHA1 Message Date
t-bltgandGitHub dc51f2c159 v1.21.2 [skip ci] 2021-08-30 22:22:05 +02:00
t-bltgandGitHub cc1f662b3a UnicodePlots: rm forced width/height (arbitrary) 2021-08-30 17:50:41 +02:00
t-bltgandGitHub 7b77527f80 UnicodePlots: display fix, simplify axis labels 2021-08-30 14:04:00 +02:00
8b6073c088 Format .jl files [skip ci] (#3780)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-08-29 10:53:46 +02:00
t-bltgandGitHub 09d35d7b9f UnicodePlots: heatmap support (#3774)
* UnicodePlots: heatmap support

* Fix type check
2021-08-28 21:29:04 +02:00
Simon ChristandGitHub 0a9da21443 sanitize axis strings (#3772) 2021-08-28 21:08:21 +02:00
Simon ChristandGitHub ea686c331b improve axis decorations (#3756)
* improve handling of LaTeXStrings in tick labels

* respect guidefonthalign
2021-08-28 21:08:03 +02:00
t-bltgandGitHub 25a36bab85 merge root codecov.yml [skip ci] 2021-08-28 17:05:13 +02:00
t-bltgandGitHub b227fb8943 move codecov.yml 2021-08-28 00:12:43 +02:00
t-bltgandGitHub 22651e8728 UnicodePlots: disable some unsupported examples 2021-08-26 19:54:58 +02:00
5acf967a9e v1.21.1 | No exception thrown in apply_recipe fallback (#3765)
* No exception thrown in `apply_recipe` fallback

Throwing an exception here can vastly slow down plotting, as it happens frequently. Returning an error value instead, which the calling function can check, can speed up plotting 2x. An accompanying change is necessary in RecipesPipeline.jl, assuming this value is suitable.

* Bumped compat for RecipesPipeline, tentative

* Bump patch version

* Fix wrong versioning

Co-authored-by: t-bltg <tf.bltg@gmail.com>
2021-08-26 17:46:28 +02:00
Simon Christ 5afeba656b check if .zenodo.json is valid 2021-08-26 17:17:26 +02:00
LukasKrumwiedeandGitHub 7b8bd5b253 Implementation of filling the space between and under curves for gaston (#3755) 2021-08-26 16:58:05 +02:00
Pearl LiandGitHub ded808477d Add hatched fill for GR and PyPlot (#3107) 2021-08-26 16:55:56 +02:00
15 changed files with 278 additions and 163 deletions
-2
View File
@@ -1,2 +0,0 @@
github_checks:
annotations: false
+2 -2
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.21.0"
version = "1.21.2"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -46,7 +46,7 @@ NaNMath = "0.3"
PlotThemes = "2"
PlotUtils = "1"
RecipesBase = "1"
RecipesPipeline = "0.3"
RecipesPipeline = "0.3.5, 0.4"
Reexport = "0.2, 1.0"
Requires = "1"
Scratch = "1"
+3
View File
@@ -1,3 +1,6 @@
github_checks:
annotations: false
ignore:
- "src/backends/inspectdr.jl"
- "src/backends/orca.jl"
+1
View File
@@ -14,6 +14,7 @@ const _arg_desc = KW(
: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).",
:fillstyle => "Symbol. Style of the fill area. `nothing` (the default) means solid fill. Choose from :/, :\\, :|, :-, :+, :x",
:markercolor => "Color Type. Color of the interior of the marker or shape. `:match` will take the value from `:seriescolor`.",
:markeralpha => "Number in [0,1]. The alpha/opacity override for the marker interior. `nothing` (the default) means it will take the alpha value of markercolor.",
:markersize => "Number or AbstractVector. Size (radius pixels) of the markers",
+3
View File
@@ -348,6 +348,7 @@ const _series_defaults = KW(
:fillrange => nothing, # ribbons, areas, etc
:fillcolor => :match,
:fillalpha => nothing,
:fillstyle => nothing,
:markershape => :none,
:markercolor => :match,
:markeralpha => nothing,
@@ -1117,6 +1118,7 @@ function processLineArg(plotattributes::AKW, arg)
arg.color == :auto ? :auto : plot_color(arg.color)
)
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Arrow || arg in (:arrow, :arrows)
plotattributes[:arrow] = arg
@@ -1188,6 +1190,7 @@ function processFillArg(plotattributes::AKW, arg)
arg.color == :auto ? :auto : plot_color(arg.color)
)
arg.alpha === nothing || (plotattributes[:fillalpha] = arg.alpha)
arg.style === nothing || (plotattributes[:fillstyle] = arg.style)
elseif typeof(arg) <: Bool
plotattributes[:fillrange] = arg ? 0 : nothing
+1
View File
@@ -928,6 +928,7 @@ const _unicodeplots_seriestype = [
# :bar,
:shape,
:histogram2d,
:heatmap,
:spy,
]
const _unicodeplots_style = [:auto, :solid]
+10 -3
View File
@@ -225,13 +225,13 @@ function gaston_add_series(plt::Plot{GastonBackend}, series::Series)
gsp = sp.o
x, y, z = series[:x], series[:y], series[:z]
st = series[:seriestype]
curves = []
if gsp.dims == 2 && z === nothing
for (n, seg) in enumerate(series_segments(series, st; check = true))
i, rng = seg.attr_index, seg.range
fr = _cycle(series[:fillrange], 1:length(x[rng]))
for sc in gaston_seriesconf!(sp, series, i, n == 1)
push!(curves, Gaston.Curve(x[rng], y[rng], nothing, nothing, sc))
push!(curves, Gaston.Curve(x[rng], y[rng], nothing, fr, sc))
end
end
else
@@ -304,8 +304,15 @@ function gaston_seriesconf!(
pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
push!(curveconf, "w points pt $pt ps $ps lc $mc")
elseif st (:path, :straightline, :path3d)
fr = series[:fillrange]
fc = gaston_color(get_fillcolor(series, i), get_fillalpha(series, i))
lc, dt, lw = gaston_lc_ls_lw(series, clims, i)
if series[:markershape] == :none # simplepath
if fr !== nothing # filled curves, but not filled curves with markers
push!(
curveconf,
"w filledcurves fc $fc fs solid border lc $lc lw $lw dt $dt,'' w lines lc $lc lw $lw dt $dt",
)
elseif series[:markershape] == :none # simplepath
push!(curveconf, "w lines lc $lc dt $dt lw $lw")
else
pt, ps, mc = gaston_mk_ms_mc(series, clims, i)
+13 -1
View File
@@ -136,6 +136,12 @@ gr_set_arrowstyle(s::Symbol) = GR.setarrowstyle(
),
)
gr_set_fillstyle(::Nothing) = GR.setfillintstyle(GR.INTSTYLE_SOLID)
function gr_set_fillstyle(s::Symbol)
GR.setfillintstyle(GR.INTSTYLE_HATCH)
GR.setfillstyle(get(((/) = 9, (\) = 10, (|) = 7, (-) = 8, (+) = 11, (x) = 6), s, 9))
end
# --------------------------------------------------------------------------------------
# draw line segments, splitting x/y into contiguous/finite segments
@@ -1058,7 +1064,9 @@ function gr_add_legend(sp, leg, viewport_plotarea)
series[:ribbon] === nothing
)
fc = get_fillcolor(series, clims)
gr_set_fill(fc) #, series[:fillalpha])
gr_set_fill(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
l, r = xpos - leg.width_factor * 3.5, xpos - leg.width_factor / 2
b, t = ypos - 0.4 * leg.dy, ypos + 0.4 * leg.dy
x = [l, r, r, l, l]
@@ -1824,6 +1832,8 @@ function gr_draw_segments(series, x, y, fillrange, clims)
i, rng = segment.attr_index, segment.range
fc = get_fillcolor(series, clims, i)
gr_set_fillcolor(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
fx = _cycle(x, vcat(rng, reverse(rng)))
fy = vcat(_cycle(fr_from, rng), _cycle(fr_to, reverse(rng)))
gr_set_transparency(fc, get_fillalpha(series, i))
@@ -1912,6 +1922,8 @@ function gr_draw_shapes(series, clims)
# draw the interior
fc = get_fillcolor(series, clims, i)
gr_set_fill(fc)
fs = get_fillstyle(series, i)
gr_set_fillstyle(fs)
gr_set_transparency(fc, get_fillalpha(series, i))
GR.fillarea(xseg, yseg)
+23 -7
View File
@@ -1174,6 +1174,12 @@ function pgfx_sanitize_plot!(plt)
end
elseif value isa Union{AbstractString,AbstractVector{<:AbstractString}}
subplot.attr[key] = pgfx_sanitize_string.(value)
elseif value isa Axis
for (k, v) in value.plotattributes
if v isa Union{AbstractString,AbstractVector{<:AbstractString}}
value.plotattributes[k] = pgfx_sanitize_string.(v)
end
end
end
end
end
@@ -1232,6 +1238,12 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
opt,
string(letter, "label style") => PGFPlotsX.Options(
labelpos => nothing,
"at" => string(
"{(ticklabel cs:",
get((left = 0, right = 1), axis[:guidefonthalign], 0.5),
")}",
),
"anchor" => "near ticklabel",
"font" => pgfx_font(axis[:guidefontsize], pgfx_thickness_scaling(sp)),
"color" => cstr,
"draw opacity" => α,
@@ -1279,21 +1291,25 @@ function pgfx_axis!(opt::PGFPlotsX.Options, sp::Subplot, letter)
push!(opt, string(letter, "tick") => string("{", join(tick_values, ","), "}"))
if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto
# wrap the power part of label with }
tick_labels = Vector{String}(undef, length(ticks[2]))
tick_labels = similar(ticks[2])
for (i, label) in enumerate(ticks[2])
base, power = split(label, "^")
power = string("{", power, "}")
tick_labels[i] = string(base, "^", power)
end
push!(
opt,
string(letter, "ticklabels") =>
string("{\$", join(tick_labels, "\$,\$"), "\$}"),
)
if tick_labels isa Vector{String}
push!(
opt,
string(letter, "ticklabels") =>
string("{\$", join(tick_labels, "\$,\$"), "\$}"),
)
elseif tick_labels isa Vector{LaTeXString}
push!(opt, string(letter, "ticklabels") => join(tick_labels))
end
elseif axis[:showaxis]
tick_labels =
ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
if axis[:formatter] in (:scientific, :auto)
if axis[:formatter] in (:scientific, :auto) && tick_labels isa Vector{String}
tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$")
tick_labels = replace.(tick_labels, Ref("×" => "\\times"))
end
+121 -72
View File
@@ -162,6 +162,9 @@ function py_fillstepstyle(seriestype::Symbol)
return nothing
end
py_fillstyle(::Nothing) = nothing
py_fillstyle(fillstyle::Symbol) = string(fillstyle)
# # untested... return a FontProperties object from a Plots.Font
# function py_font(font::Font)
# pyfont["FontProperties"](
@@ -709,24 +712,45 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
for segment in series_segments(series)
i, rng = segment.attr_index, segment.range
if length(rng) > 1
lc = get_linecolor(series, clims, i)
la = get_linealpha(series, i)
ls = get_linestyle(series, i)
fc = get_fillcolor(series, clims, i)
fa = get_fillalpha(series, i)
fs = get_fillstyle(series, i)
has_fs = !isnothing(fs)
path = pypath."Path"(hcat(x[rng], y[rng]))
# shape outline (and potentially solid fill)
patches = pypatches."PathPatch"(
path;
label = series[:label],
zorder = series[:series_plotindex],
edgecolor = py_color(
get_linecolor(series, clims, i),
get_linealpha(series, i),
),
facecolor = py_color(
get_fillcolor(series, clims, i),
get_fillalpha(series, i),
),
edgecolor = py_color(lc, la),
facecolor = py_color(fc, has_fs ? 0 : fa),
linewidth = py_thickness_scale(plt, get_linewidth(series, i)),
linestyle = py_linestyle(st, get_linestyle(series, i)),
fill = true,
linestyle = py_linestyle(st, ls),
fill = !has_fs,
)
push!(handle, ax."add_patch"(patches))
# shape hatched fill
# hatch color/alpha are controlled by edge (not face) color/alpha
if has_fs
patches = pypatches."PathPatch"(
path;
label = "",
zorder = series[:series_plotindex],
edgecolor = py_color(fc, fa),
facecolor = py_color(fc, 0), # don't fill with solid background
hatch = py_fillstyle(fs),
linewidth = 0, # don't replot shape outline (doesn't affect hatch linewidth)
linestyle = py_linestyle(st, ls),
fill = false,
)
push!(handle, ax."add_patch"(patches))
end
end
end
push!(handles, handle)
@@ -754,16 +778,23 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng)
end
la = get_linealpha(series, i)
fc = get_fillcolor(series, clims, i)
fa = get_fillalpha(series, i)
fs = get_fillstyle(series, i)
has_fs = !isnothing(fs)
handle = getproperty(ax, f)(
args...,
trues(n),
false,
py_fillstepstyle(st);
zorder = series[:series_plotindex],
facecolor = py_color(
get_fillcolor(series, clims, i),
get_fillalpha(series, i),
),
# hatch color/alpha are controlled by edge (not face) color/alpha
# if has_fs, set edge color/alpha <- fill color/alpha and face alpha <- 0
edgecolor = py_color(fc, has_fs ? fa : la),
facecolor = py_color(fc, has_fs ? 0 : fa),
hatch = py_fillstyle(fs),
linewidths = 0,
)
push!(handles, handle)
@@ -1455,67 +1486,85 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
if should_add_to_legend(series)
clims = get_clims(sp, series)
# add a line/marker and a label
push!(
handles,
if series[:seriestype] == :shape || series[:fillrange] !== nothing
pypatches."Patch"(
edgecolor = py_color(
single_color(get_linecolor(series, clims)),
get_linealpha(series),
),
facecolor = py_color(
single_color(get_fillcolor(series, clims)),
get_fillalpha(series),
),
linewidth = py_thickness_scale(
plt,
clamp(get_linewidth(series), 0, 5),
),
linestyle = py_linestyle(
series[:seriestype],
get_linestyle(series),
),
if series[:seriestype] == :shape || series[:fillrange] !== nothing
lc = get_linecolor(series, clims)
la = get_linealpha(series)
ls = get_linestyle(series)
fc = get_fillcolor(series, clims)
fa = get_fillalpha(series)
fs = get_fillstyle(series)
has_fs = !isnothing(fs)
# line (and potentially solid fill)
line_handle = pypatches."Patch"(
edgecolor = py_color(single_color(lc), la),
facecolor = py_color(single_color(fc), has_fs ? 0 : fa),
linewidth = py_thickness_scale(
plt,
clamp(get_linewidth(series), 0, 5),
),
linestyle = py_linestyle(series[:seriestype], ls),
capstyle = "butt",
)
# hatched fill
# hatch color/alpha are controlled by edge (not face) color/alpha
if has_fs
fill_handle = pypatches."Patch"(
edgecolor = py_color(single_color(fc), fa),
facecolor = py_color(single_color(fc), 0), # don't fill with solid background
hatch = py_fillstyle(fs),
linewidth = 0, # don't replot shape outline (doesn't affect hatch linewidth)
linestyle = py_linestyle(series[:seriestype], ls),
capstyle = "butt",
)
elseif series[:seriestype] in
(:path, :straightline, :scatter, :steppre, :stepmid, :steppost)
hasline = get_linewidth(series) > 0
PyPlot.plt."Line2D"(
(0, 1),
(0, 0),
color = py_color(
single_color(get_linecolor(series, clims)),
get_linealpha(series),
),
linewidth = py_thickness_scale(
plt,
hasline * sp[:legendfontsize] / 8,
),
linestyle = py_linestyle(:path, get_linestyle(series)),
solid_capstyle = "butt",
solid_joinstyle = "miter",
dash_capstyle = "butt",
dash_joinstyle = "miter",
marker = py_marker(_cycle(series[:markershape], 1)),
markersize = py_thickness_scale(plt, 0.8 * sp[:legendfontsize]),
markeredgecolor = py_color(
single_color(get_markerstrokecolor(series)),
get_markerstrokealpha(series),
),
markerfacecolor = py_color(
single_color(get_markercolor(series, clims)),
get_markeralpha(series),
),
markeredgewidth = py_thickness_scale(
plt,
0.8 * get_markerstrokewidth(series) * sp[:legendfontsize] /
first(series[:markersize]),
), # retain the markersize/markerstroke ratio from the markers on the plot
)
# plot two handles on top of each other by passing in a tuple
# https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html
push!(handles, (line_handle, fill_handle))
else
series[:serieshandle][1]
end,
)
# plot line handle (which includes solid fill) only
push!(handles, line_handle)
end
elseif series[:seriestype] in
(:path, :straightline, :scatter, :steppre, :stepmid, :steppost)
hasline = get_linewidth(series) > 0
handle = PyPlot.plt."Line2D"(
(0, 1),
(0, 0),
color = py_color(
single_color(get_linecolor(series, clims)),
get_linealpha(series),
),
linewidth = py_thickness_scale(
plt,
hasline * sp[:legendfontsize] / 8,
),
linestyle = py_linestyle(:path, get_linestyle(series)),
solid_capstyle = "butt",
solid_joinstyle = "miter",
dash_capstyle = "butt",
dash_joinstyle = "miter",
marker = py_marker(_cycle(series[:markershape], 1)),
markersize = py_thickness_scale(plt, 0.8 * sp[:legendfontsize]),
markeredgecolor = py_color(
single_color(get_markerstrokecolor(series)),
get_markerstrokealpha(series),
),
markerfacecolor = py_color(
single_color(get_markercolor(series, clims)),
get_markeralpha(series),
),
markeredgewidth = py_thickness_scale(
plt,
0.8 * get_markerstrokewidth(series) * sp[:legendfontsize] /
first(series[:markersize]),
), # retain the markersize/markerstroke ratio from the markers on the plot
)
push!(handles, handle)
else
push!(handles, series[:serieshandle][1])
end
push!(labels, series[:label])
end
end
+57 -66
View File
@@ -7,16 +7,18 @@ warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
# --------------------------------------------------------------------------------------
_canvas_map() = (
braille = UnicodePlots.BrailleCanvas,
ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas,
dot = UnicodePlots.DotCanvas,
braille = UnicodePlots.BrailleCanvas,
density = UnicodePlots.DensityCanvas,
dot = UnicodePlots.DotCanvas,
heatmap = UnicodePlots.HeatmapCanvas,
lookup = UnicodePlots.LookupCanvas,
)
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning
function rebuildUnicodePlot!(plt::Plot, width, height)
plt.o = []
function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
plt.o = UnicodePlots.Plot[]
for sp in plt.subplots
xaxis = sp[:xaxis]
@@ -41,90 +43,81 @@ function rebuildUnicodePlot!(plt::Plot, width, height)
_canvas_map()[ct]
end
# special handling for spy
if length(sp.series_list) == 1
series = sp.series_list[1]
if series[:seriestype] == :spy
push!(
plt.o,
UnicodePlots.spy(
series[:z].surf,
width = width,
height = height,
title = sp[:title],
canvas = canvas_type,
),
)
continue
end
end
# # make it a bar canvas if plotting bar
# if any(series -> series[:seriestype] == :bar, series_list(sp))
# canvas_type = UnicodePlots.BarplotGraphics
# end
o = UnicodePlots.Plot(
x,
y,
canvas_type;
width = width,
height = height,
title = sp[:title],
xlim = xlim,
ylim = ylim,
xlabel = xaxis[:guide],
ylabel = yaxis[:guide],
border = isijulia() ? :ascii : :solid,
)
# set the axis labels
UnicodePlots.xlabel!(o, xaxis[:guide])
UnicodePlots.ylabel!(o, yaxis[:guide])
# now use the ! functions to add to the plot
for series in series_list(sp)
addUnicodeSeries!(o, series.plotattributes, sp[:legend] != :none, xlim, ylim)
o = addUnicodeSeries!(sp, o, series, sp[:legend] != :none, xlim, ylim)
end
# save the object
push!(plt.o, o)
push!(plt.o, o) # save the object
end
end
# add a single series
function addUnicodeSeries!(o, plotattributes, addlegend::Bool, xlim, ylim)
# get the function, or special handling for step/bar/hist
st = plotattributes[:seriestype]
function addUnicodeSeries!(
sp::Subplot{UnicodePlotsBackend},
o,
series,
addlegend::Bool,
xlim,
ylim,
)
attrs = series.plotattributes
st = attrs[:seriestype]
# special handling
if st == :histogram2d
UnicodePlots.densityplot!(o, plotattributes[:x], plotattributes[:y])
return
return UnicodePlots.densityplot!(o, attrs[:x], attrs[:y])
elseif st == :heatmap
rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis]))
cmap = [(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)]
return UnicodePlots.heatmap(
series[:z].surf;
title = sp[:title],
zlabel = sp[:colorbar_title],
colormap = cmap,
)
elseif st == :spy
return UnicodePlots.spy(series[:z].surf; title = sp[:title])
end
# now use the ! functions to add to the plot
if st in (:path, :straightline)
func = UnicodePlots.lineplot!
elseif st == :scatter || plotattributes[:markershape] != :none
elseif st == :scatter || attrs[:markershape] != :none
func = UnicodePlots.scatterplot!
# elseif st == :bar
# func = UnicodePlots.barplot!
elseif st == :shape
func = UnicodePlots.lineplot!
else
error("Linestyle $st not supported by UnicodePlots")
error("Series type $st not supported by UnicodePlots")
end
# get the series data and label
x, y = if st == :straightline
straightline_data(plotattributes)
straightline_data(attrs)
elseif st == :shape
shape_data(plotattributes)
shape_data(attrs)
else
[collect(float(plotattributes[s])) for s in (:x, :y)]
[collect(float(attrs[s])) for s in (:x, :y)]
end
label = addlegend ? plotattributes[:label] : ""
label = addlegend ? attrs[:label] : ""
lc = plotattributes[:linecolor]
lc = attrs[:linecolor]
if typeof(lc) <: UnicodePlots.UserColorType
color = lc
elseif lc isa RGBA{Float64}
elseif typeof(lc) <: RGBA
lc = convert(ARGB32, lc)
color = map(Int, (red(lc).i, green(lc).i, blue(lc).i))
else
@@ -141,15 +134,14 @@ end
# -------------------------------
# since this is such a hack, it's only callable using `png`... should error during normal `show`
function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString)
function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString)
fn = addExtension(fn, "png")
# make some whitespace and show the plot
println("\n\n\n\n\n\n")
gui(plt)
# @osx_only begin
@static if Sys.isapple()
# make some whitespace and show the plot
println("\n\n\n\n\n\n")
gui(plt)
# BEGIN HACK
# wait while the plot gets drawn
@@ -161,21 +153,20 @@ function png(plt::AbstractPlot{UnicodePlotsBackend}, fn::AbstractString)
# END HACK (phew)
return
elseif Sys.islinux()
run(`clear`)
gui(plt)
run(`import -window $(ENV["WINDOWID"]) $fn`)
return
end
error("Can only savepng on osx with UnicodePlots (though even then I wouldn't do it)")
error(
"Can only savepng on MacOS or Linux with UnicodePlots (though even then I wouldn't do it)",
)
end
# -------------------------------
# we don't do very much for subplots... just stack them vertically
function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
w, h = plt[:size]
plt.attr[:color_palette] = [RGB(0, 0, 0)]
rebuildUnicodePlot!(plt, div(w, 10), div(h, 20))
end
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt)
foreach(x -> show(io, x), plt.o)
@@ -184,6 +175,6 @@ end
function _display(plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt)
map(show, plt.o)
map(display, plt.o)
nothing
end
+34 -9
View File
@@ -1239,17 +1239,42 @@ _backend_skips = Dict(
: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
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],
:unicodeplots => [
6, # embedded images unsupported
10, # histogram2d
13, # markers unsupported
16, # subplots unsupported
17, # grid layout unsupported
20, # annotations unsupported
21, # custom markers unsupported
22, # contours unsupported
24, # 3D unsupported
26, # subplots unsupported
29, # layout unsupported
33, # grid lines unsupported
34, # framestyles unsupported
37, # ribbons / filled unsupported
38, # histogram2D
43, # heatmap with DateTime
45, # error bars
47, # mesh3D unsupported
48, # markershapes unsupported
49, # polar heatmap
50, # 3D surface unsupported
51, # embedded images unsupported
52, # 3D quiver unsupported
55, # 3D unsupported
],
:gaston => [
2, # animations
31, # animations
+1 -1
View File
@@ -47,7 +47,7 @@ num_series(x::AMat) = size(x, 2)
num_series(x) = 1
RecipesBase.apply_recipe(plotattributes::AKW, ::Type{T}, plt::AbstractPlot) where {T} =
throw(MethodError(T, "Unmatched plot recipe: $T"))
nothing
# ---------------------------------------------------------------------------
+2
View File
@@ -538,6 +538,7 @@ get_gradient(cp::ColorPalette) = cgrad(cp, categorical = true)
get_linewidth(series, i::Int = 1) = _cycle(series[:linewidth], i)
get_linestyle(series, i::Int = 1) = _cycle(series[:linestyle], i)
get_fillstyle(series, i::Int = 1) = _cycle(series[:fillstyle], i)
function get_markerstrokecolor(series, i::Int = 1)
msc = series[:markerstrokecolor]
@@ -556,6 +557,7 @@ const _segmenting_vector_attributes = (
:linestyle,
:fillcolor,
:fillalpha,
:fillstyle,
:markercolor,
:markeralpha,
:markersize,
+7
View File
@@ -12,6 +12,13 @@ using LibGit2
import GeometryBasics
using Dates
using RecipesBase
using JSON
@testset "Infrastructure" begin
@test_nowarn JSON.Parser.parse(
String(read(joinpath(dirname(pathof(Plots)), "..", ".zenodo.json"))),
)
end
@testset "Plotly standalone" begin
@test_nowarn Plots._init_ijulia_plotting()