Compare commits

..

2 Commits

Author SHA1 Message Date
SimonDanisch 5b6d7d10d4 use correct revision 2019-01-31 18:50:20 +01:00
SimonDanisch 71cf37cc16 use name 2019-01-31 18:27:54 +01:00
20 changed files with 246 additions and 348 deletions
-45
View File
@@ -11,51 +11,6 @@
---
## (current master)
## 0.24.0
- Update to the new PyCall and PyPlot API
## 0.23.2
- pyplot fixes
- Add option :tex_output_standalone to set the 'include_preamble' argument in the PGFPlots backend.
- fix ticks
- support plotly json mime
- fix image axis limits
- default to radius 0 at center for polar plots
## 0.23.1
- slightly faster load time
- fixed errant MethodError
- fix bar plots with unicodeplots
- better colorbars for contour
- add volume seriestype for GR
- fix passing a tuple to custom ticks
- add vline to pgfplots
- add tex output for pyplot
- better 3d axis labels for GR
## 0.23.0
- compatible with StatPlots -> StatsPlots name shift
- fix histograms for vectors with NaN and Inf
- change gif behaviour (remove cache-busting)
- improved docstrings for shorthands functions
- fix font rotation for pyplot
- fix greyscale images for pyplot
- clamp greyscale images with values outside 0,1
- support keyword argument for font options
- allow vector of markers for pyplot scatter
## 0.22.5
- improve behaviour of plotlyjs backend
## 0.22.4
- Add support for discrete contourf plots with GR
## 0.22.3
- Fix the `showtheme` function
## 0.22.2
- Allow annotations to accept a Tuple instead of the result of a text call (making it possible to specify font characteristics in recipes). E.g. `annotations = (2, 4, ("test", :right, 8, :red))` is the same as `annotations = (2, 4, text("test", :right, 8, :red))`
## 0.22.1
- push PlotsDisplay just after REPLDisplay
+1 -1
View File
@@ -13,4 +13,4 @@ JSON
NaNMath
Requires
Contour
GR 0.38.1
GR 0.37.0
+2 -2
View File
@@ -1,6 +1,6 @@
module Plots
_current_plots_version = v"0.24.0"
_current_plots_version = v"0.20.6"
using Reexport
@@ -187,7 +187,7 @@ include("backends/plotly.jl")
include("backends/gr.jl")
include("backends/web.jl")
include("shorthands.jl")
include("shorthands.jl")
let PlotOrSubplot = Union{Plot, Subplot}
global title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...)
-8
View File
@@ -106,14 +106,6 @@ function Base.show(io::IO, ::MIME"text/html", agif::AnimatedGif)
end
# Only gifs can be shown via image/gif
Base.showable(::MIME"image/gif", agif::AnimatedGif) = file_extension(agif.filename) == "gif"
function Base.show(io::IO, ::MIME"image/gif", agif::AnimatedGif)
open(fio-> write(io, fio), agif.filename)
end
# -----------------------------------------------
function _animate(forloop::Expr, args...; callgif = false)
-1
View File
@@ -63,7 +63,6 @@ const _arg_desc = KW(
: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).",
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
:tex_output_standalone => "Bool. When writing tex output, should the source include a preamble for a standalone document class.",
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
:dpi => "Number. Dots Per Inch of output figures",
:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.",
-1
View File
@@ -298,7 +298,6 @@ const _plot_defaults = KW(
:link => :none,
:overwrite_figure => true,
:html_output_format => :auto,
:tex_output_standalone => false,
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
# the parent layout and the relative bounding box of inset subplots
:dpi => DPI, # dots per inch for images, etc
+10 -10
View File
@@ -240,7 +240,7 @@ end
# return (continuous_values, discrete_values) for the ticks on this axis
function get_ticks(axis::Axis)
ticks = _transform_ticks(axis[:ticks])
ticks in (:none, nothing, false) && return nothing
ticks in (nothing, false) && return nothing
# treat :native ticks as :auto
ticks = ticks == :native ? :auto : ticks
@@ -251,7 +251,7 @@ function get_ticks(axis::Axis)
# discrete ticks...
n = length(dvals)
rng = if ticks == :auto
Int[round(Int,i) for i in range(1, stop=n, length=min(n,15))]
Int[round(Int,i) for i in range(1, stop=n, length=15)]
else # if ticks == :all
1:n
end
@@ -287,7 +287,7 @@ _transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.valu
_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2])
function get_minor_ticks(axis,ticks)
axis[:minorticks] in (:none, nothing, false) && !axis[:minorgrid] && return nothing
axis[:minorticks] in (nothing, false) && !axis[:minorgrid] && return nothing
ticks = ticks[1]
length(ticks) < 2 && return nothing
@@ -502,7 +502,7 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis)
amin, amax = 0, 2pi
elseif lims == :auto
#widen max radius so ticks dont overlap with theta axis
0, amax + 0.1 * abs(amax - amin)
amin, amax + 0.1 * abs(amax - amin)
else
amin, amax
end
@@ -614,14 +614,14 @@ function axis_drawing_info(sp::Subplot)
end
push!(xaxis_segs, (xmin, y1), (xmax, y1))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(xticks in (:none, nothing, false)) && length(xticks) > 1
if sp[:framestyle] == :origin && !(xticks in (nothing,false)) && length(xticks) > 1
showticks = xticks[1] .!= 0
xticks = (xticks[1][showticks], xticks[2][showticks])
end
end
sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine
end
if !(xaxis[:ticks] in (:none, nothing, false))
if !(xaxis[:ticks] in (nothing, false))
f = scalefunc(yaxis[:scale])
invf = invscalefunc(yaxis[:scale])
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
@@ -642,7 +642,7 @@ function axis_drawing_info(sp::Subplot)
xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid
end
end
if !(xaxis[:minorticks] in (:none, nothing, false)) || xaxis[:minorgrid]
if !(xaxis[:minorticks] in (nothing, false)) || xaxis[:minorgrid]
f = scalefunc(yaxis[:scale])
invf = invscalefunc(yaxis[:scale])
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
@@ -675,14 +675,14 @@ function axis_drawing_info(sp::Subplot)
end
push!(yaxis_segs, (x1, ymin), (x1, ymax))
# don't show the 0 tick label for the origin framestyle
if sp[:framestyle] == :origin && !(yticks in (:none, nothing,false)) && length(yticks) > 1
if sp[:framestyle] == :origin && !(yticks in (nothing,false)) && length(yticks) > 1
showticks = yticks[1] .!= 0
yticks = (yticks[1][showticks], yticks[2][showticks])
end
end
sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin), (x2, ymax)) # right spine
end
if !(yaxis[:ticks] in (:none, nothing, false))
if !(yaxis[:ticks] in (nothing, false))
f = scalefunc(xaxis[:scale])
invf = invscalefunc(xaxis[:scale])
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
@@ -703,7 +703,7 @@ function axis_drawing_info(sp::Subplot)
yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid
end
end
if !(yaxis[:minorticks] in (:none, nothing, false)) || yaxis[:minorgrid]
if !(yaxis[:minorticks] in (nothing, false)) || yaxis[:minorgrid]
f = scalefunc(xaxis[:scale])
invf = invscalefunc(xaxis[:scale])
ticks_in = yaxis[:tick_direction] == :out ? -1 : 1
+2 -4
View File
@@ -351,7 +351,7 @@ const _gr_attr = merge_with_base_supported([
const _gr_seriestype = [
:path, :scatter, :straightline,
:heatmap, :pie, :image,
:contour, :path3d, :scatter3d, :surface, :wireframe, :volume,
:contour, :path3d, :scatter3d, :surface, :wireframe,
:shape
]
const _gr_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
@@ -417,8 +417,6 @@ const _plotly_marker = [
]
const _plotly_scale = [:identity, :log10]
defaultOutputFormat(plt::Plot{Plots.PlotlyBackend}) = "html"
# ------------------------------------------------------------------------------
# pgfplots
@@ -459,7 +457,7 @@ const _pgfplots_attr = merge_with_base_supported([
])
const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape, :straightline,]
const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline, :vline] #vcat(_allMarkers, Shape)
const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline] #vcat(_allMarkers, Shape)
const _pgfplots_scale = [:identity, :ln, :log2, :log10]
# ------------------------------------------------------------------------------
+72 -88
View File
@@ -236,7 +236,6 @@ end
function gr_fill_viewport(vp::AVec{Float64}, c)
GR.savestate()
GR.selntran(0)
GR.setscale(0)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
gr_set_fillcolor(c)
GR.fillrect(vp...)
@@ -416,24 +415,16 @@ function gr_set_viewport_polar()
end
# add the colorbar
function gr_colorbar(sp::Subplot, clims, levels)
GR.savestate()
function gr_colorbar(sp::Subplot, clims)
xmin, xmax = gr_xy_axislims(sp)[1:2]
zmin, zmax = clims[1:2]
gr_set_viewport_cmap(sp)
l = if levels === nothing
(1000:1255)'
elseif length(levels) > 1
min_level, max_level = ignorenan_minimum(levels), ignorenan_maximum(levels)
round.(Int32, 1000 .+ (levels .- min_level) ./ (max_level - min_level) .* 255)
else
Int32[1000, 1255]
end
l = zeros(Int32, 1, 256)
l[1,:] = Int[round(Int, _i) for _i in range(1000, stop=1255, length=256)]
GR.setscale(0)
GR.setwindow(xmin, xmax, zmin, zmax)
GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l)
ztick = 0.5 * GR.tick(zmin, zmax)
GR.axes(0, ztick, xmax, zmin, 0, 1, 0.005)
GR.setwindow(xmin, xmax, clims[1], clims[2])
GR.cellarray(xmin, xmax, clims[2], clims[1], 1, length(l), l)
ztick = 0.5 * GR.tick(clims[1], clims[2])
GR.axes(0, ztick, xmax, clims[1], 0, 1, 0.005)
gr_set_font(guidefont(sp[:yaxis]))
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
@@ -441,7 +432,7 @@ function gr_colorbar(sp::Subplot, clims, levels)
gr_text(viewport_plotarea[2] + gr_colorbar_ratio,
gr_view_ycenter(), sp[:colorbar_title])
GR.restorestate()
gr_set_viewport_plotarea()
end
gr_view_xcenter() = 0.5 * (viewport_plotarea[1] + viewport_plotarea[2])
@@ -480,7 +471,7 @@ end
const _gr_gradient_alpha = ones(256)
function gr_set_gradient(c)
grad = c isa ColorGradient ? c : cgrad()
grad = isa(c, ColorGradient) ? c : cgrad()
for (i,z) in enumerate(range(0, stop=1, length=256))
c = grad[z]
GR.setcolorrep(999+i, red(c), green(c), blue(c))
@@ -669,10 +660,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# reduced from before... set some flags based on the series in this subplot
# TODO: can these be generic flags?
outside_ticks = false
# calculate the colorbar limits once for a subplot
clims = get_clims(sp)
clevels = nothing
cmap = hascolorbar(sp)
draw_axes = sp[:framestyle] != :none
# axes_2d = true
for series in series_list(sp)
@@ -694,9 +682,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
expand_extrema!(sp[:yaxis], y)
data_lims = gr_xy_axislims(sp)
end
# color levels overwritten by the last relevant series
hascolorbar(series) && (clevels = colorbar_levels(series, clims))
end
# set our plot area view
@@ -745,13 +730,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.setlinewidth(sp.plt[:thickness_scaling])
if is3d(sp)
# TODO do we really need a different clims computation here from the one
# computed above using get_clims(sp)?
zmin, zmax = gr_lims(zaxis, true)
clims3d = sp[:clims]
if is_2tuple(clims3d)
isfinite(clims3d[1]) && (zmin = clims3d[1])
isfinite(clims3d[2]) && (zmax = clims3d[2])
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
GR.setspace(zmin, zmax, round.(Int, sp[:camera])...)
xtick = GR.tick(xmin, xmax) / 2
@@ -926,39 +909,27 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.settextalign(halign, GR.TEXT_VALIGN_TOP)
gr_text(xpos, viewport_subplot[4], sp[:title])
end
if is3d(sp)
gr_set_font(guidefont(xaxis))
GR.titles3d(xaxis[:guide], yaxis[:guide], zaxis[:guide])
else
if xaxis[:guide] != ""
gr_set_font(guidefont(xaxis))
if xaxis[:guide_position] == :top || (xaxis[:guide_position] == :auto && xaxis[:mirror] == true)
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
gr_text(gr_view_xcenter(), viewport_subplot[4], xaxis[:guide])
else
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
gr_text(gr_view_xcenter(), viewport_subplot[3], xaxis[:guide])
end
end
if yaxis[:guide] != ""
gr_set_font(guidefont(yaxis))
GR.setcharup(-1, 0)
if yaxis[:guide_position] == :right || (yaxis[:guide_position] == :auto && yaxis[:mirror] == true)
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
if viewport_plotarea[1] - viewport_subplot[1] > 0.1
gr_text(viewport_plotarea[2] + 0.025, gr_view_ycenter(), yaxis[:guide])
else
gr_text(viewport_subplot[2], gr_view_ycenter(), yaxis[:guide])
end
else
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
if viewport_plotarea[1] - viewport_subplot[1] > 0.1
gr_text(viewport_plotarea[1] - 0.075, gr_view_ycenter(), yaxis[:guide])
else
gr_text(viewport_subplot[1], gr_view_ycenter(), yaxis[:guide])
end
end
if xaxis[:guide] != ""
gr_set_font(guidefont(xaxis))
if xaxis[:guide_position] == :top || (xaxis[:guide_position] == :auto && xaxis[:mirror] == true)
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
gr_text(gr_view_xcenter(), viewport_subplot[4], xaxis[:guide])
else
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
gr_text(gr_view_xcenter(), viewport_subplot[3], xaxis[:guide])
end
end
if yaxis[:guide] != ""
gr_set_font(guidefont(yaxis))
GR.setcharup(-1, 0)
if yaxis[:guide_position] == :right || (yaxis[:guide_position] == :auto && yaxis[:mirror] == true)
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
gr_text(viewport_subplot[2], gr_view_ycenter(), yaxis[:guide])
else
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
gr_text(viewport_subplot[1], gr_view_ycenter(), yaxis[:guide])
end
end
GR.restorestate()
@@ -968,15 +939,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# this needs to be here to point the colormap to the right indices
GR.setcolormap(1000 + GR.COLORMAP_COOLWARM)
# calculate the colorbar limits once for a subplot
clims = get_clims(sp)
for (idx, series) in enumerate(series_list(sp))
st = series[:seriestype]
# update the current stored gradient
if st in (:surface, :heatmap) ||
(st == :contour && series[:fillrange] !== nothing)
if st in (:contour, :surface, :wireframe, :heatmap)
gr_set_gradient(series[:fillcolor]) #, series[:fillalpha])
elseif st in (:contour, :wireframe)
gr_set_gradient(series[:linecolor])
elseif series[:marker_z] != nothing
series[:markercolor] = gr_set_gradient(series[:markercolor])
elseif series[:line_z] != nothing
@@ -1052,23 +1023,34 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
end
elseif st == :contour
GR.setspace(clims[1], clims[2], 0, 90)
h = colorbar_levels(series, clims)
zmin, zmax = clims
GR.setspace(zmin, zmax, 0, 90)
if typeof(series[:levels]) <: AbstractArray
h = series[:levels]
else
h = series[:levels] > 1 ? range(zmin, stop=zmax, length=series[:levels]) : [(zmin + zmax) / 2]
end
GR.setlinetype(gr_linetype[get_linestyle(series)])
GR.setlinewidth(max(0, get_linewidth(series) / (sum(gr_plot_size) * 0.001)))
is_lc_black = let black=plot_color(:black)
plot_color(series[:linecolor]) in (black,[black])
end
if series[:fillrange] != nothing
if series[:fillcolor] != series[:linecolor] && !is_lc_black
@warn("GR: filled contour only supported with black contour lines")
end
GR.contourf(x, y, h, z, series[:contour_labels] == true ? 1 : 0)
else
coff = is_lc_black ? 0 : 1000
coff = plot_color(series[:linecolor]) == [plot_color(:black)] ? 0 : 1000
GR.contour(x, y, h, z, coff + (series[:contour_labels] == true ? 1 : 0))
end
# create the colorbar of contour levels
if cmap
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
gr_set_viewport_cmap(sp)
l = (length(h) > 1) ? round.(Int32, 1000 .+ (h .- ignorenan_minimum(h)) ./ (ignorenan_maximum(h) - ignorenan_minimum(h)) .* 255) : Int32[1000, 1255]
GR.setwindow(xmin, xmax, zmin, zmax)
GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l)
ztick = 0.5 * GR.tick(zmin, zmax)
GR.axes(0, ztick, xmax, zmin, 0, 1, 0.005)
gr_set_viewport_plotarea()
end
elseif st in [:surface, :wireframe]
if st == :surface
if length(x) == length(y) == length(z)
@@ -1085,11 +1067,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.surface(x, y, z, GR.OPTION_FILLED_MESH)
end
elseif st == :volume
sp[:legend] = :none
GR.gr3.clear()
dmin, dmax = GR.gr3.volume(y.v, 0)
elseif st == :heatmap
xmin, xmax, ymin, ymax = xy_lims
zmin, zmax = clims
@@ -1200,19 +1177,19 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
elseif st == :image
z = transpose_z(series, series[:z].surf, true)'
w, h = size(z)
w, h = length(x), length(y)
xinds = sort(1:w, rev = xaxis[:flip])
yinds = sort(1:h, rev = yaxis[:flip])
z = z[xinds, yinds]
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
if eltype(z) <: Colors.AbstractGray
grey = round.(UInt8, clamp.(float(z) * 255, 0, 255))
grey = round.(UInt8, float(z) * 255)
rgba = map(c -> UInt32( 0xff000000 + UInt(c)<<16 + UInt(c)<<8 + UInt(c) ), grey)
else
rgba = map(c -> UInt32( round(UInt, clamp(alpha(c) * 255, 0, 255)) << 24 +
round(UInt, clamp(blue(c) * 255, 0, 255)) << 16 +
round(UInt, clamp(green(c) * 255, 0, 255)) << 8 +
round(UInt, clamp(red(c) * 255, 0, 255)) ), z)
rgba = map(c -> UInt32( round(UInt, alpha(c) * 255) << 24 +
round(UInt, blue(c) * 255) << 16 +
round(UInt, green(c) * 255) << 8 +
round(UInt, red(c) * 255) ), z)
end
GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba)
end
@@ -1228,7 +1205,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
end
# draw the colorbar
hascolorbar(sp) && gr_colorbar(sp, clims, clevels)
GR.savestate()
# special colorbar with steps is drawn for contours
if cmap && any(series[:seriestype] != :contour for series in series_list(sp))
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
gr_set_transparency(1)
gr_colorbar(sp, clims)
end
GR.restorestate()
# add the legend
if sp[:legend] != :none
+2 -3
View File
@@ -26,8 +26,7 @@ const _pgfplots_markers = KW(
:star6 => "asterisk",
:diamond => "diamond*",
:pentagon => "pentagon*",
:hline => "-",
:vline => "|"
:hline => "-"
)
const _pgfplots_legend_pos = KW(
@@ -564,7 +563,7 @@ end
function _show(io::IO, mime::MIME"application/x-tex", plt::Plot{PGFPlotsBackend})
fn = tempname()*".tex"
PGFPlots.save(fn, backend_object(plt), include_preamble=plt.attr[:tex_output_standalone])
PGFPlots.save(fn, backend_object(plt), include_preamble=false)
write(io, read(open(fn), String))
end
+8 -12
View File
@@ -186,6 +186,11 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis])
ax[:linecolor] = rgba_string(axis[:foreground_color_axis])
# flip
if axis[:flip]
ax[:range] = reverse(ax[:range])
end
# ticks
if axis[:ticks] != :native
ticks = get_ticks(axis)
@@ -203,10 +208,6 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot)
ax[:showgrid] = false
end
# flip
if axis[:flip]
ax[:range] = reverse(ax[:range])
end
ax
end
@@ -853,15 +854,10 @@ end
# ----------------------------------------------------------------
function _show(io::IO, ::MIME"application/vnd.plotly.v1+json", plot::Plot{PlotlyBackend})
data = []
for series in plot.series_list
append!(data, plotly_series(plot, series))
end
layout = plotly_layout(plot)
JSON.print(io, Dict(:data => data, :layout => layout))
end
function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend})
write(io, html_head(plt) * html_body(plt))
end
function _display(plt::Plot{PlotlyBackend})
standalone_html_window(plt)
-5
View File
@@ -55,11 +55,6 @@ _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(
_show(io::IO, ::MIME"application/pdf", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="pdf")
_show(io::IO, ::MIME"image/eps", plt::Plot{PlotlyJSBackend}) = PlotlyJS.savefig(io, plt.o, format="eps")
function _show(io::IO, m::MIME"application/vnd.plotly.v1+json", plt::Plot{PlotlyJSBackend})
show(io, m, plt.o)
end
function write_temp_html(plt::Plot{PlotlyJSBackend})
filename = string(tempname(), ".html")
savefig(plt, filename)
+133 -137
View File
@@ -21,7 +21,7 @@ pyfont = PyPlot.pyimport("matplotlib.font_manager")
pyticker = PyPlot.pyimport("matplotlib.ticker")
pycmap = PyPlot.pyimport("matplotlib.cm")
pynp = PyPlot.pyimport("numpy")
pynp."seterr"(invalid="ignore")
pynp["seterr"](invalid="ignore")
pytransforms = PyPlot.pyimport("matplotlib.transforms")
pycollections = PyPlot.pyimport("matplotlib.collections")
pyart3d = PyPlot.art3D
@@ -34,11 +34,6 @@ else
:set_facecolor
end
# PyCall API changes in v1.90.0
if !isdefined(PyCall, :_setproperty!)
@warn "Plots no longer supports PyCall < 1.90.0 and PyPlot < 2.8.0. Either update PyCall and PyPlot or pin Plots to a version <= 0.23.2."
end
# # convert colorant to 4-tuple RGBA
# py_color(c::Colorant, α=nothing) = map(f->float(f(convertColor(c,α))), (red, green, blue, alpha))
@@ -69,8 +64,8 @@ py_color(c::Colorant, α) = py_color(plot_color(c, α))
function py_colormap(grad::ColorGradient)
pyvals = [(z, py_color(grad[z])) for z in grad.values]
cm = pycolors."LinearSegmentedColormap"."from_list"("tmp", pyvals)
cm."set_bad"(color=(0,0,0,0.0), alpha=0.0)
cm = pycolors["LinearSegmentedColormap"][:from_list]("tmp", pyvals)
cm[:set_bad](color=(0,0,0,0.0), alpha=0.0)
cm
end
py_colormap(c) = py_colormap(cgrad())
@@ -78,8 +73,8 @@ py_colormap(c) = py_colormap(cgrad())
function py_shading(c, z)
cmap = py_colormap(c)
ls = pycolors."LightSource"(270,45)
ls."shade"(z, cmap, vert_exag=0.1, blend_mode="soft")
ls = pycolors["LightSource"](270,45)
ls[:shade](z, cmap, vert_exag=0.1, blend_mode="soft")
end
# get the style (solid, dashed, etc)
@@ -102,7 +97,7 @@ function py_marker(marker::Shape)
mat[i,2] = y[i]
end
mat[n+1,:] = mat[1,:]
pypath."Path"(mat)
pypath["Path"](mat)
end
const _path_MOVETO = UInt8(1)
@@ -187,7 +182,7 @@ end
# end
function get_locator_and_formatter(vals::AVec)
pyticker."FixedLocator"(1:length(vals)), pyticker."FixedFormatter"(vals)
pyticker["FixedLocator"](1:length(vals)), pyticker["FixedFormatter"](vals)
end
function add_pyfixedformatter(cbar, vals::AVec)
@@ -209,7 +204,7 @@ end
function py_mask_nans(z)
# pynp["ma"][:masked_invalid](z)))
PyCall.pycall(pynp."ma"."masked_invalid", Any, z)
PyCall.pycall(pynp["ma"][:masked_invalid], Any, z)
# pynp["ma"][:masked_where](pynp["isnan"](z),z)
end
@@ -253,22 +248,22 @@ py_fillcolormap(series::Series) = py_colormap(series[:fillcolor])
# Figure utils -- F*** matplotlib for making me work so hard to figure this crap out
# the drawing surface
py_canvas(fig) = fig."canvas"
py_canvas(fig) = fig[:canvas]
# the object controlling draw commands
py_renderer(fig) = py_canvas(fig)."get_renderer"()
py_renderer(fig) = py_canvas(fig)[:get_renderer]()
# draw commands... paint the screen (probably updating internals too)
py_drawfig(fig) = fig."draw"(py_renderer(fig))
py_drawfig(fig) = fig[:draw](py_renderer(fig))
# py_drawax(ax) = ax[:draw](py_renderer(ax[:get_figure]()))
# get a vector [left, right, bottom, top] in PyPlot coords (origin is bottom-left!)
py_extents(obj) = obj."get_window_extent"()."get_points"()
py_extents(obj) = obj[:get_window_extent]()[:get_points]()
# compute a bounding box (with origin top-left), however pyplot gives coords with origin bottom-left
function py_bbox(obj)
fl, fr, fb, ft = py_extents(obj."get_figure"())
fl, fr, fb, ft = py_extents(obj[:get_figure]())
l, r, b, t = py_extents(obj)
BoundingBox(l*px, (ft-t)*px, (r-l)*px, (t-b)*px)
end
@@ -284,13 +279,13 @@ end
# bounding box: union of axis tick labels
function py_bbox_ticks(ax, letter)
labels = getproperty(ax, Symbol("get_"*letter*"ticklabels"))()
labels = ax[Symbol("get_"*letter*"ticklabels")]()
py_bbox(labels)
end
# bounding box: axis guide
function py_bbox_axislabel(ax, letter)
pyaxis_label = getproperty(ax, Symbol("get_"*letter*"axis"))().label
pyaxis_label = ax[Symbol("get_"*letter*"axis")]()[:label]
py_bbox(pyaxis_label)
end
@@ -306,7 +301,7 @@ end
function py_bbox_title(ax)
bb = defaultbox
for s in (:title, :_left_title, :_right_title)
bb = bb + py_bbox(getproperty(ax, s))
bb = bb + py_bbox(ax[s])
end
bb
end
@@ -344,7 +339,7 @@ function py_init_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
proj = (proj in (nothing,:none) ? nothing : string(proj))
# add a new axis, and force it to create a new one by setting a distinct label
ax = fig."add_axes"(
ax = fig[:add_axes](
[0,0,1,1],
label = string(gensym()),
projection = proj
@@ -445,7 +440,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# push!(handles, handle)
# else
for (i, rng) in enumerate(iter_segments(series))
handle = ax."plot"((arg[rng] for arg in xyargs)...;
handle = ax[:plot]((arg[rng] for arg in xyargs)...;
label = i == 1 ? series[:label] : "",
zorder = series[:series_plotindex],
color = py_color(get_linecolor(series, clims, i), get_linealpha(series, i)),
@@ -473,7 +468,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
:linestyle => py_linestyle(st, get_linestyle(series)),
)
add_arrows(x, y) do xyprev, xy
ax."annotate"("",
ax[:annotate]("",
xytext = (0.001xyprev[1] + 0.999xy[1], 0.001xyprev[2] + 0.999xy[2]),
xy = xy,
arrowprops = arrowprops,
@@ -519,7 +514,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
for i=1:length(y)
extrakw[:c] = _cycle(markercolor, i)
push!(handle, ax."scatter"(_cycle(x,i), _cycle(y,i);
push!(handle, ax[:scatter](_cycle(x,i), _cycle(y,i);
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(_cycle(shapes,i)),
@@ -558,7 +553,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
continue
end
push!(handle, ax."scatter"(cur_x_list, cur_y_list;
push!(handle, ax[:scatter](cur_x_list, cur_y_list;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = prev_marker,
@@ -579,7 +574,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
if !isempty(cur_color_list)
push!(handle, ax."scatter"(cur_x_list, cur_y_list;
push!(handle, ax[:scatter](cur_x_list, cur_y_list;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = prev_marker,
@@ -594,7 +589,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(handles, handle)
else
# do a normal scatter plot
handle = ax."scatter"(xyargs...;
handle = ax[:scatter](xyargs...;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
marker = py_marker(series[:markershape]),
@@ -608,7 +603,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
if st == :hexbin
handle = ax."hexbin"(x, y;
handle = ax[:hexbin](x, y;
label = series[:label],
zorder = series[:series_plotindex],
gridsize = series[:bins],
@@ -640,7 +635,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
# contour lines
handle = ax."contour"(x, y, z, levelargs...;
handle = ax[:contour](x, y, z, levelargs...;
label = series[:label],
zorder = series[:series_plotindex],
linewidths = py_thickness_scale(plt, series[:linewidth]),
@@ -648,13 +643,13 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
extrakw...
)
if series[:contour_labels] == true
PyPlot."clabel"(handle, handle.levels)
PyPlot.clabel(handle, handle[:levels])
end
push!(handles, handle)
# contour fills
if series[:fillrange] != nothing
handle = ax."contourf"(x, y, z, levelargs...;
handle = ax[:contourf](x, y, z, levelargs...;
label = series[:label],
zorder = series[:series_plotindex] + 0.5,
extrakw...
@@ -680,7 +675,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
extrakw[:cmap] = py_fillcolormap(series)
end
end
handle = getproperty(ax, st == :surface ? :plot_surface : :plot_wireframe)(x, y, z;
handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z;
label = series[:label],
zorder = series[:series_plotindex],
rstride = series[:stride][1],
@@ -695,7 +690,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
if series[:contours]
for (zdir,mat) in (("x",x), ("y",y), ("z",z))
offset = (zdir == "y" ? ignorenan_maximum : ignorenan_minimum)(mat)
handle = ax."contourf"(x, y, z, levelargs...;
handle = ax[:contourf](x, y, z, levelargs...;
zdir = zdir,
cmap = py_fillcolormap(series),
offset = (zdir == "y" ? ignorenan_maximum : ignorenan_minimum)(mat) # where to draw the contour plane
@@ -707,7 +702,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
elseif typeof(z) <: AbstractVector
# tri-surface plot (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#tri-surface-plots)
handle = ax."plot_trisurf"(x, y, z;
handle = ax[:plot_trisurf](x, y, z;
label = series[:label],
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
@@ -732,7 +727,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
else
z # hopefully it's in a data format that will "just work" with imshow
end
handle = ax."imshow"(z;
handle = ax[:imshow](z;
zorder = series[:series_plotindex],
cmap = py_colormap(cgrad([:black, :white])),
vmin = 0.0,
@@ -742,7 +737,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
push!(handles, handle)
# expand extrema... handle is AxesImage object
xmin, xmax, ymax, ymin = handle."get_extent"()
xmin, xmax, ymax, ymin = handle[:get_extent]()
expand_extrema!(sp, xmin, xmax, ymin, ymax)
# sp[:yaxis].series[:flip] = true
end
@@ -757,7 +752,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
discrete_colorbar_values = dvals
end
handle = ax."pcolormesh"(x, y, py_mask_nans(z);
handle = ax[:pcolormesh](x, y, py_mask_nans(z);
label = series[:label],
zorder = series[:series_plotindex],
cmap = py_fillcolormap(series),
@@ -772,8 +767,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
handle = []
for (i, rng) in enumerate(iter_segments(series))
if length(rng) > 1
path = pypath."Path"(hcat(x[rng], y[rng]))
patches = pypatches."PathPatch"(
path = pypath["Path"](hcat(x[rng], y[rng]))
patches = pypatches["PathPatch"](
path;
label = series[:label],
zorder = series[:series_plotindex],
@@ -783,14 +778,14 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
linestyle = py_linestyle(st, get_linestyle(series, i)),
fill = true
)
push!(handle, ax."add_patch"(patches))
push!(handle, ax[:add_patch](patches))
end
end
push!(handles, handle)
end
if st == :pie
handle = ax."pie"(y;
handle = ax[:pie](y;
# colors = # a vector of colors?
labels = pie_labels(sp, series)
)[1]
@@ -825,7 +820,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng)
end
handle = getproperty(ax, f)(args..., trues(n), false, py_fillstepstyle(st);
handle = 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)),
linewidths = 0
@@ -846,27 +841,27 @@ end
function py_set_lims(ax, axis::Axis)
letter = axis[:letter]
lfrom, lto = axis_limits(axis)
getproperty(ax, Symbol("set_", letter, "lim"))(lfrom, lto)
ax[Symbol("set_", letter, "lim")](lfrom, lto)
end
function py_set_ticks(ax, ticks, letter)
ticks == :auto && return
axis = getproperty(ax, Symbol(letter,"axis"))
axis = ax[Symbol(letter,"axis")]
if ticks == :none || ticks == nothing || ticks == false
kw = KW()
for dir in (:top,:bottom,:left,:right)
kw[dir] = kw[Symbol(:label,dir)] = false
end
axis."set_tick_params"(;which="both", kw...)
axis[:set_tick_params](;which="both", kw...)
return
end
ttype = ticksType(ticks)
if ttype == :ticks
axis."set_ticks"(ticks)
axis[:set_ticks](ticks)
elseif ttype == :ticks_and_labels
axis."set_ticks"(ticks[1])
axis."set_ticklabels"(ticks[2])
axis[:set_ticks](ticks[1])
axis[:set_ticklabels](ticks[2])
else
error("Invalid input for $(letter)ticks: $ticks")
end
@@ -896,7 +891,7 @@ function py_set_scale(ax, axis::Axis)
scale = axis[:scale]
letter = axis[:letter]
scale in supported_scales() || return @warn("Unhandled scale value in pyplot: $scale")
func = getproperty(ax, Symbol("set_", letter, "scale"))
func = ax[Symbol("set_", letter, "scale")]
kw = KW()
arg = if scale == :identity
"linear"
@@ -916,16 +911,16 @@ end
function py_set_axis_colors(sp, ax, a::Axis)
for (loc, spine) in ax.spines
spine."set_color"(py_color(a[:foreground_color_border]))
for (loc, spine) in ax[:spines]
spine[:set_color](py_color(a[:foreground_color_border]))
end
axissym = Symbol(a[:letter], :axis)
if PyCall.hasproperty(ax, axissym)
if haskey(ax, axissym)
tickcolor = sp[:framestyle] in (:zerolines, :grid) ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis])
ax."tick_params"(axis=string(a[:letter]), which="both",
ax[:tick_params](axis=string(a[:letter]), which="both",
colors=tickcolor,
labelcolor=py_color(a[:tickfontcolor]))
getproperty(ax, axissym).label.set_color(py_color(a[:guidefontcolor]))
ax[axissym][:label][:set_color](py_color(a[:guidefontcolor]))
end
end
@@ -937,14 +932,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# update the fig
w, h = plt[:size]
fig = plt.o
fig."clear"()
fig[:clear]()
dpi = plt[:dpi]
fig."set_size_inches"(w/DPI, h/DPI, forward = true)
getproperty(fig, set_facecolor_sym)(py_color(plt[:background_color_outside]))
fig."set_dpi"(plt[:dpi])
fig[:set_size_inches](w/DPI, h/DPI, forward = true)
fig[set_facecolor_sym](py_color(plt[:background_color_outside]))
fig[:set_dpi](plt[:dpi])
# resize the window
PyPlot.plt."get_current_fig_manager"().resize(w, h)
PyPlot.plt[:get_current_fig_manager]()[:resize](w, h)
# initialize subplots
for sp in plt.subplots
@@ -978,10 +973,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
else
:title
end
getproperty(ax, func)."set_text"(sp[:title])
getproperty(ax, func)."set_fontsize"(py_thickness_scale(plt, sp[:titlefontsize]))
getproperty(ax, func)."set_family"(sp[:titlefontfamily])
getproperty(ax, func)."set_color"(py_color(sp[:titlefontcolor]))
ax[func][:set_text](sp[:title])
ax[func][:set_fontsize](py_thickness_scale(plt, sp[:titlefontsize]))
ax[func][:set_family](sp[:titlefontfamily])
ax[func][:set_color](py_color(sp[:titlefontcolor]))
# ax[:set_title](sp[:title], loc = loc)
end
@@ -1001,7 +996,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z, :marker_z))
cmin, cmax = get_clims(sp)
norm = pycolors."Normalize"(vmin = cmin, vmax = cmax)
norm = pycolors[:Normalize](vmin = cmin, vmax = cmax)
f = if colorbar_series[:line_z] != nothing
py_linecolormap
elseif colorbar_series[:fill_z] != nothing
@@ -1009,21 +1004,21 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
else
py_markercolormap
end
cmap = pycmap."ScalarMappable"(norm = norm, cmap = f(colorbar_series))
cmap."set_array"([])
cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series))
cmap[:set_array]([])
handle = cmap
end
# create and store the colorbar object (handle) and the axis that it is drawn on.
# note: the colorbar axis is positioned independently from the subplot axis
fig = plt.o
cbax = fig."add_axes"([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig."colorbar"(handle; cax = cbax, kw...)
cb."set_label"(sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
for lab in cb."ax"."yaxis"."get_ticklabels"()
lab."set_fontsize"(py_thickness_scale(plt, sp[:yaxis][:tickfontsize]))
lab."set_family"(sp[:yaxis][:tickfontfamily])
lab."set_color"(py_color(sp[:yaxis][:tickfontcolor]))
cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym()))
cb = fig[:colorbar](handle; cax = cbax, kw...)
cb[:set_label](sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor]))
for lab in cb[:ax][:yaxis][:get_ticklabels]()
lab[:set_fontsize](py_thickness_scale(plt, sp[:yaxis][:tickfontsize]))
lab[:set_family](sp[:yaxis][:tickfontfamily])
lab[:set_color](py_color(sp[:yaxis][:tickfontcolor]))
end
sp.attr[:cbar_handle] = cb
sp.attr[:cbar_ax] = cbax
@@ -1031,28 +1026,28 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# framestyle
if !ispolar(sp) && !is3d(sp)
ax.spines["left"]."set_linewidth"(py_thickness_scale(plt, 1))
ax.spines["bottom"]."set_linewidth"(py_thickness_scale(plt, 1))
ax[:spines]["left"][:set_linewidth](py_thickness_scale(plt, 1))
ax[:spines]["bottom"][:set_linewidth](py_thickness_scale(plt, 1))
if sp[:framestyle] == :semi
intensity = 0.5
ax.spines["right"]."set_alpha"(intensity)
ax.spines["top"]."set_alpha"(intensity)
ax.spines["right"]."set_linewidth"(py_thickness_scale(plt, intensity))
ax.spines["top"]."set_linewidth"(py_thickness_scale(plt, intensity))
ax[:spines]["right"][:set_alpha](intensity)
ax[:spines]["top"][:set_alpha](intensity)
ax[:spines]["right"][:set_linewidth](py_thickness_scale(plt, intensity))
ax[:spines]["top"][:set_linewidth](py_thickness_scale(plt, intensity))
elseif sp[:framestyle] in (:axes, :origin)
ax.spines["right"]."set_visible"(false)
ax.spines["top"]."set_visible"(false)
ax[:spines]["right"][:set_visible](false)
ax[:spines]["top"][:set_visible](false)
if sp[:framestyle] == :origin
ax.spines["bottom"]."set_position"("zero")
ax.spines["left"]."set_position"("zero")
ax[:spines]["bottom"][:set_position]("zero")
ax[:spines]["left"][:set_position]("zero")
end
elseif sp[:framestyle] in (:grid, :none, :zerolines)
for (loc, spine) in ax.spines
spine."set_visible"(false)
for (loc, spine) in ax[:spines]
spine[:set_visible](false)
end
if sp[:framestyle] == :zerolines
ax."axhline"(y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
ax."axvline"(x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75))
end
end
end
@@ -1060,22 +1055,22 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
# axis attributes
for letter in (:x, :y, :z)
axissym = Symbol(letter, :axis)
PyCall.hasproperty(ax, axissym) || continue
haskey(ax, axissym) || continue
axis = sp[axissym]
pyaxis = getproperty(ax, axissym)
pyaxis = ax[axissym]
if axis[:mirror] && letter != :z
pos = letter == :x ? "top" : "right"
pyaxis."set_label_position"(pos) # the guides
pyaxis."set_ticks_position"("both") # the hash marks
getproperty(pyaxis, Symbol(:tick_, pos))() # the tick labels
pyaxis[:set_label_position](pos) # the guides
pyaxis[:set_ticks_position]("both") # the hash marks
pyaxis[Symbol(:tick_, pos)]() # the tick labels
end
if axis[:guide_position] != :auto && letter != :z
pyaxis."set_label_position"(axis[:guide_position])
pyaxis[:set_label_position](axis[:guide_position])
end
py_set_scale(ax, axis)
axis[:ticks] != :native ? py_set_lims(ax, axis) : nothing
if ispolar(sp) && letter == :y
ax."set_rlabel_position"(90)
ax[:set_rlabel_position](90)
end
ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis)
# don't show the 0 tick label for the origin framestyle
@@ -1083,28 +1078,28 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
ticks[2][ticks[1] .== 0] .= ""
end
axis[:ticks] != :native ? py_set_ticks(ax, ticks, letter) : nothing
pyaxis."set_tick_params"(direction = axis[:tick_direction] == :out ? "out" : "in")
getproperty(ax, Symbol("set_", letter, "label"))(axis[:guide])
pyaxis[:set_tick_params](direction = axis[:tick_direction] == :out ? "out" : "in")
ax[Symbol("set_", letter, "label")](axis[:guide])
if get(axis.plotattributes, :flip, false)
getproperty(ax, Symbol("invert_", letter, "axis"))()
ax[Symbol("invert_", letter, "axis")]()
end
pyaxis."label"."set_fontsize"(py_thickness_scale(plt, axis[:guidefontsize]))
pyaxis."label"."set_family"(axis[:guidefontfamily])
for lab in getproperty(ax, Symbol("get_", letter, "ticklabels"))()
lab."set_fontsize"(py_thickness_scale(plt, axis[:tickfontsize]))
lab."set_family"(axis[:tickfontfamily])
lab."set_rotation"(axis[:rotation])
pyaxis[:label][:set_fontsize](py_thickness_scale(plt, axis[:guidefontsize]))
pyaxis[:label][:set_family](axis[:guidefontfamily])
for lab in ax[Symbol("get_", letter, "ticklabels")]()
lab[:set_fontsize](py_thickness_scale(plt, axis[:tickfontsize]))
lab[:set_family](axis[:tickfontfamily])
lab[:set_rotation](axis[:rotation])
end
if axis[:grid] && !(ticks in (:none, nothing, false))
fgcolor = py_color(axis[:foreground_color_grid])
pyaxis."grid"(true,
pyaxis[:grid](true,
color = fgcolor,
linestyle = py_linestyle(:line, axis[:gridstyle]),
linewidth = py_thickness_scale(plt, axis[:gridlinewidth]),
alpha = axis[:gridalpha])
ax."set_axisbelow"(true)
ax[:set_axisbelow](true)
else
pyaxis."grid"(false)
pyaxis[:grid](false)
end
py_set_axis_colors(sp, ax, axis)
end
@@ -1114,48 +1109,48 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
kw = KW()
for dir in (:top, :bottom)
if ispolar(sp)
ax."spines"."polar"."set_visible"(false)
ax[:spines]["polar"][:set_visible](false)
else
getproperty(ax.spines, dir).set_visible(false)
ax[:spines][string(dir)][:set_visible](false)
end
kw[dir] = kw[Symbol(:label,dir)] = false
end
ax."xaxis"."set_tick_params"(; which="both", kw...)
ax[:xaxis][:set_tick_params](; which="both", kw...)
end
if !sp[:yaxis][:showaxis]
kw = KW()
for dir in (:left, :right)
if !ispolar(sp)
getproperty(ax.spines, dir).set_visible(false)
ax[:spines][string(dir)][:set_visible](false)
end
kw[dir] = kw[Symbol(:label,dir)] = false
end
ax."yaxis"."set_tick_params"(; which="both", kw...)
ax[:yaxis][:set_tick_params](; which="both", kw...)
end
# aspect ratio
aratio = sp[:aspect_ratio]
if aratio != :none
ax."set_aspect"(isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C")
ax[:set_aspect](isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C")
end
#camera/view angle
if is3d(sp)
#convert azimuthal to match GR behaviour
#view_init(elevation, azimuthal) so reverse :camera args
ax."view_init"((sp[:camera].-(90,0))[end:-1:1]...)
ax[:view_init]((sp[:camera].-(90,0))[end:-1:1]...)
end
# legend
py_add_legend(plt, sp, ax)
# this sets the bg color inside the grid
getproperty(ax, set_facecolor_sym)(py_color(sp[:background_color_inside]))
ax[set_facecolor_sym](py_color(sp[:background_color_inside]))
# link axes
x_ax_link, y_ax_link = sp[:xaxis].sps[1].o, sp[:yaxis].sps[1].o
ax != x_ax_link && ax."get_shared_x_axes"()."join"(ax, sp[:xaxis].sps[1].o)
ax != y_ax_link && ax."get_shared_y_axes"()."join"(ax, sp[:yaxis].sps[1].o)
ax != x_ax_link && ax[:get_shared_x_axes]()[:join](ax, sp[:xaxis].sps[1].o)
ax != y_ax_link && ax[:get_shared_y_axes]()[:join](ax, sp[:yaxis].sps[1].o)
end
py_drawfig(fig)
end
@@ -1186,7 +1181,7 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend})
# optionally add the width of colorbar labels and colorbar to rightpad
if haskey(sp.attr, :cbar_ax)
bb = py_bbox(sp.attr[:cbar_handle]."ax"."get_yticklabels"())
bb = py_bbox(sp.attr[:cbar_handle][:ax][:get_yticklabels]())
sp.attr[:cbar_width] = _cbar_width + width(bb) + 2.3mm + (sp[:colorbar_title] == "" ? 0px : 30px)
rightpad = rightpad + sp.attr[:cbar_width]
end
@@ -1207,13 +1202,13 @@ end
function py_add_annotations(sp::Subplot{PyPlotBackend}, x, y, val)
ax = sp.o
ax."annotate"(val, xy = (x,y), zorder = 999)
ax[:annotate](val, xy = (x,y), zorder = 999)
end
function py_add_annotations(sp::Subplot{PyPlotBackend}, x, y, val::PlotText)
ax = sp.o
ax."annotate"(val.str,
ax[:annotate](val.str,
xy = (x,y),
family = val.font.family,
color = py_color(val.font.color),
@@ -1249,14 +1244,14 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
if should_add_to_legend(series)
# add a line/marker and a label
push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing
pypatches."Patch"(
pypatches[:Patch](
edgecolor = py_color(get_linecolor(series, clims), get_linealpha(series)),
facecolor = py_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))
)
elseif series[:seriestype] in (:path, :straightline, :scatter)
PyPlot.plt."Line2D"((0,1),(0,0),
PyPlot.plt[:Line2D]((0,1),(0,0),
color = py_color(get_linecolor(series, clims), get_linealpha(series)),
linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)),
linestyle = py_linestyle(:path, get_linestyle(series)),
@@ -1273,7 +1268,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
# if anything was added, call ax.legend and set the colors
if !isempty(handles)
leg = ax."legend"(handles,
leg = ax[:legend](handles,
labels,
loc = get(_pyplot_legend_pos, leg, "best"),
scatterpoints = 1,
@@ -1282,13 +1277,13 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
edgecolor = py_color(sp[:foreground_color_legend]),
framealpha = alpha(plot_color(sp[:background_color_legend])),
)
frame = leg."get_frame"()
frame."set_linewidth"(py_thickness_scale(plt, 1))
leg."set_zorder"(1000)
sp[:legendtitle] != nothing && leg."set_title"(sp[:legendtitle])
frame = leg[:get_frame]()
frame[:set_linewidth](py_thickness_scale(plt, 1))
leg[:set_zorder](1000)
sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle])
for txt in leg."get_texts"()
PyPlot.plt."setp"(txt, color = py_color(sp[:legendfontcolor]), family = sp[:legendfontfamily])
for txt in leg[:get_texts]()
PyPlot.plt[:setp](txt, color = py_color(sp[:legendfontcolor]), family = sp[:legendfontfamily])
end
end
end
@@ -1306,7 +1301,7 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
figw, figh = sp.plt[:size]
figw, figh = figw*px, figh*px
pcts = bbox_to_pcts(sp.plotarea, figw, figh)
ax."set_position"(pcts)
ax[:set_position](pcts)
# set the cbar position if there is one
if haskey(sp.attr, :cbar_ax)
@@ -1316,7 +1311,7 @@ function _update_plot_object(plt::Plot{PyPlotBackend})
has_toplabel = !(1e-7 < max(abs(ex.emax), abs(ex.emin)) < 1e7)
cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 6mm : 4mm))
pcts = bbox_to_pcts(cb_bbox, figw, figh)
sp.attr[:cbar_ax]."set_position"(pcts)
sp.attr[:cbar_ax][:set_position](pcts)
end
end
PyPlot.draw()
@@ -1325,7 +1320,9 @@ end
# -----------------------------------------------------------------
# display/output
_display(plt::Plot{PyPlotBackend}) = plt.o."show"()
function _display(plt::Plot{PyPlotBackend})
plt.o[:show]()
end
@@ -1335,24 +1332,23 @@ const _pyplot_mimeformats = Dict(
"application/pdf" => "pdf",
"image/png" => "png",
"application/postscript" => "ps",
"image/svg+xml" => "svg",
"application/x-tex" => "pgf"
"image/svg+xml" => "svg"
)
for (mime, fmt) in _pyplot_mimeformats
@eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{PyPlotBackend})
fig = plt.o
fig."canvas"."print_figure"(
fig[:canvas][:print_figure](
io,
format=$fmt,
# bbox_inches = "tight",
# figsize = map(px2inch, plt[:size]),
facecolor = fig."get_facecolor"(),
facecolor = fig[:get_facecolor](),
edgecolor = "none",
dpi = plt[:dpi]
)
end
end
closeall(::PyPlotBackend) = PyPlot.plt."close"("all")
closeall(::PyPlotBackend) = PyPlot.plt[:close]("all")
+1 -1
View File
@@ -116,7 +116,7 @@ function addUnicodeSeries!(o, plotattributes::KW, addlegend::Bool, xlim, ylim)
x, y = if st == :straightline
straightline_data(plotattributes)
elseif st == :shape
shape_data(plotattributes)
shape_data(series)
else
[collect(float(plotattributes[s])) for s in (:x, :y)]
end
+1 -1
View File
@@ -3,7 +3,7 @@ using REPL
function _plots_defaults()
if isdefined(Main, :PLOTS_DEFAULTS)
Dict{Symbol,Any}(Main.PLOTS_DEFAULTS)
Main.PLOTS_DEFAULTS::Dict{Symbol,Any}
else
Dict{Symbol,Any}()
end
+3 -1
View File
@@ -55,7 +55,9 @@ tex(fn::AbstractString) = tex(current(), fn)
function html(plt::Plot, fn::AbstractString)
fn = addExtension(fn, "html")
io = open(fn, "w")
_use_remote[] = true
show(io, MIME("text/html"), plt)
_use_remote[] = false
close(io)
end
html(fn::AbstractString) = html(current(), fn)
@@ -189,7 +191,7 @@ end
# for writing to io streams... first prepare, then callback
for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml",
"application/eps", "application/pdf", "application/postscript",
"application/x-tex", "application/vnd.plotly.v1+json")
"application/x-tex")
@eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot)
if haskey(io, :juno_plotsize)
showjuno(io, m, plt)
+2 -2
View File
@@ -47,7 +47,7 @@ end
num_series(x::AMat) = size(x,2)
num_series(x) = 1
RecipesBase.apply_recipe(plotattributes::KW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError(T, "Unmatched plot recipe: $T"))
RecipesBase.apply_recipe(plotattributes::KW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError("Unmatched plot recipe: $T"))
# ---------------------------------------------------------------------------
@@ -1061,7 +1061,7 @@ end
# -------------------------------------------------
"Adds ax+b... straight line over the current plot, without changing the axis limits"
"Adds a+bx... straight line over the current plot, without changing the axis limits"
abline!(plt::Plot, a, b; kw...) = plot!(plt, [0, 1], [b, b+a]; seriestype = :straightline, kw...)
abline!(args...; kw...) = abline!(current(), args...; kw...)
+3 -19
View File
@@ -431,7 +431,7 @@ isvertical(series::Series) = isvertical(series.plotattributes)
ticksType(ticks::AVec{T}) where {T<:Real} = :ticks
ticksType(ticks::AVec{T}) where {T<:AbstractString} = :labels
ticksType(ticks::Tuple{T,S}) where {T<:Union{AVec,Tuple},S<:Union{AVec,Tuple}} = :ticks_and_labels
ticksType(ticks::Tuple{T,S}) where {T<:AVec,S<:AVec} = :ticks_and_labels
ticksType(ticks) = :invalid
limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits
@@ -610,22 +610,6 @@ function hascolorbar(sp::Subplot)
hascbar
end
function colorbar_levels(series::Series, clims)
if series[:seriestype] == :contour
zmin, zmax = clims
levels = series[:levels]
levels isa AbstractArray ?
levels :
levels > 1 ?
range(zmin, stop=zmax, length=levels) :
[(zmin + zmax) / 2]
else # including heatmap, surface
nothing
end
end
for comp in (:line, :fill, :marker)
compcolor = string(comp, :color)
@@ -1224,8 +1208,8 @@ function _fmt_paragraph(io::IOBuffer,
fillwidth=60,
leadingspaces=0)
kwargs = (fillwidth = fillwidth, leadingspaces = leadingspaces)
kwargs = (fillwidth = fillwidth, leadingspaces = leadingspaces)
m = match(r"(.*?) (.*)",remaining_text)
if isa(m,Nothing)
if column_count + length(remaining_text) fillwidth
+5 -1
View File
@@ -33,7 +33,11 @@ if isinteractive()
# PackageSpec(name="LaTeXStrings"),
])
else
push!(to_add, PackageSpec(url="https://github.com/JuliaPlots/PlotReferenceImages.jl.git"))
push!(to_add, PackageSpec(
name="PlotReferenceImages",
url="https://github.com/JuliaPlots/PlotReferenceImages.jl.git",
rev = "sd-tomls"
))
end
Pkg.add(to_add)
+1 -6
View File
@@ -33,12 +33,7 @@ end
@test backend() == Plots.UnicodePlotsBackend()
# lets just make sure it runs without error
p = plot(rand(10))
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = bar(randn(10))
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
@test isa(plot(rand(10)), Plots.Plot) == true
end
# The plotlyjs testimages return a connection error on travis: