diff --git a/README.md b/README.md
index 374fc709..352df451 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,16 @@
# UnicodePlots
-[![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md) [![PkgEval](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/U/UnicodePlots.named.svg)](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/U/UnicodePlots.html) [![CI](https://github.com/JuliaPlots/UnicodePlots.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/JuliaPlots/UnicodePlots.jl/actions/workflows/ci.yml) [![Coverage Status](https://codecov.io/gh/JuliaPlots/UnicodePlots.jl/branch/master/graphs/badge.svg?branch=master)](https://app.codecov.io/gh/JuliaPlots/UnicodePlots.jl) [![JuliaHub deps](https://juliahub.com/docs/UnicodePlots/deps.svg)](https://juliahub.com/ui/Packages/UnicodePlots/Ctj9q?t=2) [![UnicodePlots Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/UnicodePlots)](https://pkgs.genieframework.com?packages=UnicodePlots)
+[![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md)
+[![PkgEval](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/U/UnicodePlots.named.svg)](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/U/UnicodePlots.html)
+[![CI](https://github.com/JuliaPlots/UnicodePlots.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/JuliaPlots/UnicodePlots.jl/actions/workflows/ci.yml)
+[![Coverage Status](https://codecov.io/gh/JuliaPlots/UnicodePlots.jl/branch/master/graphs/badge.svg?branch=master)](https://app.codecov.io/gh/JuliaPlots/UnicodePlots.jl)
+[![JuliaHub deps](https://juliahub.com/docs/UnicodePlots/deps.svg)](https://juliahub.com/ui/Packages/UnicodePlots/Ctj9q?t=2)
+[![UnicodePlots Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/UnicodePlots)](https://pkgs.genieframework.com?packages=UnicodePlots)
Advanced [`Unicode`](https://en.wikipedia.org/wiki/Unicode) plotting library designed for use in `Julia`'s `REPL`.
-Physical quantities of [`Unitful.jl`](https://github.com/PainterQubits/Unitful.jl) are supported on a subset of plotting methods.
+![Banner](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/banner.png)
## High-level Interface
@@ -13,25 +18,26 @@ There are a couple of ways to generate typical plots without much verbosity.
Here is a list of the main high-level functions for common scenarios:
- * [`scatterplot`](https://github.com/JuliaPlots/UnicodePlots.jl#scatterplot) (Scatter Plot)
- * [`lineplot`](https://github.com/JuliaPlots/UnicodePlots.jl#lineplot) (Line Plot)
- * [`stairs`](https://github.com/JuliaPlots/UnicodePlots.jl#staircase-plot) (Staircase Plot)
- * [`barplot`](https://github.com/JuliaPlots/UnicodePlots.jl#barplot) (Bar Plot - horizontal)
- * [`histogram`](https://github.com/JuliaPlots/UnicodePlots.jl#histogram) (Histogram - horizontal / vertical)
- * [`boxplot`](https://github.com/JuliaPlots/UnicodePlots.jl#boxplot) (Box Plot - horizontal)
- * [`spy`](https://github.com/JuliaPlots/UnicodePlots.jl#sparsity-pattern) (Sparsity Pattern)
- * [`densityplot`](https://github.com/JuliaPlots/UnicodePlots.jl#density-plot) (Density Plot)
- * [`contourplot`](https://github.com/JuliaPlots/UnicodePlots.jl#contour-plot) (Contour Plot)
- * [`polarplot`](https://github.com/JuliaPlots/UnicodePlots.jl#polar-plot) (Polar Plot)
- * [`heatmap`](https://github.com/JuliaPlots/UnicodePlots.jl#heatmap-plot) (Heatmap Plot)
- * [`surfaceplot`](https://github.com/JuliaPlots/UnicodePlots.jl#surface-plot) (Surface Plot - 3D)
- * [`isosurface`](https://github.com/JuliaPlots/UnicodePlots.jl#isosurface-plot) (Isosurface Plot - 3D)
-
- Introduction
-
-Here is a quick hello world example of a typical use-case:
-
-```julia
+ - [`scatterplot`](https://github.com/JuliaPlots/UnicodePlots.jl#scatterplot) (Scatter Plot)
+ - [`lineplot`](https://github.com/JuliaPlots/UnicodePlots.jl#lineplot) (Line Plot)
+ - [`stairs`](https://github.com/JuliaPlots/UnicodePlots.jl#staircase-plot) (Staircase Plot)
+ - [`barplot`](https://github.com/JuliaPlots/UnicodePlots.jl#barplot) (Bar Plot - horizontal)
+ - [`histogram`](https://github.com/JuliaPlots/UnicodePlots.jl#histogram) (Histogram - horizontal / vertical)
+ - [`boxplot`](https://github.com/JuliaPlots/UnicodePlots.jl#boxplot) (Box Plot - horizontal)
+ - [`spy`](https://github.com/JuliaPlots/UnicodePlots.jl#sparsity-pattern) (Sparsity Pattern)
+ - [`densityplot`](https://github.com/JuliaPlots/UnicodePlots.jl#density-plot) (Density Plot)
+ - [`contourplot`](https://github.com/JuliaPlots/UnicodePlots.jl#contour-plot) (Contour Plot)
+ - [`polarplot`](https://github.com/JuliaPlots/UnicodePlots.jl#polar-plot) (Polar Plot)
+ - [`heatmap`](https://github.com/JuliaPlots/UnicodePlots.jl#heatmap-plot) (Heatmap Plot)
+ - [`surfaceplot`](https://github.com/JuliaPlots/UnicodePlots.jl#surface-plot) (Surface Plot - 3D)
+ - [`isosurface`](https://github.com/JuliaPlots/UnicodePlots.jl#isosurface-plot) (Isosurface Plot - 3D)
+
+
+ Introduction
+
+ Here is a quick hello world example of a typical use-case:
+
+ ```julia
using UnicodePlots
plt = lineplot([-1, 2, 3, 7], [-1, 2, 9, 4],
title="Example Plot", name="my line", xlabel="x", ylabel="y")
@@ -39,11 +45,11 @@ plt = lineplot([-1, 2, 3, 7], [-1, 2, 9, 4],
![Basic Canvas](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot1.png)
-There are other types of `Canvas` available (see section [Low-level Interface](https://github.com/JuliaPlots/UnicodePlots.jl#low-level-interface)).
+ There are other types of `Canvas` available (see section [Low-level Interface](https://github.com/JuliaPlots/UnicodePlots.jl#low-level-interface)).
-In some situations, such as printing to a file, using `AsciiCanvas`, `DotCanvas` or `BlockCanvas` might lead to better results:
+ In some situations, such as printing to a file, using `AsciiCanvas`, `DotCanvas` or `BlockCanvas` might lead to better results:
-```julia
+ ```julia
lineplot([-1, 2, 3, 7], [-1, 2, 9, 4],
title="Example Plot", name="my line",
xlabel="x", ylabel="y", canvas=DotCanvas, border=:ascii)
@@ -51,97 +57,109 @@ lineplot([-1, 2, 3, 7], [-1, 2, 9, 4],
![Basic Canvas](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot2.png)
-Some plot methods have a mutating variant that ends with a exclamation mark:
+ Some plot methods have a mutating variant that ends with a exclamation mark:
-```julia
+ ```julia
lineplot!(plt, [0, 4, 8], [10, 1, 10], color=:blue, name="other line")
```
![Basic Canvas](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot3.png)
-
- Scatterplot
-```julia
+ Physical quantities of [`Unitful.jl`](https://github.com/PainterQubits/Unitful.jl) are supported on a subset of plotting methods.
+
+
+
+
+ Scatterplot
+
+ ```julia
scatterplot(randn(50), randn(50), title="My Scatterplot")
```
![Scatterplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/scatterplot1.png)
-Axis scaling (`xscale` and/or `yscale`) is supported: choose from (`:identity`, `:ln`, `:log2`, `:log10`) or use an arbitrary scale function:
+ Axis scaling (`xscale` and/or `yscale`) is supported: choose from (`:identity`, `:ln`, `:log2`, `:log10`) or use an arbitrary scale function:
-```julia
+ ```julia
scatterplot(1:10, 1:10, xscale=:log10, yscale=:ln)
```
![Scatterplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/scatterplot2.png)
-For the axis scale exponent, one can revert to using `ASCII` characters instead of `Unicode` ones using the keyword `unicode_exponent=false`:
+ For the axis scale exponent, one can revert to using `ASCII` characters instead of `Unicode` ones using the keyword `unicode_exponent=false`:
-```julia
+ ```julia
scatterplot(1:10, 1:10, xscale=:log10, yscale=:ln, unicode_exponent=false)
```
![Scatterplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/scatterplot3.png)
-Using a `marker` is supported, choose a `Char`, a unit length `String` or a symbol name such as `:circle` (more from `keys(UnicodePlots.MARKERS)`). One can also provide a vector of `marker`s and/or `color`s as in the following example:
+ Using a `marker` is supported, choose a `Char`, a unit length `String` or a symbol name such as `:circle` (more from `keys(UnicodePlots.MARKERS)`).
+ One can also provide a vector of `marker`s and/or `color`s as in the following example:
-```julia
+ ```julia
scatterplot([1, 2, 3], [3, 4, 1],
marker=[:circle, '', "∫"], color=[:red, nothing, :yellow])
```
![Scatterplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/scatterplot4.png)
-As with `lineplot`, `scatterplot` supports plotting physical `Unitful` quantities.
+ As with `lineplot`, `scatterplot` supports plotting physical `Unitful` quantities.
+
- Lineplot
+
+ Lineplot
-```julia
+ ```julia
lineplot([1, 2, 7], [9, -6, 8], title="My Lineplot")
```
![Lineplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot4.png)
-It's also possible to specify a function and a range:
+ It's also possible to specify a function and a range:
-```julia
+ ```julia
plt = lineplot([cos, sin], -π/2, 2π)
```
![Lineplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot5.png)
-You can also plot lines by specifying an intercept and slope:
+ You can also plot lines by specifying an intercept and slope:
-```julia
+ ```julia
lineplot!(plt, -.5, .2, name="line")
```
![Lineplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot6.png)
-Physical units are supported through `Unitful`:
+ Physical units are supported through `Unitful`:
-```julia
+ ```julia
using Unitful
a = 1u"m/s^2"
t = (0:100) * u"s"
lineplot(a / 2 * t .^ 2, a * t, xlabel = "position", ylabel = "speed")
```
![Lineplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/lineplot7.png)
-
- Staircase plot
+
-```julia
+
+ Staircase plot
+
+ ```julia
# supported style are :pre and :post
stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 7],
color=:red, style=:post, title="My Staircase Plot")
```
![Staircase](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/stairs1.png)
-
- Barplot
+
-```julia
+
+ Barplot
+
+ ```julia
barplot(["Paris", "New York", "Moskau", "Madrid"],
[2.244, 8.406, 11.92, 3.165],
title="Population")
@@ -149,112 +167,126 @@ barplot(["Paris", "New York", "Moskau", "Madrid"],
![Barplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/barplot1.png)
-*Note*: You can use the keyword argument `symbols` to specify the characters that should be used to plot the bars (e.g. `symbols=['#']`).
+ _Note_: You can use the keyword argument `symbols` to specify the characters that should be used to plot the bars (e.g. `symbols=['#']`).
+
- Histogram
+
+ Histogram
-```julia
+ ```julia
histogram(randn(1_000) .* .1, nbins=15, closed=:left)
```
![Histogram](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/histogram1.png)
-The `histogram` function also supports axis scaling using the parameter `xscale`:
+ The `histogram` function also supports axis scaling using the parameter `xscale`:
-```julia
+ ```julia
histogram(randn(1_000) .* .1, nbins=15, closed=:right, xscale=:log10)
```
![Histogram](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/histogram2.png)
-Vertical histograms are supported:
+ Vertical histograms are supported:
-```julia
+ ```julia
histogram(randn(1_000_000) .* .1, nbins=100, vertical=true)
```
![Histogram](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/histogram3.png)
-
- Boxplot
+
-```julia
+
+ Boxplot
+
+ ```julia
boxplot([1, 3, 3, 4, 6, 10])
```
![Boxplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/boxplot1.png)
-```julia
+ ```julia
boxplot(["one", "two"],
[[1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7, 8, 9]],
title="Grouped Boxplot", xlabel="x")
```
![Boxplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/boxplot2.png)
-
- Sparsity Pattern
+
-```julia
+
+ Sparsity Pattern
+
+ ```julia
using SparseArrays
spy(sprandn(50, 120, .05))
```
![Spy](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/spy1.png)
-Plotting the zeros pattern is also possible using `show_zeros=true`:
+ Plotting the zeros pattern is also possible using `show_zeros=true`:
-```julia
+ ```julia
using SparseArrays
spy(sprandn(50, 120, .9), show_zeros=true)
```
![Spy](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/spy2.png)
-
- Density Plot
+
+
+
+ Density Plot
-```julia
+ ```julia
plt = densityplot(randn(1_000), randn(1_000))
densityplot!(plt, randn(1_000) .+ 2, randn(1_000) .+ 2)
```
![Densityplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/densityplot1.png)
-
- Contour Plot
+
-```julia
+
+ Contour Plot
+
+ ```julia
contourplot(-3:.01:3, -7:.01:3, (x, y) -> exp(-(x / 2)^2 - ((y + 2) / 4)^2))
```
![Contourplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/contourplot1.png)
-The keyword `levels` controls the number of contour levels. One can also choose a `colormap` as with `heatmap`, and disable the colorbar using `colorbar=false`.
+ The keyword `levels` controls the number of contour levels. One can also choose a `colormap` as with `heatmap`, and disable the colorbar using `colorbar=false`.
+
- Heatmap Plot
+
+ Heatmap Plot
-```julia
+ ```julia
heatmap(repeat(collect(0:10)', outer=(11, 1)), zlabel="z")
```
![Heatmap](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/heatmap1.png)
-The `heatmap` function also supports axis scaling using the parameters `xfact`, `yfact` and axis offsets after scaling using `xoffset` and `yoffset`.
+ The `heatmap` function also supports axis scaling using the parameters `xfact`, `yfact` and axis offsets after scaling using `xoffset` and `yoffset`.
-The `colormap` parameter may be used to specify a named or custom colormap. See the `heatmap` function documentation for more details.
+ The `colormap` parameter may be used to specify a named or custom colormap. See the `heatmap` function documentation for more details.
-In addition, the `colorbar` and `colorbar_border` options may be used to toggle the colorbar and configure its border.
+ In addition, the `colorbar` and `colorbar_border` options may be used to toggle the colorbar and configure its border.
-The `zlabel` option and `zlabel!` method may be used to set the `z` axis (colorbar) label.
+ The `zlabel` option and `zlabel!` method may be used to set the `z` axis (colorbar) label.
-```julia
+ ```julia
heatmap(collect(0:30) * collect(0:30)', xfact=.1, yfact=.1, xoffset=-1.5, colormap=:inferno)
```
![Heatmap](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/heatmap2.png)
-
- Polar Plot
+
-Plots data in polar coordinates with `θ` the angles in radians.
+
+ Polar Plot
-```julia
+ Plots data in polar coordinates with `θ` the angles in radians.
+
+ ```julia
polarplot(range(0, 2π, length = 20), range(0, 2, length = 20))
```
![Polarplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/polarplot1.png)
@@ -262,117 +294,121 @@ polarplot(range(0, 2π, length = 20), range(0, 2, length = 20))
- Surface Plot
+
+ Surface Plot
-Plots a colored surface using height values `z` above a `x-y` plane, in three dimensions (masking values using `NaN`s is supported).
+ Plots a colored surface using height values `z` above a `x-y` plane, in three dimensions (masking values using `NaN`s is supported).
-```julia
+ ```julia
sombrero(x, y) = 15sinc(√(x^2 + y^2) / π)
surfaceplot(-8:.5:8, -8:.5:8, sombrero, colormap=:jet)
```
![Surfaceplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/surfaceplot1.png)
-Use `lines=true` to increase the density (underlying call to `lineplot` instead of `scatterplot`, with color interpolation). To plot a slice in 3D, use an anonymous function which maps to a constant value: `zscale=z -> a_constant`:
+ Use `lines=true` to increase the density (underlying call to `lineplot` instead of `scatterplot`, with color interpolation).
+ To plot a slice in 3D, use an anonymous function which maps to a constant value: `zscale=z -> a_constant`:
-```julia
+ ```julia
surfaceplot(
-2:2, -2:2, (x, y) -> 15sinc(√(x^2 + y^2) / π),
zscale=z -> 0, lines=true, colormap=:jet
)
```
![Surfaceplot](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/surfaceplot2.png)
-
- Isosurface Plot
+
-Uses [`MarchingCubes.jl`](https://github.com/JuliaGeometry/MarchingCubes.jl) to extract an isosurface, where `isovalue` controls the surface isovalue. Using `centroid` enables plotting the triangulation centroids instead of the triangle vertices (better for small plots). Back face culling (hide not visible facets) can be activated using `cull=true`. One can use the legacy 'Marching Cubes' algorithm using `legacy=true`.
+
+ Isosurface Plot
-```julia
+ Uses [`MarchingCubes.jl`](https://github.com/JuliaGeometry/MarchingCubes.jl) to extract an isosurface, where `isovalue` controls the surface isovalue.
+ Using `centroid` enables plotting the triangulation centroids instead of the triangle vertices (better for small plots).
+ Back face culling (hide not visible facets) can be activated using `cull=true`.
+ One can use the legacy 'Marching Cubes' algorithm using `legacy=true`.
+
+ ```julia
torus(x, y, z, r=0.2, R=0.5) = (√(x^2 + y^2) - R)^2 + z^2 - r^2
isosurface(-1:.1:1, -1:.1:1, -1:.1:1, torus, cull=true, zoom=2, elevation=50)
```
![Isosurface](https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs/2.10/isosurface.png)
-
+
+
## Documentation
- Installation
+
+ Installation
-To install UnicodePlots, start up `Julia` and type the following code snippet into the `REPL` (makes use of the native `Julia` package manager `Pkg`):
+ To install UnicodePlots, start up `Julia` and type the following code snippet into the `REPL` (makes use of the native `Julia` package manager `Pkg`):
```julia
julia> using Pkg
julia> Pkg.add("UnicodePlots")
```
-
-
- Saving figures
-Saving plots as `png` or `txt` files using the `savefig` command is supported (saving as `png` is experimental and resulting images might slightly change without warnings).
-
-To recover the plot as a string with ansi color codes use `string(p; color=true)`.
-
- Color mode
+
-When the `COLORTERM` environment variable is set to either `24bit` or `truecolor`, `UnicodePlots` will use [24bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit) as opposed to [8bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) or even [4bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit) for named colors.
+
+ Saving figures
-One can force a specific colormode using either `UnicodePlots.truecolors!()` or `UnicodePlots.colors256!()`.
+ Saving plots as `png` or `txt` files using the `savefig` command is supported (saving as `png` is experimental and resulting images might slightly change without warnings).
-Named colors such as `:red` or `:light_red` will use `256` color values (rendering will be terminal dependent). In order to force named colors to use true colors instead, use `UnicodePlots.USE_LUT[]=true`.
+ To recover the plot as a string with ansi color codes use `string(p; color=true)`.
+
-The default color cycle can be changed to bright (high intensity) colors using `UnicodePlots.brightcolors!()` instead of the default `UnicodePlots.faintcolors!()`.
+
+ Color mode
- 3D plots
+ When the `COLORTERM` environment variable is set to either `24bit` or `truecolor`, `UnicodePlots` will use [24bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit) as opposed to [8bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) or even [4bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit) for named colors.
-3d plots use a so-called "Model-View-Projection" transformation matrix `MVP` on input data to project 3D plots to a 2D screen.
+ One can force a specific colormode using either `UnicodePlots.truecolors!()` or `UnicodePlots.colors256!()`.
-Use keywords`elevation`, `azimuth`, `up` or `zoom` to control the "View" matrix, a.k.a., camera.
+ Named colors such as `:red` or `:light_red` will use `256` color values (rendering will be terminal dependent). In order to force named colors to use true colors instead, use `UnicodePlots.USE_LUT[]=true`.
-The `projection` type for `MVP` can be set to either `:perspective` or `:orthographic`.
+ The default color cycle can be changed to bright (high intensity) colors using `UnicodePlots.brightcolors!()` instead of the default `UnicodePlots.faintcolors!()`.
+
-Displaying the `x`, `y`, and `z` axes can be controlled using the `axes3d` keyword.
+
+ 3D plots
-For enhanced resolution, use a wider and/or taller `Plot` (this can be achieved using `default_size!(width=60)` for all future plots).
+ 3d plots use a so-called "Model-View-Projection" transformation matrix `MVP` on input data to project 3D plots to a 2D screen.
- Layout
+ Use keywords`elevation`, `azimuth`, `up` or `zoom` to control the "View" matrix, a.k.a., camera.
-`UnicodePlots` is integrated in [`Plots`](https://github.com/JuliaPlots/Plots.jl) as a backend, with support for [basic layout](https://docs.juliaplots.org/stable/gallery/unicodeplots/generated/unicodeplots-ref17).
+ The `projection` type for `MVP` can be set to either `:perspective` or `:orthographic`.
-For a more complex layout, use [`Term`](https://github.com/FedeClaudi/Term.jl):
+ Displaying the `x`, `y`, and `z` axes can be controlled using the `axes3d` keyword.
-```julia
-using UnicodePlots, Term
+ For enhanced resolution, use a wider and/or taller `Plot` (this can be achieved using `default_size!(width=60)` for all future plots).
+
-panel(plot; kw...) = Panel(string(plot, color=true); fit=true, kw...)
+
+ Layout
-print(
- panel(lineplot([cos, sin], -π/2, 2π); title="lineplot", style="yellow") *
- panel(contourplot(-3:.01:3, -7:.01:3, (x, y) -> exp(-(x / 2)^2 - ((y + 2) / 4)^2)); title="contourplot", style="red") *
- panel(surfaceplot(-8:.5:8, -8:.5:8, (x, y) -> 15sinc(√(x^2 + y^2) / π)); title="surfaceplot", style="blue") / (
- panel(histogram(randn(1_000_000), nbins=100, vertical=true); title="histogram", style="green") *
- panel(densityplot(randn(1_000), randn(1_000)); title="densityplot", style="cyan")
- )
-)
-```
+ `UnicodePlots` is integrated in [`Plots`](https://github.com/JuliaPlots/Plots.jl) as a backend, with support for [basic layout](https://docs.juliaplots.org/stable/gallery/unicodeplots/generated/unicodeplots-ref17).
+ For a more complex layout, use the [`grid`](https://fedeclaudi.github.io/Term.jl/dev/layout/grid) function from [`Term`](https://github.com/FedeClaudi/Term.jl).
- Know Issues
+
+ Know Issues
-Using a non `true monospace font` can lead to visual problems on a `BrailleCanvas` (border versus canvas).
+ Using a non `true monospace font` can lead to visual problems on a `BrailleCanvas` (border versus canvas).
-Either change the font to e.g. [JuliaMono](https://juliamono.netlify.app/) or use `border=:dotted` keyword argument in the plots.
+ Either change the font to e.g. [JuliaMono](https://juliamono.netlify.app/) or use `border=:dotted` keyword argument in the plots.
-For a `Jupyter` notebook with the `IJulia` kernel see [here](https://juliamono.netlify.app/faq/#can_i_use_this_font_in_a_jupyter_notebook_and_how_do_i_do_it).
+ For a `Jupyter` notebook with the `IJulia` kernel see [here](https://juliamono.netlify.app/faq/#can_i_use_this_font_in_a_jupyter_notebook_and_how_do_i_do_it).
-(Experimental) Terminals seem to respect a standard aspect ratio of `4:3`, hence a square matrix does not often look square in the terminal.
+ (Experimental) Terminals seem to respect a standard aspect ratio of `4:3`, hence a square matrix does not often look square in the terminal.
-You can pass the experimental keyword `fix_ar=true` to `spy` or `heatmap` in order to recover a unit aspect ratio.
+ You can pass the experimental keyword `fix_ar=true` to `spy` or `heatmap` in order to recover a unit aspect ratio.
+
- Methods (API)
+
+ Methods (API)
- - `title!(plot::Plot, title::String)`
+ - `title!(plot::Plot, title::String)`
- `title` the string to write in the top center of the plot window. If the title is empty the whole line of the title will not be drawn
@@ -418,11 +454,13 @@ The method `label!` is responsible for the setting all the textual decorations o
- `annotate!(plot::Plot, x::Number, y::Number, text::AbstractString; kw...)`
- `text` arbitrary annotation at position (x, y)
-
- Keywords description (API)
+
+
+
+ Keywords description (API)
-All plots support the set (or a subset) of the following named parameters:
+ All plots support the set (or a subset) of the following named parameters:
- `symbols::Array = ['■']`: characters used to render the bars.
- `title::String = ""`: text displayed on top of the plot.
@@ -506,11 +544,13 @@ All plots support the set (or a subset) of the following named parameters:
_Note_: If you want to print the plot into a file but have monospace issues with your font, you should probably try setting `border=:ascii` and `canvas=AsciiCanvas` (or `canvas=DotCanvas` for scatterplots).
-
- Low-level Interface
+
-The primary structures that do all the heavy lifting behind the curtain are subtypes of `Canvas`. A canvas is a graphics object for rasterized plotting. Basically, it uses Unicode characters to represent pixel.
+
+ Low-level Interface
+
+ The primary structures that do all the heavy lifting behind the curtain are subtypes of `Canvas`. A canvas is a graphics object for rasterized plotting. Basically, it uses Unicode characters to represent pixel.
Here is a simple example:
@@ -560,11 +600,13 @@ The following types of `Canvas` are implemented:
- **BarplotGraphics**:
This graphics area is special in that it does not support any pixel manipulation. It is essentially the barplot without decorations but the numbers. It does only support one method `addrow!` which allows the user to add additional bars to the graphics object.
-
- Documentation update
+
-The following snippet:
+
+ Documentation update
+
+ The following snippet:
```bash
$ cd docs
$ julia generate_docs.jl
@@ -572,7 +614,8 @@ $ (cd imgs; julia gen_imgs.jl)
```
will regenerate `README.md` and the example images with root (prefix) url https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs.
-
+
+
## License
@@ -581,3 +624,4 @@ This code is free to use under the terms of the MIT license.
## Acknowledgement
Inspired by [TextPlots.jl](https://github.com/sunetos/TextPlots.jl), which in turn was inspired by [Drawille](https://github.com/asciimoo/drawille).
+
diff --git a/docs/generate_docs.jl b/docs/generate_docs.jl
index bbbe4c11..517ba361 100644
--- a/docs/generate_docs.jl
+++ b/docs/generate_docs.jl
@@ -1,8 +1,10 @@
using UnicodePlots
using Markdown
+using Term
import Markdown: MD, Paragraph, plain
main() = begin
+ warn = "WARNING: this file has been automatically generated, please update UnicodePlots/docs/generate_docs.jl instead"
docs_url = "https://github.com/JuliaPlots/UnicodePlots.jl/raw/unicodeplots-docs"
ver = "2.10"
@@ -243,7 +245,7 @@ main() = begin
will regenerate `README.md` and the example images with root (prefix) url $(docs_url).
""")
- readme = plain(md"""
+ readme = plain_md_par("""
# UnicodePlots
[![License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](LICENSE.md)
@@ -255,7 +257,7 @@ main() = begin
Advanced [`Unicode`](https://en.wikipedia.org/wiki/Unicode) plotting library designed for use in `Julia`'s `REPL`.
-Physical quantities of [`Unitful.jl`](https://github.com/PainterQubits/Unitful.jl) are supported on a subset of plotting methods.
+![Banner]($docs_url/$ver/banner.png)
## High-level Interface
@@ -293,6 +295,9 @@ Here is a list of the main high-level functions for common scenarios:
Some plot methods have a mutating variant that ends with a exclamation mark:
$(examples.lineplot3)
+
+ Physical quantities of [`Unitful.jl`](https://github.com/PainterQubits/Unitful.jl) are supported on a subset of plotting methods.
+
@@ -490,23 +495,7 @@ Here is a list of the main high-level functions for common scenarios:
`UnicodePlots` is integrated in [`Plots`](https://github.com/JuliaPlots/Plots.jl) as a backend, with support for [basic layout](https://docs.juliaplots.org/stable/gallery/unicodeplots/generated/unicodeplots-ref17).
- For a more complex layout, use [`Term`](https://github.com/FedeClaudi/Term.jl):
-
-```julia
-using UnicodePlots, Term
-
-panel(plot; kw...) = Panel(string(plot, color=true); fit=true, kw...)
-
-print(
- panel(lineplot([cos, sin], -π/2, 2π); title="lineplot", style="yellow") *
- panel(contourplot(-3:.01:3, -7:.01:3, (x, y) -> exp(-(x / 2)^2 - ((y + 2) / 4)^2)); title="contourplot", style="red") *
- panel(surfaceplot(-8:.5:8, -8:.5:8, (x, y) -> 15sinc(√(x^2 + y^2) / π)); title="surfaceplot", style="blue") / (
- panel(histogram(randn(1_000_000), nbins=100, vertical=true); title="histogram", style="green") *
- panel(densityplot(randn(1_000), randn(1_000)); title="densityplot", style="cyan")
- )
-)
-```
-
+ For a more complex layout, use the [`grid`](https://fedeclaudi.github.io/Term.jl/dev/layout/grid) function from [`Term`](https://github.com/FedeClaudi/Term.jl).
@@ -557,47 +546,123 @@ Inspired by [TextPlots.jl](https://github.com/sunetos/TextPlots.jl), which in tu
""")
mkpath("imgs/$ver")
+
open("imgs/gen_imgs.jl", "w") do io
println(io, """
- # WARNING: this file has been automatically generated, please update UnicodePlots/docs/generate_docs.jl instead
- using UnicodePlots, StableRNGs, SparseArrays, Unitful
+ # $warn
+ using UnicodePlots, StableRNGs, SparseArrays, Unitful, Term
# UnicodePlots.brightcolors!()
include(joinpath(dirname(pathof(UnicodePlots)), "..", "test", "fixes.jl"))
+ cursor_hide(io::IO) = print(io, "\x1b[?25l")
+ cursor_show(io::IO) = print(io, "\x1b[?25h")
+
+ banner() = begin
+ default_size!(height=10)
+
+ panel(plt; kw...) = Panel(string(plt, color=true); fit=true, kw...)
+
+ panels = (
+ line = panel(lineplot(t -> exp(-.15t) * sinpi(.5t), xlabel="t", ylabel="y(t)", name = "decay"); title="lineplot", style="orange1"),
+ scat = panel(scatterplot(1:6, 1:6, xscale=:log10, yscale=:ln); title="scatterplot", style="yellow1"),
+ cont = panel(contourplot(-3:.01:3, -7:.01:3, (x, y) -> exp(-(x / 2)^2 - ((y + 2) / 4)^2)); title="contourplot", style="red1"),
+ surf = panel(surfaceplot(-8:.5:8, -8:.5:8, (x, y) -> 15sinc(√(x^2 + y^2) / π)); title="surfaceplot", style="royal_blue1"),
+ iso = panel(isosurface(-1:.1:1, -1:.1:1, -1:.1:1, (x, y, z) -> (√(x^2 + y^2) - 0.5)^2 + z^2 - 0.2^2, cull=true, zoom=2, elevation=50); title="isosurface", style="cornsilk1"),
+ vhist = panel(histogram(randn(1_000_000), nbins=60, vertical=true); title="vertical histogram", style="green1"),
+ hhist = panel(histogram(randn(1_000) .* 0.1, nbins=15); title="horizontal histogram", style="dodger_blue2"),
+ dens = panel(densityplot(randn(1_000), randn(1_000)); title="densityplot", style="cyan1"),
+ hmap = panel(heatmap(collect(0:20) * collect(0:20)', xfact=.1, yfact=.1); title="heatmap", style="magenta1"),
+ bar = panel(barplot(["Paris", "New York", "Madrid"], [2.244, 8.406, 3.165]); title="barplot", style="gold1"),
+ polar = panel(polarplot(range(0, 2π, length = 20), range(0, 2, length = 20)); title="polarplot", style="chartreuse1"),
+ box = panel(boxplot(["one", "two"], [collect(1:5), collect(4:9)]); title="boxplot", style="grey11"),
+ stair = panel(stairs([1, 2, 4, 7, 8], [1, 3, 4, 2, 2]); title="stair", style="aquamarine1"),
+ spy = panel(spy([1 -1 0; -1 2 1; 0 -1 1]); title="spy", style="salmon1"),
+ )
+ g = grid(panels, layout=:((line * scat * polar * stair) / (dens * cont * surf * iso) / (hhist * vhist * (bar / (box * spy)))))
+
+ if true
+ cursor_hide(stdout)
+ run(`clear`)
+ print(stdout, g)
+ win = if "WINDOWID" in keys(ENV)
+ ENV["WINDOWID"]
+ else
+ readchomp(`xdotool getactivewindow`)
+ end
+ run(`import -window \$win $ver/banner.png`)
+ cursor_show(stdout)
+ else
+ print(stdout, g)
+ open("$ver/banner.txt", "w") do io
+ print(io, g)
+ end
+ end
+ end
+
main() = begin
- rng = StableRNG(1337)
+ rng = StableRNG(1337)
+
+ bb = parse(Bool, get(ENV, "BB", "false")) ? 9 : nothing
+ bb_glyph = parse(Bool, get(ENV, "BB_GL", "false")) ? 8 : nothing
- bb = parse(Bool, get(ENV, "BB", "false")) ? 9 : nothing
- bb_glyph = parse(Bool, get(ENV, "BB_GL", "false")) ? 8 : nothing
+ banner()
"""
)
for (i, (k, e)) in enumerate(pairs(exs))
- println(io, "# $k")
+ println(io, " # $k")
code = filter(x -> length(x) != 0 && !startswith(lstrip(x), r"using|import"), [lstrip(c) for c in split(e[2], '\n')])
code = [replace(c, r"\bsprandn\b\(" => "_stable_sprand(rng, ", r"\brandn\b\(" => "randn(rng, ", r"\brand\b\(" => "rand(rng, ") for c in code]
println(io, """
- println("ex n°$i - $k")
- _ex_$i(rng) = begin
- $(indent(join(code, '\n'), 1))
- end
- plt = _ex_$i(rng)
- display(plt)
- savefig(plt, "$ver/$k.png"; transparent=false, bounding_box=bb, bounding_box_glyph=bb_glyph, pixelsize=16)
- # savefig(plt, "$ver/$k.txt"; color=true)
+ println("ex n°$i - $k")
+ default_size!()
+ _func_$i(rng) = begin
+ $(indent(join(code, '\n'), 1))
+ end
+ plt = _func_$i(rng)
+ display(plt)
+ savefig(plt, "$ver/$k.png"; transparent=false, bounding_box=bb, bounding_box_glyph=bb_glyph, pixelsize=16)
+ # savefig(plt, "$ver/$k.txt"; color=true)
"""
)
end
- println(io, "\nreturn\nend\nmain()")
+ println(io, " return\nend\nmain()")
end
write(stdout, readme)
open("../README.md", "w") do io
- write(io, "\n")
+ write(io, "\n")
write(io, readme)
end
return
end
main()
+
+#=
+open("imgs/gen_all.sh", "w") do io
+ write(io, """
+ #!/usr/bin/env bash
+ # $warn
+
+ echo '== julia =='
+ \${JULIA-julia} gen_imgs.jl
+
+ txt2png() {
+ html=\${1%.txt}.html
+ cat \$1 | \${ANSI2HTML-ansi2html} --input-encoding=utf-8 --output-encoding=utf-8 >\$html
+ sed -i "s,background-color: #000000,background-color: #282828," \$html
+ \${WKHTMLTOIMAGE-wkhtmltoimage} --quiet --quality 85 \$html \${html%.html}.png
+ }
+ echo '== txt2png =='
+ for f in $ver/*.txt; do
+ txt2png \$f & pids+=(\$!)
+ done
+ wait \${pids[@]}
+ rm $ver/*.txt
+ rm $ver/*.html
+ """
+ )
+end
+=#
\ No newline at end of file
diff --git a/src/canvas/braillecanvas.jl b/src/canvas/braillecanvas.jl
index 5471f6f3..ac4a79db 100644
--- a/src/canvas/braillecanvas.jl
+++ b/src/canvas/braillecanvas.jl
@@ -50,8 +50,8 @@ function BrailleCanvas(
xscale::Function = identity,
yscale::Function = identity,
)
- width > 0 || throw(ArgumentError("width has to be positive"))
- height > 0 || throw(ArgumentError("height has to be positive"))
+ width > 0 || throw(ArgumentError("`width` has to be positive"))
+ height > 0 || throw(ArgumentError("`height` has to be positive"))
char_width = max(char_width, 5)
char_height = max(char_height, 2)
pixel_width = char_width * x_pixel_per_char(BrailleCanvas)
@@ -75,14 +75,13 @@ function BrailleCanvas(
end
function pixel_to_char_point(c::BrailleCanvas, pixel_x::Number, pixel_y::Number)
+ cw, ch = size(c.grid)
pixel_x < c.pixel_width || (pixel_x -= 1)
pixel_y < c.pixel_height || (pixel_y -= 1)
- cw, ch = size(c.grid)
- tmp = pixel_x / c.pixel_width * cw
- char_x = floor(Int, tmp) + 1
- char_x_off = (pixel_x % 2) + 1
+ char_x = floor(Int, pixel_x / c.pixel_width * cw) + 1
+ char_x_off = (pixel_x % x_pixel_per_char(BrailleCanvas)) + 1
char_y = floor(Int, pixel_y / c.pixel_height * ch) + 1
- char_y_off = (pixel_y % 4) + 1
+ char_y_off = (pixel_y % y_pixel_per_char(BrailleCanvas)) + 1
char_x, char_y, char_x_off, char_y_off
end
diff --git a/src/canvas/dotcanvas.jl b/src/canvas/dotcanvas.jl
index b3fda498..19e17c29 100644
--- a/src/canvas/dotcanvas.jl
+++ b/src/canvas/dotcanvas.jl
@@ -9,17 +9,13 @@ DOT_DECODE[4] = ':'
DOT_DECODE[(N_DOT + 1):typemax(UInt16)] = UNICODE_TABLE[1:(typemax(UInt16) - N_DOT)]
"""
-Similar to the `AsciiCanvas`, the `DotCanvas` only uses
-ASCII characters to draw it's content. Naturally,
-it doesn't look quite as nice as the Unicode-based
-ones. However, in some situations it might yield
-better results. Printing plots to a file is one
-of those situations.
+Similar to the `AsciiCanvas`, the `DotCanvas` only uses ASCII characters to draw it's content.
+Naturally, it doesn't look quite as nice as the Unicode-based ones.
+However, in some situations it might yield better results.
+Printing plots to a file is one of those situations.
-The DotCanvas is best utilized in combination
-with `scatterplot`.
-For `lineplot` we suggest to use the `AsciiCanvas`
-instead.
+The DotCanvas is best utilized in combination with `scatterplot`.
+For `lineplot` we suggest to use the `AsciiCanvas` instead.
"""
struct DotCanvas{XS<:Function,YS<:Function} <: LookupCanvas
grid::Matrix{UInt16}
diff --git a/src/interface/polarplot.jl b/src/interface/polarplot.jl
index 832796df..4bfd3da1 100644
--- a/src/interface/polarplot.jl
+++ b/src/interface/polarplot.jl
@@ -28,24 +28,25 @@ $(arguments(
```julia-repl
julia> polarplot(range(0, 2π, length = 20), range(0, 2, length = 20))
- ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
- 2 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡤⠤⠒⠒⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠓⠒⠦⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
- ⠀⠀⠀⠀⠀⠀⠀⢀⡤⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠒⠤⡀⠀⠀⠀⠀⠀⠀⠀
- ⠀⠀⠀⠀⠀⡠⠞⠓⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠓⢄⠀⠀⠀⠀⠀
- ⠀⠀⠀⣠⠊⠀⠀⠀⠀⠉⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠁⠀⠀⠀⠱⣄⠀⠀⠀
- ⠀⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀⠑⠤⡀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⡠⠔⠁⠀⠀⠀⠀⠀⠀⠀⠈⢦⠀⠀
- ⠀⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣈⠶⢖⠒⠒⠒⠢⣇⡀⠀⠀⢀⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⠀
- ⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠉⠢⣀⠀⡇⢣⡠⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀
- ⠀⡧⠤⠤⠤⠤⠤⠤⠤⠤⢤⠧⠤⠤⠤⠤⠤⠤⠤⠤⡵⡷⡭⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼⠀
- ⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢀⠔⠊⠀⡇⠈⠒⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢿⠀
- ⠀⢱⡀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⢀⡠⠊⠁⠀⠀⠀⡇⠀⠀⠀⠉⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢎⡏⠀
- ⠀⠀⠳⡀⠀⠀⠀⠀⠀⠀⠀⠱⡠⠔⠁⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠑⠤⡀⠀⠀⠀⠀⠀⢀⠔⢁⠞⠀⠀
- ⠀⠀⠀⠙⢄⠀⠀⠀⠀⢀⠔⠊⠈⠢⣀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠈⠒⢄⢀⡠⠔⠁⡰⠋⠀⠀⠀
- ⠀⠀⠀⠀⠀⠑⢦⡠⠊⠁⠀⠀⠀⠀⠀⠉⠒⠢⢄⣀⠀⡇⠀⠀⠀⠀⠀⢀⣀⣀⡠⠔⠊⠉⢢⡤⠊⠀⠀⠀⠀⠀
- ⠀⠀⠀⠀⠀⠀⠀⠈⠓⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⡏⠉⠉⠉⠉⠉⠁⠀⠀⠀⣀⠤⠒⠁⠀⠀⠀⠀⠀⠀⠀
- -2 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⠒⠤⠤⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⡤⠤⠖⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
- ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
- ⠀-2⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀2⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀90°⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡤⠤⠒⠒⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠓⠒⠦⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⢀⡤⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠒⠤⡀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⡠⠞⠓⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜2⢄⠀⠀⠀⠀⠀
+ ⠀⠀⠀⣠⠊⠀⠀⠀⠀⠉⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠊⠁⠀⠀⠀⠱⣄⠀⠀⠀
+ ⠀⠀⡴⠁⠀⠀⠀⠀⠀⠀⠀⠀⠑⠤⡀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀1⠔⠁⠀⠀⠀⠀⠀⠀⠀⠈⢦⠀⠀
+ ⠀⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣈⠶⢖⠒⠒⠒⠢⣇⡀⠀⠀⢀⠔⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣇⠀
+ ⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠉⠢⣀⠀⡇⢣⡠⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀
+ 180° ⠀⡧⠤⠤⠤⠤⠤⠤⠤⠤⢤⠧⠤⠤⠤⠤⠤⠤⠤⠤⡵0⡭⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⢼⠀ 0°
+ ⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⢀⠔⠊⠀⡇⠈⠒⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢿⠀
+ ⠀⢱⡀⠀⠀⠀⠀⠀⠀⠀⠸⡀⠀⠀⢀⡠⠊⠁⠀⠀⠀⡇⠀⠀⠀⠉⠢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢎⡏⠀
+ ⠀⠀⠳⡀⠀⠀⠀⠀⠀⠀⠀⠱⡠⠔⠁⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠑⠤⡀⠀⠀⠀⠀⠀⢀⠔⢁⠞⠀⠀
+ ⠀⠀⠀⠙⢄⠀⠀⠀⠀⢀⠔⠊⠈⠢⣀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠈⠒⢄⢀⡠⠔⠁⡰⠋⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠑⢦⡠⠊⠁⠀⠀⠀⠀⠀⠉⠒⠢⢄⣀⠀⡇⠀⠀⠀⠀⠀⢀⣀⣀⡠⠔⠊⠉⢢⡤⠊⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠈⠓⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⡏⠉⠉⠉⠉⠉⠁⠀⠀⠀⣀⠤⠒⠁⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⠒⠤⠤⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⡤⠤⠖⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
+ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀270°⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
"""
function polarplot(θ::AbstractVector, 𝓇::Union{Function,AbstractVector}; kw...)
diff --git a/src/plot.jl b/src/plot.jl
index 3c823590..0d04c28a 100644
--- a/src/plot.jl
+++ b/src/plot.jl
@@ -643,7 +643,7 @@ function print_labels(
right_pad::AbstractString,
blank::Char,
)
- p.labels || return
+ p.labels || return 0
bc = BORDER_COLOR[]
lloc = Symbol(mloc, :l)
rloc = Symbol(mloc, :r)
@@ -668,8 +668,9 @@ function print_labels(
print_nc(io, pad)
print_col(io, right_col, right_str)
print_nc(io, right_pad)
+ return 1
end
- nothing
+ return 0
end
Base.show(io::IO, p::Plot) = _show(io, print, print_color, p)
@@ -740,7 +741,7 @@ function _show(io::IO, print_nc, print_col, p::Plot)
p_width = p_width,
color = io_color ? Crayon(foreground = :white, bold = true) : nothing,
)
- print_labels(
+ h_lbl = print_labels(
io,
print_nc,
print_col,
@@ -763,7 +764,7 @@ function _show(io::IO, print_nc, print_col, p::Plot)
)
# compute position of ylabel
- y_lab_row = round(nrows(c) / 2, RoundNearestTiesUp)
+ y_lab_row = round(nr / 2, RoundNearestTiesUp)
callback = colormap_callback(p.colormap)
@@ -832,7 +833,7 @@ function _show(io::IO, print_nc, print_col, p::Plot)
row < nrows(c) && print_nc(io, '\n')
end
- # draw bottom border and bottom labels
+ # draw bottom border
c.visible && print_border(
io,
print_nc,
@@ -843,9 +844,10 @@ function _show(io::IO, print_nc, print_col, p::Plot)
border_right_pad,
bmap,
)
- h_lbl = w_lbl = 0
+ # print bottom labels
+ w_lbl = 0
if p.labels
- print_labels(
+ h_lbl += print_labels(
io,
print_nc,
print_col,
@@ -856,7 +858,6 @@ function _show(io::IO, print_nc, print_col, p::Plot)
🗹 * border_right_pad,
🗹,
)
- h_lbl += 1
if !p.compact
h_w = print_title(
io,
@@ -893,6 +894,8 @@ fallback_font(mono::Bool = false) =
end
# COV_EXCL_STOP
+const FT_FONTS = Dict{String,FreeTypeAbstraction.FTFont}()
+
"""
png_image(p::Plot, font = nothing, pixelsize = 16, transparent = true, foreground = nothing, background = nothing, bounding_box = nothing, bounding_box_glyph = nothing)
@@ -1020,9 +1023,12 @@ function png_image(
# render image
face = nothing
- for font_name in filter(!isnothing, (font, "JuliaMono", fallback_font()))
- if (ft = FreeTypeAbstraction.findfont(font_name)) ≢ nothing
- face = ft
+ for name in filter(!isnothing, (font, "JuliaMono", fallback_font()))
+ if haskey(FT_FONTS, name)
+ face = FT_FONTS[name]
+ break
+ elseif (ft = FreeTypeAbstraction.findfont(name)) ≢ nothing
+ face = FT_FONTS[name] = ft
break
end
end