Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d6bebe1ce2 | |||
| e2c387894f | |||
| bf85afe9d6 | |||
| 217e67fb7f | |||
| 3053bb4cc2 | |||
| 8dcff1f73d | |||
| c73a5aaabc | |||
| 806d4671ce |
@@ -3,7 +3,7 @@ name: SnoopCompile
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master' # NOTE: to run the bot only on pushes to master
|
||||
# - 'master' # NOTE: to run the bot only on pushes to master
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
version: # NOTE: the versions below should match those in your botconfig
|
||||
- '1.3'
|
||||
- '1.4'
|
||||
- '1.5.0-rc1'
|
||||
- '1.5'
|
||||
os: # NOTE: should match the os setting of your botconfig
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
name = "Plots"
|
||||
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
author = ["Tom Breloff (@tbreloff)"]
|
||||
version = "1.5.8"
|
||||
version = "1.6.0"
|
||||
|
||||
[deps]
|
||||
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||
@@ -33,7 +33,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
||||
[compat]
|
||||
Contour = "0.5"
|
||||
FFMPEG = "0.2, 0.3"
|
||||
FFMPEG = "0.2, 0.3, 0.4"
|
||||
FixedPointNumbers = "0.6, 0.7, 0.8"
|
||||
GR = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51"
|
||||
GeometryBasics = "0.2"
|
||||
@@ -45,7 +45,7 @@ PGFPlotsX = "1.2.0"
|
||||
PlotThemes = "2"
|
||||
PlotUtils = "1"
|
||||
RecipesBase = "1"
|
||||
RecipesPipeline = "0.1.7"
|
||||
RecipesPipeline = "0.1.12"
|
||||
Reexport = "0.2"
|
||||
Requires = "1"
|
||||
Showoff = "0.3.1"
|
||||
|
||||
+3
-3
@@ -90,15 +90,15 @@ function buildanimation(anim::Animation, fn::AbstractString,
|
||||
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"
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
|
||||
else
|
||||
# generate a colorpalette first so ffmpeg does not have to guess it
|
||||
ffmpeg_exe(`-v $verbose_level -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
|
||||
# then apply the palette to get better results
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -loop $loop -y $fn`)
|
||||
end
|
||||
else
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -y $fn`)
|
||||
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -loop $loop -y $fn`)
|
||||
end
|
||||
|
||||
show_msg && @info("Saved animation to ", fn)
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ const _arg_desc = KW(
|
||||
:foreground_color => "Color Type. Base color for all foregrounds.",
|
||||
:size => "NTuple{2,Int}. (width_px, height_px) of the whole Plot",
|
||||
:pos => "NTuple{2,Int}. (left_px, top_px) position of the GUI window (note: currently unimplemented)",
|
||||
:window_title => "String. Title of the window.",
|
||||
:window_title => "String. Title of the standalone gui-window.",
|
||||
:show => "Bool. Should this command open/refresh a GUI/display? This allows displaying in scripts or functions without explicitly calling `display`",
|
||||
:layout => "Integer (number of subplots), NTuple{2,Integer} (grid dimensions), AbstractLayout (for example `grid(2,2)`), or the return from the `@layout` macro. This builds the layout of subplots.",
|
||||
: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).",
|
||||
|
||||
+30
-9
@@ -38,7 +38,7 @@ const _axesAliases = Dict{Symbol,Symbol}(
|
||||
)
|
||||
|
||||
const _3dTypes = [
|
||||
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume
|
||||
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume, :mesh3d
|
||||
]
|
||||
const _allTypes = vcat([
|
||||
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||
@@ -288,12 +288,20 @@ const _series_defaults = KW(
|
||||
# one logical series to be broken up (path and markers, for example)
|
||||
:hover => nothing, # text to display when hovering over the data points
|
||||
:stride => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride.
|
||||
:connections => nothing, # tuple of arrays to specifiy connectivity of a 3d mesh
|
||||
:extra_kwargs => Dict()
|
||||
)
|
||||
|
||||
|
||||
const _plot_defaults = KW(
|
||||
:plot_title => "",
|
||||
:plot_titlefontsize => 16,
|
||||
:plot_title_location => :center, # also :left or :right
|
||||
:plot_titlefontfamily => :match,
|
||||
:plot_titlefonthalign => :hcenter,
|
||||
:plot_titlefontvalign => :vcenter,
|
||||
:plot_titlefontrotation => 0.0,
|
||||
:plot_titlefontcolor => :match,
|
||||
:background_color => colorant"white", # default for all backgrounds,
|
||||
:background_color_outside => :match, # background outside grid,
|
||||
:foreground_color => :auto, # default for all foregrounds, and title color,
|
||||
@@ -360,10 +368,18 @@ const _subplot_defaults = KW(
|
||||
:right_margin => :match,
|
||||
:bottom_margin => :match,
|
||||
:subplot_index => -1,
|
||||
:colorbar_title => "",
|
||||
:framestyle => :axes,
|
||||
:camera => (30,30),
|
||||
:extra_kwargs => Dict()
|
||||
:colorbar_title => "",
|
||||
:colorbar_titlefontsize => 10,
|
||||
:colorbar_title_location => :center, # also :left or :right
|
||||
:colorbar_fontfamily => :match,
|
||||
:colorbar_titlefontfamily => :match,
|
||||
:colorbar_titlefonthalign => :hcenter,
|
||||
:colorbar_titlefontvalign => :vcenter,
|
||||
:colorbar_titlefontrotation => 0.0,
|
||||
:colorbar_titlefontcolor => :match,
|
||||
:framestyle => :axes,
|
||||
:camera => (30,30),
|
||||
:extra_kwargs => Dict()
|
||||
)
|
||||
|
||||
const _axis_defaults = KW(
|
||||
@@ -468,7 +484,7 @@ const _subplot_args = sort(union(collect(keys(_subplot_defaults))))
|
||||
const _plot_args = sort(union(collect(keys(_plot_defaults))))
|
||||
|
||||
const _magic_axis_args = [:axis, :tickfont, :guidefont, :grid, :minorgrid]
|
||||
const _magic_subplot_args = [:titlefont, :legendfont, :legendtitlefont, ]
|
||||
const _magic_subplot_args = [:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont]
|
||||
const _magic_series_args = [:line, :marker, :fill]
|
||||
|
||||
const _all_axis_args = sort(union([_axis_args; _magic_axis_args]))
|
||||
@@ -1048,7 +1064,7 @@ function RecipesPipeline.preprocess_attributes!(plotattributes::AKW)
|
||||
end
|
||||
|
||||
# fonts
|
||||
for fontname in (:titlefont, :legendfont, :legendtitlefont)
|
||||
for fontname in (:titlefont, :legendfont, :legendtitlefont, :plot_titlefont, :colorbar_titlefont)
|
||||
args = RecipesPipeline.pop_kw!(plotattributes, fontname, ())
|
||||
for arg in wraptuple(args)
|
||||
processFontArg!(plotattributes, fontname, arg)
|
||||
@@ -1285,11 +1301,16 @@ const _match_map = KW(
|
||||
:right_margin => :margin,
|
||||
:bottom_margin => :margin,
|
||||
:titlefontfamily => :fontfamily_subplot,
|
||||
:legendfontfamily => :fontfamily_subplot,
|
||||
:legendtitlefontfamily => :fontfamily_subplot,
|
||||
:titlefontcolor => :foreground_color_subplot,
|
||||
:legendfontfamily => :fontfamily_subplot,
|
||||
:legendfontcolor => :foreground_color_subplot,
|
||||
:legendtitlefontfamily => :fontfamily_subplot,
|
||||
:legendtitlefontcolor => :foreground_color_subplot,
|
||||
:colorbar_fontfamily => :fontfamily_subplot,
|
||||
:colorbar_titlefontfamily => :fontfamily_subplot,
|
||||
:colorbar_titlefontcolor => :foreground_color_subplot,
|
||||
:plot_titlefontfamily => :fontfamily,
|
||||
:plot_titlefontcolor => :foreground_color,
|
||||
:tickfontcolor => :foreground_color_text,
|
||||
:guidefontcolor => :foreground_color_guide,
|
||||
)
|
||||
|
||||
@@ -429,6 +429,7 @@ const _plotly_seriestype = [
|
||||
:shape,
|
||||
:scattergl,
|
||||
:straightline,
|
||||
:mesh3d
|
||||
]
|
||||
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||
const _plotly_marker = [
|
||||
|
||||
+26
-4
@@ -1,4 +1,3 @@
|
||||
|
||||
# https://plot.ly/javascript/getting-started
|
||||
|
||||
is_subplot_supported(::PlotlyBackend) = true
|
||||
@@ -446,7 +445,7 @@ function plotly_data(series::Series, letter::Symbol, data)
|
||||
data
|
||||
end
|
||||
|
||||
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe)
|
||||
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe, :mesh3d)
|
||||
plotly_surface_data(series, data)
|
||||
else
|
||||
plotly_data(data)
|
||||
@@ -553,7 +552,7 @@ function plotly_series(plt::Plot, series::Series)
|
||||
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
|
||||
|
||||
elseif st in (:surface, :wireframe)
|
||||
plotattributes_out[:type] = "surface"
|
||||
plotattributes_out[:type] = "surface"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
if st == :wireframe
|
||||
plotattributes_out[:hidesurface] = true
|
||||
@@ -572,7 +571,30 @@ function plotly_series(plt::Plot, series::Series)
|
||||
end
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
end
|
||||
|
||||
elseif st == :mesh3d
|
||||
plotattributes_out[:type] = "mesh3d"
|
||||
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||
|
||||
if series[:connections] != nothing
|
||||
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
|
||||
i,j,k = series[:connections]
|
||||
if !(length(i) == length(j) == length(k))
|
||||
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
|
||||
end
|
||||
plotattributes_out[:i] = i
|
||||
plotattributes_out[:j] = j
|
||||
plotattributes_out[:k] = k
|
||||
else
|
||||
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
|
||||
end
|
||||
end
|
||||
plotattributes_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||
plotattributes_out[:color] = rgba_string(plot_color(series[:fillcolor], series[:fillalpha]))
|
||||
plotattributes_out[:opacity] = series[:fillalpha]
|
||||
if series[:fill_z] !== nothing
|
||||
plotattributes_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z])
|
||||
end
|
||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||
else
|
||||
@warn("Plotly: seriestype $st isn't supported.")
|
||||
return KW()
|
||||
|
||||
@@ -640,6 +640,9 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol},
|
||||
anns
|
||||
end
|
||||
|
||||
function process_any_label(lab, font=Font())
|
||||
lab isa Tuple ? text(lab...) : text( lab, font )
|
||||
end
|
||||
# Give each annotation coordinates based on specified position
|
||||
function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText)
|
||||
position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}(
|
||||
|
||||
+33
-3
@@ -995,16 +995,45 @@ const _examples = PlotExample[
|
||||
scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25)
|
||||
end]
|
||||
),
|
||||
PlotExample(
|
||||
"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. This is only supported on the Plotly backend.
|
||||
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))
|
||||
end
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
# Some constants for PlotDocs and PlotReferenceImages
|
||||
_animation_examples = [2, 31]
|
||||
_backend_skips = Dict(
|
||||
:gr => [25, 30],
|
||||
:pyplot => [2, 25, 30, 31],
|
||||
:gr => [25, 30, 47],
|
||||
:pyplot => [2, 25, 30, 31, 47],
|
||||
:plotlyjs => [2, 21, 24, 25, 30, 31],
|
||||
:plotly => [2, 21, 24, 25, 30, 31],
|
||||
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30, 31, 34, 37, 38, 39],
|
||||
:pgfplots => [2, 5, 6, 10, 16, 20, 22, 23, 25, 28, 30, 31, 34, 37, 38, 39, 47],
|
||||
:pgfplotsx => [
|
||||
2, # animation
|
||||
6, # images
|
||||
@@ -1015,6 +1044,7 @@ _backend_skips = Dict(
|
||||
31, # animation
|
||||
32, # spy
|
||||
38, # histogram2d
|
||||
47, # mesh3d
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ function savefig(plt::Plot, fn::AbstractString)
|
||||
fn = abspath(expanduser(fn))
|
||||
|
||||
# get the extension
|
||||
fn, ext = splitext(fn)
|
||||
_, ext = splitext(fn)
|
||||
ext = chop(ext, head = 1, tail = 0)
|
||||
if isempty(ext)
|
||||
ext = defaultOutputFormat(plt)
|
||||
|
||||
+14
-1
@@ -913,6 +913,19 @@ end
|
||||
@deps pie shape
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# mesh 3d replacement for non-plotly backends
|
||||
|
||||
@recipe function f(::Type{Val{:mesh3d}}, x, y, z)
|
||||
# As long as no i,j,k are supplied this should work with PyPlot and GR
|
||||
seriestype := :surface
|
||||
if plotattributes[:connections] != nothing
|
||||
throw(ArgumentError("Giving triangles using the connections argument is only supported on Plotly backend."))
|
||||
end
|
||||
()
|
||||
end
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# scatter 3d
|
||||
|
||||
@@ -928,7 +941,6 @@ end
|
||||
|
||||
# note: don't add dependencies because this really isn't a drop-in replacement
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# lens! - magnify a region of a plot
|
||||
lens!(args...;kwargs...) = plot!(args...; seriestype=:lens, kwargs...)
|
||||
@@ -1534,3 +1546,4 @@ julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], f
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -318,6 +318,27 @@ julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
|
||||
"""
|
||||
@shorthands scatter3d
|
||||
|
||||
"""
|
||||
mesh3d(x,y,z)
|
||||
mesh3d(x,y,z; connections)
|
||||
|
||||
Plot a 3d mesh. On Plotly the triangles can be specified using the connections argument.
|
||||
|
||||
# Example
|
||||
```Julia
|
||||
x=[0, 1, 2, 0]
|
||||
y=[0, 0, 1, 2]
|
||||
z=[0, 2, 0, 1]
|
||||
|
||||
i=[0, 0, 0, 1]
|
||||
j=[1, 2, 3, 2]
|
||||
k=[2, 3, 1, 3]
|
||||
|
||||
plot(x,y,z,seriestype=:mesh3d;connections=(i,j,k))
|
||||
```
|
||||
"""
|
||||
@shorthands mesh3d
|
||||
|
||||
"""
|
||||
boxplot(x, y)
|
||||
boxplot!(x, y)
|
||||
|
||||
@@ -1004,6 +1004,24 @@ ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt))
|
||||
# ---------------------------------------------------------------
|
||||
# get fonts from objects:
|
||||
|
||||
plottitlefont(p::Plot) = font(
|
||||
p[:plot_titlefontfamily],
|
||||
p[:plot_titlefontsize],
|
||||
p[:plot_titlefontvalign],
|
||||
p[:plot_titlefonthalign],
|
||||
p[:plot_titlefontrotation],
|
||||
p[:plot_titlefontcolor],
|
||||
)
|
||||
|
||||
colorbartitlefont(sp::Subplot) = font(
|
||||
sp[:colorbar_titlefontfamily],
|
||||
sp[:colorbar_titlefontsize],
|
||||
sp[:colorbar_titlefontvalign],
|
||||
sp[:colorbar_titlefonthalign],
|
||||
sp[:colorbar_titlefontrotation],
|
||||
sp[:colorbar_titlefontcolor],
|
||||
)
|
||||
|
||||
titlefont(sp::Subplot) = font(
|
||||
sp[:titlefontfamily],
|
||||
sp[:titlefontsize],
|
||||
|
||||
@@ -302,6 +302,11 @@ end
|
||||
lines = readlines(io)
|
||||
@test count(s -> occursin("node", s), lines) == 9
|
||||
end
|
||||
# test .tikz extension
|
||||
file_path =joinpath(path,"annotations.tikz")
|
||||
@test_nowarn savefig(annotation_plot, file_path)
|
||||
@test_nowarn open(file_path) do io
|
||||
end
|
||||
end
|
||||
end # testset
|
||||
@testset "Ribbon" begin
|
||||
@@ -352,3 +357,22 @@ end # testset
|
||||
axes = Plots.pgfx_axes(pl.o)
|
||||
@test filter(x->x isa String, axes[1].contents)[1] == raw"\node at (0,0.5) {\huge hi};"
|
||||
end # testset
|
||||
|
||||
@testset "Titlefonts" begin
|
||||
pl = plot(1:5, title = "Test me", titlefont = (2, :left))
|
||||
@test pl[1][:title] == "Test me"
|
||||
@test pl[1][:titlefontsize] == 2
|
||||
@test pl[1][:titlefonthalign] == :left
|
||||
Plots._update_plot_object(pl)
|
||||
ax_opt = Plots.pgfx_axes(pl.o)[1].options
|
||||
@test ax_opt["title"] == "Test me"
|
||||
@test(haskey(ax_opt.dict, "title style")) isa Test.Pass
|
||||
pl = plot(1:5, plot_title = "Test me", plot_titlefont = (2, :left))
|
||||
@test pl[:plot_title] == "Test me"
|
||||
@test pl[:plot_titlefontsize] == 2
|
||||
@test pl[:plot_titlefonthalign] == :left
|
||||
pl = heatmap(rand(3,3), colorbar_title = "Test me", colorbar_titlefont = (12, :right))
|
||||
@test pl[1][:colorbar_title] == "Test me"
|
||||
@test pl[1][:colorbar_titlefontsize] == 12
|
||||
@test pl[1][:colorbar_titlefonthalign] == :right
|
||||
end # testset
|
||||
|
||||
Reference in New Issue
Block a user