Compare commits

...

52 Commits

Author SHA1 Message Date
Simon Christ 217e67fb7f 1.5.9 [skip ci] 2020-08-11 10:58:03 +02:00
ztangent 3053bb4cc2 Fix error when setting animation loop count (#2904)
When creating an animation with a custom loop count, via, e.g., `gif(anim; loop=-1)`, so `mov(anim; loop=-1)`, FFMPEG throws the following error:

```
[image2 demuxer @ 000001fdf77ec280] Unable to parse option value "-1" as boolean
[image2 demuxer @ 000001fdf77ec280] Error setting option loop to value -1. 
```

This PR fixes the error by moving the `-loop` flag to after the `-i` input flag in the call to `ffmpeg_exe`. I believe the error is caused because the `-loop` flag occuring before `-i` controls how the input is interpreted, whereas the `-loop` flag occuring after `-i` controls how many loops are in the output.
2020-08-11 10:31:29 +02:00
Simon Christ 8dcff1f73d Update SnoopCompile.yml (#2902) 2020-08-07 22:36:29 +02:00
Simon Christ c73a5aaabc fix saving as .tikz (#2901) 2020-08-07 12:45:50 +02:00
github-actions[bot] 806d4671ce CompatHelper: bump compat for "FFMPEG" to "0.4" (#2891)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-05 10:18:47 +02:00
Simon Christ c4a64351ca set version to 1.5.8 [skip ci] 2020-08-04 11:05:28 +02:00
Simon Christ 345bceb526 conserve extra_kwargs (#2885)
* conserve extra_kwargs

* Update test_pgfplotsx.jl

* remove wraptuples

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Update test_pgfplotsx.jl

* Revert "remove wraptuples"

This reverts commit 6d66d69692.

* Auto stash before revert of "remove wraptuples"
2020-08-01 00:34:04 +02:00
Simon Christ 5673ced5d7 set version to 1.5.7 [skip ci] 2020-07-28 10:23:15 +02:00
Simon Christ a929903a63 Update SnoopCompile.yml (#2873)
* Update SnoopCompile.yml

I don't think we need to run on all branches and nightly.
Also we don't have benchmarks, right?

* Update SnoopCompile.yml
2020-07-27 09:34:32 +02:00
Maaz Bin Tahir Saeed b9cf8c3928 Fix guides not being considered in calculating plot area (#2878) 2020-07-26 21:43:22 +02:00
Simon Christ 9b573dce49 set version to 1.5.6 [skip ci] 2020-07-23 11:59:08 +02:00
isentropic c2bb17cece pyplot fonts fixed (#2858) 2020-07-23 11:57:24 +02:00
Maaz Bin Tahir Saeed 7e122bdfea Fix #2848: Legend :top should start below axis spine (#2870)
* Account for adding dy to ymax in legend pos

* Subtract x legend offset from :right symbols
2020-07-23 09:48:14 +02:00
Yuval 1ee999af33 Merge pull request #2867 from yha/animation-no-yuv
Don't use `-pix_fmt yuv420p` when calling ffmpeg
2020-07-22 19:49:03 +03:00
Daniel Schwabeneder 381f14b657 Merge pull request #2869 from MLH-Fellowship/diaga-2808
Fix #2808: Make legend width proportional to plot size
2020-07-22 14:02:15 +02:00
Diaga 3fec5ae1cf Include legend width changes for shapes and increase width 2020-07-21 18:27:06 +05:00
Diaga b154a1a3e4 Make white space and marker pos dynamic 2020-07-21 14:19:20 +05:00
Yuval cef0a55870 Merge pull request #2866 from yha/offset-fillrange
Support offset vectors as fillrange and ribbon
2020-07-20 12:35:00 +03:00
yha 61e80e96cf Don't use yuv240p format for video 2020-07-20 01:05:14 +03:00
yha 0db321aecc Support offset vectors as fillrange and ribbon 2020-07-20 00:12:47 +03:00
Daniel Schwabeneder 8b7f87506a Merge pull request #2865 from daschw/pyplot-image
fix wrong image limits in pyplot (fix #2864)
2020-07-16 23:36:45 +02:00
Simon Christ f9f6e0ff57 remove show comments 2020-07-16 21:25:46 +02:00
Daniel Schwabeneder 6f36d0998f fix wrong image limits in pyplot (fix #2864) 2020-07-16 20:17:02 +02:00
Josef Heinen 943bdca05e Update Project.toml 2020-07-15 21:19:28 +02:00
Josef Heinen bece65e922 Update Project.toml 2020-07-15 21:17:25 +02:00
Simon Christ 2fb315af0e fix typo 2020-07-13 10:09:43 +02:00
Simon Christ 849c2911a7 fix ribbon, fillbetween distinction 2020-07-09 22:07:04 +02:00
Simon Christ fa720d6ad4 patch release [skip ci] 2020-07-09 12:32:04 +02:00
Simon Christ 1ab681f509 fix ribbons (#2853)
* fix ribbons

* fix tests
2020-07-09 12:23:27 +02:00
Daniel Schwabeneder 0d776fd09d Merge pull request #2850 from daschw/gr-error
fix yerror and marker_z
2020-07-08 08:58:12 +02:00
Daniel Schwabeneder 45e33f5b6f fix yerror and marker_z 2020-07-07 21:44:47 +02:00
Daniel Schwabeneder 1c4910f90e Merge pull request #2807 from MLH-Fellowship/diaga-issue-2202-2330
Fix #2330, #2202: Position legends closer to the borders
2020-07-07 20:55:00 +02:00
Simon Christ 2f4eb7b558 change z buffer for surface plots (#2843) 2020-07-04 19:37:42 +02:00
Daniel Schwabeneder 07ed5e7162 Merge pull request #2846 from daschw/release
patch release
2020-07-04 12:17:23 +02:00
Daniel Schwabeneder 03716289c3 patch release [skip ci] 2020-07-04 12:16:13 +02:00
Daniel Schwabeneder 0d38f34e54 Merge pull request #2844 from daschw/errorbar
fix errorbar color
2020-07-03 17:09:17 +02:00
Daniel Schwabeneder 2544808000 update errorbar example 2020-07-03 16:31:03 +02:00
Diaga 02ca049bc6 Remove static offsets for ypos 2020-07-03 18:52:54 +05:00
Daniel Schwabeneder cd20518323 fix errorbar color for scatter 2020-07-03 15:40:46 +02:00
Diaga ff7235e9b8 Remove constant offsets for xpos 2020-07-03 17:56:13 +05:00
Daniel Schwabeneder fb5307ace6 Merge pull request #2840 from daschw/release
patch release
2020-07-02 16:42:47 +02:00
Lakshya Khatri e3512b0f0d Add label for label=0 kwarg (#2837)
* Add label for `label=0` kwarg

* Fix ambiguous comparision of label with 0

* Add methods for handling plot labels

* Remove type annotations for series indexes

* Replace label conversion code with shorter version

* Handel symbol args for labels in more consistent manner

* Broadcast label_to_string to handle Array of labels

Co-authored-by: Simon Christ <SimonChrist@gmx.de>

Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2020-07-02 16:32:37 +02:00
Diaga 376fae0d79 Make legend offset calculation dynamic 2020-07-02 18:12:23 +05:00
Daniel Schwabeneder e0e240bfd2 bump version [skip ci] 2020-07-02 14:41:04 +02:00
Daniel Schwabeneder 079152a69a Merge pull request #2839 from daschw/precompile
include precompile_includer.jl
2020-07-02 14:39:20 +02:00
Daniel Schwabeneder ffed7ebc21 undo version change in SnoopCompile.jl 2020-07-02 13:55:10 +02:00
Daniel Schwabeneder cc7c0f1251 change julia 1.5.0 version 2020-07-02 13:51:57 +02:00
Daniel Schwabeneder 30c683b201 include prercompile_includer.jl manually 2020-07-02 13:50:26 +02:00
Daniel Schwabeneder c3fa7c8941 Merge pull request #2836 from daschw/windows-tests
Make tests pass on windows julia 1.3
2020-07-01 12:07:20 +02:00
Daniel Schwabeneder ddc89e54f1 fix undefined is_ci 2020-07-01 10:32:04 +02:00
Daniel Schwabeneder 0a929d6022 try to fix tests on windows julia 1.3 2020-07-01 09:44:27 +02:00
Diaga d036794576 Fix #2330, #2202: Position legends closer to the borders 2020-06-22 17:45:23 +05:00
17 changed files with 203 additions and 131 deletions
+1 -2
View File
@@ -23,8 +23,7 @@ jobs:
version: # NOTE: the versions below should match those in your botconfig
- '1.3'
- '1.4'
- '1.5.0-rc1'
- 'nightly'
- '1.5'
os: # NOTE: should match the os setting of your botconfig
- ubuntu-latest
- windows-latest
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.version == 'nightly' || (matrix.version == '1.3' && matrix.os == 'windows-latest')}}
continue-on-error: ${{ matrix.version == 'nightly' }}
strategy:
fail-fast: false
matrix:
+3 -3
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.5.1"
version = "1.5.9"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -33,9 +33,9 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Contour = "0.5"
FFMPEG = "0.2, 0.3"
FFMPEG = "0.2, 0.3, 0.4"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.46, 0.47, 0.48, 0.49, 0.50"
GR = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51"
GeometryBasics = "0.2"
GeometryTypes = "0.7, 0.8"
JSON = "0.21, 1"
+2
View File
@@ -250,4 +250,6 @@ end
const CURRENT_BACKEND = CurrentBackend(:none)
include("precompile_includer.jl")
end # module
+3 -3
View File
@@ -90,15 +90,15 @@ function buildanimation(anim::Animation, fn::AbstractString,
if variable_palette
# generate a colorpalette for each frame for highest quality, but larger filesize
palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1"
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -lavfi "$palette" -loop $loop -y $fn`)
else
# generate a colorpalette first so ffmpeg does not have to guess it
ffmpeg_exe(`-v $verbose_level -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`)
# then apply the palette to get better results
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -loop $loop -y $fn`)
end
else
ffmpeg_exe(`-v $verbose_level -framerate $framerate -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`)
ffmpeg_exe(`-v $verbose_level -framerate $framerate -i $(animdir)/%06d.png -loop $loop -y $fn`)
end
show_msg && @info("Saved animation to ", fn)
+24 -13
View File
@@ -20,14 +20,14 @@ function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol})
end
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}, args::Vector{Symbol})
for arg in args
s = string(arg)
if '_' in s
aliases[Symbol(replace(s, "_" => ""))] = arg
end
end
end
function add_non_underscore_aliases!(aliases::Dict{Symbol,Symbol}, args::Vector{Symbol})
for arg in args
s = string(arg)
if '_' in s
aliases[Symbol(replace(s, "_" => ""))] = arg
end
end
end
# ------------------------------------------------------------
const _allAxes = [:auto, :left, :right]
@@ -235,7 +235,7 @@ const _bar_width = 0.8
# -----------------------------------------------------------------------------
const _series_defaults = KW(
:label => "AUTO",
:label => :auto,
:colorbar_entry => true,
:seriescolor => :auto,
:seriesalpha => nothing,
@@ -1569,6 +1569,20 @@ function _slice_series_args!(plotattributes::AKW, plt::Plot, sp::Subplot, comman
return plotattributes
end
label_to_string(label::Bool, series_plotindex) = label ? label_to_string(:auto, series_plotindex) : ""
label_to_string(label::Nothing, series_plotindex) = ""
label_to_string(label::Missing, series_plotindex) = ""
function label_to_string(label::Symbol, series_plotindex)
if label==:auto
return string("y", series_plotindex)
elseif label==:none
return ""
else
throw(ArgumentError("unsupported symbol $(label) passed to `label`"))
end
end
label_to_string(label, series_plotindex) = string(label) # Fallback to string promotion
function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot)
pkg = plt.backend
globalIndex = plotattributes[:series_plotindex]
@@ -1637,10 +1651,7 @@ function _update_series_attributes!(plotattributes::AKW, plt::Plot, sp::Subplot)
end
# set label
label = plotattributes[:label]
label = (label == "AUTO" ? "y$globalIndex" : label)
label = label in (:none, nothing, false) ? "" : label
plotattributes[:label] = label
plotattributes[:label] = label_to_string.(plotattributes[:label], globalIndex)
_replace_linewidth(plotattributes)
plotattributes
+43 -25
View File
@@ -349,11 +349,13 @@ function gr_draw_markers(
shapes = series[:markershape]
if shapes != :none
for i in eachindex(x)
for (i, rng) in enumerate(iter_segments(series))
ms = get_thickness_scaling(series) * _cycle(msize, i)
msw = get_thickness_scaling(series) * _cycle(strokewidth, i)
shape = _cycle(shapes, i)
gr_draw_marker(series, x[i], y[i], clims, i, ms, msw, shape)
for j in rng
gr_draw_marker(series, _cycle(x, j), _cycle(y, j), clims, i, ms, msw, shape)
end
end
end
end
@@ -565,6 +567,8 @@ gr_view_xcenter(viewport_plotarea) = 0.5 * (viewport_plotarea[1] + viewport_plot
gr_view_ycenter(viewport_plotarea) = 0.5 * (viewport_plotarea[3] + viewport_plotarea[4])
function gr_legend_pos(sp::Subplot, w, h, viewport_plotarea)
legend_leftw, legend_rightw, legend_textw, x_legend_offset = w
legend_dy, legendh, y_legend_offset = h
s = sp[:legend]
typeof(s) <: Symbol || return gr_legend_pos(s, w, h, viewport_plotarea)
str = string(s)
@@ -579,34 +583,34 @@ function gr_legend_pos(sp::Subplot, w, h, viewport_plotarea)
if occursin("right", str)
if occursin("outer", str)
# As per https://github.com/jheinen/GR.jl/blob/master/src/jlgr.jl#L525
xpos = viewport_plotarea[2] + 0.11 + ymirror * gr_axis_width(sp, sp[:yaxis])
xpos = viewport_plotarea[2] + x_legend_offset + legend_leftw + ymirror * gr_axis_width(sp, sp[:yaxis])
else
xpos = viewport_plotarea[2] - 0.05 - w
xpos = viewport_plotarea[2] - legend_rightw - legend_textw - x_legend_offset
end
elseif occursin("left", str)
if occursin("outer", str)
xpos = viewport_plotarea[1] - 0.05 - w - !ymirror * gr_axis_width(sp, sp[:yaxis])
xpos = viewport_plotarea[1] - !ymirror * gr_axis_width(sp, sp[:yaxis]) - x_legend_offset * 2 - legend_rightw - legend_textw
else
xpos = viewport_plotarea[1] + 0.11
xpos = viewport_plotarea[1] + legend_leftw + x_legend_offset
end
else
xpos = (viewport_plotarea[2]-viewport_plotarea[1])/2 - w/2 +.04 + viewport_plotarea[1]
xpos = (viewport_plotarea[2]-viewport_plotarea[1])/2 + viewport_plotarea[1] + legend_leftw - legend_rightw - legend_textw - x_legend_offset * 2
end
if occursin("top", str)
if s == :outertop
ypos = viewport_plotarea[4] + 0.02 + h + xmirror * gr_axis_height(sp, sp[:xaxis])
ypos = viewport_plotarea[4] + y_legend_offset + legendh + xmirror * gr_axis_height(sp, sp[:xaxis])
else
ypos = viewport_plotarea[4] - 0.06
ypos = viewport_plotarea[4] - y_legend_offset - legend_dy
end
elseif occursin("bottom", str)
if s == :outerbottom
ypos = viewport_plotarea[3] - 0.05 - !xmirror * gr_axis_height(sp, sp[:xaxis])
ypos = viewport_plotarea[3] - y_legend_offset - legendh - !xmirror * gr_axis_height(sp, sp[:xaxis])
else
ypos = viewport_plotarea[3] + h + 0.06
ypos = viewport_plotarea[3] + legendh + y_legend_offset
end
else
# Adding min y to shift legend pos to correct graph (#2377)
ypos = (viewport_plotarea[4]-viewport_plotarea[3])/2 + h/2 + viewport_plotarea[3]
ypos = (viewport_plotarea[4]-viewport_plotarea[3])/2 + legendh/2 + viewport_plotarea[3]
end
(xpos,ypos)
end
@@ -1003,7 +1007,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
legendn += 1
lab = series[:label]
tbx, tby = gr_inqtext(0, 0, string(lab))
legendw = max(legendw, tbx[3] - tbx[1])
legendw = max(legendw, tbx[3] - tbx[1]) # Holds text width right now
end
GR.setscale(1)
@@ -1011,18 +1015,32 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.restorestate()
end
legend_width_factor = (viewport_plotarea[2] - viewport_plotarea[1]) / 45 # Determines the width of legend box
legend_textw = legendw
legend_rightw = legend_width_factor
legend_leftw = legend_width_factor * 4
total_legendw = legend_textw + legend_leftw + legend_rightw
x_legend_offset = (viewport_plotarea[2] - viewport_plotarea[1]) / 30
y_legend_offset = (viewport_plotarea[4] - viewport_plotarea[3]) / 30
dy = gr_point_mult(sp) * sp[:legendfontsize] * 1.75
legendh = dy * legendn
leg_str = string(sp[:legend])
xaxis, yaxis = sp[:xaxis], sp[:yaxis]
xmirror = xaxis[:guide_position] == :top || (xaxis[:guide_position] == :auto && xaxis[:mirror] == true)
ymirror = yaxis[:guide_position] == :right || (yaxis[:guide_position] == :auto && yaxis[:mirror] == true)
if occursin("outer", leg_str)
if occursin("right", leg_str)
viewport_plotarea[2] -= legendw + 0.12
viewport_plotarea[2] -= total_legendw + x_legend_offset
elseif occursin("left", leg_str)
viewport_plotarea[1] += legendw + 0.11
viewport_plotarea[1] += total_legendw + x_legend_offset + !ymirror * gr_axis_width(sp, sp[:yaxis])
elseif occursin("top", leg_str)
viewport_plotarea[4] -= legendh + 0.03
viewport_plotarea[4] -= legendh + dy + y_legend_offset
elseif occursin("bottom", leg_str)
viewport_plotarea[3] += legendh + 0.04
viewport_plotarea[3] += legendh + dy + y_legend_offset + !xmirror * gr_axis_height(sp, sp[:xaxis])
end
end
if sp[:legend] == :inline
@@ -1840,17 +1858,17 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
GR.selntran(0)
GR.setscale(0)
gr_set_font(legendfont(sp), sp)
w = legendw
w = legendw # This is the legend text width
n = legendn
if w > 0
dy = gr_point_mult(sp) * sp[:legendfontsize] * 1.75
h = dy*n
xpos, ypos = gr_legend_pos(sp, w, h, viewport_plotarea)
xpos, ypos = gr_legend_pos(sp, [legend_leftw, legend_rightw, legend_textw, x_legend_offset, y_legend_offset], [dy, h, y_legend_offset], viewport_plotarea) # Passing legend width components instead of legend text width
GR.setfillintstyle(GR.INTSTYLE_SOLID)
gr_set_fillcolor(sp[:background_color_legend])
GR.fillrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n)
GR.fillrect(xpos - legend_leftw, xpos + legend_textw + legend_rightw, ypos + dy, ypos - dy * n) # Allocating white space for actual legend width here
gr_set_line(1, :solid, sp[:foreground_color_legend], sp)
GR.drawrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n)
GR.drawrect(xpos - legend_leftw, xpos + legend_textw + legend_rightw, ypos + dy, ypos - dy * n) # Drawing actual legend width here
i = 0
if sp[:legendtitle] !== nothing
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF)
@@ -1869,7 +1887,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
if (st == :shape || series[:fillrange] !== nothing) && series[:ribbon] === nothing
fc = get_fillcolor(series, clims)
gr_set_fill(fc) #, series[:fillalpha])
l, r = xpos-0.07, xpos-0.01
l, r = xpos - legend_width_factor * 3.5, xpos - legend_width_factor / 2
b, t = ypos-0.4dy, ypos+0.4dy
x = [l, r, r, l, l]
y = [b, b, t, t, b]
@@ -1884,9 +1902,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
if st in (:path, :straightline, :path3d)
gr_set_transparency(lc, get_linealpha(series))
if series[:fillrange] === nothing || series[:ribbon] !== nothing
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos])
GR.polyline([xpos - legend_width_factor * 3.5, xpos - legend_width_factor / 2], [ypos, ypos])
else
GR.polyline([xpos - 0.07, xpos - 0.01], [ypos+0.4dy, ypos+0.4dy])
GR.polyline([xpos - legend_width_factor * 3.5, xpos - legend_width_factor / 2], [ypos+0.4dy, ypos+0.4dy])
end
end
@@ -1899,7 +1917,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
0, 0.8 * sp[:legendfontsize] * msw / 8
end
gr_draw_markers(
series, xpos - 0.035, ypos, clims, s, sw
series, xpos - legend_width_factor * 2, ypos, clims, s, sw
)
end
+23 -32
View File
@@ -83,17 +83,17 @@ function Base.push!(pgfx_plot::PGFPlotsXPlot, item)
push!(pgfx_plot.the_plot, item)
end
function pgfx_split_extra_opts(extra)
return (get(extra, :add, nothing), filter( x-> first(x) != :add, extra))
end
function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
if !pgfx_plot.is_created || pgfx_plot.was_shown
pgfx_sanitize_plot!(plt)
# extract extra kwargs
extra_plot_opt = plt[:extra_plot_kwargs]
extra_plot = nothing
if haskey(extra_plot_opt, :add)
extra_plot = wraptuple(pop!(extra_plot_opt,:add))
end
extra_plot, extra_plot_opt = pgfx_split_extra_opts(plt[:extra_plot_kwargs])
the_plot = PGFPlotsX.TikzPicture(PGFPlotsX.Options(extra_plot_opt...))
if extra_plot !== nothing
extra_plot = wraptuple(extra_plot)
push!(the_plot, extra_plot...)
end
bgc = plt.attr[:background_color_outside] == :match ?
@@ -249,13 +249,10 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
else
PGFPlotsX.Axis
end
extra_sp_opt = sp[:extra_kwargs]
extra_sp = nothing
if haskey(extra_sp_opt, :add)
extra_sp = wraptuple(pop!(extra_sp_opt,:add))
end
extra_sp, extra_sp_opt = pgfx_split_extra_opts(sp[:extra_kwargs])
axis = axisf(merge(axis_opt, PGFPlotsX.Options(extra_sp_opt...)))
if extra_sp !== nothing
extra_sp = wraptuple(extra_sp)
push!(axis, extra_sp...)
end
if sp[:legendtitle] !== nothing
@@ -279,11 +276,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
"color" => single_color(opt[:linecolor]),
"name path" => string(series_id),
)
extra_series_opt = series[:extra_kwargs]
extra_series = nothing
if haskey(extra_series_opt, :add)
extra_series = wraptuple(pop!(extra_series_opt,:add))
end
extra_series, extra_series_opt = pgfx_split_extra_opts(series[:extra_kwargs])
series_opt = merge(series_opt, PGFPlotsX.Options(extra_series_opt...))
if RecipesPipeline.is3d(series) || st in (:heatmap, :contour)
series_func = PGFPlotsX.Plot3
@@ -344,9 +337,8 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
end
# add fillrange
if sf !== nothing &&
!isfilledcontour(series) &&
series[:ribbon] === nothing
if sf isa Number || sf isa AVec
!isfilledcontour(series)
if sf isa Number || sf isa AVec
pgfx_fillrange_series!(
axis,
series,
@@ -355,6 +347,17 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
_cycle(sf, rng),
rng,
)
elseif sf isa Tuple && series[:ribbon] !== nothing
for sfi in sf
pgfx_fillrange_series!(
axis,
series,
series_func,
i,
_cycle(sfi, rng),
rng,
)
end
end
if i == 1 &&
sp[:legend] != :none && pgfx_should_add_to_legend(series)
@@ -366,6 +369,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
segment_plot =
series_func(merge(series_opt, segment_opt), coordinates)
if extra_series !== nothing
extra_series = wraptuple(extra_series)
push!(segment_plot, extra_series...)
end
push!(axis, segment_plot)
@@ -384,17 +388,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
),
)
end
# add ribbons?
ribbon = series[:ribbon]
if ribbon !== nothing
pgfx_add_ribbons!(
axis,
series,
segment_plot,
series_func,
series_index,
)
end
# add to legend?
if sp[:legend] != :none
leg_entry = if opt[:label] isa AVec
@@ -412,9 +405,6 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
push!(axis.contents[end].options, "forget plot" => nothing)
else
leg_opt = PGFPlotsX.Options()
if ribbon !== nothing
pgfx_filllegend!(axis.contents[end - 3].options, opt)
end
legend = PGFPlotsX.LegendEntry(leg_opt, leg_entry, false)
push!(axis, legend)
end
@@ -558,6 +548,7 @@ function pgfx_series_coordinates!(st_val::Val{:surface}, segment_opt, opt, args)
"surf" => nothing,
"mesh/rows" => length(opt[:x]),
"mesh/cols" => length(opt[:y]),
"z buffer" => "sort",
)
return PGFPlotsX.Coordinates(args...)
end
+27 -14
View File
@@ -23,6 +23,7 @@ pynp."seterr"(invalid="ignore")
pytransforms = PyPlot.pyimport("matplotlib.transforms")
pycollections = PyPlot.pyimport("matplotlib.collections")
pyart3d = PyPlot.art3D
pyrcparams = PyPlot.PyDict(PyPlot.matplotlib."rcParams")
# "support" matplotlib v1.5
set_facecolor_sym = if PyPlot.version < v"2"
@@ -276,7 +277,6 @@ end
function py_bbox_axis(ax, letter)
ticks = py_bbox_ticks(ax, letter)
labels = py_bbox_axislabel(ax, letter)
# letter == "x" && @show ticks labels ticks+labels
ticks + labels
end
@@ -728,8 +728,10 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
if st == :image
# @show typeof(z)
xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y])
xmin, xmax = ignorenan_extrema(series[:x])
ymin, ymax = ignorenan_extrema(series[:y])
dx = (xmax - xmin) / (length(series[:x]) - 1) / 2
dy = (ymax - ymin) / (length(series[:y]) - 1) / 2
img = Array(transpose_z(series, z.surf))
z = if eltype(img) <: Colors.AbstractGray
float(img)
@@ -743,7 +745,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
cmap = py_colormap(cgrad(plot_color([:black, :white]))),
vmin = 0.0,
vmax = 1.0,
extent = (xmin-0.5, xmax+0.5, ymax+0.5, ymin-0.5)
extent = (xmin - dx, xmax + dx, ymax + dy, ymin - dy)
)
push!(handles, handle)
@@ -840,7 +842,9 @@ function py_set_lims(ax, sp::Subplot, axis::Axis)
getproperty(ax, Symbol("set_", letter, "lim"))(lfrom, lto)
end
function py_set_ticks(ax, ticks, letter)
py_surround_latextext(latexstring, env) = PyPlot.LaTeXStrings.latexstring(env, "{",latexstring[2:end-1],"}")
function py_set_ticks(ax, ticks, letter, env)
ticks == :auto && return
axis = getproperty(ax, Symbol(letter,"axis"))
if ticks == :none || ticks === nothing || ticks == false
@@ -857,7 +861,8 @@ function py_set_ticks(ax, ticks, letter)
axis."set_ticks"(ticks)
elseif ttype == :ticks_and_labels
axis."set_ticks"(ticks[1])
axis."set_ticklabels"(ticks[2])
tick_labels = [py_surround_latextext(ticklabel, env) for ticklabel in ticks[2]]
axis."set_ticklabels"(tick_labels)
else
error("Invalid input for $(letter)ticks: $ticks")
end
@@ -1106,7 +1111,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
pyaxis."set_label_position"(axis[:guide_position])
end
py_set_scale(ax, sp, axis)
axis[:ticks] != :native ? py_set_lims(ax, sp, axis) : nothing
axis[:ticks] == :native ? nothing : py_set_lims(ax, sp, axis)
if ispolar(sp) && letter == :y
ax."set_rlabel_position"(90)
end
@@ -1115,10 +1120,22 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
if sp[:framestyle] == :origin && length(ticks) > 1
ticks[2][ticks[1] .== 0] .= ""
end
axis[:ticks] != :native ? py_set_ticks(ax, ticks, letter) : nothing
# Set ticks
fontProperties = PyPlot.PyCall.PyDict(Dict("family" => axis[:tickfontfamily],
"size" => py_thickness_scale(plt, axis[:tickfontsize]),
"useTex" => false,
"rotation" => axis[:tickfontrotation]))
getproperty(ax, Symbol("set_",letter,"ticklabels"))(getproperty(ax, Symbol("get_",letter,"ticks"))(), fontProperties)
# workaround to set mathtext.fontspec per Text element
env = "\\mathregular" # matches the outer fonts https://matplotlib.org/tutorials/text/mathtext.html
axis[:ticks] == :native ? nothing : py_set_ticks(ax, ticks, letter, env)
# Tick marks
intensity = 0.5 # This value corresponds to scaling of other grid elements
pyaxis."set_tick_params"(direction = axis[:tick_direction] == :out ? "out" : "in", width=py_thickness_scale(plt, intensity))
pyaxis."set_tick_params"(direction = axis[:tick_direction] == :out ? "out" : "in", width=py_thickness_scale(plt, intensity),
length= 5 * py_thickness_scale(plt, intensity))
getproperty(ax, Symbol("set_", letter, "label"))(axis[:guide])
if get(axis.plotattributes, :flip, false)
@@ -1137,11 +1154,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
pyaxis."label"."set_rotation"(axis[:guidefontrotation])
end
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])
end
if axis[:grid] && !(ticks in (:none, nothing, false))
fgcolor = py_color(axis[:foreground_color_grid])
pyaxis."grid"(true,
+3 -2
View File
@@ -885,6 +885,7 @@ const _examples = PlotExample[
sv = SVector{10}(rand(10))
ov = OffsetVector(rand(10), -2)
plot([sv, ov], label = ["StaticArray" "OffsetArray"])
plot!(3ov, ribbon=ov, label="OffsetArray ribbon")
end
end,
],
@@ -973,8 +974,8 @@ const _examples = PlotExample[
surf = Measurement.((1:10) .* (1:10)', rand(10,10))
plot(
scatter(x, [x y], msw = 0),
scatter(x, y, z, msw = 0),
scatter(x, [x y]),
scatter(x, y, z),
heatmap(x, y, surf),
wireframe(x, y, surf),
legend = :topleft
+1 -1
View File
@@ -112,7 +112,7 @@ function savefig(plt::Plot, fn::AbstractString)
fn = abspath(expanduser(fn))
# get the extension
fn, ext = splitext(fn)
_, ext = splitext(fn)
ext = chop(ext, head = 1, tail = 0)
if isempty(ext)
ext = defaultOutputFormat(plt)
+1 -1
View File
@@ -49,7 +49,7 @@ RecipesPipeline.splittable_attribute(plt::Plot, key, val::SeriesAnnotations, len
RecipesPipeline.splittable_attribute(plt, key, val.strs, len)
function RecipesPipeline.split_attribute(plt::Plot, key, val::SeriesAnnotations, indices)
split_strs = _RecipesPipeline.split_attribute(key, val.strs, indices)
split_strs = RecipesPipeline.split_attribute(key, val.strs, indices)
return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor)
end
+17 -1
View File
@@ -1027,8 +1027,24 @@ end
# Error Bars
function error_style!(plotattributes::AKW)
msc = plotattributes[:markerstrokecolor]
msc = if msc === :match
plotattributes[:subplot][:foreground_color_subplot]
elseif msc === :auto
get_series_color(
plotattributes[:linecolor],
plotattributes[:subplot],
plotattributes[:series_plotindex],
plotattributes[:seriestype],
)
else
msc
end
plotattributes[:seriestype] = :path
plotattributes[:markercolor] = plotattributes[:markerstrokecolor]
plotattributes[:markerstrokecolor] = msc
plotattributes[:markercolor] = msc
plotattributes[:linecolor] = msc
plotattributes[:linewidth] = plotattributes[:markerstrokewidth]
plotattributes[:label] = ""
end
+6 -6
View File
@@ -126,8 +126,8 @@ isnothing(x) = false
_cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj
_cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj
_cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
_cycle(v::AVec, idx::Int) = v[mod(idx, axes(v,1))]
_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[end, mod(idx, axes(v,2))] : v[:, mod(idx, axes(v,2))]
_cycle(v, idx::Int) = v
_cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices)
@@ -362,10 +362,10 @@ end
ok(tup::Tuple) = ok(tup...)
# compute one side of a fill range from a ribbon
function make_fillrange_side(y, rib)
frs = zeros(length(y))
for (i, (yi, ri)) in enumerate(zip(y, Base.Iterators.cycle(rib)))
frs[i] = yi + ri
function make_fillrange_side(y::AVec, rib)
frs = zeros(axes(y))
for (i, yi) in pairs(y)
frs[i] = yi + _cycle(rib,i)
end
frs
end
+24 -14
View File
@@ -16,14 +16,21 @@ function fix_rand!(ex)
pushfirst!(ex.args[1].args, :(rng = StableRNG(1234)))
end
function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !is_ci(), sigma = [1,1], tol = 1e-2)
function image_comparison_tests(
pkg::Symbol,
idx::Int;
debug = false,
popup = !is_ci(),
sigma = [1, 1],
tol = 1e-2,
)
Plots._debugMode.on = debug
example = Plots._examples[idx]
Plots.theme(:default)
@info("Testing plot: $pkg:$idx:$(example.header)")
backend(pkg)
backend()
default(size=(500,300))
default(size = (500, 300))
fn = "ref$idx.png"
reffn = reference_file(pkg, idx, _current_plots_version)
@@ -40,19 +47,22 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = !i
# the test
vtest = VisualTest(func, reffn, idx)
test_images(vtest, popup=popup, sigma=sigma, tol=tol, newfn = newfn)
test_images(vtest, popup = popup, sigma = sigma, tol = tol, newfn = newfn)
end
function image_comparison_facts(pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1,1], # number of pixels to "blur"
tol = 1e-2) # acceptable error (percent)
for i in 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug=debug, sigma=sigma, tol=tol) |> success == true
function image_comparison_facts(
pkg::Symbol;
skip = [], # skip these examples (int index)
only = nothing, # limit to these examples (int index)
debug = false, # print debug information?
sigma = [1, 1], # number of pixels to "blur"
tol = 1e-2,
) # acceptable error (percent)
for i = 1:length(Plots._examples)
i in skip && continue
if only === nothing || i in only
@test image_comparison_tests(pkg, i, debug = debug, sigma = sigma, tol = tol) |>
success == true
end
end
end
end
+6 -6
View File
@@ -45,27 +45,27 @@ include("imgcomp.jl")
Random.seed!(1234)
default(show=false, reuse=true)
is_ci() = get(ENV, "CI", "false") == "true"
img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1
const IMG_TOL = VERSION < v"1.4" && Sys.iswindows() ? 1e-1 : is_ci() ? 1e-2 : 1e-3
## Uncomment the following lines to update reference images for different backends
# @testset "GR" begin
# image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
# image_comparison_facts(:gr, tol=IMG_TOL, skip = Plots._backend_skips[:gr])
# end
#
# plotly()
# @testset "Plotly" begin
# image_comparison_facts(:plotly, tol=img_tol, skip = Plots._backend_skips[:plotlyjs])
# image_comparison_facts(:plotly, tol=IMG_TOL, skip = Plots._backend_skips[:plotlyjs])
# end
#
# pyplot()
# @testset "PyPlot" begin
# image_comparison_facts(:pyplot, tol=img_tol, skip = Plots._backend_skips[:pyplot])
# image_comparison_facts(:pyplot, tol=IMG_TOL, skip = Plots._backend_skips[:pyplot])
# end
#
# pgfplotsx()
# @testset "PGFPlotsX" begin
# image_comparison_facts(:pgfplotsx, tol=img_tol, skip = Plots._backend_skips[:pgfplotsx])
# image_comparison_facts(:pgfplotsx, tol=IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
# 10 Histogram2D
@@ -83,7 +83,7 @@ img_tol = is_ci() ? 1e-2 : Sys.islinux() ? 1e-3 : 0.1
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(:gr, tol=img_tol, skip = Plots._backend_skips[:gr])
image_comparison_facts(:gr, tol=IMG_TOL, skip = Plots._backend_skips[:gr])
end
end
+18 -7
View File
@@ -302,6 +302,11 @@ end
lines = readlines(io)
@test count(s -> occursin("node", s), lines) == 9
end
# test .tikz extension
file_path =joinpath(path,"annotations.tikz")
@test_nowarn savefig(annotation_plot, file_path)
@test_nowarn open(file_path) do io
end
end
end # testset
@testset "Ribbon" begin
@@ -314,16 +319,12 @@ end
Plots._update_plot_object(ribbon_plot)
axis = Plots.pgfx_axes(ribbon_plot.o)[1]
plots = filter(x -> x isa PGFPlotsX.Plot, axis.contents)
@test length(plots) == 4
@test !haskey(plots[1].options.dict, "fill")
@test !haskey(plots[2].options.dict, "fill")
@test length(plots) == 3
@test haskey(plots[1].options.dict, "fill")
@test haskey(plots[2].options.dict, "fill")
@test !haskey(plots[3].options.dict, "fill")
@test haskey(plots[4].options.dict, "fill")
@test ribbon_plot.o !== nothing
@test ribbon_plot.o.the_plot !== nothing
# mktempdir() do path
# @test_nowarn savefig(ribbon_plot, path*"ribbon.svg")
# end
end # testset
end # testset
@@ -345,4 +346,14 @@ end # testset
axes = Plots.pgfx_axes(pl.o)
@test !haskey(axes[1].options.dict, "axis line shift")
@test haskey(axes[2].options.dict, "axis line shift")
pl = plot(x->x, -1:1; add = raw"\node at (0,0.5) {\huge hi};", extra_kwargs = :subplot)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x->x isa String, axes[1].contents)[1] == raw"\node at (0,0.5) {\huge hi};"
plot!(pl)
@test pl[1][:extra_kwargs] == Dict(:add => raw"\node at (0,0.5) {\huge hi};")
Plots._update_plot_object(pl)
axes = Plots.pgfx_axes(pl.o)
@test filter(x->x isa String, axes[1].contents)[1] == raw"\node at (0,0.5) {\huge hi};"
end # testset