Merge remote-tracking branch 'JuliaPlots/master'
This commit is contained in:
commit
9804debe86
@ -1,4 +1,4 @@
|
|||||||
__precompile__(false)
|
__precompile__(true)
|
||||||
|
|
||||||
module Plots
|
module Plots
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ const _arg_desc = KW(
|
|||||||
:z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.",
|
:z => "Various. Input data. Third Dimension. May be wrapped by a `Surface` for surface and heatmap types.",
|
||||||
:marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.",
|
:marker_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series data point, which correspond to the color to be used from a markercolor gradient.",
|
||||||
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).",
|
:line_z => "AbstractVector, Function `f(x,y,z) -> z_value`, or nothing. z-values for each series line segment, which correspond to the color to be used from a linecolor gradient. Note that for N points, only the first N-1 values are used (one per line-segment).",
|
||||||
|
:fill_z => "Matrix{Float64} of the same size as z matrix, which specifies the color of the 3D surface; the default value is `nothing`.",
|
||||||
:levels => "Integer, NTuple{2,Integer}. Number of levels (or x-levels/y-levels) for a contour type.",
|
:levels => "Integer, NTuple{2,Integer}. Number of levels (or x-levels/y-levels) for a contour type.",
|
||||||
:orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
|
:orientation => "Symbol. Horizontal or vertical orientation for bar types. Values `:h`, `:hor`, `:horizontal` correspond to horizontal (sideways, anchored to y-axis), and `:v`, `:vert`, and `:vertical` correspond to vertical (the default).",
|
||||||
:bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)",
|
:bar_position => "Symbol. Choose from `:overlay` (default), `:stack`. (warning: May not be implemented fully)",
|
||||||
|
|||||||
@ -188,6 +188,7 @@ const _series_defaults = KW(
|
|||||||
:z => nothing, # depth for contour, surface, etc
|
:z => nothing, # depth for contour, surface, etc
|
||||||
:marker_z => nothing, # value for color scale
|
:marker_z => nothing, # value for color scale
|
||||||
:line_z => nothing,
|
:line_z => nothing,
|
||||||
|
:fill_z => nothing,
|
||||||
:levels => 15,
|
:levels => 15,
|
||||||
:orientation => :vertical,
|
:orientation => :vertical,
|
||||||
:bar_position => :overlay, # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
|
:bar_position => :overlay, # for bar plots and histograms: could also be stack (stack up) or dodge (side by side)
|
||||||
@ -431,6 +432,7 @@ add_aliases(:zguide, :zlabel, :zlab, :zl)
|
|||||||
add_aliases(:zlims, :zlim, :zlimit, :zlimits)
|
add_aliases(:zlims, :zlim, :zlimit, :zlimits)
|
||||||
add_aliases(:zticks, :ztick)
|
add_aliases(:zticks, :ztick)
|
||||||
add_aliases(:zrotation, :zrot, :zr)
|
add_aliases(:zrotation, :zrot, :zr)
|
||||||
|
add_aliases(:fill_z, :fillz, :fz, :surfacecolor, :surfacecolour, :sc, :surfcolor, :surfcolour)
|
||||||
add_aliases(:legend, :leg, :key)
|
add_aliases(:legend, :leg, :key)
|
||||||
add_aliases(:colorbar, :cb, :cbar, :colorkey)
|
add_aliases(:colorbar, :cb, :cbar, :colorkey)
|
||||||
add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits)
|
add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits)
|
||||||
|
|||||||
@ -276,6 +276,7 @@ end
|
|||||||
@init_backend GR
|
@init_backend GR
|
||||||
@init_backend GLVisualize
|
@init_backend GLVisualize
|
||||||
@init_backend PGFPlots
|
@init_backend PGFPlots
|
||||||
|
@init_backend InspectDR
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
531
src/backends/inspectdr.jl
Normal file
531
src/backends/inspectdr.jl
Normal file
@ -0,0 +1,531 @@
|
|||||||
|
|
||||||
|
# https://github.com/ma-laforge/InspectDR.jl
|
||||||
|
|
||||||
|
#=TODO:
|
||||||
|
Tweak scale factor for width & other sizes
|
||||||
|
|
||||||
|
Not supported by InspectDR:
|
||||||
|
:foreground_color_grid
|
||||||
|
:foreground_color_border
|
||||||
|
:polar,
|
||||||
|
|
||||||
|
Add in functionality to Plots.jl:
|
||||||
|
:aspect_ratio,
|
||||||
|
=#
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
#TODO: remove features
|
||||||
|
const _inspectdr_attr = merge_with_base_supported([
|
||||||
|
:annotations,
|
||||||
|
:background_color_legend, :background_color_inside, :background_color_outside,
|
||||||
|
:foreground_color_grid, :foreground_color_legend, :foreground_color_title,
|
||||||
|
:foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text,
|
||||||
|
:label,
|
||||||
|
:linecolor, :linestyle, :linewidth, :linealpha,
|
||||||
|
:markershape, :markercolor, :markersize, :markeralpha,
|
||||||
|
:markerstrokewidth, :markerstrokecolor, :markerstrokealpha,
|
||||||
|
:markerstrokestyle, #Causes warning not to have it... what is this?
|
||||||
|
:fillcolor, :fillalpha, #:fillrange,
|
||||||
|
# :bins, :bar_width, :bar_edges, :bar_position,
|
||||||
|
:title, :title_location, :titlefont,
|
||||||
|
:window_title,
|
||||||
|
:guide, :lims, :scale, #:ticks, :flip, :rotation,
|
||||||
|
:tickfont, :guidefont, :legendfont,
|
||||||
|
:grid, :legend, #:colorbar,
|
||||||
|
# :marker_z,
|
||||||
|
# :line_z,
|
||||||
|
# :levels,
|
||||||
|
# :ribbon, :quiver, :arrow,
|
||||||
|
# :orientation,
|
||||||
|
:overwrite_figure,
|
||||||
|
:polar,
|
||||||
|
# :normalize, :weights,
|
||||||
|
# :contours, :aspect_ratio,
|
||||||
|
:match_dimensions,
|
||||||
|
# :clims,
|
||||||
|
# :inset_subplots,
|
||||||
|
:dpi,
|
||||||
|
# :colorbar_title,
|
||||||
|
])
|
||||||
|
const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot]
|
||||||
|
const _inspectdr_seriestype = [
|
||||||
|
:path, :scatter, :shape #, :steppre, :steppost
|
||||||
|
]
|
||||||
|
#see: _allMarkers, _shape_keys
|
||||||
|
const _inspectdr_marker = Symbol[
|
||||||
|
:none, :auto,
|
||||||
|
:circle, :rect, :diamond,
|
||||||
|
:cross, :xcross,
|
||||||
|
:utriangle, :dtriangle, :rtriangle, :ltriangle,
|
||||||
|
:pentagon, :hexagon, :heptagon, :octagon,
|
||||||
|
:star4, :star5, :star6, :star7, :star8,
|
||||||
|
:vline, :hline, :+, :x,
|
||||||
|
]
|
||||||
|
|
||||||
|
const _inspectdr_scale = [:identity, :ln, :log2, :log10]
|
||||||
|
|
||||||
|
is_marker_supported(::InspectDRBackend, shape::Shape) = true
|
||||||
|
|
||||||
|
_inspectdr_to_pixels(bb::BoundingBox) =
|
||||||
|
InspectDR.BoundingBox(to_pixels(left(bb)), to_pixels(right(bb)), to_pixels(top(bb)), to_pixels(bottom(bb)))
|
||||||
|
|
||||||
|
#Do we avoid Map to avoid possible pre-comile issues?
|
||||||
|
function _inspectdr_mapglyph(s::Symbol)
|
||||||
|
s == :rect && return :square
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function _inspectdr_mapglyph(s::Shape)
|
||||||
|
x, y = coords(s)
|
||||||
|
return InspectDR.GlyphPolyline(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
# py_marker(markers::AVec) = map(py_marker, markers)
|
||||||
|
function _inspectdr_mapglyph(markers::AVec)
|
||||||
|
warn("Vectors of markers are currently unsupported in InspectDR.")
|
||||||
|
_inspectdr_mapglyph(markers[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
_inspectdr_mapglyphsize(v::Real) = v
|
||||||
|
function _inspectdr_mapglyphsize(v::Vector)
|
||||||
|
warn("Vectors of marker sizes are currently unsupported in InspectDR.")
|
||||||
|
_inspectdr_mapglyphsize(v[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
_inspectdr_mapcolor(v::Colorant) = v
|
||||||
|
function _inspectdr_mapcolor(g::PlotUtils.ColorGradient)
|
||||||
|
warn("Color gradients are currently unsupported in InspectDR.")
|
||||||
|
#Pick middle color:
|
||||||
|
_inspectdr_mapcolor(g.colors[div(1+end,2)])
|
||||||
|
end
|
||||||
|
function _inspectdr_mapcolor(v::AVec)
|
||||||
|
warn("Vectors of colors are currently unsupported in InspectDR.")
|
||||||
|
#Pick middle color:
|
||||||
|
_inspectdr_mapcolor(v[div(1+end,2)])
|
||||||
|
end
|
||||||
|
|
||||||
|
#Hack: suggested point size does not seem adequate relative to plot size, for some reason.
|
||||||
|
_inspectdr_mapptsize(v) = 1.5*v
|
||||||
|
|
||||||
|
function _inspectdr_add_annotations(plot, x, y, val)
|
||||||
|
#What kind of annotation is this?
|
||||||
|
end
|
||||||
|
|
||||||
|
#plot::InspectDR.Plot2D
|
||||||
|
function _inspectdr_add_annotations(plot, x, y, val::PlotText)
|
||||||
|
vmap = Dict{Symbol, Symbol}(:top=>:t, :bottom=>:b) #:vcenter
|
||||||
|
hmap = Dict{Symbol, Symbol}(:left=>:l, :right=>:r) #:hcenter
|
||||||
|
align = Symbol(get(vmap, val.font.valign, :c), get(hmap, val.font.halign, :c))
|
||||||
|
fnt = InspectDR.Font(val.font.family, val.font.pointsize,
|
||||||
|
color =_inspectdr_mapcolor(val.font.color)
|
||||||
|
)
|
||||||
|
ann = InspectDR.atext(val.str, x=x, y=y,
|
||||||
|
font=fnt, angle=val.font.rotation, align=align
|
||||||
|
)
|
||||||
|
InspectDR.add(plot, ann)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function _inspectdr_getscale(s::Symbol, yaxis::Bool)
|
||||||
|
#TODO: Support :asinh, :sqrt
|
||||||
|
kwargs = yaxis? (:tgtmajor=>8, :tgtminor=>2): () #More grid lines on y-axis
|
||||||
|
if :log2 == s
|
||||||
|
return InspectDR.AxisScale(:log2; kwargs...)
|
||||||
|
elseif :log10 == s
|
||||||
|
return InspectDR.AxisScale(:log10; kwargs...)
|
||||||
|
elseif :ln == s
|
||||||
|
return InspectDR.AxisScale(:ln; kwargs...)
|
||||||
|
else #identity
|
||||||
|
return InspectDR.AxisScale(:lin; kwargs...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function add_backend_string(::InspectDRBackend)
|
||||||
|
"""
|
||||||
|
if !Plots.is_installed("InspectDR")
|
||||||
|
Pkg.add("InspectDR")
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
function _initialize_backend(::InspectDRBackend; kw...)
|
||||||
|
@eval begin
|
||||||
|
import InspectDR
|
||||||
|
export InspectDR
|
||||||
|
|
||||||
|
#Glyph used when plotting "Shape"s:
|
||||||
|
const INSPECTDR_GLYPH_SHAPE = InspectDR.GlyphPolyline(
|
||||||
|
2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y
|
||||||
|
)
|
||||||
|
|
||||||
|
type InspecDRPlotRef
|
||||||
|
mplot::Union{Void, InspectDR.Multiplot}
|
||||||
|
gui::Union{Void, InspectDR.GtkPlot}
|
||||||
|
end
|
||||||
|
|
||||||
|
_inspectdr_getmplot(::Any) = nothing
|
||||||
|
_inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot
|
||||||
|
|
||||||
|
_inspectdr_getgui(::Any) = nothing
|
||||||
|
_inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed? nothing: gplot)
|
||||||
|
_inspectdr_getgui(r::InspecDRPlotRef) = _inspectdr_getgui(r.gui)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Create the window/figure for this backend.
|
||||||
|
function _create_backend_figure(plt::Plot{InspectDRBackend})
|
||||||
|
mplot = _inspectdr_getmplot(plt.o)
|
||||||
|
gplot = _inspectdr_getgui(plt.o)
|
||||||
|
|
||||||
|
#:overwrite_figure: want to reuse current figure
|
||||||
|
if plt[:overwrite_figure] && mplot != nothing
|
||||||
|
mplot.subplots = [] #Reset
|
||||||
|
if gplot != nothing #Ensure still references current plot
|
||||||
|
gplot.src = mplot
|
||||||
|
end
|
||||||
|
else #want new one:
|
||||||
|
mplot = InspectDR.Multiplot()
|
||||||
|
gplot = nothing #Will be created later
|
||||||
|
end
|
||||||
|
|
||||||
|
#break link with old subplots
|
||||||
|
for sp in plt.subplots
|
||||||
|
sp.o = nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
return InspecDRPlotRef(mplot, gplot)
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# # this is called early in the pipeline, use it to make the plot current or something
|
||||||
|
# function _prepare_plot_object(plt::Plot{InspectDRBackend})
|
||||||
|
# end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Set up the subplot within the backend object.
|
||||||
|
function _initialize_subplot(plt::Plot{InspectDRBackend}, sp::Subplot{InspectDRBackend})
|
||||||
|
plot = sp.o
|
||||||
|
|
||||||
|
#Don't do anything without a "subplot" object: Will process later.
|
||||||
|
if nothing == plot; return; end
|
||||||
|
plot.data = []
|
||||||
|
plot.markers = [] #Clear old markers
|
||||||
|
plot.atext = [] #Clear old annotation
|
||||||
|
plot.apline = [] #Clear old poly lines
|
||||||
|
|
||||||
|
return plot
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Add one series to the underlying backend object.
|
||||||
|
# Called once per series
|
||||||
|
# NOTE: Seems to be called when user calls plot()... even if backend
|
||||||
|
# plot, sp.o has not yet been constructed...
|
||||||
|
function _series_added(plt::Plot{InspectDRBackend}, series::Series)
|
||||||
|
st = series[:seriestype]
|
||||||
|
sp = series[:subplot]
|
||||||
|
plot = sp.o
|
||||||
|
|
||||||
|
#Don't do anything without a "subplot" object: Will process later.
|
||||||
|
if nothing == plot; return; end
|
||||||
|
|
||||||
|
_vectorize(v) = isa(v, Vector)? v: collect(v) #InspectDR only supports vectors
|
||||||
|
x = _vectorize(series[:x]); y = _vectorize(series[:y])
|
||||||
|
|
||||||
|
#No support for polar grid... but can still perform polar transformation:
|
||||||
|
if ispolar(sp)
|
||||||
|
Θ = x; r = y
|
||||||
|
x = r.*cos(Θ); y = r.*sin(Θ)
|
||||||
|
end
|
||||||
|
|
||||||
|
# doesn't handle mismatched x/y - wrap data (pyplot behaviour):
|
||||||
|
nx = length(x); ny = length(y)
|
||||||
|
if nx < ny
|
||||||
|
series[:x] = Float64[x[mod1(i,nx)] for i=1:ny]
|
||||||
|
elseif ny > nx
|
||||||
|
series[:y] = Float64[y[mod1(i,ny)] for i=1:nx]
|
||||||
|
end
|
||||||
|
|
||||||
|
#= TODO: Eventually support
|
||||||
|
series[:fillcolor] #I think this is fill under line
|
||||||
|
zorder = series[:series_plotindex]
|
||||||
|
|
||||||
|
For st in :shape:
|
||||||
|
zorder = series[:series_plotindex],
|
||||||
|
=#
|
||||||
|
|
||||||
|
if st in (:shape,)
|
||||||
|
nmax = 0
|
||||||
|
for (i,rng) in enumerate(iter_segments(x, y))
|
||||||
|
nmax = i
|
||||||
|
if length(rng) > 1
|
||||||
|
linewidth = series[:linewidth]
|
||||||
|
linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i))
|
||||||
|
fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i))
|
||||||
|
line = InspectDR.line(
|
||||||
|
style=:solid, width=linewidth, color=linecolor
|
||||||
|
)
|
||||||
|
apline = InspectDR.PolylineAnnotation(
|
||||||
|
x[rng], y[rng], line=line, fillcolor=fillcolor
|
||||||
|
)
|
||||||
|
push!(plot.apline, apline)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
i = (nmax >= 2? div(nmax, 2): nmax) #Must pick one set of colors for legend
|
||||||
|
if i > 1 #Add dummy waveform for legend entry:
|
||||||
|
linewidth = series[:linewidth]
|
||||||
|
linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i))
|
||||||
|
fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i))
|
||||||
|
wfrm = InspectDR.add(plot, Float64[], Float64[], id=series[:label])
|
||||||
|
wfrm.line = InspectDR.line(
|
||||||
|
style=:none, width=linewidth, #linewidth affects glyph
|
||||||
|
)
|
||||||
|
wfrm.glyph = InspectDR.glyph(
|
||||||
|
shape = INSPECTDR_GLYPH_SHAPE, size = 8,
|
||||||
|
color = linecolor, fillcolor = fillcolor
|
||||||
|
)
|
||||||
|
end
|
||||||
|
elseif st in (:path, :scatter) #, :steppre, :steppost)
|
||||||
|
#NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think).
|
||||||
|
linewidth = series[:linewidth]
|
||||||
|
#More efficient & allows some support for markerstrokewidth:
|
||||||
|
_style = (0==linewidth? :none: series[:linestyle])
|
||||||
|
wfrm = InspectDR.add(plot, x, y, id=series[:label])
|
||||||
|
wfrm.line = InspectDR.line(
|
||||||
|
style = _style,
|
||||||
|
width = series[:linewidth],
|
||||||
|
color = series[:linecolor],
|
||||||
|
)
|
||||||
|
#InspectDR does not control markerstrokewidth independently.
|
||||||
|
if :none == _style
|
||||||
|
#Use this property only if no line is displayed:
|
||||||
|
wfrm.line.width = series[:markerstrokewidth]
|
||||||
|
end
|
||||||
|
wfrm.glyph = InspectDR.glyph(
|
||||||
|
shape = _inspectdr_mapglyph(series[:markershape]),
|
||||||
|
size = _inspectdr_mapglyphsize(series[:markersize]),
|
||||||
|
color = _inspectdr_mapcolor(series[:markerstrokecolor]),
|
||||||
|
fillcolor = _inspectdr_mapcolor(series[:markercolor]),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# this is all we need to add the series_annotations text
|
||||||
|
anns = series[:series_annotations]
|
||||||
|
for (xi,yi,str,fnt) in EachAnn(anns, x, y)
|
||||||
|
_inspectdr_add_annotations(plot, xi, yi, PlotText(str, fnt))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# When series data is added/changed, this callback can do dynamic updates to the backend object.
|
||||||
|
# note: if the backend rebuilds the plot from scratch on display, then you might not do anything here.
|
||||||
|
function _series_updated(plt::Plot{InspectDRBackend}, series::Series)
|
||||||
|
#Nothing to do
|
||||||
|
end
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend})
|
||||||
|
const gridon = InspectDR.GridRect(vmajor=true, hmajor=true)
|
||||||
|
const gridoff = InspectDR.GridRect()
|
||||||
|
const plot = sp.o
|
||||||
|
const strip = plot.strips[1] #Only 1 strip supported with Plots.jl
|
||||||
|
|
||||||
|
#No independent control of grid???
|
||||||
|
strip.grid = sp[:grid]? gridon: gridoff
|
||||||
|
|
||||||
|
xaxis = sp[:xaxis]; yaxis = sp[:yaxis]
|
||||||
|
plot.xscale = _inspectdr_getscale(xaxis[:scale], false)
|
||||||
|
strip.yscale = _inspectdr_getscale(yaxis[:scale], true)
|
||||||
|
xmin, xmax = axis_limits(xaxis)
|
||||||
|
ymin, ymax = axis_limits(yaxis)
|
||||||
|
if ispolar(sp)
|
||||||
|
#Plots.jl appears to give (xmin,xmax) ≜ (Θmin,Θmax) & (ymin,ymax) ≜ (rmin,rmax)
|
||||||
|
rmax = max(abs(ymin), abs(ymax))
|
||||||
|
xmin, xmax = -rmax, rmax
|
||||||
|
ymin, ymax = -rmax, rmax
|
||||||
|
end
|
||||||
|
plot.xext = InspectDR.PExtents1D() #reset
|
||||||
|
strip.yext = InspectDR.PExtents1D() #reset
|
||||||
|
plot.xext_full = InspectDR.PExtents1D(xmin, xmax)
|
||||||
|
strip.yext_full = InspectDR.PExtents1D(ymin, ymax)
|
||||||
|
a = plot.annotation
|
||||||
|
a.title = sp[:title]
|
||||||
|
a.xlabel = xaxis[:guide]; a.ylabels = [yaxis[:guide]]
|
||||||
|
|
||||||
|
l = plot.layout
|
||||||
|
l.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot])
|
||||||
|
l.framedata.fillcolor = _inspectdr_mapcolor(sp[:background_color_inside])
|
||||||
|
l.framedata.line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis])
|
||||||
|
l.fnttitle = InspectDR.Font(sp[:titlefont].family,
|
||||||
|
_inspectdr_mapptsize(sp[:titlefont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(sp[:foreground_color_title])
|
||||||
|
)
|
||||||
|
#Cannot independently control fonts of axes with InspectDR:
|
||||||
|
l.fntaxlabel = InspectDR.Font(xaxis[:guidefont].family,
|
||||||
|
_inspectdr_mapptsize(xaxis[:guidefont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(xaxis[:foreground_color_guide])
|
||||||
|
)
|
||||||
|
l.fntticklabel = InspectDR.Font(xaxis[:tickfont].family,
|
||||||
|
_inspectdr_mapptsize(xaxis[:tickfont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(xaxis[:foreground_color_text])
|
||||||
|
)
|
||||||
|
leg = l.legend
|
||||||
|
leg.enabled = (sp[:legend] != :none)
|
||||||
|
#leg.width = 150 #TODO: compute???
|
||||||
|
leg.font = InspectDR.Font(sp[:legendfont].family,
|
||||||
|
_inspectdr_mapptsize(sp[:legendfont].pointsize),
|
||||||
|
color = _inspectdr_mapcolor(sp[:foreground_color_legend])
|
||||||
|
)
|
||||||
|
leg.frame.fillcolor = _inspectdr_mapcolor(sp[:background_color_legend])
|
||||||
|
end
|
||||||
|
|
||||||
|
# called just before updating layout bounding boxes... in case you need to prep
|
||||||
|
# for the calcs
|
||||||
|
function _before_layout_calcs(plt::Plot{InspectDRBackend})
|
||||||
|
const mplot = _inspectdr_getmplot(plt.o)
|
||||||
|
if nothing == mplot; return; end
|
||||||
|
|
||||||
|
mplot.title = plt[:plot_title]
|
||||||
|
if "" == mplot.title
|
||||||
|
#Don't use window_title... probably not what you want.
|
||||||
|
#mplot.title = plt[:window_title]
|
||||||
|
end
|
||||||
|
mplot.frame.fillcolor = _inspectdr_mapcolor(plt[:background_color_outside])
|
||||||
|
|
||||||
|
resize!(mplot.subplots, length(plt.subplots))
|
||||||
|
nsubplots = length(plt.subplots)
|
||||||
|
for (i, sp) in enumerate(plt.subplots)
|
||||||
|
if !isassigned(mplot.subplots, i)
|
||||||
|
mplot.subplots[i] = InspectDR.Plot2D()
|
||||||
|
end
|
||||||
|
sp.o = mplot.subplots[i]
|
||||||
|
plot = sp.o
|
||||||
|
_initialize_subplot(plt, sp)
|
||||||
|
_inspectdr_setupsubplot(sp)
|
||||||
|
graphbb = _inspectdr_to_pixels(plotarea(sp))
|
||||||
|
plot.plotbb = InspectDR.plotbounds(plot.layout, graphbb)
|
||||||
|
|
||||||
|
# add the annotations
|
||||||
|
for ann in sp[:annotations]
|
||||||
|
_inspectdr_add_annotations(plot, ann...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#Do not yet support absolute plot positionning.
|
||||||
|
#Just try to make things look more-or less ok:
|
||||||
|
if nsubplots <= 1
|
||||||
|
mplot.ncolumns = 1
|
||||||
|
elseif nsubplots <= 4
|
||||||
|
mplot.ncolumns = 2
|
||||||
|
elseif nsubplots <= 6
|
||||||
|
mplot.ncolumns = 3
|
||||||
|
elseif nsubplots <= 12
|
||||||
|
mplot.ncolumns = 4
|
||||||
|
else
|
||||||
|
mplot.ncolumns = 5
|
||||||
|
end
|
||||||
|
|
||||||
|
for series in plt.series_list
|
||||||
|
_series_added(plt, series)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# Set the (left, top, right, bottom) minimum padding around the plot area
|
||||||
|
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||||
|
function _update_min_padding!(sp::Subplot{InspectDRBackend})
|
||||||
|
plot = sp.o
|
||||||
|
if !isa(plot, InspectDR.Plot2D); return sp.minpad; end
|
||||||
|
#Computing plotbounds with 0-BoundingBox returns required padding:
|
||||||
|
bb = InspectDR.plotbounds(plot.layout, InspectDR.BoundingBox(0,0,0,0))
|
||||||
|
#NOTE: plotbounds always pads for titles, legends, etc. even if not in use.
|
||||||
|
#TODO: possibly zero-out items not in use??
|
||||||
|
|
||||||
|
# add in the user-specified margin to InspectDR padding:
|
||||||
|
leftpad = abs(bb.xmin)*px + sp[:left_margin]
|
||||||
|
toppad = abs(bb.ymin)*px + sp[:top_margin]
|
||||||
|
rightpad = abs(bb.xmax)*px + sp[:right_margin]
|
||||||
|
bottompad = abs(bb.ymax)*px + sp[:bottom_margin]
|
||||||
|
sp.minpad = (leftpad, toppad, rightpad, bottompad)
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations])
|
||||||
|
function _update_plot_object(plt::Plot{InspectDRBackend})
|
||||||
|
mplot = _inspectdr_getmplot(plt.o)
|
||||||
|
if nothing == mplot; return; end
|
||||||
|
|
||||||
|
#TODO: should plotbb be computed here??
|
||||||
|
|
||||||
|
gplot = _inspectdr_getgui(plt.o)
|
||||||
|
if nothing == gplot; return; end
|
||||||
|
|
||||||
|
gplot.src = mplot #Ensure still references current plot
|
||||||
|
InspectDR.refresh(gplot)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
const _inspectdr_mimeformats_dpi = Dict(
|
||||||
|
"image/png" => "png"
|
||||||
|
)
|
||||||
|
const _inspectdr_mimeformats_nodpi = Dict(
|
||||||
|
"image/svg+xml" => "svg",
|
||||||
|
"application/eps" => "eps",
|
||||||
|
"image/eps" => "eps",
|
||||||
|
# "application/postscript" => "ps", #TODO: support once Cairo supports PSSurface
|
||||||
|
"application/pdf" => "pdf"
|
||||||
|
)
|
||||||
|
_inspectdr_show(io::IO, mime::MIME, ::Void, w, h) =
|
||||||
|
throw(ErrorException("Cannot show(::IO, ...) plot - not yet generated"))
|
||||||
|
function _inspectdr_show(io::IO, mime::MIME, mplot, w, h)
|
||||||
|
InspectDR._show(io, mime, mplot, Float64(w), Float64(h))
|
||||||
|
end
|
||||||
|
|
||||||
|
for (mime, fmt) in _inspectdr_mimeformats_dpi
|
||||||
|
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
|
||||||
|
dpi = plt[:dpi]#TODO: support
|
||||||
|
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for (mime, fmt) in _inspectdr_mimeformats_nodpi
|
||||||
|
@eval function _show(io::IO, mime::MIME{Symbol($mime)}, plt::Plot{InspectDRBackend})
|
||||||
|
_inspectdr_show(io, mime, _inspectdr_getmplot(plt.o), plt[:size]...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_show(io::IO, mime::MIME"text/plain", plt::Plot{InspectDRBackend}) = nothing #Don't show
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# Display/show the plot (open a GUI window, or browser page, for example).
|
||||||
|
function _display(plt::Plot{InspectDRBackend})
|
||||||
|
mplot = _inspectdr_getmplot(plt.o)
|
||||||
|
if nothing == mplot; return; end
|
||||||
|
gplot = _inspectdr_getgui(plt.o)
|
||||||
|
|
||||||
|
if nothing == gplot
|
||||||
|
gplot = display(InspectDR.GtkDisplay(), mplot)
|
||||||
|
else
|
||||||
|
#redundant... Plots.jl will call _update_plot_object:
|
||||||
|
#InspectDR.refresh(gplot)
|
||||||
|
end
|
||||||
|
plt.o = InspecDRPlotRef(mplot, gplot)
|
||||||
|
return gplot
|
||||||
|
end
|
||||||
@ -3,7 +3,7 @@
|
|||||||
# significant contributions by: @pkofod
|
# significant contributions by: @pkofod
|
||||||
|
|
||||||
const _pgfplots_attr = merge_with_base_supported([
|
const _pgfplots_attr = merge_with_base_supported([
|
||||||
# :annotations,
|
:annotations,
|
||||||
# :background_color_legend,
|
# :background_color_legend,
|
||||||
:background_color_inside,
|
:background_color_inside,
|
||||||
# :background_color_outside,
|
# :background_color_outside,
|
||||||
@ -27,12 +27,12 @@ const _pgfplots_attr = merge_with_base_supported([
|
|||||||
# :ribbon, :quiver, :arrow,
|
# :ribbon, :quiver, :arrow,
|
||||||
# :orientation,
|
# :orientation,
|
||||||
# :overwrite_figure,
|
# :overwrite_figure,
|
||||||
# :polar,
|
:polar,
|
||||||
# :normalize, :weights, :contours,
|
# :normalize, :weights, :contours,
|
||||||
:aspect_ratio,
|
:aspect_ratio,
|
||||||
# :match_dimensions,
|
# :match_dimensions,
|
||||||
])
|
])
|
||||||
const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour]
|
const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape]
|
||||||
const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon] #vcat(_allMarkers, Shape)
|
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon] #vcat(_allMarkers, Shape)
|
||||||
const _pgfplots_scale = [:identity, :ln, :log2, :log10]
|
const _pgfplots_scale = [:identity, :ln, :log2, :log10]
|
||||||
@ -136,6 +136,20 @@ function pgf_marker(d::KW)
|
|||||||
}"""
|
}"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function pgf_add_annotation!(o,x,y,val)
|
||||||
|
# Construct the style string.
|
||||||
|
# Currently supports color and orientation
|
||||||
|
halign = val.font.halign == :hcenter ? "" : string(val.font.halign)
|
||||||
|
cstr,a = pgf_color(val.font.color)
|
||||||
|
push!(o, PGFPlots.Plots.Node(val.str, # Annotation Text
|
||||||
|
x, y,
|
||||||
|
style="""
|
||||||
|
$halign,
|
||||||
|
color=$cstr, draw opacity=$(convert(Float16,a)),
|
||||||
|
rotate=$(val.font.rotation)
|
||||||
|
"""))
|
||||||
|
end
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
function pgf_series(sp::Subplot, series::Series)
|
function pgf_series(sp::Subplot, series::Series)
|
||||||
@ -147,7 +161,7 @@ function pgf_series(sp::Subplot, series::Series)
|
|||||||
push!(style, pgf_linestyle(d))
|
push!(style, pgf_linestyle(d))
|
||||||
push!(style, pgf_marker(d))
|
push!(style, pgf_marker(d))
|
||||||
|
|
||||||
if d[:fillrange] != nothing
|
if d[:fillrange] != nothing || st in (:shape,)
|
||||||
push!(style, pgf_fillstyle(d))
|
push!(style, pgf_fillstyle(d))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -211,6 +225,9 @@ function pgf_axis(sp::Subplot, letter)
|
|||||||
# axis guide
|
# axis guide
|
||||||
kw[Symbol(letter,:label)] = axis[:guide]
|
kw[Symbol(letter,:label)] = axis[:guide]
|
||||||
|
|
||||||
|
# Add ticklabel rotations
|
||||||
|
push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}")
|
||||||
|
|
||||||
# flip/reverse?
|
# flip/reverse?
|
||||||
axis[:flip] && push!(style, "$letter dir=reverse")
|
axis[:flip] && push!(style, "$letter dir=reverse")
|
||||||
|
|
||||||
@ -249,8 +266,11 @@ end
|
|||||||
|
|
||||||
function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
||||||
plt.o = PGFPlots.Axis[]
|
plt.o = PGFPlots.Axis[]
|
||||||
|
# Obtain the total height of the plot by extracting the maximal bottom
|
||||||
|
# coordinate from the bounding box.
|
||||||
|
total_height = bottom(bbox(plt.layout))
|
||||||
for sp in plt.subplots
|
for sp in plt.subplots
|
||||||
# first build the PGFPlots.Axis object
|
# first build the PGFPlots.Axis object
|
||||||
style = ["unbounded coords=jump"]
|
style = ["unbounded coords=jump"]
|
||||||
kw = KW()
|
kw = KW()
|
||||||
|
|
||||||
@ -265,10 +285,12 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
|
|
||||||
# bounding box values are in mm
|
# bounding box values are in mm
|
||||||
# note: bb origin is top-left, pgf is bottom-left
|
# note: bb origin is top-left, pgf is bottom-left
|
||||||
|
# A round on 2 decimal places should be enough precision for 300 dpi
|
||||||
|
# plots.
|
||||||
bb = bbox(sp)
|
bb = bbox(sp)
|
||||||
push!(style, """
|
push!(style, """
|
||||||
xshift = $(left(bb).value)mm,
|
xshift = $(left(bb).value)mm,
|
||||||
yshift = $((height(bb) - (bottom(bb))).value)mm,
|
yshift = $(round((total_height - (bottom(bb))).value,2))mm,
|
||||||
axis background/.style={fill=$(pgf_color(sp[:background_color_inside])[1])}
|
axis background/.style={fill=$(pgf_color(sp[:background_color_inside])[1])}
|
||||||
""")
|
""")
|
||||||
kw[:width] = "$(width(bb).value)mm"
|
kw[:width] = "$(width(bb).value)mm"
|
||||||
@ -288,19 +310,34 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend})
|
|||||||
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
kw[:legendPos] = _pgfplots_legend_pos[legpos]
|
||||||
end
|
end
|
||||||
|
|
||||||
o = PGFPlots.Axis(; style = style, kw...)
|
axisf = PGFPlots.Axis
|
||||||
|
if sp[:projection] == :polar
|
||||||
|
axisf = PGFPlots.PolarAxis
|
||||||
|
end
|
||||||
|
o = axisf(; style = style, kw...)
|
||||||
|
|
||||||
# add the series object to the PGFPlots.Axis
|
# add the series object to the PGFPlots.Axis
|
||||||
for series in series_list(sp)
|
for series in series_list(sp)
|
||||||
push!(o, pgf_series(sp, series))
|
push!(o, pgf_series(sp, series))
|
||||||
|
|
||||||
|
# add series annotations
|
||||||
|
anns = series[:series_annotations]
|
||||||
|
for (xi,yi,str,fnt) in EachAnn(anns, series[:x], series[:y])
|
||||||
|
pgf_add_annotation!(o, xi, yi, PlotText(str, fnt))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# add the annotations
|
||||||
|
for ann in sp[:annotations]
|
||||||
|
pgf_add_annotation!(o,ann...)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# add the PGFPlots.Axis to the list
|
# add the PGFPlots.Axis to the list
|
||||||
push!(plt.o, o)
|
push!(plt.o, o)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function _show(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend})
|
function _show(io::IO, mime::MIME"image/svg+xml", plt::Plot{PGFPlotsBackend})
|
||||||
show(io, mime, plt.o)
|
show(io, mime, plt.o)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const _plotly_attr = merge_with_base_supported([
|
|||||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :colorbar,
|
:grid, :legend, :colorbar,
|
||||||
:marker_z, :levels,
|
:marker_z, :fill_z, :levels,
|
||||||
:ribbon, :quiver,
|
:ribbon, :quiver,
|
||||||
:orientation,
|
:orientation,
|
||||||
# :overwrite_figure,
|
# :overwrite_figure,
|
||||||
@ -371,6 +371,7 @@ end
|
|||||||
plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α)
|
plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α)
|
||||||
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
|
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
|
||||||
|
|
||||||
|
|
||||||
const _plotly_markers = KW(
|
const _plotly_markers = KW(
|
||||||
:rect => "square",
|
:rect => "square",
|
||||||
:xcross => "x",
|
:xcross => "x",
|
||||||
@ -488,6 +489,9 @@ function plotly_series(plt::Plot, series::Series)
|
|||||||
d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines)
|
||||||
else
|
else
|
||||||
d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha])
|
||||||
|
if series[:fill_z] != nothing
|
||||||
|
d_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif st == :pie
|
elseif st == :pie
|
||||||
|
|||||||
@ -102,8 +102,18 @@ _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hac
|
|||||||
_show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "pdf")
|
_show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "pdf")
|
||||||
_show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "eps")
|
_show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "eps")
|
||||||
|
|
||||||
|
function write_temp_html(plt::Plot{PlotlyJSBackend})
|
||||||
|
filename = string(tempname(), ".html")
|
||||||
|
savefig(plt, filename)
|
||||||
|
filename
|
||||||
|
end
|
||||||
|
|
||||||
function _display(plt::Plot{PlotlyJSBackend})
|
function _display(plt::Plot{PlotlyJSBackend})
|
||||||
display(plt.o)
|
if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes")
|
||||||
|
display(plt.o)
|
||||||
|
else
|
||||||
|
standalone_html_window(plt)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,7 @@ const _pyplot_attr = merge_with_base_supported([
|
|||||||
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
:guide, :lims, :ticks, :scale, :flip, :rotation,
|
||||||
:tickfont, :guidefont, :legendfont,
|
:tickfont, :guidefont, :legendfont,
|
||||||
:grid, :legend, :colorbar,
|
:grid, :legend, :colorbar,
|
||||||
:marker_z,
|
:marker_z, :line_z, :fill_z,
|
||||||
:line_z,
|
|
||||||
:levels,
|
:levels,
|
||||||
:ribbon, :quiver, :arrow,
|
:ribbon, :quiver, :arrow,
|
||||||
:orientation,
|
:orientation,
|
||||||
@ -56,6 +55,10 @@ function add_backend_string(::PyPlotBackend)
|
|||||||
withenv("PYTHON" => "") do
|
withenv("PYTHON" => "") do
|
||||||
Pkg.build("PyPlot")
|
Pkg.build("PyPlot")
|
||||||
end
|
end
|
||||||
|
import Conda
|
||||||
|
Conda.add("qt=4.8.5")
|
||||||
|
|
||||||
|
# now restart julia!
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -82,7 +85,17 @@ function _initialize_backend(::PyPlotBackend)
|
|||||||
const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections"))
|
const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections"))
|
||||||
const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d"))
|
const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d"))
|
||||||
end
|
end
|
||||||
|
if is_linux()
|
||||||
|
@eval begin
|
||||||
|
# avoid Conda update that causes Segfault with qt >=4.8.6 on Ubuntu https://github.com/JuliaPy/PyPlot.jl/issues/234
|
||||||
|
import Conda
|
||||||
|
kw = Conda._installed_packages_dict()
|
||||||
|
if (!haskey(kw,"qt") || (qt_version=get(kw,"qt",0)[1]!=v"4.8.5"))
|
||||||
|
print("\n If the code has a Segmentation fault error switch to qt v4.8.5 by pasting the following code into julia: \n \n")
|
||||||
|
print(add_backend_string(PyPlotBackend()))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
# we don't want every command to update the figure
|
# we don't want every command to update the figure
|
||||||
PyPlot.ioff()
|
PyPlot.ioff()
|
||||||
end
|
end
|
||||||
@ -124,8 +137,8 @@ end
|
|||||||
py_colormap(c) = py_colormap(cgrad())
|
py_colormap(c) = py_colormap(cgrad())
|
||||||
|
|
||||||
|
|
||||||
function py_shading(c, z, α=nothing)
|
function py_shading(c, z)
|
||||||
cmap = py_colormap(c, α)
|
cmap = py_colormap(c)
|
||||||
ls = pycolors.pymember("LightSource")(270,45)
|
ls = pycolors.pymember("LightSource")(270,45)
|
||||||
ls[:shade](z, cmap, vert_exag=0.1, blend_mode="soft")
|
ls[:shade](z, cmap, vert_exag=0.1, blend_mode="soft")
|
||||||
end
|
end
|
||||||
@ -668,21 +681,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
x = repmat(x', length(y), 1)
|
x = repmat(x', length(y), 1)
|
||||||
y = repmat(y, 1, length(series[:x]))
|
y = repmat(y, 1, length(series[:x]))
|
||||||
end
|
end
|
||||||
# z = z'
|
|
||||||
z = transpose_z(series, z)
|
z = transpose_z(series, z)
|
||||||
if st == :surface
|
if st == :surface
|
||||||
if series[:marker_z] != nothing
|
if series[:fill_z] != nothing
|
||||||
extrakw[:facecolors] = py_shading(series[:fillcolor], series[:marker_z], series[:fillalpha])
|
# the surface colors are different than z-value
|
||||||
|
extrakw[:facecolors] = py_shading(series[:fillcolor], transpose_z(series, series[:fill_z].surf))
|
||||||
extrakw[:shade] = false
|
extrakw[:shade] = false
|
||||||
clims = sp[:clims]
|
|
||||||
if is_2tuple(clims)
|
|
||||||
isfinite(clims[1]) && (extrakw[:vmin] = clims[1])
|
|
||||||
isfinite(clims[2]) && (extrakw[:vmax] = clims[2])
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
extrakw[:cmap] = py_fillcolormap(series)
|
extrakw[:cmap] = py_fillcolormap(series)
|
||||||
needs_colorbar = true
|
|
||||||
end
|
end
|
||||||
|
needs_colorbar = true
|
||||||
end
|
end
|
||||||
handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z;
|
handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z;
|
||||||
label = series[:label],
|
label = series[:label],
|
||||||
|
|||||||
@ -27,7 +27,7 @@ function open_browser_window(filename::AbstractString)
|
|||||||
return run(`xdg-open $(filename)`)
|
return run(`xdg-open $(filename)`)
|
||||||
end
|
end
|
||||||
@static if is_windows()
|
@static if is_windows()
|
||||||
return run(`$(ENV["COMSPEC"]) /c start $(filename)`)
|
return run(`$(ENV["COMSPEC"]) /c start "" "$(filename)"`)
|
||||||
end
|
end
|
||||||
warn("Unknown OS... cannot open browser window.")
|
warn("Unknown OS... cannot open browser window.")
|
||||||
end
|
end
|
||||||
|
|||||||
@ -302,6 +302,10 @@ function setup_atom()
|
|||||||
Media.render(pane, Atom.div(".fill", Atom.HTML(stringmime(MIME("text/html"), plt))))
|
Media.render(pane, Atom.div(".fill", Atom.HTML(stringmime(MIME("text/html"), plt))))
|
||||||
plt[:size] = sz
|
plt[:size] = sz
|
||||||
end
|
end
|
||||||
|
# special handling for PlotlyJS
|
||||||
|
function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyJSBackend})
|
||||||
|
display(Plots.PlotsDisplay(), plt)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
#
|
#
|
||||||
function Media.render(pane::Atom.PlotPane, plt::Plot)
|
function Media.render(pane::Atom.PlotPane, plt::Plot)
|
||||||
@ -317,11 +321,5 @@ function setup_atom()
|
|||||||
s = "PlotPane turned off. The plotly and plotlyjs backends cannot render in the PlotPane due to javascript issues."
|
s = "PlotPane turned off. The plotly and plotlyjs backends cannot render in the PlotPane due to javascript issues."
|
||||||
Media.render(pane, Atom.div(Atom.HTML(s)))
|
Media.render(pane, Atom.div(Atom.HTML(s)))
|
||||||
end
|
end
|
||||||
|
|
||||||
# special handling for PlotlyJS to pass through to that render method
|
|
||||||
function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyJSBackend})
|
|
||||||
Plots.prepare_output(plt)
|
|
||||||
Media.render(pane, plt.o)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -257,12 +257,23 @@ end
|
|||||||
# # 1 argument
|
# # 1 argument
|
||||||
# # --------------------------------------------------------------------
|
# # --------------------------------------------------------------------
|
||||||
|
|
||||||
|
# helper function to ensure relevant attributes are wrapped by Surface
|
||||||
|
function wrap_surfaces(d::KW)
|
||||||
|
if haskey(d, :fill_z)
|
||||||
|
v = d[:fill_z]
|
||||||
|
if !isa(v, Surface)
|
||||||
|
d[:fill_z] = Surface(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
|
@recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing)
|
||||||
|
|
||||||
# return a surface if this is a 3d plot, otherwise let it be sliced up
|
# return a surface if this is a 3d plot, otherwise let it be sliced up
|
||||||
@recipe function f{T<:Union{Integer,AbstractFloat}}(mat::AMat{T})
|
@recipe function f{T<:Union{Integer,AbstractFloat}}(mat::AMat{T})
|
||||||
if all3D(d)
|
if all3D(d)
|
||||||
n,m = size(mat)
|
n,m = size(mat)
|
||||||
|
wrap_surfaces(d)
|
||||||
SliceIt, 1:m, 1:n, Surface(mat)
|
SliceIt, 1:m, 1:n, Surface(mat)
|
||||||
else
|
else
|
||||||
SliceIt, nothing, mat, nothing
|
SliceIt, nothing, mat, nothing
|
||||||
@ -274,6 +285,7 @@ end
|
|||||||
if all3D(d)
|
if all3D(d)
|
||||||
mat = fmt.data
|
mat = fmt.data
|
||||||
n,m = size(mat)
|
n,m = size(mat)
|
||||||
|
wrap_surfaces(d)
|
||||||
SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter)
|
SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter)
|
||||||
else
|
else
|
||||||
SliceIt, nothing, fmt, nothing
|
SliceIt, nothing, fmt, nothing
|
||||||
@ -391,6 +403,7 @@ end
|
|||||||
# seriestype := :path3d
|
# seriestype := :path3d
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
|
wrap_surfaces(d)
|
||||||
SliceIt, x, y, z
|
SliceIt, x, y, z
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -400,6 +413,7 @@ end
|
|||||||
@recipe function f(x::AVec, y::AVec, zf::Function)
|
@recipe function f(x::AVec, y::AVec, zf::Function)
|
||||||
# x = X <: Number ? sort(x) : x
|
# x = X <: Number ? sort(x) : x
|
||||||
# y = Y <: Number ? sort(y) : y
|
# y = Y <: Number ? sort(y) : y
|
||||||
|
wrap_surfaces(d)
|
||||||
SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
|
SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -410,6 +424,7 @@ end
|
|||||||
if !like_surface(get(d, :seriestype, :none))
|
if !like_surface(get(d, :seriestype, :none))
|
||||||
d[:seriestype] = :contour
|
d[:seriestype] = :contour
|
||||||
end
|
end
|
||||||
|
wrap_surfaces(d)
|
||||||
SliceIt, x, y, Surface(z)
|
SliceIt, x, y, Surface(z)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user