Add :mesh3d series type for Plotly (#2909)
* Add :mesh3d seriestype (in theory) * Make it work in practice * Clean up code * Add support for arbitrary 3d mesh * Add fallback for other backends * Add shorthand * Change i,j,k to series keyword * Small bugfix * Update shorthands example * Add mesh3d example * Add some documentation to example * Make color work * Move mesh3d example and add to skip list * Update fallback recipie * Update example * Update src/args.jl Co-authored-by: Simon Christ <SimonChrist@gmx.de> * Update src/backends/plotly.jl Co-authored-by: Simon Christ <SimonChrist@gmx.de> * Update src/examples.jl Co-authored-by: Simon Christ <SimonChrist@gmx.de> * Cosmetic changes Co-authored-by: Simon Christ <SimonChrist@gmx.de>
This commit is contained in:
parent
bf85afe9d6
commit
e2c387894f
@ -38,7 +38,7 @@ const _axesAliases = Dict{Symbol,Symbol}(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const _3dTypes = [
|
const _3dTypes = [
|
||||||
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume
|
:path3d, :scatter3d, :surface, :wireframe, :contour3d, :volume, :mesh3d
|
||||||
]
|
]
|
||||||
const _allTypes = vcat([
|
const _allTypes = vcat([
|
||||||
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
|
||||||
@ -288,6 +288,7 @@ const _series_defaults = KW(
|
|||||||
# one logical series to be broken up (path and markers, for example)
|
# one logical series to be broken up (path and markers, for example)
|
||||||
:hover => nothing, # text to display when hovering over the data points
|
: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.
|
: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()
|
:extra_kwargs => Dict()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -429,6 +429,7 @@ const _plotly_seriestype = [
|
|||||||
:shape,
|
:shape,
|
||||||
:scattergl,
|
:scattergl,
|
||||||
:straightline,
|
:straightline,
|
||||||
|
:mesh3d
|
||||||
]
|
]
|
||||||
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
|
const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||||
const _plotly_marker = [
|
const _plotly_marker = [
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
# https://plot.ly/javascript/getting-started
|
# https://plot.ly/javascript/getting-started
|
||||||
|
|
||||||
is_subplot_supported(::PlotlyBackend) = true
|
is_subplot_supported(::PlotlyBackend) = true
|
||||||
@ -446,7 +445,7 @@ function plotly_data(series::Series, letter::Symbol, data)
|
|||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe)
|
if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe, :mesh3d)
|
||||||
plotly_surface_data(series, data)
|
plotly_surface_data(series, data)
|
||||||
else
|
else
|
||||||
plotly_data(data)
|
plotly_data(data)
|
||||||
@ -553,7 +552,7 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
|
plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)
|
||||||
|
|
||||||
elseif st in (:surface, :wireframe)
|
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
|
plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z
|
||||||
if st == :wireframe
|
if st == :wireframe
|
||||||
plotattributes_out[:hidesurface] = true
|
plotattributes_out[:hidesurface] = true
|
||||||
@ -572,7 +571,30 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
end
|
end
|
||||||
plotattributes_out[:showscale] = hascolorbar(sp)
|
plotattributes_out[:showscale] = hascolorbar(sp)
|
||||||
end
|
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
|
else
|
||||||
@warn("Plotly: seriestype $st isn't supported.")
|
@warn("Plotly: seriestype $st isn't supported.")
|
||||||
return KW()
|
return KW()
|
||||||
|
|||||||
@ -995,16 +995,45 @@ const _examples = PlotExample[
|
|||||||
scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25)
|
scatter!(Point2.(eachcol(rand(d,1000))), alpha=0.25)
|
||||||
end]
|
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
|
# Some constants for PlotDocs and PlotReferenceImages
|
||||||
_animation_examples = [2, 31]
|
_animation_examples = [2, 31]
|
||||||
_backend_skips = Dict(
|
_backend_skips = Dict(
|
||||||
:gr => [25, 30],
|
:gr => [25, 30, 47],
|
||||||
:pyplot => [2, 25, 30, 31],
|
:pyplot => [2, 25, 30, 31, 47],
|
||||||
:plotlyjs => [2, 21, 24, 25, 30, 31],
|
:plotlyjs => [2, 21, 24, 25, 30, 31],
|
||||||
:plotly => [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 => [
|
:pgfplotsx => [
|
||||||
2, # animation
|
2, # animation
|
||||||
6, # images
|
6, # images
|
||||||
@ -1015,6 +1044,7 @@ _backend_skips = Dict(
|
|||||||
31, # animation
|
31, # animation
|
||||||
32, # spy
|
32, # spy
|
||||||
38, # histogram2d
|
38, # histogram2d
|
||||||
|
47, # mesh3d
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -913,6 +913,19 @@ end
|
|||||||
@deps pie shape
|
@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
|
# scatter 3d
|
||||||
|
|
||||||
@ -928,7 +941,6 @@ end
|
|||||||
|
|
||||||
# note: don't add dependencies because this really isn't a drop-in replacement
|
# note: don't add dependencies because this really isn't a drop-in replacement
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# lens! - magnify a region of a plot
|
# lens! - magnify a region of a plot
|
||||||
lens!(args...;kwargs...) = plot!(args...; seriestype=:lens, kwargs...)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -318,6 +318,27 @@ julia> scatter3d([0,1,2,3],[0,1,4,9],[0,1,8,27])
|
|||||||
"""
|
"""
|
||||||
@shorthands scatter3d
|
@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)
|
||||||
boxplot!(x, y)
|
boxplot!(x, y)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user