Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4757bd89c0 | |||
| 1e56bf939d | |||
| dbd5ae46dd | |||
| 7c6095b6e8 | |||
| 04888646e7 | |||
| f6ed3fbb76 | |||
| 7bf2918438 | |||
| 92fefc7089 | |||
| e6df4d977d | |||
| 62ca787e6e | |||
| 32d59fff61 | |||
| 1949b6fe0f | |||
| 95a5b5025a | |||
| aa22fd2ff2 | |||
| 50df9a70c9 | |||
| 6d88e150d0 | |||
| b1817e513b | |||
| ce737a9491 | |||
| 6ff4dce62a | |||
| 89b5582d0d | |||
| 09c5e8a375 | |||
| a1a7dcd6b8 | |||
| d223d872fb | |||
| 91eaa32ad7 | |||
| 6cdccf4353 | |||
| ac9aee97fd | |||
| 5be95be9ae | |||
| e402f5dfce | |||
| 61be113714 | |||
| a637f43edd | |||
| 4bb43887a4 | |||
| 802b20be6f | |||
| 216a9c3666 | |||
| d52b2a9adc | |||
| 81782c3927 | |||
| 2c2ebbba0e | |||
| 3d323a734d | |||
| 93263a61b1 | |||
| 8b551e5285 | |||
| e11c91ddd9 | |||
| 938c83533b | |||
| 46136d616f | |||
| 8fe902e96c | |||
| 2fb7dddffb | |||
| 5d1876ab6d | |||
| 1aa4e7eee6 | |||
| 995e12bd57 | |||
| 349b6e8254 | |||
| ee6dbb9ac7 | |||
| 5b85cd83f2 | |||
| 1645c3f66b | |||
| 084d45141d | |||
| 50bec7a461 | |||
| f80afddd8f | |||
| 5d2c630b05 | |||
| f655b2313c | |||
| 2a819c2849 | |||
| 0ef13dcf7a | |||
| 5e5f3c1e95 | |||
| c76ca2dd6e | |||
| ab490b8f95 | |||
| bd42d9e7cc | |||
| e3d8f4a223 | |||
| 34567e1282 | |||
| 0f3928ec9a | |||
| a8380334df | |||
| 70bead1eb1 | |||
| 22d8ecffe5 | |||
| b987331b4f | |||
| 899afd625a |
@@ -11,6 +11,32 @@
|
||||
---
|
||||
## (current master)
|
||||
|
||||
## 0.14.3
|
||||
|
||||
- improve resolution of png output of GR with savefig()
|
||||
- add check for ticks=nothing
|
||||
- allow transparency in heatmaps
|
||||
- fix line_z for GR
|
||||
- fix legendcolor for pyplot
|
||||
- fix pyplot ignoring alpha values of images
|
||||
- don't let `abline!` change subplot limits
|
||||
- update showtheme recipe
|
||||
|
||||
## 0.14.2
|
||||
|
||||
- fix plotly bar lines bug
|
||||
- allow passing multiple series to `ribbon`
|
||||
- add a new example for `line_z`
|
||||
|
||||
## 0.14.1
|
||||
|
||||
- Add linestyle argument to the legend
|
||||
- Plotly: bar_width and stroke_width support for bar plots
|
||||
- abline! does not change axis limits
|
||||
- Fix default log scale ticks in GR backend
|
||||
- Use the :fontsize keys so the scalefontsizes command works
|
||||
- Prepare support for new PlotTheme type in PlotThemes
|
||||
|
||||
## 0.14.0
|
||||
|
||||
- remove use of imagemagick; saving gifs now requires ffmpeg
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
__precompile__(false)
|
||||
__precompile__(true)
|
||||
|
||||
module Plots
|
||||
|
||||
|
||||
+9
-5
@@ -417,12 +417,13 @@ const _all_defaults = KW[
|
||||
]
|
||||
|
||||
const _initial_defaults = deepcopy(_all_defaults)
|
||||
const _initial_axis_defaults = deepcopy(_axis_defaults)
|
||||
|
||||
# to be able to reset font sizes to initial values
|
||||
const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefontsize],
|
||||
:legendfont => _subplot_defaults[:legendfontsize],
|
||||
:tickfont => _axis_defaults[:tickfontsize],
|
||||
:guidefont => _axis_defaults[:guidefontsize])
|
||||
const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize],
|
||||
:legendfontsize => _subplot_defaults[:legendfontsize],
|
||||
:tickfontsize => _axis_defaults[:tickfontsize],
|
||||
:guidefontsize => _axis_defaults[:guidefontsize])
|
||||
|
||||
const _all_args = sort(collect(union(map(keys, _all_defaults)...)))
|
||||
|
||||
@@ -616,7 +617,10 @@ function default(d::KW, k::Symbol)
|
||||
get(d, k, default(k))
|
||||
end
|
||||
|
||||
reset_defaults() = foreach(merge!, _all_defaults, _initial_defaults)
|
||||
function reset_defaults()
|
||||
foreach(merge!, _all_defaults, _initial_defaults)
|
||||
merge!(_axis_defaults, _initial_axis_defaults)
|
||||
end
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
+2
-2
@@ -552,7 +552,7 @@ 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 && 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
|
||||
@@ -591,7 +591,7 @@ 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 && 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
|
||||
|
||||
@@ -336,7 +336,7 @@ end
|
||||
function extract_stroke(d, kw_args)
|
||||
extract_c(d, kw_args, :line)
|
||||
if haskey(d, :linewidth)
|
||||
kw_args[:thickness] = d[:linewidth] * 3
|
||||
kw_args[:thickness] = Float32(d[:linewidth] * 3)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -404,7 +404,7 @@ function extract_linestyle(d, kw_args)
|
||||
haskey(d, :linestyle) || return
|
||||
ls = d[:linestyle]
|
||||
lw = d[:linewidth]
|
||||
kw_args[:thickness] = lw
|
||||
kw_args[:thickness] = Float32(lw)
|
||||
if ls == :dash
|
||||
points = [0.0, lw, 2lw, 3lw, 4lw]
|
||||
insert_pattern!(points, kw_args)
|
||||
@@ -576,7 +576,7 @@ function draw_grid_lines(sp, grid_segs, thickness, style, model, color)
|
||||
)
|
||||
d = Dict(
|
||||
:linestyle => style,
|
||||
:linewidth => thickness,
|
||||
:linewidth => Float32(thickness),
|
||||
:linecolor => color
|
||||
)
|
||||
Plots.extract_linestyle(d, kw_args)
|
||||
@@ -1350,7 +1350,7 @@ function gl_surface(x,y,z, kw_args)
|
||||
end
|
||||
color = get(kw_args, :stroke_color, RGBA{Float32}(0,0,0,1))
|
||||
kw_args[:color] = color
|
||||
kw_args[:thickness] = get(kw_args, :stroke_width, 1f0)
|
||||
kw_args[:thickness] = Float32(get(kw_args, :stroke_width, 1f0))
|
||||
kw_args[:indices] = faces
|
||||
delete!(kw_args, :stroke_color)
|
||||
delete!(kw_args, :stroke_width)
|
||||
|
||||
+57
-11
@@ -222,6 +222,13 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
|
||||
sinf = sind.(a)
|
||||
cosf = cosd.(a)
|
||||
rtick_values, rtick_labels = get_ticks(yaxis)
|
||||
rtick_labels = if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto
|
||||
rtick_labels = string.(convert_sci_unicode.(rtick_labels),"\\ ")
|
||||
# unicode × messes up superscript alignment so add space to superscript
|
||||
replace.(rtick_labels, "{", "{ ")
|
||||
else
|
||||
rtick_labels
|
||||
end
|
||||
|
||||
#draw angular grid
|
||||
if xaxis[:grid]
|
||||
@@ -543,7 +550,7 @@ function gr_set_gradient(c)
|
||||
end
|
||||
|
||||
# this is our new display func... set up the viewport_canvas, compute bounding boxes, and display each subplot
|
||||
function gr_display(plt::Plot)
|
||||
function gr_display(plt::Plot, fmt="")
|
||||
GR.clearws()
|
||||
|
||||
# collect some monitor/display sizes in meters and pixels
|
||||
@@ -554,17 +561,25 @@ function gr_display(plt::Plot)
|
||||
# compute the viewport_canvas, normalized to the larger dimension
|
||||
viewport_canvas = Float64[0,1,0,1]
|
||||
w, h = plt[:size]
|
||||
if !haskey(ENV, "PLOTS_TEST")
|
||||
dpi_factor = plt[:dpi] / DPI
|
||||
if fmt == "png"
|
||||
dpi_factor *= 6
|
||||
end
|
||||
else
|
||||
dpi_factor = 1
|
||||
end
|
||||
gr_plot_size[:] = [w, h]
|
||||
if w > h
|
||||
ratio = float(h) / w
|
||||
msize = display_width_ratio * w
|
||||
msize = display_width_ratio * w * dpi_factor
|
||||
GR.setwsviewport(0, msize, 0, msize * ratio)
|
||||
GR.setwswindow(0, 1, 0, ratio)
|
||||
viewport_canvas[3] *= ratio
|
||||
viewport_canvas[4] *= ratio
|
||||
else
|
||||
ratio = float(w) / h
|
||||
msize = display_height_ratio * h
|
||||
msize = display_height_ratio * h * dpi_factor
|
||||
GR.setwsviewport(0, msize * ratio, 0, msize)
|
||||
GR.setwswindow(0, ratio, 0, 1)
|
||||
viewport_canvas[1] *= ratio
|
||||
@@ -780,10 +795,23 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
ztick = GR.tick(zmin, zmax) / 2
|
||||
ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1])
|
||||
|
||||
# GR.setlinetype(GR.LINETYPE_DOTTED)
|
||||
xaxis[:grid] && GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0)
|
||||
yaxis[:grid] && GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
||||
zaxis[:grid] && GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2)
|
||||
if xaxis[:grid]
|
||||
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
|
||||
GR.settransparency(xaxis[:gridalpha])
|
||||
GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0)
|
||||
end
|
||||
if yaxis[:grid]
|
||||
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
|
||||
GR.settransparency(yaxis[:gridalpha])
|
||||
GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0)
|
||||
end
|
||||
if zaxis[:grid]
|
||||
gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid])
|
||||
GR.settransparency(zaxis[:gridalpha])
|
||||
GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2)
|
||||
end
|
||||
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
|
||||
GR.settransparency(1)
|
||||
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize)
|
||||
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize)
|
||||
|
||||
@@ -860,7 +888,16 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
# use xor ($) to get the right y coords
|
||||
xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin)
|
||||
# @show cv dv ymin xi yi flip mirror (flip $ mirror)
|
||||
gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv))
|
||||
# ensure correct dispatch in gr_text for automatic log ticks
|
||||
dv = if xaxis[:scale] in (:ln, :log10, :log2) && xaxis[:ticks] == :auto
|
||||
string(dv, "\\ ")
|
||||
elseif xaxis[:formatter] == :scientific && xaxis[:ticks] == :auto
|
||||
# unicode × messes up superscript alignment so add space to superscript
|
||||
string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ")
|
||||
else
|
||||
string(dv)
|
||||
end
|
||||
gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), dv)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -871,7 +908,16 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
# use xor ($) to get the right y coords
|
||||
xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv)
|
||||
# @show cv dv xmin xi yi
|
||||
gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv))
|
||||
# ensure correct dispatch in gr_text for automatic log ticks
|
||||
dv = if yaxis[:scale] in (:ln, :log10, :log2) && yaxis[:ticks] == :auto
|
||||
string(dv, "\\ ")
|
||||
elseif yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto
|
||||
# unicode × messes up superscript alignment so add space to superscript
|
||||
string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ")
|
||||
else
|
||||
string(dv)
|
||||
end
|
||||
gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, dv)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1057,7 +1103,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
zmin, zmax = clims
|
||||
GR.setspace(zmin, zmax, 0, 90)
|
||||
grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad()
|
||||
colors = [grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)] for zi=z]
|
||||
colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z]
|
||||
rgba = map(c -> UInt32( round(Int, alpha(c) * 255) << 24 +
|
||||
round(Int, blue(c) * 255) << 16 +
|
||||
round(Int, green(c) * 255) << 8 +
|
||||
@@ -1331,7 +1377,7 @@ for (mime, fmt) in _gr_mimeformats
|
||||
env = get(ENV, "GKSwstype", "0")
|
||||
ENV["GKSwstype"] = $fmt
|
||||
ENV["GKS_FILEPATH"] = filepath
|
||||
gr_display(plt)
|
||||
gr_display(plt, $fmt)
|
||||
GR.emergencyclosegks()
|
||||
write(io, readstring(filepath))
|
||||
rm(filepath)
|
||||
|
||||
@@ -272,6 +272,9 @@ function pgf_axis(sp::Subplot, letter)
|
||||
style = []
|
||||
kw = KW()
|
||||
|
||||
# turn off scaled ticks
|
||||
push!(style, "scaled $(letter) ticks = false")
|
||||
|
||||
# set to supported framestyle
|
||||
framestyle = pgf_framestyle(sp[:framestyle])
|
||||
|
||||
@@ -326,6 +329,7 @@ function pgf_axis(sp::Subplot, letter)
|
||||
push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}"))
|
||||
elseif axis[:showaxis]
|
||||
tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2]
|
||||
tick_labels = axis[:formatter] == :scientific ? string.("\$", convert_sci_unicode.(tick_labels), "\$") : tick_labels
|
||||
push!(style, string(letter, "ticklabels = {", join(tick_labels,","), "}"))
|
||||
else
|
||||
push!(style, string(letter, "ticklabels = {}"))
|
||||
@@ -497,6 +501,7 @@ end
|
||||
|
||||
function _display(plt::Plot{PGFPlotsBackend})
|
||||
# prepare the object
|
||||
PGFPlots.pushPGFPlotsPreamble("\\usepackage{fontspec}")
|
||||
pgfplt = PGFPlots.plot(plt.o)
|
||||
|
||||
# save an svg
|
||||
|
||||
@@ -259,7 +259,7 @@ function plotly_axis(axis::Axis, sp::Subplot)
|
||||
ax[:tickangle] = -axis[:rotation]
|
||||
lims = axis_limits(axis)
|
||||
ax[:range] = map(scalefunc(axis[:scale]), lims)
|
||||
|
||||
|
||||
if !(axis[:ticks] in (nothing, :none))
|
||||
ax[:titlefont] = plotly_font(guidefont(axis))
|
||||
ax[:type] = plotly_scale(axis[:scale])
|
||||
@@ -289,7 +289,7 @@ function plotly_axis(axis::Axis, sp::Subplot)
|
||||
ax[:showgrid] = false
|
||||
end
|
||||
|
||||
|
||||
|
||||
ax
|
||||
end
|
||||
|
||||
@@ -430,7 +430,7 @@ end
|
||||
|
||||
|
||||
function plotly_colorscale(grad::ColorGradient, α)
|
||||
[[grad.values[i], rgb_string(grad.colors[i])] for i in 1:length(grad.colors)]
|
||||
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in 1:length(grad.colors)]
|
||||
end
|
||||
plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α)
|
||||
# plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha)
|
||||
@@ -541,7 +541,9 @@ function plotly_series(plt::Plot, series::Series)
|
||||
else
|
||||
y, x, "h"
|
||||
end
|
||||
d_out[:marker] = KW(:color => rgba_string(series[:fillcolor]))
|
||||
d_out[:width] = series[:bar_width]
|
||||
d_out[:marker] = KW(:color => _cycle(rgba_string.(series[:fillcolor]),eachindex(series[:x])),
|
||||
:line => KW(:width => series[:linewidth]))
|
||||
|
||||
elseif st == :heatmap
|
||||
d_out[:type] = "heatmap"
|
||||
@@ -608,14 +610,14 @@ function plotly_series(plt::Plot, series::Series)
|
||||
:size => 2 * series[:markersize],
|
||||
# :color => rgba_string(series[:markercolor]),
|
||||
:line => KW(
|
||||
:color => rgba_string(series[:markerstrokecolor]),
|
||||
:color => _cycle(rgba_string.(series[:markerstrokecolor]),eachindex(series[:x])),
|
||||
:width => series[:markerstrokewidth],
|
||||
),
|
||||
)
|
||||
|
||||
# gotta hack this (for now?) since plotly can't handle rgba values inside the gradient
|
||||
if series[:marker_z] == nothing
|
||||
d_out[:marker][:color] = rgba_string(series[:markercolor])
|
||||
d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]),eachindex(series[:x]))
|
||||
else
|
||||
# grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha])
|
||||
# grad = as_gradient(series[:markercolor], series[:markeralpha])
|
||||
|
||||
@@ -736,7 +736,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
||||
z = if eltype(img) <: Colors.AbstractGray
|
||||
float(img)
|
||||
elseif eltype(img) <: Colorant
|
||||
map(c -> Float64[red(c),green(c),blue(c)], img)
|
||||
map(c -> Float64[red(c),green(c),blue(c),alpha(c)], img)
|
||||
else
|
||||
z # hopefully it's in a data format that will "just work" with imshow
|
||||
end
|
||||
@@ -768,6 +768,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
|
||||
label = series[:label],
|
||||
zorder = series[:series_plotindex],
|
||||
cmap = py_fillcolormap(series),
|
||||
alpha = series[:fillalpha],
|
||||
# edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"),
|
||||
extrakw...
|
||||
)
|
||||
@@ -1234,8 +1235,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
|
||||
)
|
||||
elseif series[:seriestype] == :path
|
||||
PyPlot.plt[:Line2D]((0,1),(0,0),
|
||||
color = py_color(_cycle(series[:fillcolor],1)),
|
||||
color = py_color(_cycle(series[:linecolor],1)),
|
||||
linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)),
|
||||
linestyle = py_linestyle(:path,series[:linestyle]),
|
||||
marker = py_marker(series[:markershape]),
|
||||
markeredgecolor = py_markerstrokecolor(series),
|
||||
markerfacecolor = py_markercolor(series)
|
||||
|
||||
+4
-4
@@ -305,7 +305,7 @@ end
|
||||
|
||||
function scalefontsize(k::Symbol, factor::Number)
|
||||
f = default(k)
|
||||
f.pointsize = round(Int, factor * f.pointsize)
|
||||
f = round(Int, factor * f)
|
||||
default(k, f)
|
||||
end
|
||||
|
||||
@@ -315,7 +315,7 @@ end
|
||||
Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()`
|
||||
"""
|
||||
function scalefontsizes(factor::Number)
|
||||
for k in (:titlefont, :guidefont, :tickfont, :legendfont)
|
||||
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
|
||||
scalefontsize(k, factor)
|
||||
end
|
||||
end
|
||||
@@ -326,10 +326,10 @@ end
|
||||
Resets font sizes to initial default values.
|
||||
"""
|
||||
function scalefontsizes()
|
||||
for k in (:titlefont, :guidefont, :tickfont, :legendfont)
|
||||
for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize)
|
||||
f = default(k)
|
||||
if k in keys(_initial_fontsizes)
|
||||
factor = f.pointsize / _initial_fontsizes[k]
|
||||
factor = f / _initial_fontsizes[k]
|
||||
scalefontsize(k, 1.0/factor)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -416,6 +416,22 @@ attribute. The default framestyle is `:axes`.
|
||||
end)]
|
||||
),
|
||||
|
||||
PlotExample("Lines and markers with varying colors",
|
||||
"""
|
||||
You can use the `line_z` and `marker_z` properties to associate a color with
|
||||
each line segment or marker in the plot.
|
||||
""",
|
||||
[:(begin
|
||||
t = linspace(0, 1, 100)
|
||||
θ = 6π .* t
|
||||
x = t .* cos.(θ)
|
||||
y = t .* sin.(θ)
|
||||
p1 = plot(x, y, line_z=t, linewidth=3, legend=false)
|
||||
p2 = scatter(x, y, marker_z=t, color=:bluesreds, legend=false)
|
||||
plot(p1, p2)
|
||||
end)]
|
||||
),
|
||||
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
+8
-2
@@ -985,9 +985,15 @@ end
|
||||
|
||||
# -------------------------------------------------
|
||||
|
||||
"Adds a+bx... straight line over the current plot"
|
||||
"Adds a+bx... straight line over the current plot, without changing the axis limits"
|
||||
function abline!(plt::Plot, a, b; kw...)
|
||||
plot!(plt, [ignorenan_extrema(plt)...], x -> b + a*x; kw...)
|
||||
xl, yl = xlims(plt), ylims(plt)
|
||||
x1, x2 = max(xl[1], (yl[1] - b)/a), min(xl[2], (yl[2] - b)/a)
|
||||
if x2 > x1
|
||||
plot!(plt, x -> b + a*x, x1, x2; kw...)
|
||||
else
|
||||
nothing
|
||||
end
|
||||
end
|
||||
|
||||
abline!(args...; kw...) = abline!(current(), args...; kw...)
|
||||
|
||||
@@ -140,6 +140,14 @@ struct SliceIt end
|
||||
end
|
||||
mf = length(fillranges)
|
||||
|
||||
rib = pop!(plotattributes, :ribbon, nothing)
|
||||
ribbons, _ = if typeof(rib) <: Number
|
||||
([fr],nothing)
|
||||
else
|
||||
convertToAnyVector(rib, plotattributes)
|
||||
end
|
||||
mr = length(ribbons)
|
||||
|
||||
# @show zs
|
||||
|
||||
mx = length(xs)
|
||||
@@ -156,6 +164,10 @@ struct SliceIt end
|
||||
fr = fillranges[mod1(i,mf)]
|
||||
di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr
|
||||
|
||||
# handle ribbons
|
||||
rib = ribbons[mod1(i,mr)]
|
||||
di[:ribbon] = isa(rib, Function) ? map(rib, di[:x]) : rib
|
||||
|
||||
push!(series_list, RecipeData(di, ()))
|
||||
end
|
||||
end
|
||||
|
||||
+154
-32
@@ -4,43 +4,165 @@
|
||||
Specify the colour theme for plots.
|
||||
"""
|
||||
function theme(s::Symbol; kw...)
|
||||
# reset?
|
||||
if s == :none || s == :default
|
||||
PlotUtils.clibrary(:Plots)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
|
||||
default(;
|
||||
bg = :white,
|
||||
bglegend = :match,
|
||||
bginside = :match,
|
||||
bgoutside = :match,
|
||||
fg = :auto,
|
||||
fglegend = :match,
|
||||
fggrid = :match,
|
||||
fgaxis = :match,
|
||||
fgtext = :match,
|
||||
fgborder = :match,
|
||||
fgguide = :match,
|
||||
palette = :auto
|
||||
)
|
||||
return
|
||||
end
|
||||
defaults = _get_defaults(s)
|
||||
_theme(s, defaults; kw...)
|
||||
end
|
||||
|
||||
# update the default gradient and other defaults
|
||||
function _get_defaults(s::Symbol)
|
||||
thm = PlotThemes._themes[s]
|
||||
if thm.gradient != nothing
|
||||
if :defaults in fieldnames(thm)
|
||||
return thm.defaults
|
||||
else # old PlotTheme type
|
||||
defaults = KW(
|
||||
:bg => thm.bg_secondary,
|
||||
:bginside => thm.bg_primary,
|
||||
:fg => thm.lines,
|
||||
:fgtext => thm.text,
|
||||
:fgguide => thm.text,
|
||||
:fglegend => thm.text,
|
||||
:palette => thm.palette,
|
||||
)
|
||||
if thm.gradient != nothing
|
||||
push!(defaults, :gradient => thm.gradient)
|
||||
end
|
||||
return defaults
|
||||
end
|
||||
end
|
||||
|
||||
function _theme(s::Symbol, defaults::KW; kw...)
|
||||
# Reset to defaults to overwrite active theme
|
||||
reset_defaults()
|
||||
|
||||
# Set the theme's gradient as default
|
||||
if haskey(defaults, :gradient)
|
||||
PlotUtils.clibrary(:misc)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s))
|
||||
else
|
||||
PlotUtils.clibrary(:Plots)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = :inferno)
|
||||
end
|
||||
default(;
|
||||
bg = thm.bg_secondary,
|
||||
bginside = thm.bg_primary,
|
||||
fg = thm.lines,
|
||||
fgtext = thm.text,
|
||||
fgguide = thm.text,
|
||||
fglegend = thm.text,
|
||||
palette = thm.palette,
|
||||
kw...
|
||||
)
|
||||
|
||||
# maybe overwrite the theme's gradient
|
||||
kw = KW(kw)
|
||||
if haskey(kw, :gradient)
|
||||
kwgrad = pop!(kw, :gradient)
|
||||
for clib in clibraries()
|
||||
if kwgrad in cgradients(clib)
|
||||
PlotUtils.clibrary(clib)
|
||||
PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Set the theme's defaults
|
||||
default(; defaults..., kw...)
|
||||
return
|
||||
end
|
||||
|
||||
@deprecate set_theme(s) theme(s)
|
||||
|
||||
@userplot ShowTheme
|
||||
|
||||
_color_functions = KW(
|
||||
:protanopic => protanopic,
|
||||
:deuteranopic => deuteranopic,
|
||||
:tritanopic => tritanopic,
|
||||
)
|
||||
_get_showtheme_args(thm::Symbol) = thm, identity
|
||||
_get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func, identity)
|
||||
|
||||
@recipe function showtheme(st::ShowTheme)
|
||||
thm, cfunc = _get_showtheme_args(st.args...)
|
||||
defaults = _get_defaults(thm)
|
||||
|
||||
# get the gradient
|
||||
gradient_colors = get(defaults, :gradient, cgrad(:inferno).colors)
|
||||
gradient = cgrad(cfunc.(RGB.(gradient_colors)))
|
||||
|
||||
# get the palette
|
||||
palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17))
|
||||
palette = cfunc.(RGB.(palette))
|
||||
|
||||
# apply the theme
|
||||
for k in keys(defaults)
|
||||
k in (:gradient, :palette) && continue
|
||||
def = defaults[k]
|
||||
arg = get(_keyAliases, k, k)
|
||||
plotattributes[arg] = if typeof(def) <: Colorant
|
||||
cfunc(RGB(def))
|
||||
elseif eltype(def) <: Colorant
|
||||
cfunc.(RGB.(def))
|
||||
elseif contains(string(arg), "color")
|
||||
cfunc.(RGB.(plot_color.(def)))
|
||||
else
|
||||
def
|
||||
end
|
||||
end
|
||||
|
||||
srand(1)
|
||||
|
||||
label := ""
|
||||
colorbar := false
|
||||
layout := (2, 3)
|
||||
|
||||
for j in 1:4
|
||||
@series begin
|
||||
subplot := 1
|
||||
palette := palette
|
||||
seriestype := :path
|
||||
cumsum(randn(50))
|
||||
end
|
||||
|
||||
@series begin
|
||||
subplot := 2
|
||||
seriestype := :scatter
|
||||
palette := palette
|
||||
marker := (:circle, :diamond, :star5, :square)[j]
|
||||
randn(10), randn(10)
|
||||
end
|
||||
end
|
||||
|
||||
@series begin
|
||||
subplot := 3
|
||||
seriestype := :histogram
|
||||
palette := palette
|
||||
randn(1000) .+ (0:2:4)'
|
||||
end
|
||||
|
||||
f(r) = sin(r) / r
|
||||
_norm(x, y) = norm([x, y])
|
||||
x = y = linspace(-3π, 3π, 30)
|
||||
z = f.(_norm.(x, y'))
|
||||
wi = 2:3:30
|
||||
|
||||
@series begin
|
||||
subplot := 4
|
||||
seriestype := :heatmap
|
||||
seriescolor := gradient
|
||||
ticks := -5:5:5
|
||||
x, y, z
|
||||
end
|
||||
|
||||
@series begin
|
||||
subplot := 5
|
||||
seriestype := :surface
|
||||
seriescolor := gradient
|
||||
x, y, z
|
||||
end
|
||||
|
||||
n = 100
|
||||
ts = linspace(0, 10π, n)
|
||||
x = ts .* cos.(ts)
|
||||
y = (0.1ts) .* sin.(ts)
|
||||
z = 1:n
|
||||
|
||||
@series begin
|
||||
subplot := 6
|
||||
seriescolor := gradient
|
||||
linewidth := 3
|
||||
line_z := z
|
||||
x, y, z
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
+27
-1
@@ -553,8 +553,9 @@ zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
|
||||
|
||||
function get_clims(sp::Subplot)
|
||||
zmin, zmax = Inf, -Inf
|
||||
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
|
||||
for series in series_list(sp)
|
||||
for vals in (series[:z], series[:line_z], series[:marker_z], series[:fill_z])
|
||||
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
|
||||
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real)
|
||||
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
|
||||
elseif (vals != nothing) && (eltype(vals) <: Real)
|
||||
@@ -1047,3 +1048,28 @@ guidefont(ax::Axis) = font(
|
||||
ax[:guidefontrotation],
|
||||
ax[:guidefontcolor],
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# converts unicode scientific notation unsupported by pgfplots and gr
|
||||
# into a format that works
|
||||
|
||||
function convert_sci_unicode(label::AbstractString)
|
||||
unicode_dict = Dict(
|
||||
'⁰' => "0",
|
||||
'¹' => "1",
|
||||
'²' => "2",
|
||||
'³' => "3",
|
||||
'⁴' => "4",
|
||||
'⁵' => "5",
|
||||
'⁶' => "6",
|
||||
'⁷' => "7",
|
||||
'⁸' => "8",
|
||||
'⁹' => "9",
|
||||
'⁻' => "-",
|
||||
"×10" => "×10^{",
|
||||
)
|
||||
for key in keys(unicode_dict)
|
||||
label = replace(label, key, unicode_dict[key])
|
||||
end
|
||||
string(label, "}")
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ default(show=false, reuse=true)
|
||||
img_eps = isinteractive() ? 1e-2 : 10e-2
|
||||
|
||||
@testset "GR" begin
|
||||
ENV["PLOTS_TEST"] = "true"
|
||||
ENV["GKSwstype"] = "100"
|
||||
@test gr() == Plots.GRBackend()
|
||||
@test backend() == Plots.GRBackend()
|
||||
|
||||
Reference in New Issue
Block a user