Compare commits

..

39 Commits

Author SHA1 Message Date
Simon Christ f0ad66da36 1.22.4 [skip ci] 2021-10-05 19:25:45 +02:00
Nicholas Bauer aca2aa49b8 Generalize GR tick label rotations (#3782)
* gr tick rotations

* consistency

* start of angle offset work

* Working!

* simplify logic

* gr tick rotations

* consistency

* start of angle offset work

* Working!

* simplify logic

* all offsets

* Rebase

* tick factor reversion

* Fix for 3d plots

* simplification

* offset update

* bump offset

* Remove conflict error

* Resolve merge conflict error.

* Resolve merge conflict error

* 3d done

* remove excess

* adjust offset

* restore offset

* fix sign check

Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-10-05 13:44:12 +02:00
t-bltg 9d56e72f6a Update .zenodo.json
Fix broken .json
2021-10-05 09:43:40 +02:00
Lee Phillips f06225655d Allow styling of magnification shape in lens!() (#3860)
* Allow styling of magnification shape in lens!()

The guide lines that indicate the region of the plot magnified in the
inset lens plot, called the magnification shape, are hard-coded with
the :lightgray color and are drawn with the default other line
attributes. This is often too light to be seen clearly and could be a
problem for publication. This commit allows the user to set the
linecolor, linewidth, and linestyle in the call to lens!().

* Update src/recipes.jl

Co-authored-by: t-bltg <tf.bltg@gmail.com>

* Update .zenodo.json

Co-authored-by: t-bltg <tf.bltg@gmail.com>
Co-authored-by: Simon Christ <SimonChrist@gmx.de>
2021-10-04 17:38:59 +02:00
github-actions[bot] 4f0f84f400 Format .jl files [skip ci] (#3861)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-10-04 13:23:01 +02:00
Jan Schneider a65cda8b7e change docs link to httpS (#3852)
always bugs me to get a warning from my browser about the not secure connection.
Could someone also update the About section at the right of the Github page to a https URL?
2021-09-28 16:15:26 +02:00
Simon Christ 37744d7b6a 1.22.3 [skip ci] 2021-09-27 19:24:47 +02:00
Jan Schneider 09a66224ce Update Plots.jl's colorbar_titel maps to PGFPlotsX's color bar style={ylabel} (#3848)
* Update PGFPlotsX colorbar_titel map to ylabel

For most of the backends supported by Polts.jl the `colorbar_title` attribute maps to the attribute in the backend that ultimately is displayed on the vertical axis of the colorbar, which is vertically aligned. Not for PGFPlotsX as in this backend the `title` attribute is displayed on top of the colorbar while the `ylabel` is shown on the vertical bar.

* Update .zenodo.json

added my name to the contributors list
2021-09-27 16:16:16 +02:00
Nicholas Bauer 405bc0820b Speed up get_clims (#3839)
* For Shape type, cut off process

* Remove fillcolor for now

* Address type inference failure instead

* Store value instead of re-evaluating

* Works, but not ideal

* Unnecessary to update here, I think

* return type

* Remove unnecessary default arg

* Typo

* Change to clims

* missed one

* reconfigured to free up clims property

* fix

* Remove debug println, add hook for updating clims after series added

* restore docstring

* typo

* Change to _update_subplot_colorbars
2021-09-27 14:01:18 +02:00
github-actions[bot] 1c89bd8727 Update precompile_*.jl file [skip ci] (#3841)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-26 15:44:10 +02:00
github-actions[bot] 8e17a182f9 Format .jl files [skip ci] (#3846)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-26 15:42:31 +02:00
t-bltg 032c5d1638 UnicodePlots: support markers (#3845) 2021-09-25 12:18:41 +02:00
BerndR 8d95333d1e Legend positioning for 3d plots in plotly (#3840)
* Remove hardoced numbers, shift for 3d plots

* Revert changes

* Fixed some missed reverts
2021-09-23 19:14:55 +02:00
github-actions[bot] 7bfc97285c Update precompile_*.jl file [skip ci] (#3828)
Co-authored-by: BeastyBlacksmith <BeastyBlacksmith@users.noreply.github.com>
2021-09-23 10:26:58 +02:00
Simon Christ acca707f34 1.22.2 [skip ci] 2021-09-22 21:21:13 +02:00
Nicholas Bauer 6fa3dae166 Fix type inference failure in get_clims (#3838)
* For Shape type, cut off process

* Remove fillcolor for now

* NaN

* Address type inference failure instead
2021-09-22 19:18:57 +02:00
Lukas Hauertmann 866cb0c335 Add :mesh3d seriesstyle for PyPlot backend (#3835)
* Add `:mesh3d` seriesstyle for PyPlot backend

via `Poly3DCollection`.

* Add `:connections` to lists of supported keywords

for the backends which support `:mesh3d` as series type.

* Remove #47 from list of skipping examples for PyPlot

* Add support for only-triangle syntax for `:connections` kw

for PyPlot

* Add 1-based indexing syntax for `connections` kw in `:mesh3d`

* Update description for example `#47` (`:mesh3d`)

* Hotfix 1-based indexing for mesh3d in pgfplotsx
2021-09-22 17:12:11 +02:00
t-bltg 4d40bae9cc Update bug.md
update supported backends
2021-09-21 00:28:51 +02:00
github-actions[bot] 5a48002d31 Format .jl files [skip ci] (#3829)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-20 16:10:29 +02:00
t-bltg 0cd81243ad UnicodePlots: compact plots 2021-09-18 14:13:37 +02:00
t-bltg ed3bab0e6f 1.22.1 [skip ci] 2021-09-17 22:11:50 +02:00
github-actions[bot] 4621c18b23 Update precompile_*.jl file [skip ci] (#3822)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-17 22:10:48 +02:00
BerndR 4f8a265c6a Fix generic aliases (#3824) 2021-09-17 21:43:26 +02:00
t-bltg e2539a3d19 UnicodePlots: adjust layout width per column (#3825) 2021-09-17 21:42:50 +02:00
t-bltg 85739932f0 Negate condition on :warn_on_unsupported (#3816) 2021-09-17 14:55:43 +02:00
t-bltg 9d84e53bcb Test cleanup (#3821) 2021-09-17 12:00:40 +02:00
zhanibek 82f31c48b7 pyplot fixing ticks=:native 2021-09-17 16:30:22 +09:00
zhanibek 81571fe534 fix typos 2021-09-17 14:44:16 +09:00
zhanibek 293b8b112e instructions for matplotlib update 2021-09-17 14:38:24 +09:00
t-bltg d988d4c9d1 1.22.0 [skip ci] 2021-09-15 12:54:42 +02:00
github-actions[bot] 85bd3ea53f Update precompile_*.jl file [skip ci] (#3810)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-15 12:53:58 +02:00
t-bltg cd6a8c87b6 GR: fix NaN tick size (#3813) 2021-09-15 12:28:53 +02:00
t-bltg 175c87cec6 Avoid Vararg usage (#3809) 2021-09-15 12:28:24 +02:00
t-bltg c3f45dd712 UnicodePlots: minor fixes (#3812) 2021-09-15 11:21:41 +02:00
t-bltg 198a59b621 UnicodePlots: propagate xyscale (#3811) 2021-09-15 01:29:23 +02:00
t-bltg c5d7283473 Update examples.jl
UnicodePlots: annotations are supported
2021-09-14 21:02:30 +02:00
t-bltg 7a1bc88f66 Use hyphens to specify version ranges 2021-09-14 20:27:44 +02:00
github-actions[bot] ad5cd2f1da Update precompile_*.jl file [skip ci] (#3807)
Co-authored-by: t-bltg <t-bltg@users.noreply.github.com>
2021-09-14 19:01:40 +02:00
t-bltg 6cf01229bb UnicodePlots: support :annotations (#3804) 2021-09-14 18:46:46 +02:00
19 changed files with 571 additions and 265 deletions
+2 -1
View File
@@ -20,10 +20,11 @@ Backend | yes | no | untested
-------------|-----|-----|---------
gr (default) | | |
pyplot | | |
plotly | | |
plotlyjs | | |
pgfplotsx | | |
unicodeplots | | |
inspectdr | | |
gaston | | |
### Versions
+10
View File
@@ -692,6 +692,16 @@
{
"name": "Fred Callaway",
"type": "Other"
},
{
"name": "Jan Thorben Schneider",
"type": "Other"
},
{
"orcid": "0000-0003-4102-2460",
"affiliation": "Alogus Research Corporation",
"name": "Lee Phillips",
"type": "Other"
}
],
"upload_type": "software"
+7 -7
View File
@@ -1,7 +1,7 @@
name = "Plots"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
author = ["Tom Breloff (@tbreloff)"]
version = "1.21.3"
version = "1.22.4"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
@@ -35,12 +35,12 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[compat]
Contour = "0.5"
FFMPEG = "0.2, 0.3, 0.4"
FixedPointNumbers = "0.6, 0.7, 0.8"
GR = "0.53, 0.54, 0.55, 0.57, 0.58, 0.59"
FFMPEG = "0.2 - 0.4"
FixedPointNumbers = "0.6 - 0.8"
GR = "0.53 - 0.59"
GeometryBasics = "0.2, 0.3.1, 0.4"
JSON = "0.21, 1"
Latexify = "0.14, 0.15"
Latexify = "0.14 - 0.15"
Measures = "0.3"
NaNMath = "0.3"
PlotThemes = "2"
@@ -51,8 +51,8 @@ Reexport = "0.2, 1.0"
Requires = "1"
Scratch = "1"
Showoff = "0.3.1, 1.0"
StatsBase = "0.32, 0.33"
UnicodePlots = "2.2"
StatsBase = "0.32 - 0.33"
UnicodePlots = "2.4"
julia = "1.5"
[extras]
+1 -1
View File
@@ -10,7 +10,7 @@
[gitter-url]: https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[docs-img]: https://img.shields.io/badge/docs-stable-blue.svg
[docs-url]: http://docs.juliaplots.org/latest/
[docs-url]: https://docs.juliaplots.org/latest/
[![][gh-ci-img]][gh-ci-url]
[![][pkgeval-img]][pkgeval-url]
+11 -13
View File
@@ -107,7 +107,6 @@ function _precompile_()
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},UnitRange{Int64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),UnitRange{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_polyline)),NamedTuple{(:arrowside, :arrowstyle), Tuple{Symbol, Symbol}},typeof(gr_polyline),Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(gr_set_font)),NamedTuple{(:halign, :valign, :rotation), Tuple{Symbol, Symbol, Int64}},typeof(gr_set_font),Font,Subplot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(hline!)),Any,typeof(hline!),Any})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{GRBackend},Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:alpha, :seriestype), Tuple{Float64, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{GeometryBasics.Point2{Float64}}})
@@ -127,6 +126,7 @@ function _precompile_()
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),Plot{PlotlyBackend},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:marker, :series_annotations, :seriestype), Tuple{Tuple{Int64, Float64, Symbol}, Vector{Any}, Symbol}},typeof(plot!),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Plot{PlotlyBackend},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:markersize, :c, :seriestype), Tuple{Int64, Symbol, Symbol}},typeof(plot!),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{GRBackend},Vector{Int64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:seriestype, :inset), Tuple{Symbol, Tuple{Int64, BoundingBox{Tuple{Length{:w, Float64}, Length{:h, Float64}}, Tuple{Length{:w, Float64}, Length{:h, Float64}}}}}},typeof(plot!),Plot{PlotlyBackend},Vector{Int64},Vector{Float64}})
@@ -139,6 +139,7 @@ function _precompile_()
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:title,), Tuple{String}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:w,), Tuple{Int64}},typeof(plot!),Plot{GRBackend},Vector{Float64},Vector{Float64},Vararg{Any, N} where N})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:xgrid,), Tuple{Tuple{Symbol, Symbol, Int64, Symbol, Float64}}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{GRBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!),Plot{PlotlyBackend}})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:yaxis, :minorgrid), Tuple{Tuple{String, Symbol}, Bool}},typeof(plot!)})
Base.precompile(Tuple{Core.kwftype(typeof(plot!)),NamedTuple{(:zcolor, :m, :ms, :lab, :seriestype), Tuple{Vector{Float64}, Tuple{Symbol, Float64, Stroke}, Vector{Float64}, String, Symbol}},typeof(plot!),Plot{GRBackend},Vector{Float64}})
@@ -198,6 +199,7 @@ function _precompile_()
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype, :markershape, :markersize, :color), Tuple{Matrix{Symbol}, Vector{Symbol}, Int64, Vector{Symbol}}},typeof(plot),Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{DateTime},UnitRange{Int64},Matrix{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:seriestype,), Tuple{Symbol}},typeof(plot),Vector{OHLC}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:st, :xlabel, :ylabel, :zlabel), Tuple{Symbol, String, String, String}},typeof(plot),Vector{Float64},Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{Core.kwftype(typeof(plot)),NamedTuple{(:title, :l, :seriestype), Tuple{String, Float64, Symbol}},typeof(plot),Vector{String},Vector{Float64}})
@@ -235,6 +237,7 @@ function _precompile_()
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{GRBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.plot_setup!),Plot{PlotlyBackend},Dict{Symbol, Any},Vector{Dict{Symbol, Any}}})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_attributes!),Plot{GRBackend},DefaultsDict})
Base.precompile(Tuple{typeof(RecipesPipeline.preprocess_axis_args!),Plot{PlotlyBackend},Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{GRBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.process_userrecipe!),Plot{PlotlyBackend},Vector{Dict{Symbol, Any}},Dict{Symbol, Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.warn_on_recipe_aliases!),Plot{GRBackend},DefaultsDict,Symbol,Any})
@@ -249,7 +252,7 @@ function _precompile_()
Base.precompile(Tuple{typeof(_cbar_unique),Vector{Symbol},String})
Base.precompile(Tuple{typeof(_cycle),Base.OneTo{Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),StepRange{Int64, Int64},Vector{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},UnitRange{Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},StepRange{Int64, Int64}})
Base.precompile(Tuple{typeof(_cycle),Vector{Float64},Vector{Int64}})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{GRBackend},Bool})
Base.precompile(Tuple{typeof(_do_plot_show),Plot{PlotlyBackend},Bool})
@@ -274,7 +277,7 @@ function _precompile_()
Base.precompile(Tuple{typeof(error_coords),Vector{Float64},Vector{Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(error_zipit),Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})
Base.precompile(Tuple{typeof(fakedata),Int64,Int64})
Base.precompile(Tuple{typeof(fakedata),MersenneTwister,Int64,Vararg{Int64, N} where N})
Base.precompile(Tuple{typeof(get_clims),Subplot{GRBackend},Series,Function})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_minor_ticks),Subplot{GRBackend},Axis,Tuple{Vector{Int64}, Vector{String}}})
Base.precompile(Tuple{typeof(get_series_color),Vector{Symbol},Subplot{GRBackend},Int64,Symbol})
@@ -288,22 +291,16 @@ function _precompile_()
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_add_legend),Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_display),Subplot{GRBackend},AbsoluteLength,AbsoluteLength,Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_colorbar),GRColorbar,Subplot{GRBackend},Tuple{Float64, Float64},Vector{Float64}})
Base.precompile(Tuple{typeof(gr_draw_contour),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_heatmap),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Float64,Float64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Float64,Float64,Tuple{Float64, Float64},Int64,Int64,Int64,Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Float64,Tuple{Float64, Float64},Int64,Float64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_marker),Series,Int64,Int64,Tuple{Float64, Float64},Int64,Int64,Int64,Symbol})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Base.OneTo{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,UnitRange{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_markers),Series,Vector{Int64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},UnitRange{Int64},Tuple{Vector{Float64}, Vector{Float64}},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Base.OneTo{Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,StepRange{Int64, Int64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_segments),Series,Vector{Float64},Vector{Float64},Int64,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_shapes),Series,Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Matrix{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_draw_surface),Series,Vector{Float64},Vector{Float64},Vector{Float64},Tuple{Float64, Float64}})
Base.precompile(Tuple{typeof(gr_fill_viewport),Vector{Float64},RGBA{Float64}})
@@ -312,7 +309,6 @@ function _precompile_()
Base.precompile(Tuple{typeof(gr_label_ticks),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_label_ticks_3d),Subplot{GRBackend},Symbol,Tuple{Vector{Float64}, Vector{String}}})
Base.precompile(Tuple{typeof(gr_polaraxes),Int64,Float64,Subplot{GRBackend}})
Base.precompile(Tuple{typeof(gr_polyline),Vector{Float64},Vector{Float64},Function})
Base.precompile(Tuple{typeof(gr_set_gradient),PlotUtils.ContinuousColorGradient})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), NTuple{9, Float64}}})
Base.precompile(Tuple{typeof(gr_update_viewport_legend!),Vector{Float64},Subplot{GRBackend},NamedTuple{(:w, :h, :dy, :leftw, :textw, :rightw, :xoffset, :yoffset, :width_factor), Tuple{Int64, Int64, Int64, Float64, Int64, Float64, Float64, Float64, Float64}}})
@@ -339,6 +335,7 @@ function _precompile_()
Base.precompile(Tuple{typeof(plot),Plot{GRBackend},Plot{GRBackend}})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend},Plot{PlotlyBackend},Vararg{Plot{PlotlyBackend}, N} where N})
Base.precompile(Tuple{typeof(plot),Plot{PlotlyBackend},Plot{PlotlyBackend}})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Float64,Symbol})
Base.precompile(Tuple{typeof(processGridArg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Matrix{Symbol}})
Base.precompile(Tuple{typeof(processLineArg),Dict{Symbol, Any},Symbol})
@@ -347,7 +344,6 @@ function _precompile_()
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Shape{Float64, Float64}})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Stroke})
Base.precompile(Tuple{typeof(processMarkerArg),Dict{Symbol, Any},Symbol})
Base.precompile(Tuple{typeof(processMinorGridArg!),Dict{Symbol, Any},Bool,Symbol})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,PlotText})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Int64, Symbol, Symbol}})
Base.precompile(Tuple{typeof(process_annotation),Subplot{GRBackend},Int64,Float64,Tuple{String, Symbol, Int64, String}})
@@ -357,8 +353,6 @@ function _precompile_()
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},StepRange{Int64, Int64},Symbol})
Base.precompile(Tuple{typeof(process_axis_arg!),Dict{Symbol, Any},Symbol,Symbol})
Base.precompile(Tuple{typeof(push!),Plot{GRBackend},Float64,Vector{Float64}})
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Float64, Float64, Float64},Tuple{Float64, Float64, Float64}})
Base.precompile(Tuple{typeof(push!),Segments{Tuple{Float64, Float64, Float64}},Tuple{Int64, Float64, Int64},Tuple{Int64, Float64, Int64}})
Base.precompile(Tuple{typeof(resetfontsizes)})
Base.precompile(Tuple{typeof(scalefontsizes),Float64})
Base.precompile(Tuple{typeof(series_annotations),Vector{Any}})
@@ -375,6 +369,10 @@ function _precompile_()
Base.precompile(Tuple{typeof(stroke),Int64,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(title!),AbstractString})
Base.precompile(Tuple{typeof(unzip),Vector{GeometryBasics.Point2{Float64}}})
Base.precompile(Tuple{typeof(unzip),Vector{Tuple{Float64, Float64, Float64}}})
Base.precompile(Tuple{typeof(unzip),Vector{Tuple{Float64, Float64}}})
Base.precompile(Tuple{typeof(unzip),Vector{Tuple{Int64, Int64}}})
Base.precompile(Tuple{typeof(unzip),Vector{Tuple{Vector{Float64}, Vector{Float64}}}})
Base.precompile(Tuple{typeof(vline!),Any})
Base.precompile(Tuple{typeof(xgrid!),Plot{GRBackend},Symbol,Vararg{Any, N} where N})
Base.precompile(Tuple{typeof(xlims),Subplot{PlotlyBackend}})
+20 -5
View File
@@ -24,8 +24,9 @@ function add_aliases(sym::Symbol, aliases::Symbol...)
return nothing
end
function add_axes_aliases(sym::Symbol, aliases::Symbol...)
function add_axes_aliases(sym::Symbol, aliases::Symbol...; generic::Bool = true)
sym in keys(_axis_defaults) || throw(ArgumentError("Invalid `$sym`"))
generic && add_aliases(sym, aliases...)
for letter in (:x, :y, :z)
add_aliases(Symbol(letter, sym), (Symbol(letter, a) for a in aliases)...)
end
@@ -841,13 +842,20 @@ add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :ms
add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity)
# axes attributes
add_axes_aliases(:guide, :label, :lab, :l)
add_axes_aliases(:guide, :label, :lab, :l; generic = false)
add_axes_aliases(:lims, :lim, :limit, :limits, :range)
add_axes_aliases(:ticks, :tick)
add_axes_aliases(:rotation, :rot, :r)
add_axes_aliases(:guidefontsize, :labelfontsize)
add_axes_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity)
add_axes_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls)
add_axes_aliases(
:gridstyle,
:grid_style,
:gridlinestyle,
:grid_linestyle,
:grid_ls,
:gridls,
)
add_axes_aliases(
:foreground_color_grid,
:fg_grid,
@@ -872,7 +880,14 @@ add_axes_aliases(
:fg_colour_minor_grid,
:minorgridcolor,
)
add_axes_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw)
add_axes_aliases(
:gridlinewidth,
:gridwidth,
:grid_linewidth,
:grid_width,
:gridlw,
:grid_lw,
)
add_axes_aliases(
:minorgridstyle,
:minorgrid_style,
@@ -1570,7 +1585,7 @@ function warn_on_unsupported_args(pkg::AbstractBackend, plotattributes)
end
if !isempty(_to_warn) &&
!get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
get(plotattributes, :warn_on_unsupported, _plot_defaults[:warn_on_unsupported])
for k in sort(collect(_to_warn))
push!(already_warned, k)
@warn(
+45 -6
View File
@@ -402,6 +402,7 @@ const _gr_attr = merge_with_base_supported([
:tick_direction,
:camera,
:contour_labels,
:connections,
])
const _gr_seriestype = [
:path,
@@ -521,6 +522,7 @@ const _plotly_attr = merge_with_base_supported([
:tick_direction,
:camera,
:contour_labels,
:connections,
])
const _plotly_seriestype = [
@@ -777,6 +779,7 @@ const _pyplot_attr = merge_with_base_supported([
:tick_direction,
:camera,
:contour_labels,
:connections,
])
const _pyplot_seriestype = [
:path,
@@ -793,6 +796,7 @@ const _pyplot_seriestype = [
:contour3d,
:path3d,
:scatter3d,
:mesh3d,
:surface,
:wireframe,
]
@@ -860,6 +864,7 @@ const _gaston_attr = merge_with_base_supported([
# :framestyle,
# :camera,
# :contour_labels,
:connections,
])
const _gaston_seriestype = [
@@ -910,16 +915,22 @@ const _gaston_scale = [:identity, :ln, :log2, :log10]
# unicodeplots
const _unicodeplots_attr = merge_with_base_supported([
:annotations,
:bins,
:guide,
# :grid,
:label,
:layout,
:legend,
:seriescolor,
:seriesalpha,
:lims,
:linealpha,
:linecolor,
:linestyle,
:markershape,
:bins,
:seriesalpha,
:seriescolor,
:scale,
:title,
:guide,
:lims,
])
const _unicodeplots_seriestype = [
:path,
@@ -932,7 +943,34 @@ const _unicodeplots_seriestype = [
:spy,
]
const _unicodeplots_style = [:auto, :solid]
const _unicodeplots_marker = [:none, :auto, :circle]
const _unicodeplots_marker = [
:none,
:auto,
:pixel,
# vvvvvvvvvv shapes
:circle,
:rect,
:star5,
:diamond,
:hexagon,
:cross,
:xcross,
:utriangle,
:dtriangle,
:rtriangle,
:ltriangle,
:pentagon,
# :heptagon,
# :octagon,
:star4,
:star6,
# :star7,
:star8,
:vline,
:hline,
:+,
:x,
]
const _unicodeplots_scale = [:identity, :ln, :log2, :log10]
# Additional constants
@@ -1234,6 +1272,7 @@ const _pgfplotsx_attr = merge_with_base_supported([
:tick_direction,
:camera,
:contour_labels,
:connections,
])
const _pgfplotsx_seriestype = [
:path,
+85 -35
View File
@@ -671,31 +671,19 @@ end
function gr_set_tickfont(sp, letter)
axis = sp[get_attr_symbol(letter, :axis)]
# invalidate alignment changes for small rotations (|θ| < 45°)
trigger(rot) = abs(sind(rot)) < abs(cosd(rot)) ? 0 : sign(rot)
rot = axis[:rotation]
if letter === :x || (RecipesPipeline.is3d(sp) && letter === :y)
halign = (:left, :hcenter, :right)[trigger(rot) + 2]
valign = (axis[:mirror] ? :bottom : :top, :vcenter)[trigger(abs(rot)) + 1]
else
halign = (axis[:mirror] ? :left : :right, :hcenter)[trigger(abs(rot)) + 1]
valign = (:top, :vcenter, :bottom)[trigger(rot) + 2]
end
gr_set_font(
tickfont(axis),
sp,
halign = halign,
valign = valign,
rotation = axis[:rotation],
color = axis[:tickfontcolor],
)
end
# size of the text with no rotation
function gr_text_size(str)
GR.savestate()
GR.selntran(0)
GR.setcharup(0, 1)
xs, ys = gr_inqtext(0, 0, string(str))
l, r = extrema(xs)
b, t = extrema(ys)
@@ -705,9 +693,11 @@ function gr_text_size(str)
return w, h
end
# size of the text with rotation applied
function gr_text_size(str, rot)
GR.savestate()
GR.selntran(0)
GR.setcharup(0, 1)
xs, ys = gr_inqtext(0, 0, string(str))
l, r = extrema(xs)
b, t = extrema(ys)
@@ -720,12 +710,21 @@ end
text_box_width(w, h, rot) = abs(cosd(rot)) * w + abs(cosd(rot + 90)) * h
text_box_height(w, h, rot) = abs(sind(rot)) * w + abs(sind(rot + 90)) * h
function gr_get_3d_axis_angle(cvs, nt, ft, letter)
length(cvs) < 2 && return 0
tickpoints = [gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...) for cv cvs]
dx = tickpoints[2][1] - tickpoints[1][1]
dy = tickpoints[2][2] - tickpoints[1][2]
return atand(dy, dx)
end
function gr_get_ticks_size(ticks, rot)
w, h = 0.0, 0.0
for (cv, dv) in zip(ticks...)
wi, hi = gr_text_size(dv, rot)
w = max(w, wi)
h = max(h, hi)
w = NaNMath.max(w, wi)
h = NaNMath.max(h, hi)
end
return w, h
end
@@ -1560,13 +1559,35 @@ function gr_label_ticks(sp, letter, ticks)
oamin, oamax = axis_limits(sp, oletter)
gr_set_tickfont(sp, letter)
out_factor = ifelse(axis[:tick_direction] === :out, 1.5, 1)
x_offset = isy ? -1.5e-2 * out_factor : 0
y_offset = isy ? 0 : -8e-3 * out_factor
x_base_offset = isy ? -1.5e-2 * out_factor : 0
y_base_offset = isy ? 0 : -8e-3 * out_factor
rot = axis[:rotation] % 360
ov = sp[:framestyle] == :origin ? 0 : xor(oaxis[:flip], axis[:mirror]) ? oamax : oamin
sgn = axis[:mirror] ? -1 : 1
sgn2 = iseven(Int(floor(rot / 90))) ? -1 : 1
sgn3 = if isy
-360 < rot < -180 || 0 < rot < 180 ? 1 : -1
else
rot < -270 || -90 < rot < 90 || rot > 270 ? 1 : -1
end
for (cv, dv) in zip(ticks...)
x, y = GR.wctondc(reverse_if((cv, ov), isy)...)
sz_rot = gr_text_size(dv, rot)
sz = gr_text_size(dv)
x_offset = x_base_offset
y_offset = y_base_offset
if isy
x_offset += -first(sz_rot) / 2
if rot % 90 != 0
y_offset += sgn2 * last(sz_rot) / 2 + sgn3 * last(sz) * cosd(rot) / 2
end
else
if rot % 90 != 0
x_offset += sgn2 * first(sz_rot) / 2 + sgn3 * last(sz) * sind(rot) / 2
end
y_offset += -last(sz_rot) / 2
end
gr_text(x + sgn * x_offset, y + sgn * y_offset, dv)
end
end
@@ -1577,6 +1598,9 @@ function gr_label_ticks_3d(sp, letter, ticks)
near_letter = letter in (:x, :z) ? :y : :x
far_letter = letter in (:x, :y) ? :z : :x
isy = letter === :y
isz = letter === :z
ax = sp[get_attr_symbol(letter, :axis)]
nax = sp[get_attr_symbol(near_letter, :axis)]
fax = sp[get_attr_symbol(far_letter, :axis)]
@@ -1584,7 +1608,7 @@ function gr_label_ticks_3d(sp, letter, ticks)
amin, amax = axis_limits(sp, letter)
namin, namax = axis_limits(sp, near_letter)
famin, famax = axis_limits(sp, far_letter)
n0, n1 = letter === :y ? (namax, namin) : (namin, namax)
n0, n1 = isy ? (namax, namin) : (namin, namax)
# find out which axes we are dealing with
i = findfirst(==(letter), (:x, :y, :z))
@@ -1601,27 +1625,52 @@ function gr_label_ticks_3d(sp, letter, ticks)
nt = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? n1 : n0
ft = sp[:framestyle] == :origin ? 0 : ax[:mirror] ? famax : famin
xoffset = if letter === :x
(sp[:yaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:xaxis][:tick_direction] == :out ? 1.5 : 1)
elseif letter === :y
(sp[:yaxis][:mirror] ? -1 : 1) * 1e-2 * (sp[:yaxis][:tick_direction] == :out ? 1.5 : 1)
else
(sp[:zaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:zaxis][:tick_direction] == :out ? 1.5 : 1)
end
yoffset = if letter === :x
(sp[:xaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:xaxis][:tick_direction] == :out ? 1.5 : 1)
elseif letter === :y
(sp[:yaxis][:mirror] ? 1 : -1) * 1e-2 * (sp[:yaxis][:tick_direction] == :out ? 1.5 : 1)
else
0
end
rot = mod(ax[:rotation], 360)
sgn = ax[:mirror] ? -1 : 1
cvs, dvs = ticks
ax[:flip] && reverse!(cvs)
axisθ = isz ? 270 : mod(gr_get_3d_axis_angle(cvs, nt, ft, letter), 360) # issue: doesn't work with 1 tick
axisϕ = mod(axisθ - 90, 360)
out_factor = ifelse(ax[:tick_direction] === :out, 1.5, 1)
axisoffset = out_factor * 1.2e-2
x_base_offset = axisoffset * cosd(axisϕ)
y_base_offset = axisoffset * sind(axisϕ)
sgn2a = sgn2b = sgn3 = 0
if axisθ != 0 || rot % 90 != 0
sgn2a = (axisθ != 90) &&
(axisθ == 0 && (rot < 90 || 180 rot < 270)) ||
(axisθ == 270) ||
(axisθ < 90 && (axisθ < rot < 90 || axisθ + 180 < rot < 270)) ||
(axisθ > 270 && (rot < 90 || axisθ - 180 < rot < 270 || rot > axisθ)) ? -1 : 1
end
if (axisθ - 90) % 180 != 0 || (rot - 90) % 180 != 0
sgn2b = axisθ == 0 ||
(axisθ == 90 && (90 rot < 180 || 270 rot < 360)) ||
(axisθ == 270 && (rot < 90 || 180 rot < 270)) ||
(axisθ < 90 && (axisθ < rot < 180 || axisθ + 180 < rot)) ||
(axisθ > 270 && (rot < axisθ - 180 || 180 rot < axisθ)) ? -1 : 1
end
if !(axisθ == 0 && rot % 180 == 0) && ((rot - 90) % 180 != 0)
sgn3 = (axisθ == 0 && 90 < rot < 270) ||
(axisθ == 90 && rot < 180) ||
(axisθ == 270 && rot > 180) ||
(axisθ < 90 && (rot < axisθ || 90 rot < 180 || axisθ + 180 < rot < 270)) ||
(axisθ > 270 && (90 rot < axisθ - 180 || 180 rot < 270 || rot > axisθ)) ? -1 : 1
end
for (cv, dv) in zip((cvs, dvs)...)
xi, yi = gr_w3tondc(sort_3d_axes(cv, nt, ft, letter)...)
gr_text(xi + xoffset, yi + yoffset, dv)
sz_rot = gr_text_size(dv, rot)
sz = gr_text_size(dv)
x_offset = x_base_offset + sgn2a * first(sz_rot) / 2 + sgn3 * last(sz) * sind(rot) / 2
y_offset = y_base_offset + sgn2b * last(sz_rot) / 2 + sgn3 * last(sz) * cosd(rot) / 2
gr_text(xi + sgn * x_offset, yi + sgn * y_offset, dv)
end
end
@@ -2084,3 +2133,4 @@ function _display(plt::Plot{GRBackend})
end
closeall(::GRBackend) = GR.emergencyclosegks()
+24 -5
View File
@@ -203,7 +203,7 @@ function (pgfx_plot::PGFPlotsXPlot)(plt::Plot{PGFPlotsXBackend})
if hascolorbar(sp)
cticks = get_colorbar_ticks(sp)[2]
colorbar_style = PGFPlotsX.Options("title" => sp[:colorbar_title])
colorbar_style = PGFPlotsX.Options("ylabel" => sp[:colorbar_title])
if sp[:colorbar] === :top
push!(
colorbar_style,
@@ -512,10 +512,29 @@ function pgfx_add_series!(::Val{:heatmap}, axis, series_opt, series, series_func
end
function pgfx_add_series!(::Val{:mesh3d}, axis, series_opt, series, series_func, opt)
ptable = join(
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)],
"\n ",
)
if opt[:connections] isa Tuple{Array,Array,Array}
# 0-based indexing
ptable = join(
[string(i, " ", j, " ", k, "\\\\") for (i, j, k) in zip(opt[:connections]...)],
"\n ",
)
elseif typeof(opt[:connections]) <: AbstractVector{NTuple{3,Int}}
# 1-based indexing
ptable = join(
[
string(i - 1, " ", j - 1, " ", k - 1, "\\\\") for
(i, j, k) in opt[:connections]
],
"\n ",
)
else
throw(
ArgumentError(
"Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
),
)
end
push!(
series_opt,
"patch" => nothing,
+18 -6
View File
@@ -362,6 +362,7 @@ end
function plotly_legend_pos(pos::Symbol)
xleft = 0.07
xright = 1.0
ybot = 0.07
ytop = 1.0
xcenter = 0.55
@@ -372,14 +373,14 @@ function plotly_legend_pos(pos::Symbol)
xouterright = 1.05
xouterleft = -0.15
plotly_legend_position_mapping = (
right = (coords = [1.0, ycenter], xanchor = "right", yanchor = "middle"),
right = (coords = [xright, ycenter], xanchor = "right", yanchor = "middle"),
left = (coords = [xleft, ycenter], xanchor = "left", yanchor = "middle"),
top = (coords = [xcenter, ytop], xanchor = "center", yanchor = "top"),
bottom = (coords = [xcenter, ybot], xanchor = "center", yanchor = "bottom"),
bottomleft = (coords = [xleft, ybot], xanchor = "left", yanchor = "bottom"),
bottomright = (coords = [1.0, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [1.0, 1.0], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, 1.0], xanchor = "left", yanchor = "top"),
bottomright = (coords = [xright, ybot], xanchor = "right", yanchor = "bottom"),
topright = (coords = [xright, ytop], xanchor = "right", yanchor = "top"),
topleft = (coords = [xleft, ytop], xanchor = "left", yanchor = "top"),
outertop = (coords = [center, youtertop], xanchor = "upper", yanchor = "middle"),
outerbottom = (coords = [center, youterbot], xanchor = "lower", yanchor = "middle"),
outerleft = (coords = [xouterleft, center], xanchor = "left", yanchor = "top"),
@@ -400,7 +401,7 @@ function plotly_legend_pos(pos::Symbol)
xanchor = "lower",
yanchor = "right",
),
default = (coords = [1.0, 1.0], xanchor = "auto", yanchor = "auto"),
default = (coords = [xright, ytop], xanchor = "auto", yanchor = "auto"),
)
legend_position =
@@ -678,6 +679,7 @@ function plotly_series(plt::Plot, series::Series)
if series[:connections] !== nothing
if typeof(series[:connections]) <: Tuple{Array,Array,Array}
# 0-based indexing
i, j, k = series[:connections]
if !(length(i) == length(j) == length(k))
throw(
@@ -689,10 +691,20 @@ function plotly_series(plt::Plot, series::Series)
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
elseif typeof(series[:connections]) <: AbstractVector{NTuple{3,Int}}
# 1-based indexing
i, j, k = broadcast(
i -> [inds[i] - 1 for inds in series[:connections]],
(1, 2, 3),
)
plotattributes_out[:i] = i
plotattributes_out[:j] = j
plotattributes_out[:k] = k
else
throw(
ArgumentError(
"Argument connections has to be a tuple of three arrays.",
"Argument connections has to be either a tuple of three arrays (0-based indexing)
or an AbstractVector{NTuple{3,Int}} (1-based indexing).",
),
)
end
+71 -4
View File
@@ -26,9 +26,25 @@ pyrcparams = PyPlot.PyDict(PyPlot.matplotlib."rcParams")
# "support" matplotlib v3.4
if PyPlot.version < v"3.4"
@warn("You are using Matplotlib $(PyPlot.version), which is no longer
@warn("""You are using Matplotlib $(PyPlot.version), which is no longer
officialy supported by the Plots community. To ensure smooth Plots.jl
integration update your Matplotlib library to a version >= 3.4.0")
integration update your Matplotlib library to a version >= 3.4.0
If you have used Conda.jl to install PyPlot (default installation),
upgrade your matplotlib via Conda.jl and rebuild the PyPlot.
If you are not sure, here are the default instructions:
In Julia REPL:
```
import Pkg;
Pkg.add("Conda")
import Conda
Conda.update()
Pkg.build("PyPlot")
```
""")
end
set_facecolor_sym = if PyPlot.version < v"2"
@@ -682,6 +698,50 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
end
if st == :mesh3d
polygons = if series[:connections] isa AbstractVector{<:AbstractVector{Int}}
# Combination of any polygon types
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa AbstractVector{NTuple{N,Int}} where {N}
# Only N-gons - connections have to be 1-based (indexing)
broadcast(inds -> broadcast(i -> [x[i], y[i], z[i]], inds), series[:connections])
elseif series[:connections] isa NTuple{3,<:AbstractVector{Int}}
# Only triangles - connections have to be 0-based (indexing)
ci, cj, ck = series[:connections]
if !(length(ci) == length(cj) == length(ck))
throw(
ArgumentError(
"Argument connections must consist of equally sized arrays.",
),
)
end
broadcast(
j -> broadcast(i -> [x[i], y[i], z[i]], [ci[j] + 1, cj[j] + 1, ck[j] + 1]),
eachindex(ci),
)
else
throw(
ArgumentError(
"Unsupported `:connections` type $(typeof(series[:connections])) for seriestype=$st",
),
)
end
col = mplot3d.art3d.Poly3DCollection(
polygons,
linewidths = py_thickness_scale(plt, series[:linewidth]),
edgecolor = py_color(get_linecolor(series)),
facecolor = py_color(series[:fillcolor]),
alpha = get_fillalpha(series),
zorder = series[:series_plotindex],
)
handle = ax."add_collection3d"(col)
# Fix for handle: https://stackoverflow.com/questions/54994600/pyplot-legend-poly3dcollection-object-has-no-attribute-edgecolors2d
# It seems there aren't two different alpha values for edge and face
handle._facecolors2d = py_color(series[:fillcolor])
handle._edgecolors2d = py_color(get_linecolor(series))
push!(handles, handle)
end
if st == :image
xmin, xmax = ignorenan_extrema(series[:x])
ymin, ymax = ignorenan_extrema(series[:y])
@@ -1219,7 +1279,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
end
py_set_scale(ax, sp, axis)
axis[:ticks] == :native ? nothing : py_set_lims(ax, sp, axis)
py_set_lims(ax, sp, axis)
if ispolar(sp) && letter == :y
ax."set_rlabel_position"(90)
end
@@ -1254,7 +1314,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
)
end
axis[:ticks] == :native ? nothing : py_set_ticks(sp, ax, ticks, letter)
py_set_ticks(sp, ax, ticks, letter)
if axis[:ticks] == :native # It is easier to reset than to account for this
py_set_lims(ax, sp, axis)
pyaxis.set_major_locator(pyticker.AutoLocator())
pyaxis.set_major_formatter(pyticker.ScalarFormatter())
end
# Tick marks
intensity = 0.5 # This value corresponds to scaling of other grid elements
pyaxis."set_tick_params"(
+88 -58
View File
@@ -1,12 +1,10 @@
# https://github.com/JuliaPlots/UnicodePlots.jl
# don't warn on unsupported... there's just too many warnings!!
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes::KW) = nothing
warn_on_unsupported_args(::UnicodePlotsBackend, plotattributes) = nothing
# --------------------------------------------------------------------------------------
_canvas_map() = (
# ------------------------------------------------------------------------------------------
const _canvas_map = (
ascii = UnicodePlots.AsciiCanvas,
block = UnicodePlots.BlockCanvas,
braille = UnicodePlots.BrailleCanvas,
@@ -16,59 +14,78 @@ _canvas_map() = (
lookup = UnicodePlots.LookupCanvas,
)
# do all the magic here... build it all at once, since we need to know about all the series at the very beginning
# do all the magic here... build it all at once,
# since we need to know about all the series at the very beginning
function unicodeplots_rebuild(plt::Plot{UnicodePlotsBackend})
plt.o = UnicodePlots.Plot[]
canvas_map = _canvas_map()
for sp in plt.subplots
xaxis = sp[:xaxis]
yaxis = sp[:yaxis]
xlim = axis_limits(sp, :x)
ylim = axis_limits(sp, :y)
xlim = collect(axis_limits(sp, :x))
ylim = collect(axis_limits(sp, :y))
# make vectors
xlim = [xlim[1], xlim[2]]
ylim = [ylim[1], ylim[2]]
# we set x/y to have a single point, since we need to create the plot with some data.
# since this point is at the bottom left corner of the plot, it shouldn't actually be shown
# we set x/y to have a single point,
# since we need to create the plot with some data.
# since this point is at the bottom left corner of the plot,
# it shouldn't actually be shown
x = Float64[xlim[1]]
y = Float64[ylim[1]]
# create a plot window with xlim/ylim set, but the X/Y vectors are outside the bounds
# create a plot window with xlim/ylim set,
# but the X/Y vectors are outside the bounds
canvas_type = if (ct = _canvas_type[]) == :auto
isijulia() ? :ascii : :braille
else
ct
end
o = UnicodePlots.Plot(
x,
y,
canvas_map[canvas_type];
kw = (
compact = true,
title = sp[:title],
xlim = xlim,
ylim = ylim,
xlabel = xaxis[:guide],
ylabel = yaxis[:guide],
xscale = xaxis[:scale],
yscale = yaxis[:scale],
border = isijulia() ? :ascii : :solid,
xlim = xlim,
ylim = ylim,
)
o = UnicodePlots.Plot(x, y, _canvas_map[canvas_type]; kw...)
for series in series_list(sp)
o = addUnicodeSeries!(sp, o, series, sp[:legend] != :none, xlim, ylim)
o = addUnicodeSeries!(sp, o, kw, series, sp[:legend] != :none)
end
for ann in sp[:annotations]
x, y, val = locate_annotation(sp, ann...)
o = UnicodePlots.annotate!(
o,
x,
y,
val.str;
color = up_color(val.font.color),
halign = val.font.halign,
valign = val.font.valign,
)
end
push!(plt.o, o) # save the object
end
end
up_color(col::UnicodePlots.UserColorType) = col
up_color(col::RGBA) =
(c = convert(ARGB32, col); map(Int, (red(c).i, green(c).i, blue(c).i)))
up_color(col) = :auto
# add a single series
function addUnicodeSeries!(
sp::Subplot{UnicodePlotsBackend},
up::UnicodePlots.Plot,
kw,
series,
addlegend::Bool,
xlim,
ylim,
)
st = series[:seriestype]
@@ -83,25 +100,29 @@ function addUnicodeSeries!(
# special handling (src/interface)
if st == :histogram2d
return UnicodePlots.densityplot(x, y)
kw[:xlim][:] .= kw[:ylim][:] .= 0
return UnicodePlots.densityplot(x, y; kw...)
elseif st == :heatmap
rng = range(0, 1, length = length(UnicodePlots.COLOR_MAP_DATA[:viridis]))
cmap = [(red(c), green(c), blue(c)) for c in get(get_colorgradient(series), rng)]
return UnicodePlots.heatmap(
series[:z].surf;
title = sp[:title],
zlabel = sp[:colorbar_title],
colormap = cmap,
kw...,
)
elseif st == :spy
return UnicodePlots.spy(series[:z].surf; title = sp[:title])
return UnicodePlots.spy(series[:z].surf; kw...)
end
series_kw = (;)
# now use the ! functions to add to the plot
if st in (:path, :straightline, :shape)
func = UnicodePlots.lineplot!
elseif st == :scatter || series[:markershape] != :none
func = UnicodePlots.scatterplot!
series_kw = (; marker = series[:markershape])
else
error("Series type $st not supported by UnicodePlots")
end
@@ -111,23 +132,35 @@ function addUnicodeSeries!(
for (n, segment) in enumerate(series_segments(series, st; check = true))
i, rng = segment.attr_index, segment.range
lc = get_linecolor(series, i)
if typeof(lc) <: UnicodePlots.UserColorType
color = lc
elseif typeof(lc) <: RGBA
lc = convert(ARGB32, lc)
color = map(Int, (red(lc).i, green(lc).i, blue(lc).i))
else
color = :auto
end
up = func(up, x[rng], y[rng]; color = color, name = n == 1 ? label : "")
up = func(
up,
x[rng],
y[rng];
color = up_color(lc),
name = n == 1 ? label : "",
series_kw...,
)
end
for (xi, yi, str, fnt) in EachAnn(series[:series_annotations], x, y)
up = UnicodePlots.annotate!(
up,
xi,
yi,
str;
color = up_color(fnt.color),
halign = fnt.halign,
valign = fnt.valign,
)
end
return up
end
# -------------------------------
# ------------------------------------------------------------------------------------------
# since this is such a hack, it's only callable using `png`... should error during normal `show`
# since this is such a hack, it's only callable using `png`...
# should error during normal `show`
function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString)
fn = addExtension(fn, "png")
@@ -135,17 +168,10 @@ function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString)
# make some whitespace and show the plot
println("\n\n\n\n\n\n")
gui(plt)
# BEGIN HACK
# wait while the plot gets drawn
sleep(0.5)
# use osx screen capture when my terminal is maximized and cursor starts at the bottom (I know, right?)
# TODO: compute size of plot to adjust these numbers (or maybe implement something good??)
# use osx screen capture when my terminal is maximized
# and cursor starts at the bottom (I know, right?)
run(`screencapture -R50,600,700,420 $fn`)
# END HACK (phew)
return
elseif Sys.islinux()
run(`clear`)
@@ -155,12 +181,14 @@ function png(plt::Plot{UnicodePlotsBackend}, fn::AbstractString)
end
error(
"Can only savepng on MacOS or Linux with UnicodePlots (though even then I wouldn't do it)",
"Can only savepng on MacOS or Linux with UnicodePlots " *
"(though even then I wouldn't do it)",
)
end
# -------------------------------
Base.show(plt::Plot{UnicodePlotsBackend}) = _show(stdout, MIME("text/plain"), plt)
# ------------------------------------------------------------------------------------------
Base.show(plt::Plot{UnicodePlotsBackend}) = show(stdout, plt)
Base.show(io::IO, plt::Plot{UnicodePlotsBackend}) = _show(io, MIME("text/plain"), plt)
function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
unicodeplots_rebuild(plt)
@@ -168,9 +196,11 @@ function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
lines_colored = Array{Union{Nothing,Vector{String}}}(undef, nr, nc)
lines_uncolored = copy(lines_colored)
l_max = zeros(Int, nr)
w_max = zeros(Int, nc)
buf = IOBuffer()
cbuf = IOContext(buf, :color => true)
sps = wmax = 0
re_col = r"\x1B\[[0-9;]*[a-zA-Z]"
sps = 0
for r in 1:nr
lmax = 0
for c in 1:nc
@@ -184,27 +214,27 @@ function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend})
sp = plt.o[sps += 1]
show(cbuf, sp)
colored = String(take!(buf))
uncolored = replace(colored, r"\x1B\[[0-9;]*[a-zA-Z]" => "")
uncolored = replace(colored, re_col => "")
lines_colored[r, c] = lc = split(colored, "\n")
lines_uncolored[r, c] = lu = split(uncolored, "\n")
lmax = max(length(lc), lmax)
wmax = max(maximum(length.(lu)), wmax)
w_max[c] = max(maximum(length.(lu)), w_max[c])
end
end
end
l_max[r] = lmax
end
empty = ' '^wmax
empty = String[' '^w for w in w_max]
for r in 1:nr
for n in 1:l_max[r]
for c in 1:nc
pre = c == 1 ? '\0' : ' '
lc = lines_colored[r, c]
if lc === nothing || length(lc) < n
print(io, pre, empty)
print(io, pre, empty[c])
else
lu = lines_uncolored[r, c]
print(io, pre, lc[n], ' '^(wmax - length(lu[n])))
print(io, pre, lc[n], ' '^(w_max[c] - length(lu[n])))
end
end
println(io)
+16 -16
View File
@@ -5,33 +5,32 @@ process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f
function get_clims(sp::Subplot, op = process_clims(sp[:clims]))
get_clims(sp::Subplot)::Tuple{Float64,Float64} = sp[:crange]
get_clims(series::Series)::Tuple{Float64,Float64} = series[:crange]
get_clims(sp::Subplot, series::Series)::Tuple{Float64,Float64} =
series[:colorbar_entry] ? sp[:crange] : series[:crange]
function update_clims(sp::Subplot, op = process_clims(sp[:clims]))::Tuple{Float64,Float64}
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...)
zmin, zmax = _update_clims(zmin, zmax, update_clims(series, op)...)
else
update_clims(series, op)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series, op = process_clims(sp[:clims]))
zmin, zmax = if series[:colorbar_entry]
get_clims(sp, op)
else
get_clims(series, op)
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
return sp[:crange] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
"""
get_clims(::Series, op=Plots.ignorenan_extrema)
update_clims(::Series, op=Plots.ignorenan_extrema)
Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`,
which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input.
values of the input. The value is stored as a series property, which is retrieved by `get_clims`.
"""
function get_clims(series::Series, op = ignorenan_extrema)
function update_clims(series::Series, op = ignorenan_extrema)::Tuple{Float64,Float64}
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface, :hexbin)
for vals in (
@@ -46,7 +45,7 @@ function get_clims(series::Series, op = ignorenan_extrema)
zmin, zmax = _update_clims(zmin, zmax, op(vals)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
return series[:crange] = zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
_update_clims(zmin, zmax, emin, emax) = NaNMath.min(zmin, emin), NaNMath.max(zmax, emax)
@@ -94,4 +93,5 @@ end
function _update_subplot_colorbars(sp::Subplot)
# Dynamic callback from the pipeline if needed
update_clims(sp)
end
+9 -7
View File
@@ -962,8 +962,10 @@ const _examples = PlotExample[
"""
Allows to plot arbitrary 3d meshes. If only x,y,z are given the mesh is generated automatically.
You can also specify the connections using the connections keyword.
The connections are specified using a tuple of vectors. Each vector contains the 0-based indices of one point of a triangle,
such that elements at the same position of these vectors form a triangle.
The connections can be specified in two ways: Either as a tuple of vectors where each vector
contains the 0-based indices of one point of a triangle, such that elements at the same
position of these vectors form a triangle. Or as a vector of NTuple{3,Ints} where each element
contains the 1-based indices of the three points of a triangle.
""",
[
:(
@@ -979,13 +981,14 @@ const _examples = PlotExample[
i = [0, 0, 0, 1]
j = [1, 2, 3, 2]
k = [2, 3, 1, 3]
# Or: cns = [(1, 2, 3), (1, 3, 4), (1, 4, 2), (2, 3, 4)] (1-based indexing)
# the four triangles gives above give a tetrahedron
mesh3d(
x,
y,
z;
connections = (i, j, k),
connections = (i, j, k), # connections = cns
title = "triangles",
xlabel = "x",
ylabel = "y",
@@ -1235,7 +1238,7 @@ const _examples = PlotExample[
_animation_examples = [2, 31]
_backend_skips = Dict(
:gr => [25, 30],
:pyplot => [2, 25, 30, 31, 47, 49, 55],
:pyplot => [2, 25, 30, 31, 49, 55],
:plotlyjs => [2, 21, 24, 25, 30, 31, 49, 51, 55],
:plotly => [2, 21, 24, 25, 30, 31, 49, 50, 51, 55],
:pgfplotsx => [
@@ -1250,14 +1253,14 @@ _backend_skips = Dict(
],
:inspectdr => [4, 6, 10, 22, 24, 28, 30, 38, 43, 45, 47, 48, 49, 50, 51, 55],
:unicodeplots => [
5, # limits issue
6, # embedded images unsupported
13, # markers unsupported
16, # nested layout unsupported
20, # annotations unsupported
21, # custom markers unsupported
22, # contours unsupported
24, # 3D unsupported
26, # nested layout unsupported
27, # polar plots unsupported
29, # nested layout unsupported
33, # grid lines unsupported
34, # framestyle unsupported
@@ -1265,7 +1268,6 @@ _backend_skips = Dict(
43, # heatmap with DateTime
45, # error bars
47, # mesh3D unsupported
48, # markershapes unsupported
49, # polar heatmap
50, # 3D surface unsupported
51, # embedded images unsupported
+1
View File
@@ -416,4 +416,5 @@ function _add_the_series(plt, sp, plotattributes)
push!(plt.series_list, series)
push!(sp.series_list, series)
_series_added(plt, series)
_update_subplot_colorbars(sp)
end
+7 -1
View File
@@ -1042,7 +1042,13 @@ export lens!
series_plotindex := backup[:series_plotindex]
seriestype := :path
primary := false
linecolor := :lightgray
linecolor := get(backup, :linecolor, :lightgray)
if haskey(backup, :linestyle)
linestyle := backup[:linestyle]
end
if haskey(backup, :linewidth)
linewidth := backup[:linewidth]
end
bbx_mag = (x1 + x2) / 2
bby_mag = (y1 + y2) / 2
xi_lens, yi_lens =
+37 -13
View File
@@ -202,10 +202,16 @@ makevec(v::T) where {T} = T[v]
maketuple(x::Real) = (x, x)
maketuple(x::Tuple{T,S}) where {T,S} = x
RecipesPipeline.unzip(v::Union{AVec{<:Tuple},AVec{<:GeometryBasics.Point}) = tuple((([t[j] for t in v]) for j in 1:length(v[1]))...)
for i in 2:4
@eval begin
RecipesPipeline.unzip(
v::Union{AVec{<:NTuple{$i,T} where {T}},AVec{<:GeometryBasics.Point{$i}}},
) = $(Expr(:tuple, (:([t[$j] for t in v]) for j in 1:i)...))
end
end
RecipesPipeline.unzip(
::Union{AVec{<:GeometryBasics.Point{N}},AVec{<:Tuple}},
::Union{AVec{<:GeometryBasics.Point{N}},AVec{<:NTuple{N,T} where {T}}},
) where {N} = error("$N-dimensional unzip not implemented.")
RecipesPipeline.unzip(::Union{AVec{<:GeometryBasics.Point},AVec{<:Tuple}}) =
@@ -1175,16 +1181,10 @@ end
_document_argument(S::AbstractString) =
_fmt_paragraph("`$S`: " * _arg_desc[Symbol(S)], leadingspaces = 6 + length(S))
function mesh3d_triangles(x, y, z, cns)
if typeof(cns) <: Tuple{Array,Array,Array}
ci, cj, ck = cns
if !(length(ci) == length(cj) == length(ck))
throw(
ArgumentError("Argument connections must consist of equally sized arrays."),
)
end
else
throw(ArgumentError("Argument connections has to be a tuple of three arrays."))
function mesh3d_triangles(x, y, z, cns::Tuple{Array,Array,Array})
ci, cj, ck = cns
if !(length(ci) == length(cj) == length(ck))
throw(ArgumentError("Argument connections must consist of equally sized arrays."))
end
X = zeros(eltype(x), 4length(ci))
Y = zeros(eltype(y), 4length(cj))
@@ -1209,6 +1209,30 @@ function mesh3d_triangles(x, y, z, cns)
end
return X, Y, Z
end
function mesh3d_triangles(x, y, z, cns::AbstractVector{NTuple{3,Int}})
X = zeros(eltype(x), 4length(cns))
Y = zeros(eltype(y), 4length(cns))
Z = zeros(eltype(z), 4length(cns))
@inbounds for I in 1:length(cns)
i = cns[I][1] # connections are 1-based
j = cns[I][2]
k = cns[I][3]
m = 4(I - 1) + 1
n = m + 1
o = m + 2
p = m + 3
X[m] = X[p] = x[i]
Y[m] = Y[p] = y[i]
Z[m] = Z[p] = z[i]
X[n] = x[j]
Y[n] = y[j]
Z[n] = z[j]
X[o] = x[k]
Y[o] = y[k]
Z[o] = z[k]
end
return X, Y, Z
end
# cache joined symbols so they can be looked up instead of constructed each time
const _attrsymbolcache = Dict{Symbol,Dict{Symbol,Symbol}}()
+81 -78
View File
@@ -1,18 +1,20 @@
using Plots: guidefont, series_annotations, PLOTS_SEED
import ImageMagick
using VisualRegressionTests
using Plots
using Random
using StableRNGs
using Test
using TestImages
using FileIO
using Gtk
using LibGit2
import GeometryBasics
using Dates
using RecipesBase
using StableRNGs
using TestImages
using LibGit2
using Random
using FileIO
using Plots
using Dates
using JSON
using Test
using Gtk
import GeometryBasics
import ImageMagick
@testset "Infrastructure" begin
@test_nowarn JSON.Parser.parse(
@@ -33,7 +35,7 @@ end
end
Plots.plotly_local_file_path[] = nothing
Plots.use_local_dependencies[] = temp
end # testset
end
include("test_defaults.jl")
include("test_pipeline.jl")
@@ -55,7 +57,6 @@ function reference_file(backend, i, version)
refdir = reference_dir("Plots", string(backend))
fn = "ref$i.png"
versions = sort(VersionNumber.(readdir(refdir)), rev = true)
reffn = joinpath(refdir, string(version), fn)
for v in versions
tmpfn = joinpath(refdir, string(v), fn)
@@ -64,7 +65,6 @@ function reference_file(backend, i, version)
break
end
end
return reffn
end
@@ -79,9 +79,10 @@ if !isdir(reference_dir())
end
include("imgcomp.jl")
# don't actually show the plots
Random.seed!(PLOTS_SEED)
default(show = false, reuse = true)
default(show = false, reuse = true) # don't actually show the plots
is_ci() = get(ENV, "CI", "false") == "true"
const PLOTS_IMG_TOL = parse(Float64, get(ENV, "PLOTS_IMG_TOL", is_ci() ? "1e-4" : "1e-5"))
@@ -106,66 +107,8 @@ const PLOTS_IMG_TOL = parse(Float64, get(ENV, "PLOTS_IMG_TOL", is_ci() ? "1e-4"
# image_comparison_facts(:pgfplotsx, tol=PLOTS_IMG_TOL, skip = Plots._backend_skips[:pgfplotsx])
# end
# 10 Histogram2D
##
@testset "Backends" begin
@testset "GR" begin
ENV["PLOTS_TEST"] = "true"
ENV["GKSwstype"] = "100"
@test gr() == Plots.GRBackend()
@test backend() == Plots.GRBackend()
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(
:gr,
tol = PLOTS_IMG_TOL,
skip = Plots._backend_skips[:gr],
)
end
end
@testset "UnicodePlots" begin
@test unicodeplots() == Plots.UnicodePlotsBackend()
@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
p = plot([1, 2], [3, 4])
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
hline!(p, [3.1])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
hline!(p, [3.1])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
hline!(p, [3.1])
@test isa(p, Plots.Plot) == true
@test isa(display(p), Nothing) == true
end
@testset "PlotlyJS" begin
@test plotlyjs() == Plots.PlotlyJSBackend()
@test backend() == Plots.PlotlyJSBackend()
p = plot(rand(10))
@test isa(p, Plots.Plot) == true
@test_broken isa(display(p), Nothing) == true
end
end
@testset "Axes" begin
p = plot()
axis = p.subplots[1][:xaxis]
@@ -181,10 +124,12 @@ end
end
@testset "NoFail" begin
#ensure backend with tested display
# ensure backend with tested display
@test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend()
dsp = TextDisplay(IOContext(IOBuffer(), :color => true))
@testset "Plot" begin
plots = [
histogram([1, 0, 0, 0, 0, 0]),
@@ -197,15 +142,15 @@ end
plot(["a" "b"; missing "d"], [1 2; 3 4]),
]
for plt in plots
display(plt)
display(dsp, plt)
end
@test_nowarn plot(x -> x^2, 0, 2)
end
@testset "Bar" begin
p = bar([3, 2, 1], [1, 2, 3])
@test isa(p, Plots.Plot)
@test isa(display(p), Nothing) == true
@test p isa Plots.Plot
@test display(dsp, p) isa Nothing
end
end
@@ -255,3 +200,61 @@ end
Plots.process_clims(missing) ==
Plots.process_clims(:auto)
end
@testset "Backends" begin
@testset "UnicodePlots" begin
@test unicodeplots() == Plots.UnicodePlotsBackend()
@test backend() == Plots.UnicodePlotsBackend()
io = IOContext(IOBuffer(), :color => true)
# lets just make sure it runs without error
p = plot(rand(10))
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = bar(randn(10))
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([1, 2], [3, 4])
annotate!(p, [(1.5, 3.2, Plots.text("Test", :red, :center))])
hline!(p, [3.1])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
hline!(p, [3.1])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, Plots.text("Test", :red, :center))])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
p = plot([Dates.Date(2019, 1, 1), Dates.Date(2019, 2, 1)], [3, 4])
annotate!(p, [(Dates.Date(2019, 1, 15), 3.2, :auto)])
hline!(p, [3.1])
@test p isa Plots.Plot
@test show(io, p) isa Nothing
end
@testset "PlotlyJS" begin
@test plotlyjs() == Plots.PlotlyJSBackend()
@test backend() == Plots.PlotlyJSBackend()
p = plot(rand(10))
@test p isa Plots.Plot
@test_broken display(p) isa Nothing
end
@testset "GR" begin
ENV["PLOTS_TEST"] = "true"
ENV["GKSwstype"] = "100"
@test gr() == Plots.GRBackend()
@test backend() == Plots.GRBackend()
@static if haskey(ENV, "APPVEYOR")
@info "Skipping GR image comparison tests on AppVeyor"
else
image_comparison_facts(
:gr,
tol = PLOTS_IMG_TOL,
skip = Plots._backend_skips[:gr],
)
end
end
end
+38 -9
View File
@@ -64,7 +64,7 @@ end
@test twpl[:bottom_margin] == 2Plots.cm
end
@testset "aliases" begin
@testset "axis-aliases" begin
p = plot(1:2, xl = "x label")
@test p[1][:xaxis][:guide] === "x label"
p = plot(1:2, xrange = (0, 3))
@@ -73,18 +73,47 @@ end
@test p[1][:xaxis][:ticks] == [1.25, 1.5, 1.75]
p = plot(1:2, xlabelfontsize = 4)
@test p[1][:xaxis][:guidefontsize] == 4
p = plot(1:2, xgα = .07)
@test p[1][:xaxis][:gridalpha] .07
p = plot(1:2, xgα = 0.07)
@test p[1][:xaxis][:gridalpha] 0.07
p = plot(1:2, xgridls = :dashdot)
@test p[1][:xaxis][:gridstyle] === :dashdot
p = plot(1:2, xgridcolor = :red)
@test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.,0.,0.,1.)
@test p[1][:xaxis][:foreground_color_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
p = plot(1:2, xminorgridcolor = :red)
@test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.,0.,0.,1.)
p = plot(1:2, xgrid_lw = .01)
@test p[1][:xaxis][:gridlinewidth] .01
p = plot(1:2, xminorgrid_lw = .01)
@test p[1][:xaxis][:minorgridlinewidth] .01
@test p[1][:xaxis][:foreground_color_minor_grid] === RGBA{Float64}(1.0, 0.0, 0.0, 1.0)
p = plot(1:2, xgrid_lw = 0.01)
@test p[1][:xaxis][:gridlinewidth] 0.01
p = plot(1:2, xminorgrid_lw = 0.01)
@test p[1][:xaxis][:minorgridlinewidth] 0.01
p = plot(1:2, xtickor = :out)
@test p[1][:xaxis][:tick_direction] === :out
end
@testset "aliases" begin
compare(p::Plots.Plot, s::Symbol, val, op) =
op(p[1][:xaxis][s], val) && op(p[1][:yaxis][s], val) && op(p[1][:zaxis][s], val)
p = plot(1:2, guide = "all labels")
@test compare(p, :guide, "all labels", ===)
p = plot(1:2, label = "test")
@test compare(p, :guide, "", ===)
p = plot(1:2, lim = (0, 3))
@test xlims(p) === ylims(p) === zlims(p) === (0, 3)
p = plot(1:2, tick = [1.25, 1.5, 1.75])
@test compare(p, :ticks, [1.25, 1.5, 1.75], ==)
p = plot(1:2, labelfontsize = 4)
@test compare(p, :guidefontsize, 4, ==)
p = plot(1:2, gα = 0.07)
@test compare(p, :gridalpha, 0.07, )
p = plot(1:2, gridls = :dashdot)
@test compare(p, :gridstyle, :dashdot, ===)
p = plot(1:2, gridcolor = :red)
@test compare(p, :foreground_color_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
p = plot(1:2, minorgridcolor = :red)
@test compare(p, :foreground_color_minor_grid, RGBA{Float64}(1.0, 0.0, 0.0, 1.0), ===)
p = plot(1:2, grid_lw = 0.01)
@test compare(p, :gridlinewidth, 0.01, )
p = plot(1:2, minorgrid_lw = 0.01)
@test compare(p, :minorgridlinewidth, 0.01, )
p = plot(1:2, tickor = :out)
@test compare(p, :tick_direction, :out, ===)
end