diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..69218aa8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +on: [push, pull_request] +name: CI +jobs: + build: + name: "Build on Racket '${{ matrix.racket-version }}' (${{ matrix.racket-variant }})" + runs-on: ubuntu-latest + strategy: + # Let all jobs run to completion -- this will allow us to determine if + # the failure is specific to a Racket version. + fail-fast: false + matrix: + racket-version: ["8.9", "current"] + racket-variant: ["BC", "CS"] + steps: + - uses: actions/checkout@v3.3.0 + - uses: Bogdanp/setup-racket@v1.10 + with: + architecture: x64 + distribution: minimal + variant: ${{ matrix.racket-variant }} + version: ${{ matrix.racket-version }} + dest: '${HOME}/racket' + sudo: never + + # Setup this source repository as a package catalog which has higher + # priority than the main catalog + + - run: ${HOME}/racket/bin/racket -l- pkg/dirs-catalog --link catalog . + - run: echo "file://`pwd`/catalog" > catalogs.txt + - run: ${HOME}/racket/bin/raco pkg config catalogs >> catalogs.txt + - run: ${HOME}/racket/bin/raco pkg config --set catalogs `cat catalogs.txt` + - run: ${HOME}/racket/bin/raco pkg config catalogs + + # Install plot and its dependencies. Since we installed minimal racket, + # this will fetch most of the packages from the main package catalog, + # except for the packages inside this directory, which have higher + # priority. + + - run: ${HOME}/racket/bin/raco pkg install --batch --auto plot + + # This runs any tests inside the plot, plot-lib, plot-gui-lib and + # plot-doc packages, but NOT the plot-test package. The actual tests + # are in the `plot-test` package, so we don't expect any tests here, but + # just in case someone wrote a test module... + + - run: xvfb-run ${HOME}/racket/bin/raco test --deps --package plot + + # Install the plot-test package and run the tests + + - run: ${HOME}/racket/bin/raco pkg install --batch --auto plot-test + - run: xvfb-run ${HOME}/racket/bin/raco test --package plot-test + + # If any of the plot-test tests failed, they will generate new draw step + # files and sample images. Upload these as an Github Actions Artifact, + # so they can be inspected by the developer. + + - uses: actions/upload-artifact@v3.1.2 + if: failure() + with: + name: New Test Data Files ${{ matrix.racket-version }} ${{ matrix.racket-variant }} + path: plot-test/plot/tests/**/test-data/new-* diff --git a/.github/workflows/resyntax-analyze.yml b/.github/workflows/resyntax-analyze.yml new file mode 100644 index 00000000..8f132da2 --- /dev/null +++ b/.github/workflows/resyntax-analyze.yml @@ -0,0 +1,53 @@ +name: Resyntax Analysis + +# The Resyntax integration is split into two phases: a workflow that analyzes the code and uploads +# the analysis as an artifact, and a workflow that downloads the analysis artifact and creates a +# review of the pull request. This split is for permissions reasons; the analysis workflow checks out +# the pull request branch and compiles it, executing arbitrary code as it does so. For that reason, +# the first workflow has read-only permissions in the github repository. The second workflow only +# downloads the pull request review artifact and submits it, and it executes with read-write permissions +# without executing any code in the repository. This division of responsibilities allows Resyntax to +# safely analyze pull requests from forks. This strategy is outlined in the following article: +# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - ready_for_review + +jobs: + analyze: + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: Checkout code + uses: actions/checkout@v3.3.0 + # See https://github.com/actions/checkout/issues/118. + with: + fetch-depth: 0 + - name: Install Racket + uses: Bogdanp/setup-racket@v1.9.1 + with: + version: current + distribution: minimal + local_catalogs: $GITHUB_WORKSPACE + dest: '"${HOME}/racketdist-minimal-CS"' + sudo: never + - name: Register local packages + run: raco pkg install --auto --no-setup plot plot-compat plot-doc plot-gui-lib plot-lib plot-test + - name: Install local packages + run: raco setup --pkgs plot plot-compat plot-doc plot-gui-lib plot-lib plot-test + - name: Install Resyntax + run: raco pkg install --auto resyntax + - name: Analyze changed files + run: xvfb-run racket -l- resyntax/cli analyze --local-git-repository . "origin/${GITHUB_BASE_REF}" --output-as-github-review --output-to-file ./resyntax-review.json + - name: Upload analysis artifact + uses: actions/upload-artifact@v3.1.2 + with: + name: resyntax-review + path: resyntax-review.json diff --git a/.github/workflows/resyntax-submit-review.yml b/.github/workflows/resyntax-submit-review.yml new file mode 100644 index 00000000..5cb99944 --- /dev/null +++ b/.github/workflows/resyntax-submit-review.yml @@ -0,0 +1,56 @@ +name: Resyntax Review Submission + +# The Resyntax integration is split into two workflows. See ./resyntax-analyze.yml for details about +# why it works this way. + +on: + workflow_run: + workflows: ["Resyntax Analysis"] + types: + - completed + +jobs: + review: + runs-on: ubuntu-latest + if: > + ${{ github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v3.3.0 + - name: Download Resyntax analysis + # This uses a github script instead of the download-artifact action because + # that action doesn't work for artifacts uploaded by other workflows. See + # https://github.com/actions/download-artifact/issues/130 for more info. + uses: actions/github-script@v6.4.0 + with: + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{github.event.workflow_run.id}}, + }); + var matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "resyntax-review" + })[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/resyntax-review.zip', Buffer.from(download.data)); + - run: unzip resyntax-review.zip + - name: Create pull request review + uses: actions/github-script@v6.4.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var create_review_request = require('./resyntax-review.json'); + await github.rest.pulls.createReview(create_review_request); diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a2147765 --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +This component of Racket is distributed under the under the Apache 2.0 +and MIT licenses. The user can choose the license under which they +will be using the software. There may be other licenses within the +distribution with which the user must also comply. + +See the files + https://github.com/racket/racket/blob/master/racket/src/LICENSE-APACHE.txt +and + https://github.com/racket/racket/blob/master/racket/src/LICENSE-MIT.txt +for the full text of the licenses. diff --git a/README.md b/README.md new file mode 100644 index 00000000..7bdf4c6b --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +![](plot-test/plot/tests/test-data/is-2.png) + +This is the source code for the Racket "plot" package which used to make 2D +and 3D plots. This package is included in the +[Racket](https://racket-lang.org/) installation, so, if you installed Racket, +you can use it straight away. Open DrRacket and type in the follwing in the +command window: + +```racket +(require plot) +(plot (function sin -5 5)) +``` + +## To Get Help + +* The [Plot Documentation](https://docs.racket-lang.org/plot/index.html) shows + how to use the package. +* The [Plot Cookbook](https://github.com/Racket-Cookbooks/Plot-cookbook) + contains more plot examples. +* The [Racket Discourse](https://racket.discourse.group/) group can be used + for questions and assistance. +* The [Issue Tracker](https://github.com/racket/plot/issues) can be used for + reporting bugs or feature requests. + +## Contributing + +You can contribute to this package by creating a pull request, but we +recommend joining the [Racket Discourse](https://racket.discourse.group/) +group to discuss the features you plan to add or bugs you intend to fix. Other +Racket developers may be able to assist you with advice and providing links to +the relevant pieces of code. + +By making a contribution, you are agreeing that your contribution is licensed +under the [Apache 2.0] license and the [MIT] license. + +## License + +Racket, including these packages, is free software, see [LICENSE] for more +details. + +[MIT]: https://github.com/racket/racket/blob/master/racket/src/LICENSE-MIT.txt +[Apache 2.0]: https://www.apache.org/licenses/LICENSE-2.0.txt +[LICENSE]: LICENSE diff --git a/plot-compat/LICENSE.txt b/plot-compat/LICENSE.txt deleted file mode 100644 index dbb89375..00000000 --- a/plot-compat/LICENSE.txt +++ /dev/null @@ -1,11 +0,0 @@ -plot -Copyright (c) 2010-2014 PLT Design Inc. - -This package is distributed under the GNU Lesser General Public -License (LGPL). This means that you can link this package into proprietary -applications, provided you follow the rules stated in the LGPL. You -can also modify this package; if you distribute a modified version, -you must distribute it under the terms of the LGPL, which in -particular means that you must release the source code for the -modified software. See http://www.gnu.org/copyleft/lesser.html -for more information. diff --git a/plot-compat/info.rkt b/plot-compat/info.rkt index 5f70c7a9..c6909f4a 100644 --- a/plot-compat/info.rkt +++ b/plot-compat/info.rkt @@ -13,3 +13,8 @@ (define pkg-desc "Compatibility library for Plot 5.1.3 and earlier") (define pkg-authors '(ntoronto)) + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT)) diff --git a/plot-compat/plot/info.rkt b/plot-compat/plot/info.rkt index e0c94f27..adaa196e 100644 --- a/plot-compat/plot/info.rkt +++ b/plot-compat/plot/info.rkt @@ -1 +1,2 @@ #lang info +(define test-responsibles '((all AlexHarsanyi@gmail.com))) diff --git a/plot-compat/plot/private/compat.rkt b/plot-compat/plot/private/compat.rkt index 188c7d2c..f2a9105f 100644 --- a/plot-compat/plot/private/compat.rkt +++ b/plot-compat/plot/private/compat.rkt @@ -165,7 +165,7 @@ (define bm (make-bitmap (ceiling width) (ceiling height))) (define dc (make-object bitmap-dc% bm)) (define area (make-object 2d-plot-area% - bounds-rect x-ticks x-ticks y-ticks y-ticks dc 0 0 width height)) + bounds-rect x-ticks x-ticks y-ticks y-ticks '() dc 0 0 width height #f)) (define data+axes (mix x-axis-data y-axis-data data)) @@ -214,7 +214,7 @@ (define bm (make-bitmap (ceiling width) (ceiling height))) (define dc (make-object bitmap-dc% bm)) (define area (make-object 3d-plot-area% - bounds-rect x-ticks x-ticks y-ticks y-ticks z-ticks z-ticks dc 0 0 width height)) + bounds-rect x-ticks x-ticks y-ticks y-ticks z-ticks z-ticks '() dc 0 0 width height #f)) (send area start-plot) (send area start-renderer bounds-rect) diff --git a/plot-doc/LICENSE.txt b/plot-doc/LICENSE.txt deleted file mode 100644 index dbb89375..00000000 --- a/plot-doc/LICENSE.txt +++ /dev/null @@ -1,11 +0,0 @@ -plot -Copyright (c) 2010-2014 PLT Design Inc. - -This package is distributed under the GNU Lesser General Public -License (LGPL). This means that you can link this package into proprietary -applications, provided you follow the rules stated in the LGPL. You -can also modify this package; if you distribute a modified version, -you must distribute it under the terms of the LGPL, which in -particular means that you must release the source code for the -modified software. See http://www.gnu.org/copyleft/lesser.html -for more information. diff --git a/plot-doc/info.rkt b/plot-doc/info.rkt index 3036ede9..ba75e2b7 100644 --- a/plot-doc/info.rkt +++ b/plot-doc/info.rkt @@ -19,10 +19,17 @@ "scribble-lib" "slideshow-doc" "slideshow-lib" - "srfi-doc")) + "srfi-doc" + "math-lib" + "math-doc")) (define update-implies '("plot-lib")) (define pkg-desc "Documentation for plot") (define pkg-authors '(ntoronto)) + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT)) diff --git a/plot-doc/plot/scribblings/common.rkt b/plot-doc/plot/scribblings/common.rkt index f93e3cc4..67374d69 100644 --- a/plot-doc/plot/scribblings/common.rkt +++ b/plot-doc/plot/scribblings/common.rkt @@ -6,7 +6,9 @@ pict db plot - plot/utils + (except-in plot/utils sample) ; need the one from math/distributions + plot/snip + math/distributions (only-in racket/sequence sequence/c))) (provide (all-defined-out) @@ -16,7 +18,9 @@ pict db plot - plot/utils) + plot/snip + plot/utils + math/distributions) sequence/c)) (require (for-syntax racket/base @@ -24,6 +28,7 @@ racket/syntax) (prefix-in s. scribble/manual) (only-in racket/contract any/c) + (only-in racket/format ~a) (for-label (only-in racket/contract any/c))) (define (author-email) "neil.toronto@gmail.com") @@ -35,8 +40,58 @@ (eval '(begin (require racket/math racket/match racket/list racket/draw racket/class plot/pict - plot/utils))) + plot/utils + math/distributions))) eval)) (define (close-plot-eval) (close-eval plot-eval)) + +(require plot/no-gui plot/utils pict racket/match racket/class racket/draw) +(define (pretty-print-color-maps (width 400) (height 30)) + (define cm-names + (sort (color-map-names) + (lambda (a b) + (string<=? (symbol->string a) (symbol->string b))))) + (define cm-labels + (for/list ([cm cm-names]) + (text (symbol->string cm) null 16))) + (define cm-picts + (for/list ([cm cm-names]) + (parameterize ([plot-pen-color-map cm]) + (define w (/ width (color-map-size cm))) + (apply + hc-append 0 + (for/list ([c (in-range (color-map-size cm))]) + (match-define (list r g b) (->pen-color c)) + (define color (make-object color% r g b)) + (filled-rectangle w height #:draw-border? #f #:color color)))))) + (define picts + (let loop ([result '()] + [labels cm-labels] + [picts cm-picts]) + (if (null? labels) + (reverse result) + (loop (cons (car picts) (cons (car labels) result)) + (cdr labels) + (cdr picts))))) + (table 2 picts lc-superimpose cc-superimpose 15 3)) + +(define (pretty-print-known-point-symbols) + (define num-rows 3) + (define yoffset 4) + + (parameterize ([plot-width 800] + [plot-height 600] + [plot-decorations? #f]) + (plot-pict + (for/list ([s (in-list (sort known-point-symbols symbolpen-style). } +@defthing[plot-pen-cap/c contract? #:value (one-of/c 'round 'projecting 'butt)]{ + + The contract for caps, or line endings, for lines drawn on the plot. Used + by the @racket[plot-line-cap] and @racket[line-cap] parameters. + + @history[#:added "8.10"] + +} + @defthing[plot-brush-style/c contract? #:value (or/c exact-integer? (one-of/c 'transparent 'solid 'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch @@ -78,7 +133,16 @@ from @racketmodname[racket/draw]. } @defthing[point-sym/c contract? #:value (or/c char? string? integer? (apply one-of/c known-point-symbols))]{ -The contract for the @(racket #:sym) arguments in @(racket points) and @(racket points3d), and the parameter @(racket point-sym). + +The contract for the @(racket #:sym) arguments in @(racket points) and +@(racket points3d), and the parameter @(racket point-sym). + +Characters and strings will render that character or string for each point on +the plot, one of the symbols in @racket[known-point-symbols] will render the +corresponding symbol, while an integer value represents an index into the +@racket[known-point-symbols] list, this can be used to automatically generate +distinct symbols for different point renderers by incrementing a number. + } @defthing[known-point-symbols (listof symbol?) @@ -102,10 +166,20 @@ The contract for the @(racket #:sym) arguments in @(racket points) and @(racket 'circle7 'circle8 'bullet 'fullcircle1 'fullcircle2 'fullcircle3 'fullcircle4 'fullcircle5 'fullcircle6 - 'fullcircle7 'fullcircle8)]{ -A list containing the symbols that are valid @(racket points) symbols. + 'fullcircle7 'fullcircle8 'none)]{ + +A list containing the symbols that are valid @(racket points) symbols, the +rendering of each symbol is shown below. + +@centered{@(pretty-print-known-point-symbols)} + } +@defthing[plot-file-format/c contract? #:value (or/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg)]{ + A contract for an argument that describes an image file format. +} + + @section{Appearance Argument List Contracts} @defproc[(maybe-function/c [in-contract contract?] [out-contract contract?]) @@ -183,7 +257,7 @@ Like @(racket plot-colors/c), but for fill styles. Like @(racket plot-colors/c), but for opacities. } -@defproc[(labels/c [in-contract contract?]) contract? #:value (maybe-function/c in-contract (listof (or/c string? #f)))]{ +@defproc[(labels/c [in-contract contract?]) contract? #:value (maybe-function/c in-contract (listof (or/c string? pict? #f)))]{ Like @racket[plot-colors/c], but for strings. This is used, for example, to label @racket[stacked-histogram]s. } diff --git a/plot-doc/plot/scribblings/params.scrbl b/plot-doc/plot/scribblings/params.scrbl index 8cebb048..7f23121c 100644 --- a/plot-doc/plot/scribblings/params.scrbl +++ b/plot-doc/plot/scribblings/params.scrbl @@ -39,6 +39,29 @@ If @(racket #t), @(racket plot-file) and @(racket plot3d-file) open a dialog whe @section{General Appearance} +@defparam[plot-aspect-ratio ratio (or/c (and/c rational? positive?) #f) #:value #f]{ + + Controls the aspect ratio of the plot area, independently from the width and + height of the entire plot. + + When the aspect ratio is @(racket #f), the plot area fill fill the entire + area of the plot, leaving room only for the axis labels and title. + + When an aspect ratio is a positive number, the plot area will maintain this + aspect ratio, possibly leaving empty areas around the plot. + + This feature is useful when the aspect ratio needs to be maintained for the + plot output to look correct, for example when plotting a circle: + + @interaction[#:eval plot-eval + (parameterize ([plot-aspect-ratio 1/1] + [plot-background "lightyellow"]) + (plot (polar (lambda (t) 1)) #:width 400 #:height 200))] + + @history[#:added "8.1"] + +} + @deftogether[((defparam plot-title title (or/c string? #f) #:value #f) (defparam plot-x-label label (or/c string? #f) #:value "x axis") (defparam plot-y-label label (or/c string? #f) #:value "y axis") @@ -77,6 +100,44 @@ Used as default keyword arguments of plotting procedures such as @racket[plot3d] Amount of ambient light, and whether 3D plots are rendered with diffuse and specular reflectance. } +@defparam[plot-line-width width (>=/c 0) #:value 1]{ + The width of the lines used to draw plot axes and other non-renderer + elements. + + The line width for plot renderers, such as @racket[function] and + @racket[lines], is controlled by the @racket[line-width] parameter. +} + +@defparam[plot-line-cap cap plot-pen-cap/c #:value 'round]{ + + The cap of the lines used to draw plot axes and other non-renderer elements. + See also @racket[line-cap]. + + @history[#:added "8.10"] + +} + +@defparam[plot-inset inset (or/c (>=/c 0) (list (>=/c 0) (>=/c 0) (>=/c 0) (>=/c 0))) #:value 0]{ + + The amount of space around the plot to leave unused, when calculating plot + layouts for ticks and axis labels. The parameter can be specified as a + single value, which applies to all sides of the plot image, or as a list of + four separate values for the left, right, top, and bottom margins of the + plot image. + + One example use for this parameter is to avoid clipping tick marks when + lines for plot elements are very thick, see @racket[plot-line-width] and + @racket[line-width]. In such a case, the end of axis ticks can be drawn + beyond the end point of the line, and might be clipped at the edge of the + drawing region. A non-zero @racket[plot-inset] value can be used to avoid + this clipping. + + See also @racket[plot-legend-padding] for an equivalent setting for the plot + legend. + + @history[#:added "8.11"] +} + @deftogether[((defparam plot-foreground color plot-color/c #:value 0) (defparam plot-background color plot-color/c #:value 0))]{ The plot foreground and background color. @@ -95,10 +156,51 @@ The opacity of the background and foreground colors. The font size (in drawing units), face, and family of the title, axis labels, tick labels, and other labels. } -@deftogether[((defparam plot-legend-anchor anchor anchor/c #:value 'top-left) +@deftogether[((defparam plot-legend-font-size size (or/c (>=/c 0) #f) #:value #f) + (defparam plot-legend-font-face face (or/c string? #f) #:value #f) + (defparam plot-legend-font-family family (or/c font-family/c #f) #:value #f))]{ +The font size (in drawing units), face, and family to prefer for the legend text. If set to @racket[#f], then the corresponding @racket[plot-font-X] parameter is used. +} + +@deftogether[((defparam plot-legend-anchor legend-anchor legend-anchor/c #:value 'top-left) (defparam plot-legend-box-alpha alpha (real-in 0 1) #:value 2/3))]{ The placement of the legend and the opacity of its background. } +@defparam[plot-legend-layout layout (list/c (or/c 'columns 'rows) positive-integer? (or/c 'equal-size 'compact)) #:value '(columns 1 equal-size)]{ +Defines the way in which individual entries are placed in the legend. This is a list of three + elements: +@itemlist[@item{the placement direction (@racket['columns] or @racket['rows])} + @item{the number of columns or rows} + @item{whether all the entries will have the same size (@racket['equal-size]), + or the entries will only occupy the minimum size (@racket['compact])}] + +For example, the value @racket['(columns 1 equal-size)] will place the legend entries vertically from + top to bottom and all entries will have the same height. A value of @racket['(rows 2 'compact)] will + place legend entries horizontally on two rows -- this type of layout is useful when the legend is + placed at the top or bottom of the plot. + +@history[#:added "7.9"] +} + +@defparam[plot-legend-padding padding (or/c (>=/c 0) (list (>=/c 0) (>=/c 0) (>=/c 0) (>=/c 0))) #:value 0]{ + + The amount of space to add between the legend entries and the border drawn + around the legend. The parameter can be specified as a single value, which + applies to all sides, or as a list of four separate values for the left, + right, top, and bottom sides of the legend. + + One example use for this parameter is to avoid clipping thick lines used in + legend entries, see @racket[plot-line-width] and @racket[line-width]. In + such a case, the end of the lines can be drawn outside the border of the + legend, a non-zero @racket[plot-legend-padding] value can be used to avoid + this situation. + + See also @racket[plot-inset] for a similar setting for the entire plot + image. + + @history[#:added "8.11"] +} + @defparam[plot-tick-size size (>=/c 0) #:value 10]{ The length of tick lines, in drawing units. @@ -136,6 +238,16 @@ When any of these is @racket[#f], the corresponding axis is not drawn. Use these along with @racket[x-axis] and @racket[y-axis] renderers if you want axes that intersect the origin or some other point. } +@deftogether[((defparam plot-x-tick-labels? draw? boolean? #:value #t) + (defparam plot-y-tick-labels? draw? boolean? #:value #t) + (defparam plot-z-tick-labels? draw? boolean? #:value #t) + (defparam plot-x-far-tick-labels? draw? boolean?) + (defparam plot-y-far-tick-labels? draw? boolean?) + (defparam plot-z-far-tick-labels? draw? boolean?))]{ +When any of these is @racket[#f], the corresponding labels for the ticks on the axis are not drawn. +These parameters work together with the parameters like @racket[plot-x-axis?] that control the drawing of the axes; i.e. tick labels won't be drawn unless the axis itself is drawn. +} + @defparam[plot-animating? animating? boolean? #:value #f]{ When @(racket #t), certain renderers draw simplified plots to speed up drawing. @(plot-name) sets it to @(racket #t), for example, when a user is clicking and dragging a 3D plot to rotate it. @@ -151,6 +263,34 @@ This returns @racket[samples] when @racket[plot-animating?] is @racket[#f]. When @(racket #f), axes, axis labels, ticks, tick labels, and the title are not drawn. } +@deftogether[((defparam plot-pen-color-map name (or/c symbol? #f) #:value #f) + (defparam plot-brush-color-map name (or/c symbol? #f) #:value #f))]{ + +Specify the color maps to be used by @racket[->pen-color] and +@racket[->brush-color] respectively, for converting integer values into RGB +triplets, or when integer values are used with the @racket[#:color] keyword of +various plot renderers. You can determine the list of available color map +names using @racket[color-map-names]. + +If @racket[name] is not a valid color map name, the internal color map will be +used, this is the same as specifying @racket[#f]. + +When the color map value is set to @racket[#f], internal color maps will be +used, one for pen and one for brush colors. The internal color map used for +pen colors has darker and more saturated colors than the one used for brush +colors. These colors are chosen for good pairwise contrast, especially +between neighbors and they repeat starting with @(racket 128). + +The color maps available by default are shown below and additional ones can be +added using @racket[register-color-map]: + +@centered{@(pretty-print-color-maps)} + +@history[#:added "7.3"] + +} + + @section{Lines} @defparam[line-samples n (and/c exact-integer? (>=/c 2)) #:value 500]{ @@ -164,11 +304,21 @@ Used as a default keyword argument in @racket[function], @racket[inverse], @rack @deftogether[((defparam line-color color plot-color/c #:value 1) (defparam line-width width (>=/c 0) #:value 1) (defparam line-style style plot-pen-style/c #:value 'solid) + (defparam line-cap cap plot-pen-cap/c #:value 'round) (defparam line-alpha alpha (real-in 0 1) #:value 1))]{ -The pen color, pen width, pen style and opacity of lines in plots. -Used as default keyword arguments of @racket[function], @racket[inverse], @racket[lines], -@racket[parametric], @racket[polar], @racket[density], @racket[isoline], @racket[lines3d], -@racket[parametric3d] and @racket[isoline3d]. + + The pen color, pen width, pen style, pen cap and opacity of lines in plots. + + Except for @racket[line-cap], all other parameters are used as default + keyword arguments of @racket[function], @racket[inverse], @racket[lines], + @racket[parametric], @racket[polar], @racket[density], @racket[isoline], + @racket[lines3d], @racket[parametric3d] and @racket[isoline3d]. + + The @racket[line-cap] parameter applies to lines drawn by renderers in a + plot. See also @racket[plot-line-cap]. + + @history[#:added "8.10"] + } @section{Intervals} @@ -224,7 +374,7 @@ Used as default keyword arguments of @racket[point-label], @racket[function-labe @racket[inverse-label], @racket[parametric-label], @racket[polar-label] and @racket[point-label3d]. } -@section{Vector Fields} +@section{Vector Fields & Arrows} @deftogether[((defparam vector-field-samples n exact-positive-integer? #:value 20) (defparam vector-field3d-samples n exact-positive-integer? #:value 9))]{ @@ -239,6 +389,22 @@ The default number of samples @racket[vector-field] and @racket[vector-field3d] The default pen color, pen width, pen style, scaling factor, and opacity used by @racket[vector-field] and @racket[vector-field3d]. } +@deftogether[((defparam arrows-color color plot-color/c #:value 1) + (defparam arrows-line-width width (>=/c 0) #:value 2/3) + (defparam arrows-line-style style plot-pen-style/c #:value 'solid) + (defparam arrows-alpha alpha (real-in 0 1) #:value 1))]{ +The default pen color, pen width, pen style, and opacity used by +@racket[arrows] and @racket[arrows3d]. +@history[#:added "7.9"] +} + +@deftogether[((defparam arrow-head-size-or-scale size (or/c (>=/c 0) (list/c '= (>=/c 0))) #:value 2/5) + (defparam arrow-head-angle alpha (>=/c 0) #:value (/ pi 6)))]{ +The default size and angle of the arrow head in @racket[vector-field], @racket[vector-field3d], @racket[arrows] and @racket[arrows3d]. +When the @racket[arrow-head-size-or-scale] is a number, it is interpreted as a proportion of the arrow length , and will be bigger for longer arrows. When it is in the form @racket[(list '= size)], it is interpreted as the size of the arrow head in drawing units (pixels). +@history[#:added "7.9"] +} + @section{Error Bars} @@ -258,14 +424,22 @@ The default width, pen color/width/style, and opacity used by @racket[error-bars (defparam candlestick-line-width pen-width (>=/c 0) #:value 1) (defparam candlestick-line-style pen-style plot-pen-style/c #:value 'solid) (defparam candlestick-alpha alpha (real-in 0 1) #:value 2/3))]{ -The default width, pen color/width/style, and opacity used by @racket[candlesticks]. Both the up (a candle whose -open value is lower than its close value) color and the down (a candle whose open value is higher than its close -value) color can be specified independently. The width parameter will be important to specify if your x-axis is -in units like days, weeks, or months. Because dates are actually represented as seconds from an epoch, your -width should take that into consideration. For example, a width of 86400 may be useful for x-axis values in days +The default width, pen color/width/style, and opacity used by @racket[candlesticks]. Both the up (a candle whose +open value is lower than its close value) color and the down (a candle whose open value is higher than its close +value) color can be specified independently. The width parameter will be important to specify if your x-axis is +in units like days, weeks, or months. Because dates are actually represented as seconds from an epoch, your +width should take that into consideration. For example, a width of 86400 may be useful for x-axis values in days as there are 86400 seconds in a day. This candle will be exactly one day in width. } +@section{Color fields} + +@deftogether[((defparam color-field-samples n exact-positive-integer? #:value 20) + (defparam color-field-alpha alpha (real-in 0 1) #:value 1))]{ +The default sample rate and opacity used by @racket[color-field]. +@history[#:added "7.9"] +} + @section{Contours and Contour Intervals} @deftogether[( diff --git a/plot-doc/plot/scribblings/plotting.scrbl b/plot-doc/plot/scribblings/plotting.scrbl index 99cb4114..eb370934 100644 --- a/plot-doc/plot/scribblings/plotting.scrbl +++ b/plot-doc/plot/scribblings/plotting.scrbl @@ -25,13 +25,14 @@ Each 3D plotting procedure behaves the same way as its corresponding 2D procedur [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] [#:width width exact-positive-integer? (plot-width)] [#:height height exact-positive-integer? (plot-height)] - [#:title title (or/c string? #f) (plot-title)] - [#:x-label x-label (or/c string? #f) (plot-x-label)] - [#:y-label y-label (or/c string? #f) (plot-y-label)] - [#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)] + [#:title title (or/c string? pict? #f) (plot-title)] + [#:x-label x-label (or/c string? pict? #f) (plot-x-label)] + [#:y-label y-label (or/c string? pict? #f) (plot-y-label)] + [#:aspect-ratio aspect-ratio (or/c (and/c rational? positive?) #f) (plot-aspect-ratio)] + [#:legend-anchor legend-anchor legend-anchor/c (plot-legend-anchor)] [#:out-file out-file (or/c path-string? output-port? #f) #f] - [#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto] - ) (or/c (is-a?/c snip%) void?)]{ + [#:out-kind out-kind plot-file-format/c 'auto] + ) (or/c (and/c (is-a?/c snip%) (is-a?/c plot-metrics<%>)) void?)]{ Plots a 2D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points), @(racket function), @(racket contours), @(racket discrete-histogram), and others. By default, @(racket plot) produces a Racket value that is displayed as an image and can be manipulated like any other value. @@ -51,6 +52,9 @@ When @(racket #:out-file) is given, @(racket plot) writes the plot to a file usi When given, the @(racket x-min), @(racket x-max), @(racket y-min) and @(racket y-max) arguments determine the bounds of the plot, but not the bounds of the renderers. For example, +When given, the @(racket aspect-ratio) argument defines the aspect ratio of +the plot area, see @(racket plot-aspect-ratio) for more details. + @interaction[#:eval plot-eval (plot (function (λ (x) (sin (* 4 x))) -1 1) #:x-min -1.5 #:x-max 1.5 #:y-min -1.5 #:y-max 1.5)] @@ -60,6 +64,9 @@ Here, the renderer draws in [-1,1] × [-1,1], but the plot area is [-1.5,1.5] × @bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future. Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments. The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing. + +@history[#:changed "7.9" "Added support for pictures for #:title, #:x-label and #:y-label. And to plot the legend outside the plot-area with #:legend-anchor"] +@history[#:changed "8.1" "Added #:aspect-ratio"] } @defproc[(plot3d [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] @@ -70,14 +77,15 @@ The @(racket #:lncolor) keyword argument is also accepted for backward compatibi [#:height height exact-positive-integer? (plot-height)] [#:angle angle real? (plot3d-angle)] [#:altitude altitude real? (plot3d-altitude)] - [#:title title (or/c string? #f) (plot-title)] - [#:x-label x-label (or/c string? #f) (plot-x-label)] - [#:y-label y-label (or/c string? #f) (plot-y-label)] - [#:z-label z-label (or/c string? #f) (plot-z-label)] - [#:legend-anchor legend-anchor anchor/c (plot-legend-anchor)] + [#:title title (or/c string? pict? #f) (plot-title)] + [#:x-label x-label (or/c string? pict? #f) (plot-x-label)] + [#:y-label y-label (or/c string? pict? #f) (plot-y-label)] + [#:z-label z-label (or/c string? pict? #f) (plot-z-label)] + [#:aspect-ratio aspect-ratio (or/c (and/c rational? positive?) #f) (plot-aspect-ratio)] + [#:legend-anchor legend-anchor legend-anchor/c (plot-legend-anchor)] [#:out-file out-file (or/c path-string? output-port? #f) #f] - [#:out-kind out-kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto] - ) (or/c (is-a?/c snip%) void?)]{ + [#:out-kind out-kind plot-file-format/c 'auto] + ) (or/c (and/c (is-a?/c snip%) (is-a/c plot-metrics<%>)) void?)]{ Plots a 3D renderer or list of renderers (or more generally, a tree of renderers), as returned by @(racket points3d), @(racket parametric3d), @(racket surface3d), @(racket isosurface3d), and others. When the parameter @(racket plot-new-window?) is @(racket #t), @(racket plot3d) opens a new window to display the plot and returns @(racket (void)). @@ -86,17 +94,23 @@ When @(racket #:out-file) is given, @(racket plot3d) writes the plot to a file u When given, the @(racket x-min), @(racket x-max), @(racket y-min), @(racket y-max), @(racket z-min) and @(racket z-max) arguments determine the bounds of the plot, but not the bounds of the renderers. +When given, the @(racket aspect-ratio) argument defines the aspect ratio of +the plot area, see @(racket plot-aspect-ratio) for more details. + @bold{Deprecated keywords.} The @(racket #:fgcolor) and @(racket #:bgcolor) keyword arguments are currently supported for backward compatibility, but may not be in the future. Please set the @(racket plot-foreground) and @(racket plot-background) parameters instead of using these keyword arguments. The @(racket #:lncolor) keyword argument is also accepted for backward compatibility but deprecated. It does nothing. The @(racket #:az) and @(racket #:alt) keyword arguments are backward-compatible, deprecated aliases for @(racket #:angle) and @(racket #:altitude), respectively. + +@history[#:changed "7.9" "Added support for pictures for #:title, #:x-label and #:y-label. And to plot the legend outside the plot-area with #:legend-anchor"] +@history[#:changed "8.1" "Added #:aspect-ratio"] } @defproc[(plot-snip [ ] ...) - (is-a?/c snip%)] + (and/c (is-a?/c 2d-plot-snip%) (is-a?/c plot-metrics<%>))] @defproc[(plot3d-snip [ ] ...) - (is-a?/c snip%)] + (and/c (is-a?/c snip%) (is-a?/c plot-metrics<%>))] @defproc[(plot-frame [ ] ...) (is-a?/c frame%)] @defproc[(plot3d-frame [ ] ...) @@ -107,6 +121,10 @@ These procedures accept the same arguments as @(racket plot) and @(racket plot3d Use @(racket plot-frame) and @(racket plot3d-frame) to create a @(racket frame%) regardless of the value of @(racket plot-new-window?). The frame is initially hidden. Use @(racket plot-snip) and @(racket plot3d-snip) to create an interactive @(racket snip%) regardless of the value of @(racket plot-new-window?). + +The @racket[snip%] objects returned by @racket[plot-snip] can be used to +construct interactive plots. See @secref["2d-plot-snip-interactive-overlays"] +for more details. } @section{Non-GUI Plotting Procedures} @@ -115,22 +133,22 @@ Use @(racket plot-snip) and @(racket plot3d-snip) to create an interactive @(rac @defproc[(plot-file [renderer-tree (treeof (or/c renderer2d? nonrenderer?))] [output (or/c path-string? output-port?)] - [kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto] + [kind plot-file-format/c 'auto] [#: ] ...) void?] @defproc[(plot3d-file [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] [output (or/c path-string? output-port?)] - [kind (one-of/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg) 'auto] + [kind plot-file-format/c 'auto] [#: ] ...) void?] @defproc[(plot-pict [ ] ...) - pict?] + plot-pict?] @defproc[(plot3d-pict [ ] ...) - pict?] + plot-pict?] @defproc[(plot-bitmap [ ] ...) - (is-a?/c bitmap%)] + (and/c (is-a?/c bitmap%) (is-a?/c plot-metrics<%>))] @defproc[(plot3d-bitmap [ ] ...) - (is-a?/c bitmap%)]{ + (and/c (is-a?/c bitmap%) (is-a?/c plot-metrics<%>))]{ Plot to different non-GUI backends. These procedures accept the same arguments as @(racket plot) and @(racket plot3d), except deprecated keywords, and @racket[#:out-file] and @racket[#:out-kind]. @@ -164,7 +182,7 @@ Use @(racket plot-bitmap) or @(racket plot3d-bitmap) to create a @(racket bitmap [width (>=/c 0)] [height (>=/c 0)] [#: ] ...) - void?] + (is-a?/c plot-metrics<%>)] @defproc[(plot3d/dc [renderer-tree (treeof (or/c renderer3d? nonrenderer?))] [dc (is-a?/c dc<%>)] [x real?] @@ -172,7 +190,7 @@ Use @(racket plot-bitmap) or @(racket plot3d-bitmap) to create a @(racket bitmap [width (>=/c 0)] [height (>=/c 0)] [#: ] ...) - void?]{ + (is-a?/c plot-metrics<%>)]{ Plot to an arbitrary device context, in the rectangle with width @(racket width), height @(racket height), and upper-left corner @(racket x),@(racket y). These procedures accept the same arguments as @(racket plot) and @(racket plot3d), except deprecated keywords, and @racket[#:out-file] and @racket[#:out-kind]. diff --git a/plot-doc/plot/scribblings/renderer2d.scrbl b/plot-doc/plot/scribblings/renderer2d.scrbl index 96151a16..f7d2d6eb 100644 --- a/plot-doc/plot/scribblings/renderer2d.scrbl +++ b/plot-doc/plot/scribblings/renderer2d.scrbl @@ -39,7 +39,15 @@ Every appearance keyword argument defaults to the value of a parameter. This allows whole families of plots to be altered with little work. For example, setting @(racket (line-color 3)) causes every subsequent renderer that draws connected lines to draw its lines in blue. -@bold{Label argument.} Lastly, there is @(racket #:label). If given, the @(racket function) renderer will generate a label entry that @(racket plot) puts in the legend. +@bold{Label argument.} Lastly, there is @(racket #:label). If given, the +@(racket function) renderer will generate a label entry that @(racket plot) +puts in the legend. The label argument can be a string or a @(racket pict). +For most use cases, the string will be sufficient, especially since it allows +using Unicode characters, and thus some mathematical notation. For more +complex cases, a @(racket pict) can be used, whic allows arbitrary text and +graphics to be used as label entries. + +@history[#:changed "7.9" "Added support for pictures for #:label"] Not every renderer-producing function has a @(racket #:label) argument; for example, @(racket error-bars). @@ -57,7 +65,7 @@ Not every renderer-producing function has a @(racket #:label) argument; for exam [#:size size (>=/c 0) (point-size)] [#:line-width line-width (>=/c 0) (point-line-width)] [#:alpha alpha (real-in 0 1) (point-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a @tech{renderer} that draws points. Use it, for example, to draw 2D scatter plots. @@ -114,6 +122,8 @@ For example: @item{To see the distribution of 1-dimensional data; as a substitute for box or violin plots.} @item{To anonymize spatial data, showing i.e. an office's neighborhood but hiding its address.} ] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(vector-field @@ -127,7 +137,7 @@ For example: [#:line-width line-width (>=/c 0) (vector-field-line-width)] [#:line-style line-style plot-pen-style/c (vector-field-line-style)] [#:alpha alpha (real-in 0 1) (vector-field-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that draws a vector field. @@ -135,10 +145,14 @@ If @(racket scale) is a real number, arrow lengths are multiplied by @(racket sc If @(racket 'auto), the scale is calculated in a way that keeps arrows from overlapping. If @(racket 'normalized), each arrow is made the same length: the maximum length that would have been allowed by @(racket 'auto). +The shape of the arrow-head can be controlled with @racket[arrow-head-size-or-scale] and @racket[arrow-head-angle]. + An example of automatic scaling: @interaction[#:eval plot-eval (plot (vector-field (λ (x y) (vector (+ x y) (- x y))) -2 2 -2 2))] + +@history[#:changed "7.9" "Added support for pictures for #:label and controlling the arrowhead"] } @defproc[(error-bars @@ -150,6 +164,7 @@ An example of automatic scaling: [#:line-style line-style plot-pen-style/c (error-bar-line-style)] [#:width width (>=/c 0) (error-bar-width)] [#:alpha alpha (real-in 0 1) (error-bar-alpha)] + [#:invert? invert? boolean? #f] ) renderer2d?]{ Returns a renderer that draws error bars. The first and second element in each vector in @(racket bars) comprise the coordinate; the third is the height. @@ -158,7 +173,12 @@ The first and second element in each vector in @(racket bars) comprise the coord (error-bars (list (vector 2 4 12) (vector 4 16 20) (vector 6 36 10)))))] -} + +If @racket[invert?] is @racket[#t], the x and y coordinates are inverted, and the bars are drawn horizontally +rather than vertically. This is intended for use with the corresponding option of @racket[discrete-histogram] +and @racket[stacked-histogram]. + +@history[#:changed "1.1" @elem{Added the @racket[#:invert?] option.}]} @defproc[(candlesticks [candles (sequence/c (sequence/c #:min-count 5 real?))] @@ -180,6 +200,22 @@ fourth, and fifth elements in each vector comprise the open, high, low, and clos (vector 6 24 36 10 24)))))] } +@defproc[(color-field + [f (or/c (-> real? real? plot-color/c) + (-> (vector/c real? real?) plot-color/c))] + [x-min (or/c rational? #f) #f] [x-max (or/c rational? #f) #f] + [y-min (or/c rational? #f) #f] [y-max (or/c rational? #f) #f] + [#:samples samples exact-positive-integer? (color-field-samples)] + [#:alpha alpha (real-in 0 1) (color-field-alpha)] + ) renderer2d?]{ +Returns a renderer that draws rectangles filled with a color based on the center point. + +@interaction[#:eval plot-eval + (plot (color-field (λ (x y) (if (< (+ (sqr x) (sqr y)) 1) (random 10) 'black)) + -2 2 -2 2))] +@history[#:added "7.9"] +} + @section{2D Line Renderers} @defproc[(function [f (real? . -> . real?)] @@ -190,10 +226,32 @@ fourth, and fifth elements in each vector comprise the open, high, low, and clos [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:marker marker point-sym/c 'none] + [#:marker-color marker-color (or/c 'auto plot-color/c) 'auto] + [#:marker-fill-color marker-fill-color (or/c 'auto plot-color/c) 'auto] + [#:marker-size marker-size (>=/c 0) (point-size)] + [#:marker-line-width marker-line-width (>=/c 0) (point-line-width)] + [#:marker-alpha marker-alpha (real-in 0 1) (point-alpha)] + [#:marker-count marker-count positive-integer? 20] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ -Returns a renderer that plots a function of @italic{x}. For example, a parabola: -@interaction[#:eval plot-eval (plot (function sqr -2 2))] + + Returns a renderer that plots a function of @italic{x}. For example, a parabola: + + @interaction[#:eval plot-eval (plot (function sqr -2 2))] + + When @(racket marker) is not @racket['none], markers will be placed on the + on the line drawn for the function at equal intervals. The marker and + related arguments are the same as for the @racket[points] renderer. The + number of markers shown on the plot is specified by @racket[marker-count] + parameter. + + Using markers has the same effect as using both a @racket[function] and a + @racket[points] renderer in a single plot, exept that using @racket[marker]s + will show the marker super-imposed over the line style in the plot legend. + + @history[#:changed "7.9" "#:label argument supports pictures"] + @history[#:changed "8.10" "#:marker and related arguments added"] } @defproc[(inverse [f (real? . -> . real?)] @@ -204,15 +262,30 @@ Returns a renderer that plots a function of @italic{x}. For example, a parabola: [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] - ) renderer2d?]{ -Like @(racket function), but regards @(racket f) as a function of @italic{y}. -For example, a parabola, an inverse parabola, and the reflection line: + [#:marker marker point-sym/c 'none] + [#:marker-color marker-color (or/c 'auto plot-color/c) 'auto] + [#:marker-fill-color marker-fill-color (or/c 'auto plot-color/c) 'auto] + [#:marker-size marker-size (>=/c 0) (point-size)] + [#:marker-line-width marker-line-width (>=/c 0) (point-line-width)] + [#:marker-alpha marker-alpha (real-in 0 1) (point-alpha)] + [#:marker-count marker-count positive-integer? 20] + [#:label label (or/c string? pict? #f) #f]) renderer2d?]{ + + Like @(racket function), but regards @(racket f) as a function of + @italic{y}. For example, a parabola, an inverse parabola, and the + reflection line: + @interaction[#:eval plot-eval (plot (list (axes) - (function sqr -2 2 #:label "y = x^2") + (function sqr -2 2 #:label "y = x²") (function (λ (x) x) #:color 0 #:style 'dot #:label "y = x") - (inverse sqr -2 2 #:color 3 #:label "x = y^2")))] + (inverse sqr -2 2 #:color 3 #:label "x = y²")))] + + The @(racket marker) and related arguments have the same meaning as for the + @racket[function] renderer. + + @history[#:changed "7.9" "#:label argument supports pictures"] + @history[#:changed "8.10" "#:marker and related arguments added"] } @defproc[(lines [vs (sequence/c (sequence/c #:min-count 2 real?))] @@ -222,10 +295,21 @@ For example, a parabola, an inverse parabola, and the reflection line: [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:marker marker point-sym/c 'none] + [#:marker-color marker-color (or/c 'auto plot-color/c) 'auto] + [#:marker-fill-color marker-fill-color (or/c 'auto plot-color/c) 'auto] + [#:marker-size marker-size (>=/c 0) (point-size)] + [#:marker-line-width marker-line-width (>=/c 0) (point-line-width)] + [#:marker-alpha marker-alpha (real-in 0 1) (point-alpha)] + [#:label label (or/c string? pict? #f) #f] + [#:ignore-axis-transforms? ignore-axis-transforms? boolean? #f] ) renderer2d?]{ -Returns a renderer that draws lines. -This is directly useful for plotting a time series, such as a random walk: + + Returns a renderer that draws lines connecting the points in the input + sequence @(racket vs). + + This is directly useful for plotting a time series, such as a random walk: + @interaction[#:eval plot-eval (plot (lines (reverse @@ -234,7 +318,55 @@ This is directly useful for plotting a time series, such as a random walk: (cons (vector i (+ y (* 1/100 (- (random) 1/2)))) lst))) #:color 6 #:label "Random walk"))] -The @(racket parametric) and @(racket polar) functions are defined using @(racket lines). + If any of the points in @(racket vs) is @(racket +nan.0), no line segment + will be drawn at that position. This can be used to draw several + independent data sets with one @(racket lines) renderer, improving rendering + performence for large datasets. + + When @(racket marker) is not @racket['none], markers will be placed on the + on the line at each point in @racket[vs]. The marker and related arguments + are the same as for the @racket[points] renderer. + + Using markers has the same effect as using both a @racket[lines] and a + @racket[points] renderer in a single plot, exept that using @racket[marker]s + will show the marker super-imposed over the line style in the plot legend. + + When @(racket ignore-axis-transforms?) is @racket[#t], only the individual + points in @(racket vs) are affected by axis transforms, not the lines that + connect these points. This feature can be used, for example, to plot a + convergence line on a log-log plot. + + @bold{NOTE:} It is undesirable to ignore axis transforms in plots, but this + feature can be used to replicate functionality of other plotting libraries + and it is meant for users familiar with those libraries. In Racket, it is + preferable show the convergence line on log-log plots using the @(racket + function) renderer with the power function based on slope and intercept. + +@interaction[#:eval plot-eval +(let ([data '((5 1.24) (203 510))] + [slope 1.6252] + [intercept -2.4005]) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform log-transform]) + (plot + (list + (tick-grid) + (lines data + #:ignore-axis-transforms? #f + #:label "ignore-axis-transforms? #f" + #:color 1) + (lines data + #:ignore-axis-transforms? #t + #:label "ignore-axis-transforms? #t" + #:color 2) + (function (lambda (x) (* (exp intercept)) (expt x slope)) + #:style 'long-dash + #:label "convergence line" + #:color 3)))))] + + @history[#:changed "7.9" "#:label argument supports pictures"] + @history[#:changed "8.9" "#:ignore-axis-transforms? argument added"] + @history[#:changed "8.10" "#:marker and related arguments added"] } @defproc[(parametric [f (real? . -> . (sequence/c real?))] @@ -246,12 +378,14 @@ The @(racket parametric) and @(racket polar) functions are defined using @(racke [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that plots vector-valued functions of time. For example, the circle as a function of time can be plotted using @interaction[#:eval plot-eval - (plot (parametric (λ (t) (vector (cos t) (sin t))) 0 (* 2 pi)))] + (plot (parametric (λ (t) (vector (cos t) (sin t))) 0 (* 2 pi)))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(polar [f (real? . -> . real?)] @@ -263,13 +397,15 @@ For example, the circle as a function of time can be plotted using [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that plots functions from angle to radius. Note that the angle parameters @(racket θ-min) and @(racket θ-max) default to @(racket 0) and @(racket (* 2 pi)). For example, drawing a full circle: @interaction[#:eval plot-eval (plot (polar (λ (θ) 1)))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(density [xs (sequence/c real?)] @@ -282,7 +418,7 @@ For example, drawing a full circle: [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that plots an estimated density for the given points, which are optionally weighted by @racket[ws]. The bandwidth for the kernel is calculated as @(racket (* bw-adjust 1.06 sd (expt n -0.2))), where @(racket sd) is the standard deviation of the data and @(racket n) is the number of points. @@ -298,6 +434,42 @@ For example, to plot an estimated density of the triangle distribution: 2000 (λ (n) (- (+ (random) (random)) 1))) #:color 0 #:width 2 #:style 'dot #:label "Est. density")))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] +} + + +@defproc[(arrows [vs (or/c (listof (sequence/c #:min-count 2 real?)) + (vectorof (vector/c (sequence/c #:min-count 2 real?) + (sequence/c #:min-count 2 real?))))] + [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] + [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] + [#:color color plot-color/c (arrows-color)] + [#:width width (>=/c 0) (arrows-line-width)] + [#:style style plot-pen-style/c (arrows-line-style)] + [#:alpha alpha (real-in 0 1) (arrows-alpha)] + [#:arrow-head-size-or-scale size (or/c (list/c '= (>=/c 0)) (>=/c 0)) (arrow-head-size-or-scale)] + [#:arrow-head-angle angle (>=/c 0) (arrow-head-angle)] + [#:label label (or/c string? pict? #f) #f] + ) renderer2d?]{ +Returns a renderer which draws arrows. Arrows can be specified either as sequences of 2D points, +in this case they will be drawn as connected arrows between each two adjacent points, +or they can be specified as an origin point and a rectangular magnitude vector, in which case each arrow +is drawn individually. See example below. + +In @racket[vs] list and vector are interchangeable. Arrow-heads are only drawn when the endpoint is inside the drawing area. + @interaction[#:eval plot-eval + (plot (list + (arrows + `((0 0) (2 1) (3 3) (0 0)) + #:arrow-head-size-or-scale '(= 20) + #:arrow-head-angle .2 + #:color 6 #:label "a+b+c=0") + (arrows + `(((2 0) (0 1)) ((3 0) (-1 1))) + #:arrow-head-size-or-scale .2 + #:color 2 #:label "d")))] +@history[#:added "7.9"] } @defproc[(hrule [y real?] @@ -306,10 +478,12 @@ For example, to plot an estimated density of the triangle distribution: [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Draws a horizontal line at @italic{y}. By default, the line spans the entire plot area width. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(vrule [x real?] @@ -318,10 +492,12 @@ By default, the line spans the entire plot area width. [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Draws a vertical line at @italic{x}. By default, the line spans the entire plot area height. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{2D Interval Renderers} @@ -342,12 +518,14 @@ These renderers each correspond with a line renderer, and graph the area between [#:line2-width line2-width (>=/c 0) (interval-line2-width)] [#:line2-style line2-style plot-pen-style/c (interval-line2-style)] [#:alpha alpha (real-in 0 1) (interval-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Corresponds with @(racket function). @interaction[#:eval plot-eval (plot (function-interval (λ (x) 0) (λ (x) (exp (* -1/2 (sqr x)))) -4 4 #:line1-style 'transparent))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(inverse-interval @@ -364,12 +542,14 @@ Corresponds with @(racket function). [#:line2-width line2-width (>=/c 0) (interval-line2-width)] [#:line2-style line2-style plot-pen-style/c (interval-line2-style)] [#:alpha alpha (real-in 0 1) (interval-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Corresponds with @(racket inverse). @interaction[#:eval plot-eval (plot (inverse-interval sin (λ (x) 0) (- pi) pi #:line2-style 'long-dash))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(lines-interval @@ -386,7 +566,7 @@ Corresponds with @(racket inverse). [#:line2-width line2-width (>=/c 0) (interval-line2-width)] [#:line2-style line2-style plot-pen-style/c (interval-line2-style)] [#:alpha alpha (real-in 0 1) (interval-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Corresponds with @(racket lines). @@ -396,6 +576,8 @@ Corresponds with @(racket lines). (lines-interval (list #(0 0) #(1 1/2)) (list #(0 1) #(1 3/2)) #:color 4 #:line1-color 4 #:line2-color 4 #:label "Parallelogram")))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(parametric-interval @@ -414,7 +596,7 @@ Corresponds with @(racket lines). [#:line2-width line2-width (>=/c 0) (interval-line2-width)] [#:line2-style line2-style plot-pen-style/c (interval-line2-style)] [#:alpha alpha (real-in 0 1) (interval-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Corresponds with @(racket parametric). @@ -424,6 +606,8 @@ Corresponds with @(racket parametric). (define (f2 t) (vector (* 1/2 (cos t)) (* 1/2 (sin t)))) (plot (parametric-interval f1 f2 (- pi) pi))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(polar-interval @@ -441,7 +625,7 @@ Corresponds with @(racket parametric). [#:line2-width line2-width (>=/c 0) (interval-line2-width)] [#:line2-style line2-style plot-pen-style/c (interval-line2-style)] [#:alpha alpha (real-in 0 1) (interval-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Corresponds with @(racket polar). @@ -450,6 +634,8 @@ Corresponds with @(racket polar). (define (f2 θ) (+ 1 (* 1/4 (cos (* 10 θ))))) (plot (list (polar-axes #:number 10) (polar-interval f1 f2 #:label "[f1,f2]")))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{2D Contour (Isoline) Renderers} @@ -463,12 +649,14 @@ Corresponds with @(racket polar). [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that plots a contour line, or a line of constant value (height). A circle of radius @(racket r), for example, is the line of constant value @(racket r) for the distance function: @interaction[#:eval plot-eval (plot (isoline (λ (x y) (sqrt (+ (sqr x) (sqr y)))) 1.5 -2 2 -2 2 #:label "z"))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } In this case, @(racket r) = @(racket 1.5). @@ -485,7 +673,7 @@ It may be renamed in the future, with @racket[isoline] as an alias. [#:widths widths (pen-widths/c (listof real?)) (contour-widths)] [#:styles styles (plot-pen-styles/c (listof real?)) (contour-styles)] [#:alphas alphas (alphas/c (listof real?)) (contour-alphas)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that plots contour lines, or lines of constant value (height). @@ -507,6 +695,8 @@ For example, #:colors '("blue" "red") #:widths '(4 1) #:styles '(solid dot)))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(contour-intervals @@ -521,7 +711,7 @@ For example, [#:contour-widths contour-widths (pen-widths/c (listof real?)) (contour-widths)] [#:contour-styles contour-styles (plot-pen-styles/c (listof real?)) (contour-styles)] [#:alphas alphas (alphas/c (listof ivl?)) (contour-interval-alphas)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that fills the area between contour lines, and additionally draws contour lines. @@ -531,6 +721,8 @@ For example, the canonical saddle, with its gradient field superimposed: -2 2 -2 2 #:label "z") (vector-field (λ (x y) (vector (* 2 x) (* -2 y))) #:color "black" #:label "Gradient")))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{2D Rectangle Renderers} @@ -545,12 +737,20 @@ For example, the canonical saddle, with its gradient field superimposed: [#:line-width line-width (>=/c 0) (rectangle-line-width)] [#:line-style line-style plot-pen-style/c (rectangle-line-style)] [#:alpha alpha (real-in 0 1) (rectangle-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that draws rectangles. -The rectangles are given as a sequence of sequences of intervals---each inner sequence defines the bounds of a rectangle. For example, + +The rectangles are given as a sequence of sequences of intervals---each inner +sequence defines the bounds of a rectangle. Any of the bounds can be +@racket[-inf.0] or @racket[+inf.0], in which case the rectangle extents to the +edge of the plot area in the respective direction. + +For example, @interaction[#:eval plot-eval (plot (rectangles (list (vector (ivl -1 0) (ivl -1 1)) (vector (ivl 0 2) (ivl 1 2)))))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(area-histogram @@ -565,7 +765,7 @@ The rectangles are given as a sequence of sequences of intervals---each inner se [#:line-width line-width (>=/c 0) (rectangle-line-width)] [#:line-style line-style plot-pen-style/c (rectangle-line-style)] [#:alpha alpha (real-in 0 1) (rectangle-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer2d?]{ Returns a renderer that draws a histogram approximating the area under a curve. The @(racket #:samples) argument determines the accuracy of the calculated areas. @@ -590,7 +790,7 @@ The @(racket #:samples) argument determines the accuracy of the calculated areas [#:line-width line-width (>=/c 0) (rectangle-line-width)] [#:line-style line-style plot-pen-style/c (rectangle-line-style)] [#:alpha alpha (real-in 0 1) (rectangle-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] [#:add-ticks? add-ticks? boolean? #t] [#:far-ticks? far-ticks? boolean? #f] ) renderer2d?]{ @@ -631,6 +831,8 @@ For example, #:x-label "Breakfast Food" #:y-label "Cooking Time (minutes)" #:title "Cooking Times For Breakfast Food, Per Processor")] When interleaving many histograms, consider setting the @racket[discrete-histogram-skip] parameter to change @racket[skip]'s default value. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(stacked-histogram @@ -661,6 +863,168 @@ The heights of each bar section are given as a list. #:legend-anchor 'top-right)] } +@section{Violin and Box Plot Renderers} + +@defproc[(violin + [vs (sequence/c real?)] + [#:x x real? 0] + [#:width width (>=/c 0) 1] + [#:bandwidth bandwidth (or/c real? #f) #f] + [#:invert? invert? boolean? #f] + [#:label label (or/c string? pict? #f) #f] + [#:add-ticks? add-ticks? boolean? #t] + [#:far-ticks? far-ticks? boolean? #f] + [#:y-min y-min (or/c rational? #f) #f] + [#:y-max y-max (or/c rational? #f) #f] + [#:samples samples (and/c exact-integer? (>=/c 2)) (line-samples)] + [#:color color plot-color/c (interval-color)] + [#:style style plot-brush-style/c (interval-style)] + [#:line-color line1-color plot-color/c (interval-line1-color)] + [#:line-width line1-width (>=/c 0) (interval-line1-width)] + [#:line-style line1-style plot-pen-style/c (interval-line1-style)] + [#:alpha alpha (real-in 0 1) (interval-alpha)] + ) renderer2d?]{ + +Draws a @hyperlink["https://en.wikipedia.org/wiki/Violin_plot"]{violin} plot +from the list of real values @racket[vs]. The plot is centered at @racket[x] +and the @racket[width] parameter is used as a scaling factor to control the +width of the violin. + +The default kernel density bandwidth is determined by +@racket[silverman-bandwidth]. + +When @racket[invert?] is @racket[#f], the violin plot is drawn vertically, +when it is @racket[#t], the x and y coordinates are inverted, and the violin +is drawn horizontally. + +@racket[label] defines the plot label, it is the value shown in the plot +legend as well as on the X axis under the violin plot (or Y axis if the plot +is inverted). The label is shown on the X axis on only if @racket[add-ticks?] +is @racket[#t], and, if @racket[far-ticks?] is @racket[#t] the label is placed +on the far axis. + +@racket[y-min] and @racket[y-max] define the vertical range to draw the +violin, by default, the entire violin is drawn. + +@racket[samples] defines the number of samples used by the function renderer +while drawing the violin outline. + +See @secref["renderer2d-function-arguments"] for the meaning of the other +arguments. + +@interaction[#:eval plot-eval + (parameterize ([plot-pen-color-map 'tab20] + [plot-brush-color-map 'tab20] + [plot-x-label #f] + [plot-y-label #f]) + (define (rnorm sample-count mean stddev) + (sample (normal-dist mean stddev) sample-count)) + (define a (rnorm 50 10 5)) + (define b (append (rnorm 50 13 1) (rnorm 50 18 1))) + (define c (rnorm 20 25 4)) + (define d (rnorm 10 12 2)) + (plot + (for/list ([data (list a b c d)] + [label (list "a" "b" "c" "d")] + [index (in-naturals)]) + (violin data + #:label label + #:invert? #t + #:x index + #:width 10/8 + #:color (+ (* index 2) 1) + #:line-color (* index 2))) + #:legend-anchor 'no-legend))] + +@history[#:added "8.5"] +} + +@defproc[(box-and-whisker + [vs (sequence/c real?)] + [#:weights ws (sequence/c real?) #f] + [#:x x real? 0] + [#:width width (>=/c 0) 1] + [#:iqr-scale iqr-scale (>=/c 0) 1.5] + [#:invert? invert? boolean? #f] + [#:label label (or/c string? pict? #f) #f] + [#:add-ticks? add-ticks? boolean? #t] + [#:far-ticks? far-ticks? boolean? #f] + [#:box-color box-color plot-color/c (rectangle-color)] + [#:box-style box-style plot-brush-style/c (rectangle-style)] + [#:box-line-color box-line-color plot-color/c (rectangle-line-color)] + [#:box-line-width box-line-width (>=/c 0) (rectangle-line-width)] + [#:box-line-style box-line-style plot-pen-style/c (rectangle-line-style)] + [#:box-alpha box-alpha (real-in 0 1) (rectangle-alpha)] + [#:show-outliers? show-outliers? boolean? #t] + [#:outlier-color outlier-color plot-color/c (point-color)] + [#:outlier-sym outlier-sym point-sym/c (point-sym)] + [#:outlier-fill-color outlier-fill-color (or/c plot-color/c 'auto) 'auto] + [#:outlier-size outlier-size (>=/c 0) (point-size)] + [#:outlier-line-width outlier-line-width (>=/c 0) (point-line-width)] + [#:outlier-alpha outlier-alpha (real-in 0 1) (point-alpha)] + [#:show-whiskers? show-whiskers? boolean? #t] + [#:whisker-color whisker-color plot-color/c (line-color)] + [#:whisker-width whisker-width (>=/c 0) (line-width)] + [#:whisker-style whisker-style plot-pen-style/c (line-style)] + [#:whisker-alpha whisker-alpha (real-in 0 1) (line-alpha)] + [#:show-median? show-median? boolean? #t] + [#:median-color median-color plot-color/c (line-color)] + [#:median-width median-width (>=/c 0) (line-width)] + [#:median-style median-style plot-pen-style/c (line-style)] + [#:median-alpha median-alpha (real-in 0 1) (line-alpha)] + ) renderer2d?]{ + +Draws a @hyperlink["https://en.wikipedia.org/wiki/Box_plot"]{box and whisker} +plot from the list of real values @racket[vs], possibly weighted by the values +in @racket[ws]. The plot is centered at @racket[x] and the @racket[width] +parameter is used as a scaling factor to control the width of the box. + +The @racket[iqr-scale] controls the scaling factor for the inter-quantile +range, which decides how far the whiskers extent and which points are +considered outliers. + +When @racket[invert?] is @racket[#f], the box plot is drawn vertically, when +it is @racket[#t], the x and y coordinates are inverted, and the box plot is +drawn horizontally. + +@racket[label] defines the plot label, it is the value shown in the plot +legend as well as on the X axis under the box plot (or Y axis if the plot is +inverted). The label is shown on the X axis on only if @racket[add-ticks?] is +@racket[#t], and, if @racket[far-ticks?] is @racket[#t] the label is placed on +the far axis. + +See @secref["renderer2d-function-arguments"] for the meaning of the other +arguments. + +@interaction[#:eval plot-eval + (parameterize ([plot-pen-color-map 'tab20] + [plot-brush-color-map 'tab20] + [plot-x-label #f] + [plot-y-label #f]) + (define (rnorm sample-count mean stddev) + (sample (normal-dist mean stddev) sample-count)) + (define a (rnorm 50 10 5)) + (define b (append (rnorm 50 13 1) (rnorm 50 18 1))) + (define c (rnorm 20 25 4)) + (define d (rnorm 10 12 2)) + (plot + (for/list ([data (list a b c d)] + [label (list "a" "b" "c" "d")] + [index (in-naturals)]) + (box-and-whisker data + #:label label + #:invert? #f + #:x index + #:width 6/8 + #:box-color (+ (* index 2) 1) + #:box-line-color (* index 2) + #:whisker-color (* index 2) + #:median-color "red")) + #:legend-anchor 'no-legend))] + +@history[#:added "8.5"] +} + @section{2D Plot Decoration Renderers} @defproc[(x-axis [y real? 0] @@ -738,6 +1102,27 @@ If @(racket label) is @(racket #f), the point is labeled with its position. The remaining labeled-point functions are defined in terms of this one. } +@defproc[(point-pict + [v (sequence/c real?)] + [pict pict?] + [#:anchor anchor anchor/c (label-anchor)] + [#:point-color point-color plot-color/c (point-color)] + [#:point-fill-color point-fill-color (or/c plot-color/c 'auto) 'auto] + [#:point-size point-size (>=/c 0) (label-point-size)] + [#:point-line-width point-line-width (>=/c 0) (point-line-width)] + [#:point-sym point-sym point-sym/c 'fullcircle] + [#:alpha alpha (real-in 0 1) (label-alpha)] + ) renderer2d?]{ +Returns a renderer that draws a point with a pict as the label. + +@interaction[#:eval plot-eval + (require pict) + (plot (list (function sqr 0 2) + (point-pict (vector 1 1) (standard-fish 40 15))))] + +The remaining labeled-pict functions are defined in terms of this one. +} + @defproc[(function-label [f (real? . -> . real?)] [x real?] [label (or/c string? #f) #f] [#:color color plot-color/c (plot-foreground)] @@ -761,6 +1146,19 @@ Returns a renderer that draws a labeled point on a function's graph. #:anchor 'right)))] } +@defproc[(function-pict + [f (real? . -> . real?)] [x real?] [pict pict?] + [#:anchor anchor anchor/c (label-anchor)] + [#:point-color point-color plot-color/c (point-color)] + [#:point-fill-color point-fill-color (or/c plot-color/c 'auto) 'auto] + [#:point-size point-size (>=/c 0) (label-point-size)] + [#:point-line-width point-line-width (>=/c 0) (point-line-width)] + [#:point-sym point-sym point-sym/c 'fullcircle] + [#:alpha alpha (real-in 0 1) (label-alpha)] + ) renderer2d?]{ +Returns a renderer that draws a point with a pict as the label on a function's graph. +} + @defproc[(inverse-label [f (real? . -> . real?)] [y real?] [label (or/c string? #f) #f] [#:color color plot-color/c (plot-foreground)] @@ -779,6 +1177,20 @@ Returns a renderer that draws a labeled point on a function's graph. Returns a renderer that draws a labeled point on a function's inverted graph. } +@defproc[(inverse-pict + [f (real? . -> . real?)] [y real?] [pict pict?] + [#:anchor anchor anchor/c (label-anchor)] + [#:point-color point-color plot-color/c (point-color)] + [#:point-fill-color point-fill-color (or/c plot-color/c 'auto) 'auto] + [#:point-size point-size (>=/c 0) (label-point-size)] + [#:point-line-width point-line-width (>=/c 0) (point-line-width)] + [#:point-sym point-sym point-sym/c 'fullcircle] + [#:alpha alpha (real-in 0 1) (label-alpha)] + ) renderer2d?]{ +Returns a renderer that draws a point with a pict as the label on a function's inverted graph. +} + + @defproc[(parametric-label [f (real? . -> . (sequence/c real?))] [t real?] [label (or/c string? #f) #f] [#:color color plot-color/c (plot-foreground)] @@ -797,6 +1209,19 @@ Returns a renderer that draws a labeled point on a function's inverted graph. Returns a renderer that draws a labeled point on a parametric function's graph. } +@defproc[(parametric-pict + [f (real? . -> . (sequence/c real?))] [t real?] [pict pict?] + [#:anchor anchor anchor/c (label-anchor)] + [#:point-color point-color plot-color/c (point-color)] + [#:point-fill-color point-fill-color (or/c plot-color/c 'auto) 'auto] + [#:point-size point-size (>=/c 0) (label-point-size)] + [#:point-line-width point-line-width (>=/c 0) (point-line-width)] + [#:point-sym point-sym point-sym/c 'fullcircle] + [#:alpha alpha (real-in 0 1) (label-alpha)] + ) renderer2d?]{ +Returns a renderer that draws a point with a pict as the label on a parametric function's graph. +} + @defproc[(polar-label [f (real? . -> . real?)] [θ real?] [label (or/c string? #f) #f] @@ -815,3 +1240,112 @@ Returns a renderer that draws a labeled point on a parametric function's graph. ) renderer2d?]{ Returns a renderer that draws a labeled point on a polar function's graph. } + + +@defproc[(polar-pict + [f (real? . -> . real?)] [θ real?] [pict pict?] + [#:anchor anchor anchor/c (label-anchor)] + [#:point-color point-color plot-color/c (point-color)] + [#:point-fill-color point-fill-color (or/c plot-color/c 'auto) 'auto] + [#:point-size point-size (>=/c 0) (label-point-size)] + [#:point-line-width point-line-width (>=/c 0) (point-line-width)] + [#:point-sym point-sym point-sym/c 'fullcircle] + [#:alpha alpha (real-in 0 1) (label-alpha)] + ) renderer2d?]{ +Returns a renderer that draws a point with a pict as the label on a polar function's graph. +} + +@section[#:tag "2d-plot-snip-interactive-overlays"]{Interactive Overlays for 2D plots} + +@defmodule[plot/snip] + +A plot @racket[snip%] object returned by @racket[plot-snip] can be set up to +provide interactive overlays. This feature can be used, for example, to show +the current value of the plot function at the mouse cursor. + +If the code below is evaluated in DrRacket, the resulting plot will show a +vertical line tracking the mouse and the current plot position is shown on a +label. This is achieved by adding a mouse callback to the plot snip returned +by @racket[plot-snip]. When the mouse callback is invoked, it will add a +@racket[vrule] at the current X position and a @racket[point-label] at the +current value of the plotted function. + +@racketblock[ +(require plot) +(define snip (plot-snip (function sin) #:x-min -5 #:x-max 5)) +(define (mouse-callback snip event x y) + (if (and x y) + (send snip set-overlay-renderers + (list (vrule x) + (point-label (vector x (sin x))))) + (send snip set-overlay-renderers #f))) +(send snip set-mouse-event-callback mouse-callback) +snip] + +Here are a few hints for adding common interactive elements to racket plots: + +@itemlist[ + +@item{The @racket[hrule] and @racket[vrule] renderers can be used to draw +horizontal and vertical lines that track the mouse position} + +@item{The @racket[rectangles] renderer can be used to highlight a region on +the plot. For example, to highlight a vertical region between @racket[_xmin] +and @racket[_xmax], you can use: + +@racketblock[ +(rectangles (list (vector (ivl _xmin _xmax) (ivl -inf.0 +inf.0))) + #:alpha 0.2)] +} + +@item{A @racket[point-label] renderer can be used to add a point with a +string label to the plot. To add only the label, use @racket['none] as the +value for the @racket[#:point-sym] argument.} + +@item{A @racket[point-pict] renderer can be used to add a point with an +attached @racketmodname[pict] instead of a string label. This can be used to +draw fancy labels (for example with rounded corners), or any other type of +graphics element.} + +@item{A @racket[points] renderer can be used to mark specific locations on +the plot, without specifying a label for them} +] + +@defclass[2d-plot-snip% snip% ()]{ + +An instance of this class is returned by @racket[plot-snip]. + +@defmethod[(set-mouse-event-callback [callback (or/c plot-mouse-event-callback/c #f)]) any/c]{ + +Set a callback function to be invoked with mouse events from the snip. The +callback is invoked with the actual snip object, the @racket[mouse-event%] and +the X, Y position of the mouse in plot coordinates (i.e., the coordinate system +used by the renderers in the plot). The X and Y values are +@racket[#f] when the mouse is outside the plot area (for example, when the +mouse is over the axis area). + +When a callback is installed, the default zoom functionality of the plot snips +is disabled. This can be restored by calling +@racket[set-mouse-event-callback] with a @racket[#f] argument. + +} + +@defmethod[(set-overlay-renderers [renderers (or/c (treeof renderer2d?) #f)]) any/c]{ + +Set a collection of renderers to be drawn +on top of the existing plot. This can be any combination of 2D renderers, but +it will not be able to modify the axes or the dimensions of the plot area. +Only one set of overlay renderers can be installed; calling this method a +second time will replace the previous overlays. Specifying @racket[#f] as the +renderers will cause overlays to be disabled. + +} +} + +@defthing[plot-mouse-event-callback/c contract? #:value (-> (is-a?/c snip%) + (is-a?/c mouse-event%) + (or/c real? #f) + (or/c real? #f) + any/c)]{ +A contract for callback functions passed to @racket[set-mouse-event-callback]. +} diff --git a/plot-doc/plot/scribblings/renderer3d.scrbl b/plot-doc/plot/scribblings/renderer3d.scrbl index a716ceb7..751b0d0c 100644 --- a/plot-doc/plot/scribblings/renderer3d.scrbl +++ b/plot-doc/plot/scribblings/renderer3d.scrbl @@ -21,7 +21,7 @@ See @secref["renderer2d-function-arguments"] for a detailed example. @section{3D Point Renderers} @defproc[(points3d - [vs (sequence/c (sequence/c #:min-count 3 real?))] + [vs (sequence/c (sequence/c #:min-count 3 real?))] [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] [#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f] @@ -34,7 +34,7 @@ See @secref["renderer2d-function-arguments"] for a detailed example. [#:size size (>=/c 0) (point-size)] [#:line-width line-width (>=/c 0) (point-line-width)] [#:alpha alpha (real-in 0 1) (point-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that draws points in 3D space. @@ -62,6 +62,8 @@ negative direction, so total spread along e.g. the x-axis is twice @racket[x-jit Note that adding random noise to data, via jittering or otherwise, is usually a bad idea. See the documentation for @racket[points] for examples where jittering may be appropriate. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(vector-field3d @@ -76,13 +78,15 @@ See the documentation for @racket[points] for examples where jittering may be ap [#:line-width line-width (>=/c 0) (vector-field-line-width)] [#:line-style line-style plot-pen-style/c (vector-field-line-style)] [#:alpha alpha (real-in 0 1) (vector-field-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that draws a vector field in 3D space. The arguments are interpreted identically to the corresponding arguments to @racket[vector-field]. @examples[#:eval plot-eval (plot3d (vector-field3d (λ (x y z) (vector x z y)) -2 2 -2 2 -2 2))] + +@history[#:changed "7.9" "Added support for pictures for #:label and controlling the arrowhead"] } @section{3D Line Renderers} @@ -96,10 +100,12 @@ The arguments are interpreted identically to the corresponding arguments to @rac [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that draws connected lines. The @racket[parametric3d] function is defined in terms of this one. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(parametric3d @@ -113,7 +119,7 @@ The @racket[parametric3d] function is defined in terms of this one. [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots a vector-valued function of time. For example, @interaction[#:eval plot-eval @@ -121,6 +127,30 @@ Returns a renderer that plots a vector-valued function of time. For example, (plot3d (parametric3d (λ (t) (3d-polar->3d-cartesian (* t 80) t 1)) (- pi) pi #:samples 3000 #:alpha 0.5) #:altitude 25)] + +@history[#:changed "7.9" "Added support for pictures for #:label"] +} + +@defproc[(arrows3d + [vs (or/c (listof (sequence/c #:min-count 3 real?)) + (vectorof (vector/c (sequence/c #:min-count 3 real?) + (sequence/c #:min-count 3 real?))))] + [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] + [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] + [#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f] + [#:color color plot-color/c (arrows-color)] + [#:width width (>=/c 0) (arrows-line-width)] + [#:style style plot-pen-style/c (arrows-line-style)] + [#:alpha alpha (real-in 0 1) (arrows-alpha)] + [#:arrow-head-size-or-scale size (or/c (list/c '= (>=/c 0)) (>=/c 0)) (arrow-head-size-or-scale)] + [#:arrow-head-angle angle (>=/c 0) (arrow-head-angle)] + [#:label label (or/c string? pict? #f) #f] + ) renderer3d?]{ +Returns a renderer that draws arrows. The arguments and arrow-head parameters are interpreted identically as in @racket[arrows]. +@interaction[#:eval plot-eval + (plot3d (arrows3d `((0 0 0) (1 1 1) (2 2 2) (3 2 1))) + #:altitude 25)] +@history[#:added "7.9"] } @section{3D Surface Renderers} @@ -137,14 +167,16 @@ Returns a renderer that plots a vector-valued function of time. For example, [#:line-width line-width (>=/c 0) (surface-line-width)] [#:line-style line-style plot-pen-style/c (surface-line-style)] [#:alpha alpha (real-in 0 1) (surface-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots a two-input, one-output function. For example, @interaction[#:eval plot-eval (plot3d (list (surface3d (λ (x y) (+ (sqr x) (sqr y))) -1 1 -1 1 - #:label "z = x^2 + y^2") + #:label "z = x² + y²") (surface3d (λ (x y) (- (+ (sqr x) (sqr y)))) -1 1 -1 1 #:color 4 #:line-color 4 - #:label "z = -x^2 - y^2")))] + #:label "z = -x² - y²")))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(polar3d @@ -159,27 +191,101 @@ Returns a renderer that plots a two-input, one-output function. For example, [#:line-width line-width (>=/c 0) (surface-line-width)] [#:line-style line-style plot-pen-style/c (surface-line-style)] [#:alpha alpha (real-in 0 1) (surface-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ -Returns a renderer that plots a function from latitude and longitude to radius. +Returns a renderer that plots a function from longitude and latitude to radius. +@racket[(f θ ϕ)] → @racket[r] -Currently, latitudes range from @(racket 0) to @(racket (* 2 pi)), and longitudes from @(racket (* -1/2 pi)) to @(racket (* 1/2 pi)). +Currently, longitudes(θ) range from @(racket 0) to @(racket (* 2 pi)), and latitudes(ϕ) from @(racket (* -1/2 pi)) to @(racket (* 1/2 pi)). These intervals may become optional arguments to @racket[polar3d] in the future. A sphere is the graph of a polar function of constant radius: -@interaction[#:eval plot-eval (plot3d (polar3d (λ (θ ρ) 1)) #:altitude 25)] +@interaction[#:eval plot-eval (plot3d (polar3d (λ (θ ϕ) 1)) #:altitude 25)] Combining polar function renderers allows faking latitudes or longitudes in larger ranges, to get, for example, a seashell plot: @interaction[#:eval plot-eval (parameterize ([plot-decorations? #f] [plot3d-samples 75]) - (define (f1 θ ρ) (+ 1 (/ θ 2 pi) (* 1/8 (sin (* 8 ρ))))) - (define (f2 θ ρ) (+ 0 (/ θ 2 pi) (* 1/8 (sin (* 8 ρ))))) + (define (f1 θ ϕ) (+ 1 (/ θ 2 pi) (* 1/8 (sin (* 8 ϕ))))) + (define (f2 θ ϕ) (+ 0 (/ θ 2 pi) (* 1/8 (sin (* 8 ϕ))))) (plot3d (list (polar3d f1 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) (polar3d f2 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3))))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] +} + +@defproc[(parametric-surface3d + [f (real? real? . -> . (sequence/c real?))] + [s-min rational?][s-max rational?] + [t-min rational?][t-max rational?] + [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] + [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] + [#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f] + [#:samples samples (and/c exact-integer? (>=/c 2)) (plot3d-samples)] + [#:s-samples s-samples (and/c exact-integer? (>=/c 2)) samples] + [#:t-samples t-samples (and/c exact-integer? (>=/c 2)) samples] + [#:color color plot-color/c (surface-color)] + [#:style style plot-brush-style/c (surface-style)] + [#:line-color line-color plot-color/c (surface-line-color)] + [#:line-width line-width (>=/c 0) (surface-line-width)] + [#:line-style line-style plot-pen-style/c (surface-line-style)] + [#:alpha alpha (real-in 0 1) (surface-alpha)] + [#:label label (or/c string? pict? #f) #f] + ) renderer3d?]{ +Returns a renderer that plots a two-input, one-output function. @racket[(f s t)] → @racket['(x y z)] + +For example, + @interaction[#:eval plot-eval + (plot3d (list + (parametric-surface3d + (λ (θ ϕ) + (list (* (+ 5 (sin ϕ)) (sin θ)) + (* (+ 5 (sin ϕ)) (cos θ)) + (+ 0 (cos ϕ)))) + 0 (* 2 pi) #:s-samples 50 + 0 (* 2 pi) + #:label "torus1") + (parametric-surface3d + (λ (θ ϕ) + (list (+ 4 (* (+ 3 (sin ϕ)) (sin θ))) + (+ 0 (cos ϕ)) + (* (+ 3 (sin ϕ)) (cos θ)))) + 0 (* 2 pi) #:s-samples 30 + 0 (* 2 pi) + #:color 4 + #:label "torus2")) + #:z-min -6 #:z-max 6 + #:altitude 22)] + +@history[#:changed "7.9" "Added support for pictures for #:label"] +} + +@defproc[(polygons3d + [vs (sequence/c (sequence/c (sequence/c real?)))] + [#:x-min x-min (or/c rational? #f) #f] [#:x-max x-max (or/c rational? #f) #f] + [#:y-min y-min (or/c rational? #f) #f] [#:y-max y-max (or/c rational? #f) #f] + [#:z-min z-min (or/c rational? #f) #f] [#:z-max z-max (or/c rational? #f) #f] + [#:color color plot-color/c (surface-color)] + [#:style style plot-brush-style/c (surface-style)] + [#:line-color line-color plot-color/c (surface-line-color)] + [#:line-width line-width (>=/c 0) (surface-line-width)] + [#:line-style line-style plot-pen-style/c (surface-line-style)] + [#:alpha alpha (real-in 0 1) (surface-alpha)] + [#:label label (or/c string? pict? #f) #f] + ) renderer3d?]{ +Returns a renderer that draws polygons. +The @racket[parametric-surface3d] function is defined in terms of this one. + @interaction[#:eval plot-eval (plot3d + (polygons3d (list (list (list 1 0 0)(list 0 0 1)(list 0 1 0)(list 1 1 1)) + (list (list 0 0 0)(list 0 0 1)(list 0 1 0)) + (list (list 1 0 0)(list 0 1 0)(list 0 0 0)))) + #:angle 355 + #:altitude 30)] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{3D Contour (Isoline) Renderers} @@ -194,7 +300,7 @@ Combining polar function renderers allows faking latitudes or longitudes in larg [#:width width (>=/c 0) (line-width)] [#:style style plot-pen-style/c (line-style)] [#:alpha alpha (real-in 0 1) (line-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots a single contour line on the surface of a function. @@ -205,6 +311,8 @@ This function is not terribly useful by itself, but can be when combined with ot (define (saddle x y) (- (sqr x) (sqr y))) (plot3d (list (surface3d saddle -1 1 -1 1) (isoline3d saddle 1/4 #:width 2 #:style 'long-dash)))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(contours3d @@ -218,7 +326,7 @@ This function is not terribly useful by itself, but can be when combined with ot [#:widths widths (pen-widths/c (listof real?)) (contour-widths)] [#:styles styles (plot-pen-styles/c (listof real?)) (contour-styles)] [#:alphas alphas (alphas/c (listof real?)) (contour-alphas)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots contour lines on the surface of a function. @@ -227,7 +335,9 @@ In particular, when @(racket levels) is @(racket 'auto), contour values correspo For example, @interaction[#:eval plot-eval (plot3d (contours3d (λ (x y) (+ (sqr x) (sqr y))) -1.1 1.1 -1.1 1.1 - #:label "z = x^2 + y^2"))] + #:label "z = x² + y²"))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(contour-intervals3d @@ -246,7 +356,7 @@ For example, [#:contour-widths contour-widths (pen-widths/c (listof real?)) (contour-widths)] [#:contour-styles contour-styles (plot-pen-styles/c (listof real?)) (contour-styles)] [#:alphas alphas (alphas/c (listof ivl?)) (contour-interval-alphas)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots contour intervals and contour lines on the surface of a function. The appearance keyword arguments are interpreted identically to the appearance keyword arguments to @(racket contour-intervals). @@ -254,7 +364,9 @@ The appearance keyword arguments are interpreted identically to the appearance k For example, @interaction[#:eval plot-eval (plot3d (contour-intervals3d (λ (x y) (+ (sqr x) (sqr y))) -1.1 1.1 -1.1 1.1 - #:label "z = x^2 + y^2"))] + #:label "z = x² + y²"))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{3D Isosurface Renderers} @@ -271,7 +383,7 @@ For example, [#:line-width line-width (>=/c 0) (surface-line-width)] [#:line-style line-style plot-pen-style/c (surface-line-style)] [#:alpha alpha (real-in 0 1) (surface-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots the surface of constant output value of the function @(racket f). The argument @(racket d) is the constant value. @@ -280,6 +392,8 @@ For example, a sphere is all the points in which the Euclidean distance function (λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) 1 -1 1 -1 1 -1 1) #:altitude 25)] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(isosurfaces3d @@ -296,7 +410,7 @@ For example, a sphere is all the points in which the Euclidean distance function [#:line-widths line-widths (pen-widths/c (listof real?)) (isosurface-line-widths)] [#:line-styles line-styles (plot-pen-styles/c (listof real?)) (isosurface-line-styles)] [#:alphas alphas (alphas/c (listof real?)) (isosurface-alphas)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that plots multiple isosurfaces. The appearance keyword arguments are interpreted similarly to those of @(racket contours). @@ -309,6 +423,8 @@ Use this to visualize functions from three inputs to one output; for example: #:z-min -2 #:z-max 2)] If it helps, think of the output of @(racket f) as a density or charge. + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @section{3D Rectangle Renderers} @@ -324,7 +440,7 @@ If it helps, think of the output of @(racket f) as a density or charge. [#:line-width line-width (>=/c 0) (rectangle3d-line-width)] [#:line-style line-style plot-pen-style/c (rectangle-line-style)] [#:alpha alpha (real-in 0 1) (rectangle-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] ) renderer3d?]{ Returns a renderer that draws rectangles. @@ -347,6 +463,8 @@ This can be used to draw histograms; for example, (vector x-ivl y-ivl (ivl 0 z))))) #:alpha 3/4 #:label "Appx. 2D Normal"))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(discrete-histogram3d @@ -362,7 +480,7 @@ This can be used to draw histograms; for example, [#:line-width line-width (>=/c 0) (rectangle3d-line-width)] [#:line-style line-style plot-pen-style/c (rectangle-line-style)] [#:alpha alpha (real-in 0 1) (rectangle-alpha)] - [#:label label (or/c string? #f) #f] + [#:label label (or/c string? pict? #f) #f] [#:add-x-ticks? add-x-ticks? boolean? #t] [#:add-y-ticks? add-y-ticks? boolean? #t] [#:x-far-ticks? x-far-ticks? boolean? #f] @@ -375,6 +493,8 @@ Missing pairs are not drawn; for example, (plot3d (discrete-histogram3d '(#(a a 1) #(a b 2) #(b b 3)) #:label "Missing (b,a)" #:color 4 #:line-color 4))] + +@history[#:changed "7.9" "Added support for pictures for #:label"] } @defproc[(stacked-histogram3d @@ -423,3 +543,9 @@ Returns a renderer that draws a labeled point. If @(racket label) is @(racket #f), the point is labeled with its position. Analogous to @racket[point-label]. } + +@; Needs a timeout for testing: +@(module* test racket/base + (require (submod "..")) + (module config info + (define timeout 180))) diff --git a/plot-doc/plot/scribblings/ticks.scrbl b/plot-doc/plot/scribblings/ticks.scrbl index c8bcecbe..c9dcf17f 100644 --- a/plot-doc/plot/scribblings/ticks.scrbl +++ b/plot-doc/plot/scribblings/ticks.scrbl @@ -175,7 +175,7 @@ This convenience function is used internally to transform points before renderin @section[#:tag "ticks"]{Axis Ticks} -Each plot axis has two indepedent sets of ticks: the @italic{near} ticks and the @italic{far} ticks. +Each plot axis has two independent sets of ticks: the @italic{near} ticks and the @italic{far} ticks. @deftogether[(@defparam[plot-x-ticks ticks ticks? #:value (linear-ticks)] @defparam[plot-x-far-ticks ticks ticks? #:value (ticks-mimic plot-x-ticks)] @@ -207,7 +207,7 @@ They are always identical by default. Minor tick labels are never drawn. Renderers produced by @racket[contours] and @racket[contour-intervals] use the value of @racket[plot-z-ticks] to place and label contour lines. -For example, compare plots of the same function renderered using both @racket[contour-intervals] and @racket[contour-intervals3d]: +For example, compare plots of the same function rendered using both @racket[contour-intervals] and @racket[contour-intervals3d]: @interaction[#:eval plot-eval (parameterize ([plot-z-ticks (currency-ticks)]) (define (saddle x y) (- (sqr x) (sqr y))) @@ -242,7 +242,7 @@ The ticks used for radius lines in @racket[polar-axes]. } @defstruct[ticks ([layout ticks-layout/c] [format ticks-format/c])]{ -A @racket[ticks] for a near or far axis consists of a @racket[layout] function, which determines the number of ticks and where they will be placed, and a @racket[format] function, which determines the ticks' labels. +A @racket[ticks] for a near or far axis consists of a @racket[_layout] function, which determines the number of ticks and where they will be placed, and a @racket[_format] function, which determines the ticks' labels. } @defproc[(ticks-generate [ticks ticks?] [min real?] [max real?]) (listof tick?)]{ @@ -271,9 +271,10 @@ For example, the following plot shows the actual number of major ticks for the i @deftogether[(@defproc[(linear-ticks-layout [#:number number exact-positive-integer? (ticks-default-number)] [#:base base (and/c exact-integer? (>=/c 2)) 10] - [#:divisors divisors (listof exact-positive-integer?) '(1 2 4 5)]) + [#:divisors divisors (listof exact-positive-integer?) '(1 2 4 5)] + [#:scientific? scientific? #t]) ticks-layout/c] - @defproc[(linear-ticks-format) ticks-format/c] + @defproc[(linear-ticks-format [#:scientific? scientific? #t]) ticks-format/c] @defproc[(linear-ticks [#:number number exact-positive-integer? (ticks-default-number)] [#:base base (and/c exact-integer? (>=/c 2)) 10] [#:divisors divisors (listof exact-positive-integer?) '(1 2 4 5)]) @@ -284,7 +285,10 @@ To lay out ticks, @racket[linear-ticks-layout] finds the power of @racket[base] @margin-note*{For strategic use of non-default arguments, see @racket[bit/byte-ticks], @racket[currency-ticks], and @racket[fraction-ticks].} The default arguments correspond to the standard 1-2-5-in-base-10 rule used almost everywhere in plot tick layout. -To format ticks, @racket[linear-ticks-format] uses @racket[real->plot-label], and uses @racket[digits-for-range] to determine the maximum number of fractional digits in the decimal expansion. +To format ticks, @racket[linear-ticks-format] uses @racket[real->plot-label] passing the value of @racket[scientific?], and uses @racket[digits-for-range] to determine the maximum number of fractional digits in the decimal expansion. + +@history[#:changed "1.1" @elem{Added the @racket[#:scientific?] argument to @racket[linear-ticks-format] and @racket[linear-ticks].}] + } @subsection{Log Ticks} @@ -292,16 +296,19 @@ To format ticks, @racket[linear-ticks-format] uses @racket[real->plot-label], an @deftogether[(@defproc[(log-ticks-layout [#:number number exact-positive-integer? (ticks-default-number)] [#:base base (and/c exact-integer? (>=/c 2)) 10]) ticks-layout/c] - @defproc[(log-ticks-format [#:base base (and/c exact-integer? (>=/c 2)) 10]) + @defproc[(log-ticks-format [#:base base (and/c exact-integer? (>=/c 2)) 10] + [#:scientific? scientific? #t]) ticks-format/c] @defproc[(log-ticks [#:number number exact-positive-integer? (ticks-default-number)] - [#:base base (and/c exact-integer? (>=/c 2)) 10]) + [#:base base (and/c exact-integer? (>=/c 2)) 10] + [#:scientific? scientific? #t]) ticks?])]{ The layout function, format function, and combined @racket[ticks] for exponentially spaced major ticks. (The minor ticks between are uniformly spaced.) Use these ticks for @racket[log-transform]ed axes, because when exponentially spaced tick positions are @racket[log-transform]ed, they become uniformly spaced. The @racket[#:base] keyword argument is the logarithm base. +The @racket[#:scientific] keyword argument disables scientific formatting, similarly to @racket[linear-ticks]. See @racket[plot-z-far-ticks] for an example of use. } @@ -474,7 +481,7 @@ Short-scale suffix abbreviations as commonly used in the United Kingdom since sw European Union long-scale suffix abbreviations, which stand for ``kilo,'' ``million,'' ``milliard,'' and ``billion.'' The abbreviations actually used vary with geography, even within countries, but these seem to be common. -Further long-scale suffix abbreviations such as for ``billiard'' are ommitted due to lack of even weak consensus. +Further long-scale suffix abbreviations such as for ``billiard'' are omitted due to lack of even weak consensus. } @defthing[us-currency-formats (list/c string? string? string?) #:value '("~$~w.~f~s" "(~$~w.~f~s)" "~$0")]{ @@ -530,7 +537,7 @@ The layout function, format function, and combined @racket[ticks] for no ticks w [#:size size (or/c 'byte 'bit) 'byte] [#:kind kind (or/c 'CS 'SI) 'CS]) ticks?])]{ -The format function and and combined @racket[ticks] for bit or byte values. +The format function and combined @racket[ticks] for bit or byte values. The @racket[#:kind] keyword argument indicates either International System of Units (@racket['SI]) suffixes, as used to communicate hard drive capacities, or Computer Science (@racket['CS]) suffixes, as used to communicate memory capacities. @@ -547,7 +554,7 @@ For layout, @racket[bit/byte-ticks] uses @racket[linear-ticks-layout] with @defproc[(fraction-ticks [#:base base (and/c exact-integer? (>=/c 2)) 10] [#:divisors divisors (listof exact-positive-integer?) '(1 2 3 4 5)]) ticks?])]{ -The format function and and combined @racket[ticks] for fraction-formatted values. +The format function and combined @racket[ticks] for fraction-formatted values. For layout, @racket[fraction-ticks] uses @racket[linear-ticks-layout], passing it the given @racket[divisors]. } @@ -568,7 +575,7 @@ Unlike with typical @secref["transforms"], @racket[fun] is allowed to transform (See @racket[make-axis-transform] for an explanation about transforming endpoints.) Use @racket[ticks-scale] to plot values at multiple scales simultaneously, with one scale on the near axis and one scale on the far axis. -The following example plots degrees Celsius on the left and degrees Farenheit on the right: +The following example plots degrees Celsius on the left and degrees Fahrenheit on the right: @interaction[#:eval plot-eval (parameterize ([plot-x-ticks (time-ticks)] @@ -599,11 +606,31 @@ Represents a tick with a label. } @defthing[ticks-layout/c contract? #:value (-> real? real? (listof pre-tick?))]{ -The contract for tick layout functions. Note that a layout function returns @racket[pre-tick]s, or unlabeled ticks. + + The contract for tick layout functions in @racket[ticks] structures. The + function receives axis bounds and returns a list of @racket[pre-tick]s to be + shown on the axis. + + Note that the layout function returns @racket[pre-tick]s, or unlabeled + ticks, and a separate format function is used to produce the labels for the + ticks. + } @defthing[ticks-format/c contract? #:value (-> real? real? (listof pre-tick?) (listof string?))]{ -The contract for tick format functions. A format function receives axis bounds so it can determine how many decimal digits to display (usually by applying @racket[digits-for-range] to the bounds). + + The contract for tick format functions in @racket[ticks] structures. The + format function receives axis bounds and a list of @racket[pre-tick]s. It + must return a label for each @racket[pre-tick] in this list. + + The returned labels should be usually distinct, as the plot library will + consider ticks with labels that are @racket[string=?] to be duplicates and + collapse them, however, this feature can be used by a custom format function + to force removal of some ticks from the plot. + + Axis bounds can be used to determine how many decimal digits to display, + usually by applying @racket[digits-for-range] to the bounds. + } @section[#:tag "invertible"]{Invertible Functions} diff --git a/plot-doc/plot/scribblings/utils.scrbl b/plot-doc/plot/scribblings/utils.scrbl index 13a022b8..419e79dc 100644 --- a/plot-doc/plot/scribblings/utils.scrbl +++ b/plot-doc/plot/scribblings/utils.scrbl @@ -146,6 +146,13 @@ Given optionally weighted samples and a kernel bandwidth, returns a function rep Used by @(racket density). } +@defproc[(silverman-bandwidth [xs (listof real?)]) + real?]{ +Returns the Silverman Bandwidth estimator for the given samples. This is used as the default bandwidth by the @racket[violin] renderer. See the @hyperlink["https://en.wikipedia.org/wiki/Kernel_density_estimation"]{kernel density estimation} Wikipedia article for more details. + +@history[#:added "8.5"] +} + @;==================================================================================================== @section{Plot Colors and Styles} @@ -190,11 +197,11 @@ Use @(racket ->pen-color) and @(racket ->brush-color) to convert integers. } @defproc[(->pen-color [c plot-color/c]) (list/c real? real? real?)]{ -Converts a @italic{line} color to an RGB triplet. This function interprets integer colors as darker and more saturated than @(racket ->brush-color) does. -Non-integer colors are converted using @(racket ->color). -Integer colors are chosen for good pairwise contrast, especially between neighbors. -Integer colors repeat starting with @(racket 128). +Convert a @italic{line} color to an RGB triplet. Integer colors are looked up +in the current @racket[plot-pen-color-map], and non-integer colors are +converted using @(racket ->color). When the integer color is larger than the +number of colors in the color map, it will wrap around. @examples[#:eval plot-eval (equal? (->pen-color 0) (->pen-color 8)) @@ -204,12 +211,15 @@ Integer colors repeat starting with @(racket 128). #:colors (map ->pen-color (build-list 8 values))))] } +The example above is using the internal color map, with +@racket[plot-pen-color-map] set to @racket[#f]. + @defproc[(->brush-color [c plot-color/c]) (list/c real? real? real?)]{ -Converts a @italic{fill} color to an RGB triplet. This function interprets integer colors as lighter and less saturated than @(racket ->pen-color) does. -Non-integer colors are converted using @(racket ->color). -Integer colors are chosen for good pairwise contrast, especially between neighbors. -Integer colors repeat starting with @(racket 128). +Convert a @italic{fill} color to an RGB triplet. Integer colors are looked up +in the current @racket[plot-brush-color-map] and non-integer colors are +converted using @(racket ->color). When the integer color is larger than the +number of colors in the color map, it will wrap around. @examples[#:eval plot-eval (equal? (->brush-color 0) (->brush-color 8)) @@ -218,7 +228,11 @@ Integer colors repeat starting with @(racket 128). #:levels 7 #:contour-styles '(transparent) #:colors (map ->brush-color (build-list 8 values))))] -In the above example, @(racket map)ping @(racket ->brush-color) over the list is actually unnecessary, because @(racket contour-intervals) uses @(racket ->brush-color) internally to convert fill colors. +The example above is using the internal color map, with +@racket[plot-brush-color-map] is set to @racket[#f]. In this example, @(racket +map)ping @(racket ->brush-color) over the list is actually unnecessary, +because @(racket contour-intervals) uses @(racket ->brush-color) internally to +convert fill colors. The @(racket function-interval) function generally plots areas using a fill color and lines using a line color. Both kinds of color have the default value @(racket 3). @@ -251,6 +265,34 @@ Integer brush styles repeat starting at @(racket 7). (map ->brush-style '(4 5 6))] } +@defproc[(color-map-names) (listof symbol?)]{ + +Return the list of available color map names to be used by +@racket[plot-pen-color-map] and @racket[plot-brush-color-map]. + +@history[#:added "7.3"] + +} + +@defproc[(color-map-size (name symbol?)) integer?]{ + +Return the number of colors in the color map @racket[name]. If @racket[name] +is not a valid color map name, the function will signal an error. + +@history[#:added "7.3"] + +} + +@defproc[(register-color-map (name symbol?) (color-map (vectorof (list byte? byte? byte?)))) void]{ + +Register a new color map @racket[name] with the colors being a vector of RGB +triplets. If a color map by that name already exists, it is replaced. + +@history[#:added "7.3"] + +} + + @;==================================================================================================== @section{Plot-Specific Math} @@ -258,7 +300,7 @@ Integer brush styles repeat starting at @(racket 7). @subsection{Real Functions} @defproc[(polar->cartesian [θ real?] [r real?]) (vector/c real? real?)]{ -Converts 2D polar coordinates to 3D cartesian coordinates. +Converts 2D polar coordinates to 2D cartesian coordinates. } @defproc[(3d-polar->3d-cartesian [θ real?] [ρ real?] [r real?]) (vector/c real? real? real?)]{ @@ -291,6 +333,20 @@ Returns @racket[#f] if @racket[x] is @racket[#f]; otherwise @racket[(inexact->ex Use this to convert interval endpoints, which may be @racket[#f], to exact numbers. } +@deftogether[( + @defproc[(min* [r real?] ...) real?] + @defproc[(max* [r real?] ...) real?] +)]{ + Compute the @racket[min] or @racket[max] of a sequence of numbers. + + @examples[#:eval plot-eval + (min* 3 5 4 2 1) + (max* 3 5 4 2 1) + (min*) + (max*) + ] +} + @;---------------------------------------------------------------------------------------------------- @subsection[#:tag "math.vectors"]{Vector Functions} @@ -547,3 +603,136 @@ Convert @racket[plot-time]s to real seconds, and vice-versa. (plot-time+ (plot-time 32 0 12 1) (plot-time 32 0 14 1))] } + +@section{Plot Metrics} + +@definterface[plot-metrics<%> ()]{ + + The @racket[plot-metrics<%>] interface allows obtaining plot area positions + on the plots returned by @racket[plot], @racket[plot-snip], + @racket[plot-bitmap], @racket[plot/dc], as well as their 3D variants, + @racket[plot3d], @racket[plot3d-snip], @racket[plot3d-bitmap] and + @racket[plot3d/dc]. All plot objects returned by these functions implement + this interface. + + For plots created by @racket[plot-pict] and @racket[plot3d-pict], there is a + separate set of functions that provide the same functionality, for example, + see @racket[plot-pict-bounds]. + + @defmethod[(get-plot-bounds) (vectorof (vector/c real? real?))]{ + + Return the bounds of the plot as a vector of minimum and maximum values, + one for each axis in the plot. For 2D plots, this method returns a vector + of two elements, for the X and Y axes, while 3D plots return a vector of + three elements for the X, Y and Z axes. + + The values returned are in plot coordinates, to obtain the coordinates on + the drawing surface (i.e. image coordinates), use @method[plot-metrics<%> + plot->dc] on these bounds. + + Plot bounds for interactive plots, like those produced by @racket[plot] + and @racket[plot-snip], can change as the user zoom in and out the plot, + @method[plot-metrics<%> get-plot-bounds] always returns the current bounds + of the plot, but they might be invalidated by a user operation. + + } + + @defmethod[(plot->dc [coordinates (vectorof real?)]) (vectorof real?)]{ + + Convert @racket[coordinates] from plot coordinate system to the drawing + coordinate system (that is, image coordinates). For 2D plots, + @racket[coordinates] is a vector of two values, the X and Y coordinates on + the plot, while for 3D plots it is a vector of three values, the X, Y and + Z coordinates. + + This method can be used, for example, to determine the actual location on + the image where the coordinates @racket[0], @racket[0] are. It can also + be used to determine the location of the plot area inside the image, by + calling it on the plot bounds returned by @method[plot-metrics<%> get-plot-bounds]. + + For interactive plots, the coordinates might change as the user zooms in + and out the plot. + + } + + @defmethod[(dc->plot [coordinates (vectorof real?)]) (vectorof real?)]{ + + For 2D plots, this method returns the 2D plot coordinates that correspond + to the input @racket[coordinates], which are in the draw context + coordinate system. + + For 3D plots, this method returns a 3D position on the plane perpendicular + to the user view for the plot. Together with the normal vector for this + plane, returned by @method[plot-metrics<%> plane-vector], the projection + line can be reconstructed. + + This is the reverse operation from @method[plot-metrics<%> plot->dc] and + same remark about the user zooming in and out the plot applies. + + } + + @defmethod[(plane-vector) (vectorof real?)]{ + + Return the unit vector representing the normal of the screen through the + plot origin. For 2D plots this always returns @racket[#(0 0 1)], for 3D + plots this unit vector can be used to reconstruct plot coordinates from + draw context coordinates. + + For interactive 3D plots, the returned value will change if the user + rotates the plot. + + } + + @history[#:added "8.1"] +} + +@defproc[(plot-pict? [any any/c]) boolean?]{ + + Return @racket[#t] if @racket[any] is a plot returned by @racket[plot-pict]. + This can be used to determine if the functions @racket[plot-pict-bounds], + @racket[plot-pict-plot->dc], @racket[plot-pict-dc->plot] and + @racket[plot-pict-plane-vector] can be called on it. + + @history[#:added "8.1"] + +} + +@defproc[(plot-pict-bounds [plot plot-pict?]) (vectorof (vector/c real? real?))]{ + + Return the bounds of the plot returned by @racket[plot-pict]. See + @method[plot-metrics<%> get-plot-bounds] for more details. + + @history[#:added "8.1"] + +} + +@defproc[(plot-pict-plot->dc [plot plot-pict?] [coordinates (vectorof real?)]) + (vectorof real?)]{ + + Convert the plot @racket[coordinates] to draw context coordinates for the + @racket[plot]. See @method[plot-metrics<%> plot->dc] for more details. + + @history[#:added "8.1"] + +} + +@defproc[(plot-pict-dc->plot [plot plot-pict?] [coordinates (vectorof real?)]) + (vectorof real?)]{ + + Convert the draw contect @racket[coordinates] to plot coordinates for the + @racket[plot]. See @method[plot-metrics<%> dc->plot] for more details. + + @history[#:added "8.1"] + +} + +@defproc[(plot-pict-plane-vector [plot plot-pict?]) (vectorof real?)]{ + + Return the unit vector representing the normal of the screen through the + plot origin. For 2D plots this always returns @racket[#(0 0 1)], for 3D + plots this can be used to reconstruct plot coordinates from draw context + coordinates. See @method[plot-metrics<%> plane-vector] for more details. + + @history[#:added "8.1"] + +} diff --git a/plot-gui-lib/LICENSE.txt b/plot-gui-lib/LICENSE.txt deleted file mode 100644 index dbb89375..00000000 --- a/plot-gui-lib/LICENSE.txt +++ /dev/null @@ -1,11 +0,0 @@ -plot -Copyright (c) 2010-2014 PLT Design Inc. - -This package is distributed under the GNU Lesser General Public -License (LGPL). This means that you can link this package into proprietary -applications, provided you follow the rules stated in the LGPL. You -can also modify this package; if you distribute a modified version, -you must distribute it under the terms of the LGPL, which in -particular means that you must release the source code for the -modified software. See http://www.gnu.org/copyleft/lesser.html -for more information. diff --git a/plot-gui-lib/info.rkt b/plot-gui-lib/info.rkt index e3f4ca91..6d8946cd 100644 --- a/plot-gui-lib/info.rkt +++ b/plot-gui-lib/info.rkt @@ -15,3 +15,10 @@ (define pkg-desc "Plot GUI interface") (define pkg-authors '(ntoronto)) + +(define version "1.1") + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT)) diff --git a/plot-gui-lib/plot/private/gui/gui.rkt b/plot-gui-lib/plot/private/gui/gui.rkt index aba44ac2..215c28f6 100644 --- a/plot-gui-lib/plot/private/gui/gui.rkt +++ b/plot-gui-lib/plot/private/gui/gui.rkt @@ -16,9 +16,8 @@ (super-new))) -(define (make-snip-frame snip width height label) - (define (make-snip w h) snip) - +(define (make-snip-frame make-snip width height label) + (define frame (new snip-frame% [label label] [width (+ 20 width)] [height (+ 20 height)])) diff --git a/plot-gui-lib/plot/private/gui/lazy-snip-typed.rkt b/plot-gui-lib/plot/private/gui/lazy-snip-typed.rkt index 10be8562..fa4beabf 100644 --- a/plot-gui-lib/plot/private/gui/lazy-snip-typed.rkt +++ b/plot-gui-lib/plot/private/gui/lazy-snip-typed.rkt @@ -6,7 +6,8 @@ (provide make-2d-plot-snip make-3d-plot-snip - make-snip-frame) + make-snip-frame + Plot-Snip%) (type-environment [make-2d-plot-snip (parse-type #'Make-2D-Plot-Snip)] diff --git a/plot-gui-lib/plot/private/gui/lazy-snip-types.rkt b/plot-gui-lib/plot/private/gui/lazy-snip-types.rkt index d90a0d43..58d84dd3 100644 --- a/plot-gui-lib/plot/private/gui/lazy-snip-types.rkt +++ b/plot-gui-lib/plot/private/gui/lazy-snip-types.rkt @@ -5,30 +5,33 @@ (provide (all-defined-out)) +(define-type Plot-Snip% (Class #:implements Snip% #:implements Plot-Metrics<%>)) + (define-type Make-2D-Plot-Snip (-> (Instance Bitmap%) Plot-Parameters (-> Boolean Rect Positive-Integer Positive-Integer - (Values (Instance Bitmap%) Rect (-> Rect Rect))) - Rect + (Values (Instance Bitmap%) (U #f (Instance 2D-Plot-Area%)))) Rect - (-> Rect Rect) + (U #f (Instance 2D-Plot-Area%)) Positive-Integer Positive-Integer - (Instance Snip%))) + (Instance Plot-Snip%))) (define-type Make-3D-Plot-Snip (-> (Instance Bitmap%) Plot-Parameters - (-> Boolean Real Real Positive-Integer Positive-Integer (Instance Bitmap%)) + (-> Boolean Real Real Positive-Integer Positive-Integer + (Values (Instance Bitmap%) (U #f (Instance 3D-Plot-Area%)))) Real Real + (U #f (Instance 3D-Plot-Area%)) Positive-Integer Positive-Integer - (Instance Snip%))) + (Instance Plot-Snip%))) (define-type Make-Snip-Frame - (-> (Instance Snip%) + (-> (-> Positive-Integer Positive-Integer (Instance Snip%)) Positive-Real Positive-Real String diff --git a/plot-gui-lib/plot/private/gui/lazy-snip-untyped.rkt b/plot-gui-lib/plot/private/gui/lazy-snip-untyped.rkt index ba1ca694..3e2dbf4d 100644 --- a/plot-gui-lib/plot/private/gui/lazy-snip-untyped.rkt +++ b/plot-gui-lib/plot/private/gui/lazy-snip-untyped.rkt @@ -13,17 +13,17 @@ (define (-make-2d-plot-snip init-bm saved-plot-parameters - make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height) + make-bm plot-bounds-rect area width height) (make-2d-plot-snip init-bm saved-plot-parameters - make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height)) + make-bm plot-bounds-rect area width height)) (define (-make-3d-plot-snip init-bm saved-plot-parameters - make-bm angle altitude width height) + make-bm angle altitude area width height) (make-3d-plot-snip init-bm saved-plot-parameters - make-bm angle altitude width height)) + make-bm angle altitude area width height)) (define (-make-snip-frame snip width height label) (make-snip-frame snip width height label)) diff --git a/plot-gui-lib/plot/private/gui/plot2d.rkt b/plot-gui-lib/plot/private/gui/plot2d.rkt index d8a4fbc3..f8bf1455 100644 --- a/plot-gui-lib/plot/private/gui/plot2d.rkt +++ b/plot-gui-lib/plot/private/gui/plot2d.rkt @@ -1,7 +1,38 @@ -#lang typed/racket/base +#lang typed/racket/base #:no-optimize + +;;;; About `#:no-optimize` and `unsafe-provide` + +;; This file provides the toplevel plot functions for 2D plotting and there +;; are two peculiarities in this file: the use of `#:no-optimize` and using +;; `unsafe-provide` to export the symbols. +;; +;; The plot library is written in Typed Racket (TR), but needs to be usable +;; from Racket. TR will attach contracts to all functions it exports (as well +;; as values those functions return) to ensure the values for the parameters +;; are correct when these functions are called from Racket. Unfortunately, +;; when returning the snips for the plots, the attached contracts to the snip +;; interface will slow down interactive programs significantly. To avoid this +;; problem, the plot functions are exported using `unsafe-provide`, which will +;; tell TR to not create contracts for the function parameters and return +;; values. +;; +;; Using `unsafe-provide` leaves the functions vulnerable to bad parameter +;; passing: TR will still assume the parameters have valid values, and will +;; not perform any other checks, which can result in a crash (segmentation +;; fault). To mitigate this problem, there is code inside each plot function +;; to verify that the parameters are correct. Unfortunately, TR will also +;; notice that those checks are redundant (since it knows the types for the +;; parameters) and will remove this parameter verification code during the +;; optimization phase. To prevent this removal, optimizations are disabled in +;; this file using the #:no-optimize line above. +;; +;; The #:no-optimize only applies to this file, which is the "entry point" of +;; the plot package, so the rest of the plot package remains optimized. (require (only-in typed/mred/mred Snip% Frame%) + (only-in racket/gui/base get-display-backing-scale) typed/racket/draw typed/racket/class racket/match + (only-in typed/pict pict pict?) plot/utils plot/private/common/parameter-group plot/private/common/draw @@ -11,11 +42,17 @@ plot/private/plot2d/plot-area plot/private/no-gui/plot2d plot/private/no-gui/plot2d-utils - "lazy-snip-typed.rkt") + "lazy-snip-typed.rkt" + typed/racket/unsafe) + +(unsafe-provide plot-snip + plot-frame + plot) -(provide plot-snip - plot-frame - plot) +(require/typed plot/utils + (legend-anchor/c (-> Any Boolean)) + (plot-color/c (-> Any Boolean)) + (plot-file-format/c (-> Any Boolean))) ;; =================================================================================================== ;; Plot to a snip @@ -26,11 +63,12 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] - (Instance Snip%))) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance Plot-Snip%))) (define (plot-snip renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -39,65 +77,57 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/kw (make-raise-keyword-error 'plot-snip)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] - [else - (parameterize ([plot-title title] - [plot-x-label x-label] - [plot-y-label y-label] - [plot-legend-anchor legend-anchor]) - (define saved-plot-parameters (plot-parameters)) - (define renderer-list (get-renderer-list renderer-tree)) - (define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max)) - - (: make-bm (-> Boolean Rect Positive-Integer Positive-Integer - (Values (Instance Bitmap%) Rect (-> Rect Rect)))) - (define (make-bm anim? bounds-rect width height) - (: area (U #f (Instance 2D-Plot-Area%))) - (define area #f) - (define bm - (parameterize/group ([plot-parameters saved-plot-parameters] - [plot-animating? (if anim? #t (plot-animating?))]) - ((if (plot-animating?) draw-bitmap draw-bitmap/supersampling) - (λ (dc) - (define-values (x-ticks x-far-ticks y-ticks y-far-ticks) - (get-ticks renderer-list bounds-rect)) - - (define new-area - (make-object 2d-plot-area% - bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks - dc 0 0 width height)) - - (set! area new-area) - - (plot-area new-area renderer-list)) - width height))) - - (: area-bounds->plot-bounds (-> Rect Rect)) - (define (area-bounds->plot-bounds rect) - (let ([area (assert area values)]) - (match-define (vector (ivl area-x-min area-x-max) (ivl area-y-min area-y-max)) rect) - (let ([area-x-min (assert area-x-min values)] - [area-x-max (assert area-x-max values)] - [area-y-min (assert area-y-min values)] - [area-y-max (assert area-y-max values)]) - (match-define (vector x-min y-min) (send area dc->plot (vector area-x-min area-y-min))) - (match-define (vector x-max y-max) (send area dc->plot (vector area-x-max area-y-max))) - (vector (ivl x-min x-max) (ivl y-min y-max))))) - - (values bm (send (assert area values) get-area-bounds-rect) area-bounds->plot-bounds)) - - (define-values (bm area-bounds-rect area-bounds->plot-bounds) - (make-bm #f bounds-rect width height)) - - (make-2d-plot-snip - bm saved-plot-parameters - make-bm bounds-rect area-bounds-rect area-bounds->plot-bounds width height))])) + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)]) + + (parameterize ([plot-title title] + [plot-x-label x-label] + [plot-y-label y-label] + [plot-legend-anchor legend-anchor]) + (define saved-plot-parameters (plot-parameters)) + (define renderer-list (get-renderer-list renderer-tree)) + (define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max)) + + (: make-bm (-> Boolean Rect Positive-Integer Positive-Integer + (Values (Instance Bitmap%) (U #f (Instance 2D-Plot-Area%))))) + (define (make-bm anim? bounds-rect width height) + (: area (U #f (Instance 2D-Plot-Area%))) + (define area #f) + (define bm (make-bitmap + width height #t + #:backing-scale (or (get-display-backing-scale) 1.0))) + (parameterize/group ([plot-parameters saved-plot-parameters] + [plot-animating? (if anim? #t (plot-animating?))]) + (define dc (make-object bitmap-dc% bm)) + (define-values (x-ticks x-far-ticks y-ticks y-far-ticks) + (get-ticks renderer-list bounds-rect)) + (define legend (get-legend-entry-list renderer-list bounds-rect)) + (define new-area + (make-object 2d-plot-area% + bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks legend + dc 0 0 width height aspect-ratio)) + (set! area new-area) + (plot-area new-area renderer-list)) + (values bm area)) + + (define-values (bm area) (make-bm #f bounds-rect width height)) + + (make-2d-plot-snip bm saved-plot-parameters make-bm bounds-rect area width height))) ;; =================================================================================================== ;; Plot to a frame @@ -108,10 +138,11 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] (Instance Frame%))) (define (plot-frame renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] @@ -121,20 +152,36 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/kw (make-raise-keyword-error 'plot-frame)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] - [else - (define snip - (plot-snip - renderer-tree - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) - (make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot"))])) + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)]) + + ;; make-snip will be called in a separate thread, make sure the + ;; parameters have the correct values in that thread as well. + (define saved-plot-parameters (plot-parameters)) + (: make-snip (-> Positive-Integer Positive-Integer (Instance Snip%))) + (define (make-snip width height) + (parameterize/group ([plot-parameters saved-plot-parameters]) + (plot-snip + renderer-tree + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio))) + (make-snip-frame make-snip width height (if title (format "Plot: ~a" title) "Plot"))) ;; =================================================================================================== ;; Plot to a frame or a snip, depending on (plot-new-window?) @@ -145,10 +192,11 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format) #:fgcolor Plot-Color @@ -163,6 +211,7 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto] @@ -178,29 +227,48 @@ (define fail/kw (make-raise-keyword-error 'plot)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] - [else - (parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))] - [plot-background (if bgcolor bgcolor (plot-background))]) - (when out-file - (plot-file - renderer-tree out-file out-kind - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) - - (cond [(plot-new-window?) - (define frame - (plot-frame - renderer-tree - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) - (send frame show #t) - (void)] - [else - (plot-snip - renderer-tree - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)]))])) + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)] + [(and out-kind (not (plot-file-format/c out-kind))) (fail/kw "plot-file-format/c" '#:out-kind out-kind)] + [(not (plot-file-format/c out-kind)) (fail/kw "plot-file-format/c" '#:out-kind out-kind)] + [(and fgcolor (not (plot-color/c fgcolor))) (fail/kw "plot-color/c" '#:fgcolor fgcolor)] + [(and bgcolor (not (plot-color/c bgcolor))) (fail/kw "plot-color/c" '#:bgcolor bgcolor)] + ;; NOTE: don't check this one, as it is not used anyway + ;; [(and lncolor (not (plot-color/c lncolor))) (fail/kw "plot-color/c" '#:lncolor lncolor)] + [(and out-file (not (or (path-string? out-file) (output-port? out-file)))) + (fail/kw "#f, path-string or output port" '#:out-file out-file)]) + (parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))] + [plot-background (if bgcolor bgcolor (plot-background))]) + (when out-file + (plot-file + renderer-tree out-file out-kind + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) + + (cond [(plot-new-window?) + (define frame + (plot-frame + renderer-tree + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) + (send frame show #t) + (void)] + [else + (plot-snip + renderer-tree + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)]))) diff --git a/plot-gui-lib/plot/private/gui/plot3d.rkt b/plot-gui-lib/plot/private/gui/plot3d.rkt index 1895c0de..368c0431 100644 --- a/plot-gui-lib/plot/private/gui/plot3d.rkt +++ b/plot-gui-lib/plot/private/gui/plot3d.rkt @@ -1,7 +1,12 @@ -#lang typed/racket/base +#lang typed/racket/base #:no-optimize + +;; See note at the top of plot2d.rkt for the use of `#:no-optimize` and +;; `unsafe-provide` (require (only-in typed/mred/mred Snip% Frame%) + (only-in racket/gui/base get-display-backing-scale) typed/racket/draw typed/racket/class racket/match racket/list + (only-in typed/pict pict pict?) plot/utils plot/private/common/parameter-group plot/private/common/draw @@ -12,11 +17,17 @@ plot/private/no-gui/plot3d plot/private/no-gui/plot3d-utils plot/private/no-gui/utils - "lazy-snip-typed.rkt") + "lazy-snip-typed.rkt" + typed/racket/unsafe) + +(unsafe-provide plot3d-snip + plot3d-frame + plot3d) -(provide plot3d-snip - plot3d-frame - plot3d) +(require/typed plot/utils + (legend-anchor/c (-> Any Boolean)) + (plot-color/c (-> Any Boolean)) + (plot-file-format/c (-> Any Boolean))) ;; =================================================================================================== ;; Plot to a snip @@ -29,12 +40,13 @@ #:width Positive-Integer #:height Positive-Integer #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] - (Instance Snip%))) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance Plot-Snip%))) (define (plot3d-snip renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -47,16 +59,29 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/kw (make-raise-keyword-error 'plot3d-snip)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] - [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)]) - + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(not (real? angle)) (fail/kw "real" '#:angle angle)] + [(not (real? altitude)) (fail/kw "real" '#:altitude altitude)] + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and z-label (not (or (string? z-label) (pict? z-label)))) (fail/kw "#f, string or pict" '#:y-label z-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)]) + (parameterize ([plot-title title] [plot-x-label x-label] [plot-y-label y-label] @@ -67,50 +92,48 @@ (define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max)) (define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks) (get-ticks renderer-list bounds-rect)) - + (define render-tasks-hash ((inst make-hash Boolean render-tasks))) - (define legend-entries-hash ((inst make-hash Boolean (Listof legend-entry)))) - - (: make-bm (-> Boolean Real Real Positive-Integer Positive-Integer (Instance Bitmap%))) + ;; For 3D legend can be calculated once since we don't change the bounding box + (define legend (get-legend-entry-list renderer-list bounds-rect)) + + (: make-bm (-> Boolean Real Real Positive-Integer Positive-Integer (Values (Instance Bitmap%) (U #f (Instance 3D-Plot-Area%))))) (define (make-bm anim? angle altitude width height) (parameterize/group ([plot-parameters saved-plot-parameters] [plot-animating? (if anim? #t (plot-animating?))] [plot3d-angle angle] [plot3d-altitude altitude]) - ((if (plot-animating?) draw-bitmap draw-bitmap/supersampling) - (λ (dc) - (define area (make-object 3d-plot-area% - bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks - dc 0 0 width height)) - (send area start-plot) - - (cond [(not (hash-ref render-tasks-hash (plot-animating?) #f)) - (hash-set! - legend-entries-hash (plot-animating?) - (flatten-legend-entries - (for/list : (Listof (Treeof legend-entry)) ([rend (in-list renderer-list)]) - (match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend) - (send area start-renderer (if rend-bounds-rect - (rect-inexact->exact rend-bounds-rect) - (unknown-rect 3))) - (if render-proc (render-proc area) empty)))) - - (hash-set! render-tasks-hash (plot-animating?) (send area get-render-tasks))] - [else - (send area set-render-tasks (hash-ref render-tasks-hash (plot-animating?)))]) - - (send area end-renderers) - - (define legend-entries (hash-ref legend-entries-hash (plot-animating?) #f)) - (when (and legend-entries (not (empty? legend-entries))) - (send area draw-legend legend-entries)) - - (send area end-plot)) - width height))) - + (define bm (make-bitmap + width height #t + #:backing-scale (or (get-display-backing-scale) 1.0))) + (define dc (make-object bitmap-dc% bm)) + + (define area (make-object 3d-plot-area% + bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks legend + dc 0 0 width height aspect-ratio)) + (send area start-plot) + + (cond [(not (hash-ref render-tasks-hash (plot-animating?) #f)) + (for ([rend (in-list renderer-list)]) + (match-define (renderer3d rend-bounds-rect _bf _tf label-proc render-proc) rend) + (when render-proc + (send area start-renderer (if rend-bounds-rect + (rect-inexact->exact rend-bounds-rect) + (unknown-rect 3))) + (render-proc area))) + + (hash-set! render-tasks-hash (plot-animating?) (send area get-render-tasks))] + [else + (send area set-render-tasks (hash-ref render-tasks-hash (plot-animating?)))]) + + (send area end-renderers) + (send area end-plot) + (values bm area))) + + (define-values (bm area) (make-bm #f angle altitude width height)) (make-3d-plot-snip - (make-bm #f angle altitude width height) saved-plot-parameters - make-bm angle altitude width height))) + bm saved-plot-parameters + make-bm angle altitude area width height))) ;; =================================================================================================== ;; Plot to a frame @@ -123,11 +146,12 @@ #:width Positive-Integer #:height Positive-Integer #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] (Instance Frame%))) (define (plot3d-frame renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] @@ -141,23 +165,42 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/kw (make-raise-keyword-error 'plot3d-frame)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] - [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)]) - - (define snip - (plot3d-snip - renderer-tree - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max - #:width width #:height height #:angle angle #:altitude altitude #:title title - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) - (make-snip-frame snip width height (if title (format "Plot: ~a" title) "Plot"))) + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(not (real? angle)) (fail/kw "real" '#:angle angle)] + [(not (real? altitude)) (fail/kw "real" '#:altitude altitude)] + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and z-label (not (or (string? z-label) (pict? z-label)))) (fail/kw "#f, string or pict" '#:y-label z-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)]) + + ;; make-snip will be called in a separate thread, make sure the + ;; parameters have the correct values in that thread as well. + (define saved-plot-parameters (plot-parameters)) + (: make-snip (-> Positive-Integer Positive-Integer (Instance Snip%))) + (define (make-snip width height) + (parameterize/group ([plot-parameters saved-plot-parameters]) + (plot3d-snip + renderer-tree + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max + #:width width #:height height #:angle angle #:altitude altitude #:title title + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio))) + (make-snip-frame make-snip width height (if title (format "Plot: ~a" title) "Plot"))) ;; =================================================================================================== ;; Plot to a frame or a snip, depending on the value of plot-new-window? @@ -171,11 +214,12 @@ #:height Positive-Integer #:angle Real #:altitude Real #:az Real #:alt Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format) #:fgcolor Plot-Color @@ -188,13 +232,14 @@ #:z-min [z-min #f] #:z-max [z-max #f] #:width [width (plot-width)] #:height [height (plot-height)] - #:angle [angle (plot3d-angle)] - #:altitude [altitude (plot3d-altitude)] + #:angle [angle #f] + #:altitude [altitude #f] #:az [az #f] #:alt [alt #f] ; backward-compatible aliases #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto] @@ -214,13 +259,43 @@ (define fail/kw (make-raise-keyword-error 'plot3d)) (cond + ;; check arguments, see note at the top of this file [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] - [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)]) - + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(and angle (not (real? angle))) (fail/kw "#f or real" '#:angle angle)] + [(and altitude (not (real? altitude))) (fail/kw "#f or real" '#:altitude altitude)] + [(and az (not (real? az))) (fail/kw "#f or real" '#:az az)] + [(and alt (not (real? alt))) (fail/kw "#f or real" '#:alt alt)] + [(not (and (integer? width) (positive? width))) (fail/kw "positive integer" '#:width width)] + [(not (and (integer? height) (positive? height))) (fail/kw "positive integer" '#:height height)] + [(and title (not (or (string? title) (pict? title)))) (fail/kw "#f, string or pict" '#:title title)] + [(and x-label (not (or (string? x-label) (pict? x-label)))) (fail/kw "#f, string or pict" '#:x-label x-label)] + [(and y-label (not (or (string? y-label) (pict? y-label)))) (fail/kw "#f, string or pict" '#:y-label y-label)] + [(and z-label (not (or (string? z-label) (pict? z-label)))) (fail/kw "#f, string or pict" '#:y-label z-label)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] + [(not (legend-anchor/c legend-anchor)) (fail/kw "legend-anchor/c" '#:legend-anchor legend-anchor)] + [(and out-kind (not (plot-file-format/c out-kind))) (fail/kw "plot-file-format/c" '#:out-kind out-kind)] + [(not (plot-file-format/c out-kind)) (fail/kw "plot-file-format/c" '#:out-kind out-kind)] + [(and fgcolor (not (plot-color/c fgcolor))) (fail/kw "plot-color/c" '#:fgcolor fgcolor)] + [(and bgcolor (not (plot-color/c bgcolor))) (fail/kw "plot-color/c" '#:bgcolor bgcolor)] + ;; NOTE: don't check this one, as it is not used anyway + ;; [(and lncolor (not (plot-color/c lncolor))) (fail/kw "plot-color/c" '#:lncolor lncolor)] + [(and out-file (not (or (path-string? out-file) (output-port? out-file)))) + (fail/kw "#f, path-string or output port" '#:out-file out-file)]) + + (cond ;; because this function is exported via `unsafe-provide` + [(and out-kind (not (plot-file-format/c out-kind))) + (fail/kw "plot-file-format/c" '#:out-kind out-kind)] + [(and fgcolor (not (plot-color/c fgcolor))) + (fail/kw "plot-color/c" '#:fgcolor fgcolor)] + [(and bgcolor (not (plot-color/c bgcolor))) + (fail/kw "plot-color/c" '#:bgcolor bgcolor)]) + (parameterize ([plot-foreground (if fgcolor fgcolor (plot-foreground))] [plot-background (if bgcolor bgcolor (plot-background))]) (when out-file @@ -229,8 +304,9 @@ #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle az (plot3d-angle)) #:altitude (or altitude alt (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) - + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) + (cond [(plot-new-window?) (define frame (plot3d-frame @@ -238,7 +314,8 @@ #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle az (plot3d-angle)) #:altitude (or altitude alt (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (send frame show #t) (void)] [else @@ -247,4 +324,5 @@ #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle az (plot3d-angle)) #:altitude (or altitude alt (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)]))) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)]))) diff --git a/plot-gui-lib/plot/private/gui/snip.rkt b/plot-gui-lib/plot/private/gui/snip.rkt index 0607beac..d3073392 100644 --- a/plot-gui-lib/plot/private/gui/snip.rkt +++ b/plot-gui-lib/plot/private/gui/snip.rkt @@ -6,6 +6,7 @@ plot/private/common/parameter-groups plot/private/common/parameter-group plot/private/common/draw-attribs + plot/private/common/color-map "worker-thread.rkt") (provide plot-snip%) diff --git a/plot-gui-lib/plot/private/gui/snip2d.rkt b/plot-gui-lib/plot/private/gui/snip2d.rkt index 638bb001..dc1ca1e2 100644 --- a/plot-gui-lib/plot/private/gui/snip2d.rkt +++ b/plot-gui-lib/plot/private/gui/snip2d.rkt @@ -1,6 +1,6 @@ #lang racket/base -(require racket/gui/base racket/class racket/match racket/list racket/math +(require racket/gui/base racket/class racket/contract racket/match racket/list racket/math plot/private/common/math plot/private/common/format plot/private/common/ticks @@ -8,10 +8,27 @@ plot/private/common/parameter-groups plot/private/common/parameter-group plot/private/common/draw-attribs + plot/private/common/color-map + plot/private/plot2d/plot-area + plot/private/plot2d/renderer + plot/private/no-gui/plot2d-utils + plot/private/common/contract + (submod plot/private/common/plotmetrics untyped) "worker-thread.rkt" "snip.rkt") -(provide 2d-plot-snip% make-2d-plot-snip) +(define plot-mouse-event-callback/c + (-> (is-a?/c snip%) (is-a?/c mouse-event%) (or/c real? #f) (or/c real? #f) any/c)) +(define 2d-plot-snip%/c + (class/c + (set-mouse-event-callback (->m (or/c plot-mouse-event-callback/c #f) any/c)) + (set-overlay-renderers (->m (or/c (treeof renderer2d?) #f) any/c)))) + +(provide + (contract-out + [make-2d-plot-snip (unconstrained-domain-> (instanceof/c 2d-plot-snip%/c))] + [2d-plot-snip% 2d-plot-snip%/c]) + plot-mouse-event-callback/c) (define update-delay 16) (define show-zoom-message? #t) @@ -19,10 +36,10 @@ (struct draw-command (animating? plot-bounds-rect width height) #:transparent) (define 2d-plot-snip% - (class plot-snip% + (class* plot-snip% (plot-metrics<%>) (init init-bm saved-plot-parameters) - (init-field make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height) - + (init-field make-bm plot-bounds-rect area width height) + (inherit set-bitmap get-bitmap get-saved-plot-parameters refresh @@ -33,25 +50,43 @@ (super-make-object init-bm saved-plot-parameters) (define (set-message-center) - (match-define (vector x-mid y-mid) (rect-center area-bounds-rect)) + (match-define (vector x-mid y-mid) (rect-center (send area get-area-bounds-rect))) (send this set-message-center x-mid y-mid)) (set-message-center) (define/override (copy) - (make-object this% - (get-bitmap) (get-saved-plot-parameters) - make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height)) - + (define c + (make-object this% + (get-bitmap) (get-saved-plot-parameters) + make-bm plot-bounds-rect area width height)) + (when mouse-event-callback + (send c set-mouse-event-callback mouse-event-callback)) + c) + (define left-click-x 0) (define left-click-y 0) (define left-drag-x 0) (define left-drag-y 0) - + (define plot-bounds-rects empty) + + (define (area-bounds->plot-bounds rect) + ;; assumes: (rect-known? rect) + (match-define (vector (ivl area-x-min area-x-max) (ivl area-y-min area-y-max)) rect) + (match-define (vector x-min y-min) (send area dc->plot (vector area-x-min area-y-min))) + (match-define (vector x-max y-max) (send area dc->plot (vector area-x-max area-y-max))) + (vector (ivl x-min x-max) (ivl y-min y-max))) + + (define (plot-bounds->area-bounds rect) + ;; assumes (rect-known? rect) + (match-define (vector (ivl plot-x-min plot-x-max) (ivl plot-y-min plot-y-max)) rect) + (match-define (vector x-min y-min) (send area plot->dc (vector plot-x-min plot-y-min))) + (match-define (vector x-max y-max) (send area plot->dc (vector plot-x-max plot-y-max))) + (vector (ivl x-min x-max) (ivl y-min y-max))) (define (get-new-area-bounds-rect) - (rect-meet area-bounds-rect + (rect-meet (send area get-area-bounds-rect) (rect-inexact->exact (vector (ivl left-click-x left-drag-x) (ivl left-click-y left-drag-y))))) @@ -73,8 +108,14 @@ (define (zoom-or-unzoom) (cond [dragging? (set! dragging? #f) - (define new-rect (area-bounds->plot-bounds (get-new-area-bounds-rect))) - (cond [(and (rect-rational? new-rect) (not (rect-zero-area? new-rect))) + (define new-rect + (let ([bounds (get-new-area-bounds-rect)]) + ;; BOUNDS might be +nan.0 for an empty selection + (and (rect-rational? bounds) + (area-bounds->plot-bounds bounds)))) + (cond [(and new-rect + (rect-rational? new-rect) + (not (rect-zero-area? new-rect))) #;(printf "~a: new-plot-bounds-rect = ~v~n" (current-milliseconds) new-rect) (set! plot-bounds-rects (cons plot-bounds-rect plot-bounds-rects)) @@ -96,11 +137,11 @@ (make-bm animating? plot-bounds-rect width height)]))) (λ (animating?) (draw-command animating? plot-bounds-rect width height)) (λ (rth) - (define-values (new-bm new-area-bounds-rect new-area-bounds->plot-bounds) - (worker-thread-try-get rth (λ () (values #f #f #f)))) + (define-values (new-bm new-area) + (worker-thread-try-get rth (λ () (values #f #f)))) (cond [(is-a? new-bm bitmap%) - (set! area-bounds-rect new-area-bounds-rect) - (set! area-bounds->plot-bounds new-area-bounds->plot-bounds) + (set! area new-area) + (set! plot-metrics-ok? #f) (set-bitmap new-bm) (set-message-center) #t] @@ -110,8 +151,8 @@ (define (update-plot) (start-update-thread #f) (set-update #t)) - - (define/override (on-event dc x y editorx editory evt) + + (define (zoom-or-unzoom-mouse-event-handler dc x y editorx editory evt) (define evt-type (send evt get-event-type)) (define mouse-x (- (send evt get-x) x)) (define mouse-y (- (send evt get-y) y)) @@ -136,7 +177,99 @@ [(and (not (send evt get-left-down)) (<= 0 mouse-x (send (get-bitmap) get-width)) (<= 0 mouse-y (send (get-bitmap) get-height))) - (set-click-message)])]) + (set-click-message)])])) + + (define mouse-event-callback #f) + (define mouse-event-handler zoom-or-unzoom-mouse-event-handler) + + (define (user-mouse-event-handler dc x y editorx editory evt) + (define mouse-x (- (send evt get-x) x)) + (define mouse-y (- (send evt get-y) y)) + (if (rect-contains? (send area get-area-bounds-rect) (vector mouse-x mouse-y)) + (match-let (((vector px py) (send area dc->plot (vector mouse-x mouse-y)))) + (mouse-event-callback this evt px py)) + (mouse-event-callback this evt #f #f))) + + (define/public (set-mouse-event-callback callback) + (set! mouse-event-callback callback) + (set! mouse-event-handler + (if mouse-event-callback + user-mouse-event-handler + zoom-or-unzoom-mouse-event-handler))) + + (define the-overlay-renderers #f) + + (define/public (set-overlay-renderers renderers) + (set! the-overlay-renderers (and renderers (flatten renderers))) + (refresh)) + + (define (draw-overlay-renderers dc x y left top right bottom) + (when the-overlay-renderers + ;; Implementation notes: + ;; + ;; * the `plot-area` routine used to draw plots, expects the origin of + ;; the DC to be set to the origin or (0, 0) of the plot, see + ;; `set-origin` call. + ;; + ;; * Since the DC origin has been adjusted to start at X, Y, the LEFT, + ;; TOP, RIGHT and BOTTOM values have to be adjusted accordingly. + ;; + ;; * plot Y axis grows upwards (lower values are at the bottom, higher + ;; values are at the top), draw context Y axis grows downwards (lower + ;; values are at the top, higher values are at the bottom). This + ;; results in some non-obvious `plot->dc` and `dc->plot` calls. + ;; + ;; * The area bounded by LEFT, TOP, RIGHT and BOTTOM might cover an + ;; area outside the plot area (e.g. where axis are drawn). We need to + ;; intersect the current plot bounds with this area to obtain the + ;; final overlay redraw area. + ;; + ;; * If the redraw area is at the edge of the visible part of the plot + ;; snip, we seem to have an off-by-one error and pixels are "left + ;; over" at the edge. This is adjusted using the `add1`, `sub1` calls + ;; below. + + (match-define (vector (ivl cleft cright) (ivl ctop cbottom)) + (plot-bounds->area-bounds plot-bounds-rect)) + + (define dc-x-min (max cleft (add1 (- left x)))) + (define dc-x-max (min cright (sub1 (- right x)))) + (define dc-y-min (max ctop (add1 (- top y)))) + (define dc-y-max (min cbottom (sub1 (- bottom y)))) + + (when (and (> dc-x-max dc-x-min) (> dc-y-max dc-y-min)) + (define overlay-plot-bounds + (area-bounds->plot-bounds (vector (ivl dc-x-min dc-x-max) (ivl dc-y-min dc-y-max)))) + + (define-values (scale-x scale-y) (send dc get-scale)) + (define-values (origin-x origin-y) (send dc get-origin)) + (send dc set-origin (+ origin-x (* scale-x x)) (+ origin-y (* scale-y y))) + + ;; Use the same plot parameters as the main plot -- this ensures + ;; that any axis transforms (e.g. logarithmic, stretch, etc) are + ;; applied to the overlays as well. We than omit the decorations + ;; and specify a transparent background so the main plot underneath + ;; is visible. + (parameterize/group ([plot-parameters (get-saved-plot-parameters)]) + (parameterize ([plot-decorations? #f] + [plot-background-alpha 0]) + ;; The new overlay area has to be constructed inside the + ;; parameterize call, as it picks up the value of the + ;; plot-decorations? parameter. + (define overlay-area + (make-object 2d-plot-area% + overlay-plot-bounds + '() '() '() '() '() + dc + dc-x-min dc-y-min + (- dc-x-max dc-x-min) (- dc-y-max dc-y-min) + (send area get-aspect-ratio))) + (plot-area overlay-area the-overlay-renderers))) + + (send dc set-origin origin-x origin-y)))) + + (define/override (on-event dc x y editorx editory evt) + (apply mouse-event-handler dc x y editorx editory evt '()) (super on-event dc x y editorx editory evt)) (define (draw-selection dc dc-x-min dc-y-min rect) @@ -230,22 +363,39 @@ (super draw dc x y left top right bottom dx dy draw-caret) (when dragging? (parameterize/group ([plot-parameters (get-saved-plot-parameters)]) - (draw-selection dc x y (get-new-area-bounds-rect))))) - + (draw-selection dc x y (get-new-area-bounds-rect)))) + (draw-overlay-renderers dc x y left top right bottom)) + (define/override (resize w h) (when (not (and (= w width) (= h height))) (set! width w) (set! height h) (stop-message) - (when (not (update-thread-running?)) - (start-update-thread #t)) + (start-update-thread #f) (set-update #t)) (super resize w h)) + + (define plot-metrics-ok? #f) + (match-define (list bounds ->dc ->plot plane) + (send area get-plot-metrics-functions)) + (define (update-metrics) + (match-define (list new-bounds new-->dc new-->plot new-plane) + (send area get-plot-metrics-functions)) + (set! bounds new-bounds) + (set! ->dc new-->dc) + (set! ->plot new-->plot) + (set! plane new-plane) + (set! plot-metrics-ok? #t)) + (define/public (get-plot-bounds) (unless plot-metrics-ok? (update-metrics)) (bounds)) + (define/public (plot->dc coords) (unless plot-metrics-ok? (update-metrics)) (->dc coords)) + (define/public (dc->plot coords) (unless plot-metrics-ok? (update-metrics)) (->plot coords)) + (define/public (plane-vector) (unless plot-metrics-ok? (update-metrics)) (plane)) + (define/public (get-plot-metrics-functions) (unless plot-metrics-ok? (update-metrics)) (list bounds ->dc ->plot plane)) )) (define (make-2d-plot-snip init-bm saved-plot-parameters - make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height) + make-bm plot-bounds-rect area width height) (make-object 2d-plot-snip% init-bm saved-plot-parameters - make-bm plot-bounds-rect area-bounds-rect area-bounds->plot-bounds width height)) + make-bm plot-bounds-rect area width height)) diff --git a/plot-gui-lib/plot/private/gui/snip3d.rkt b/plot-gui-lib/plot/private/gui/snip3d.rkt index 6a5d93aa..888dad0b 100644 --- a/plot-gui-lib/plot/private/gui/snip3d.rkt +++ b/plot-gui-lib/plot/private/gui/snip3d.rkt @@ -3,6 +3,7 @@ (require racket/gui/base racket/class racket/match plot/private/common/math plot/private/common/parameters + (submod plot/private/common/plotmetrics untyped) "worker-thread.rkt" "snip.rkt") @@ -15,22 +16,28 @@ (define (clamp x mn mx) (min* (max* x mn) mx)) (define 3d-plot-snip% - (class plot-snip% + (class* plot-snip% (plot-metrics<%>) (init init-bm saved-plot-parameters) - (init-field make-bm angle altitude width height) + (init-field make-bm angle altitude area width height) (inherit set-bitmap get-bitmap get-saved-plot-parameters - set-message stop-message set-message-center reset-message-timeout + set-message stop-message reset-message-timeout update-thread-running? set-update get-left-down-here?) (super-make-object init-bm saved-plot-parameters) + (define (set-message-center) + (match-define (vector x-mid y-mid) (rect-center (send area get-area-bounds-rect))) + (send this set-message-center x-mid y-mid)) + + (set-message-center) + (define/override (copy) (make-object this% (get-bitmap) (get-saved-plot-parameters) - make-bm angle altitude width height)) + make-bm angle altitude area width height)) (define mouse-x 0) (define mouse-y 0) @@ -48,7 +55,7 @@ (define (set-altitude!) (define degrees-per-pixel (/ 180 (send (get-bitmap) get-height))) (define dy (- mouse-y left-click-y)) - (set! altitude (clamp (+ last-altitude (* dy degrees-per-pixel)) 0 90))) + (set! altitude (clamp (+ last-altitude (* dy degrees-per-pixel)) -90 90))) (define (start-update-thread animating?) (send this start-update-thread @@ -58,9 +65,13 @@ (make-bm animating? angle altitude width height)]))) (λ (animating?) (draw-command animating? angle altitude width height)) (λ (rth) - (define new-bm (worker-thread-try-get rth)) + (define-values (new-bm new-area) + (worker-thread-try-get rth (λ () (values #f #f)))) (cond [(is-a? new-bm bitmap%) + (set! area new-area) + (set! plot-metrics-ok? #f) (set-bitmap new-bm) + (set-message-center) (when (not (and (= last-angle angle) (= last-altitude altitude))) (set-angles-message)) @@ -126,17 +137,33 @@ (when (not (and (= w width) (= h height))) (set! width w) (set! height h) - (set-message-center (* 1/2 w) (* 1/2 h)) (stop-message) (when (not (update-thread-running?)) (start-update-thread #t)) (set-update #t)) (super resize w h)) + + (define plot-metrics-ok? #f) + (match-define (list bounds ->dc ->plot plane) + (send area get-plot-metrics-functions)) + (define (update-metrics) + (match-define (list new-bounds new-->dc new-->plot new-plane) + (send area get-plot-metrics-functions)) + (set! bounds new-bounds) + (set! ->dc new-->dc) + (set! ->plot new-->plot) + (set! plane new-plane) + (set! plot-metrics-ok? #t)) + (define/public (get-plot-bounds) (unless plot-metrics-ok? (update-metrics)) (bounds)) + (define/public (plot->dc coords) (unless plot-metrics-ok? (update-metrics)) (->dc coords)) + (define/public (dc->plot coords) (unless plot-metrics-ok? (update-metrics)) (->plot coords)) + (define/public (plane-vector) (unless plot-metrics-ok? (update-metrics)) (plane)) + (define/public (get-plot-metrics-functions) (unless plot-metrics-ok? (update-metrics)) (list bounds ->dc ->plot plane)) )) (define (make-3d-plot-snip init-bm saved-plot-parameters - make-bm angle altitude width height) + make-bm angle altitude area width height) (make-object 3d-plot-snip% init-bm saved-plot-parameters - make-bm angle altitude width height)) + make-bm angle altitude area width height)) diff --git a/plot-gui-lib/plot/snip.rkt b/plot-gui-lib/plot/snip.rkt new file mode 100644 index 00000000..31d32009 --- /dev/null +++ b/plot-gui-lib/plot/snip.rkt @@ -0,0 +1,7 @@ +#lang racket/base + +(require "private/gui/snip2d.rkt") + +(provide + plot-mouse-event-callback/c + 2d-plot-snip%) diff --git a/plot-lib/LICENSE.txt b/plot-lib/LICENSE.txt deleted file mode 100644 index dbb89375..00000000 --- a/plot-lib/LICENSE.txt +++ /dev/null @@ -1,11 +0,0 @@ -plot -Copyright (c) 2010-2014 PLT Design Inc. - -This package is distributed under the GNU Lesser General Public -License (LGPL). This means that you can link this package into proprietary -applications, provided you follow the rules stated in the LGPL. You -can also modify this package; if you distribute a modified version, -you must distribute it under the terms of the LGPL, which in -particular means that you must release the source code for the -modified software. See http://www.gnu.org/copyleft/lesser.html -for more information. diff --git a/plot-lib/info.rkt b/plot-lib/info.rkt index b84ca09b..8a743425 100644 --- a/plot-lib/info.rkt +++ b/plot-lib/info.rkt @@ -17,3 +17,10 @@ (define pkg-desc "Plot non-GUI interface") (define pkg-authors '(ntoronto)) + +(define version "1.1") + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT)) diff --git a/plot-lib/plot/bitmap.rkt b/plot-lib/plot/bitmap.rkt index 46175e46..67793407 100644 --- a/plot-lib/plot/bitmap.rkt +++ b/plot-lib/plot/bitmap.rkt @@ -1,7 +1,73 @@ -#lang typed/racket/base +#lang racket/base -(require "no-gui.rkt" +(require typed/untyped-utils + "no-gui.rkt" "private/no-gui/plot-bitmap.rkt") +(provide (all-from-out "no-gui.rkt")) + +(module untyped racket/base + (require "private/no-gui/plot-bitmap.rkt" racket/contract + + racket/class + racket/draw + pict + "utils.rkt" + "private/common/contract.rkt" + "private/common/nonrenderer.rkt" + "private/plot2d/renderer.rkt") + (provide + (contract-out + [plot + (->* [(treeof (or/c renderer2d? nonrenderer?))] + [#:x-min (or/c real? #f) + #:x-max (or/c real? #f) + #:y-min (or/c real? #f) + #:y-max (or/c real? #f) + #:width (and/c exact-integer? (>/c 0)) + #:height (and/c exact-integer? (>/c 0)) + #:title (or/c string? #f) + #:x-label (or/c string? #f) + #:y-label (or/c string? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor anchor/c + #:out-file (or/c path? string? output-port? #f) + #:out-kind symbol?] + (is-a?/c bitmap%))] + [plot3d + (->* [(treeof (or/c renderer3d? nonrenderer?))] + [#:x-min (or/c real? #f) + #:x-max (or/c real? #f) + #:y-min (or/c real? #f) + #:y-max (or/c real? #f) + #:z-min (or/c real? #f) + #:z-max (or/c real? #f) + #:width (and/c exact-integer? (>/c 0)) + #:height (and/c exact-integer? (>/c 0)) + #:angle real? #:altitude real? + #:title (or/c string? #f) + #:x-label (or/c string? #f) + #:y-label (or/c string? #f) + #:z-label (or/c string? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor anchor/c + #:out-file (or/c path? string? output-port? #f) + #:out-kind symbol?] + (is-a?/c bitmap%))]))) + + +(require (rename-in "private/no-gui/plot-bitmap.rkt" + [plot typed-plot] + [plot3d typed-plot3d]) + (rename-in (submod "." untyped) + [plot untyped-plot] + [plot3d untyped-plot3d])) + +(define-typed/untyped-identifier plot + typed-plot + untyped-plot) +(define-typed/untyped-identifier plot3d + typed-plot3d + untyped-plot3d) + +(provide plot plot3d) -(provide (all-from-out "no-gui.rkt") - plot plot3d) diff --git a/plot-lib/plot/no-gui.rkt b/plot-lib/plot/no-gui.rkt index 91634354..1a9cdc47 100644 --- a/plot-lib/plot/no-gui.rkt +++ b/plot-lib/plot/no-gui.rkt @@ -23,12 +23,23 @@ ;; 2D exports (require (rename-in "private/no-gui/plot2d.rkt" - [plot/dc typed-plot/dc]) - "private/no-gui/plot2d-untyped.rkt") + [plot/dc typed-plot/dc] + [plot-bitmap typed-plot-bitmap] + [plot-pict typed-plot-pict]) + (rename-in "private/no-gui/plot2d-untyped.rkt" + [plot/dc untyped-plot/dc] + [plot-bitmap untyped-plot-bitmap] + [plot-pict untyped-plot-pict])) (define-typed/untyped-identifier plot/dc typed-plot/dc untyped-plot/dc) +(define-typed/untyped-identifier plot-bitmap + typed-plot-bitmap + untyped-plot-bitmap) +(define-typed/untyped-identifier plot-pict + typed-plot-pict + untyped-plot-pict) (provide plot/dc @@ -43,6 +54,14 @@ error-bars candlesticks) +(require "private/plot2d/color-field.rkt") +(provide + color-field) + +(require "private/plot2d/arrows.rkt") +(provide + arrows) + (require "private/plot2d/line.rkt") (provide lines @@ -60,7 +79,11 @@ parametric-interval polar-interval function-interval - inverse-interval) + inverse-interval + violin) + +(require "private/plot2d/box-and-whisker.rkt") +(provide box-and-whisker) (require "private/plot2d/contour.rkt") (provide @@ -85,10 +108,15 @@ y-tick-lines tick-grid point-label + point-pict parametric-label + parametric-pict polar-label + polar-pict function-label - inverse-label) + function-pict + inverse-label + inverse-pict) ;; =================================================================================================== ;; 3D exports @@ -117,6 +145,10 @@ contours3d contour-intervals3d) +(require "private/plot3d/arrows.rkt") +(provide + arrows3d) + (require "private/plot3d/line.rkt") (provide lines3d @@ -133,6 +165,11 @@ isosurfaces3d polar3d) +(require "private/plot3d/param-surf.rkt") +(provide + polygons3d + parametric-surface3d) + (require "private/plot3d/rectangle.rkt") (provide rectangles3d diff --git a/plot-lib/plot/private/common/color-map.rkt b/plot-lib/plot/private/common/color-map.rkt new file mode 100644 index 00000000..26a354dd --- /dev/null +++ b/plot-lib/plot/private/common/color-map.rkt @@ -0,0 +1,286 @@ +#lang typed/racket/base +(require racket/match + racket/math + "draw-attribs.rkt" + "type-doc.rkt" + "types.rkt" + "parameters.rkt") + + +;;.................................... declare the predefined color maps .... + +;; These color maps correspond to the Matplotlib 3.0.3 qualitative color maps +;; with the same names. See +;; https://matplotlib.org/examples/color/colormaps_reference.html + +(: color-map-pastel1 Color-Map) +(define color-map-pastel1 + #((251 180 174) + (179 205 227) + (204 235 197) + (222 203 228) + (254 217 166) + (255 255 204) + (229 216 189) + (253 218 236) + (242 242 242))) + +(: color-map-pastel2 Color-Map) +(define color-map-pastel2 + #((179 226 205) + (253 205 172) + (203 213 232) + (244 202 228) + (230 245 201) + (255 242 174) + (241 226 204) + (204 204 204))) + +(: color-map-paired Color-Map) +(define color-map-paired + #((166 206 227) + (31 120 180) + (178 223 138) + (51 160 44) + (251 154 153) + (227 26 28) + (253 191 111) + (255 127 0) + (202 178 214) + (106 61 154) + (255 255 153) + (177 89 40))) + +(: color-map-accent Color-Map) +(define color-map-accent + #((127 201 127) + (190 174 212) + (253 192 134) + (255 255 153) + (56 108 176) + (240 2 127) + (191 91 22) + (102 102 102))) + +(: color-map-dark2 Color-Map) +(define color-map-dark2 + #((27 158 119) + (217 95 2) + (117 112 179) + (231 41 138) + (102 166 30) + (230 171 2) + (166 118 29) + (102 102 102))) + +(: color-map-set1 Color-Map) +(define color-map-set1 + #((228 26 28) + (55 126 184) + (77 175 74) + (152 78 163) + (255 127 0) + (255 255 51) + (166 86 40) + (247 129 191) + (153 153 153))) + +(: color-map-set2 Color-Map) +(define color-map-set2 + #((102 194 165) + (252 141 98) + (141 160 203) + (231 138 195) + (166 216 84) + (255 217 47) + (229 196 148) + (179 179 179))) + +(: color-map-set3 Color-Map) +(define color-map-set3 + #((141 211 199) + (255 255 179) + (190 186 218) + (251 128 114) + (128 177 211) + (253 180 98) + (179 222 105) + (252 205 229) + (217 217 217) + (188 128 189) + (204 235 197) + (255 237 111))) + +(: color-map-tab10 Color-Map) +(define color-map-tab10 + #((31 119 180) + (255 127 14) + (44 160 44) + (214 39 40) + (148 103 189) + (140 86 75) + (227 119 194) + (127 127 127) + (188 189 34) + (23 190 207))) + +(: color-map-tab20 Color-Map) +(define color-map-tab20 + #((31 119 180) + (174 199 232) + (255 127 14) + (255 187 120) + (44 160 44) + (152 223 138) + (214 39 40) + (255 152 150) + (148 103 189) + (197 176 213) + (140 86 75) + (196 156 148) + (227 119 194) + (247 182 210) + (127 127 127) + (199 199 199) + (188 189 34) + (219 219 141) + (23 190 207) + (158 218 229))) + +(: color-map-tab20b Color-Map) +(define color-map-tab20b + #((57 59 121) + (82 84 163) + (107 110 207) + (156 158 222) + (99 121 57) + (140 162 82) + (181 207 107) + (206 219 156) + (140 109 49) + (189 158 57) + (231 186 82) + (231 203 148) + (132 60 57) + (173 73 74) + (214 97 107) + (231 150 156) + (123 65 115) + (165 81 148) + (206 109 189) + (222 158 214))) + +(: color-map-tab20c Color-Map) +(define color-map-tab20c + #((49 130 189) + (107 174 214) + (158 202 225) + (198 219 239) + (230 85 13) + (253 141 60) + (253 174 107) + (253 208 162) + (49 163 84) + (116 196 118) + (161 217 155) + (199 233 192) + (117 107 177) + (158 154 200) + (188 189 220) + (218 218 235) + (99 99 99) + (150 150 150) + (189 189 189) + (217 217 217))) + +;; New Tableau 10 color map from +;; https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-56782 +(: color-map-tab10n Color-Map) +(define color-map-tab10n + #((78 121 165) + (241 143 59) + (224 88 91) + (119 183 178) + (90 161 85) + (237 201 88) + (175 122 160) + (254 158 168) + (156 117 97) + (186 176 172))) + +(define color-maps + (hash-copy ; hash copy will make our hash table mutable, allowing register-color-map to work + (hash + 'pastel1 color-map-pastel1 + 'pastel2 color-map-pastel2 + 'paired color-map-paired + 'dark2 color-map-dark2 + 'set1 color-map-set1 + 'set2 color-map-set2 + 'set3 color-map-set3 + 'tab10 color-map-tab10 + 'tab10n color-map-tab10n + 'tab20 color-map-tab20 + 'tab20b color-map-tab20b + 'tab20c color-map-tab20c))) + + + +;;.................................................. color map interface .... + +(: color-map-names (-> (Listof Symbol))) +(define (color-map-names) + (hash-keys color-maps)) + +(: color-map-size (-> Symbol Nonnegative-Integer)) +(define (color-map-size name) + (define cm (hash-ref color-maps name + (lambda () (error (format "Unknown color map name: ~a" name))))) + (vector-length cm)) + +(: register-color-map (-> Symbol Color-Map Any)) +(define (register-color-map name cm) + (hash-set! color-maps name cm)) + + +(:: ->color-map-pen-color (-> Integer (List Byte Byte Byte))) +(define (->color-map-pen-color index) + (define cm + (cast + (if (symbol? (plot-pen-color-map)) + (hash-ref color-maps (plot-pen-color-map) + (lambda () default-pen-colors)) + default-pen-colors) + Color-Map)) + (define i (modulo index (vector-length cm))) + (vector-ref cm i)) + +(:: ->color-map-brush-color (-> Integer (List Byte Byte Byte))) +(define (->color-map-brush-color index) + (define cm + (cast + (if (symbol? (plot-brush-color-map)) + (hash-ref color-maps (plot-brush-color-map) + (lambda () default-brush-colors)) + default-brush-colors) + Color-Map)) + (define i (modulo index (vector-length cm))) + (vector-ref cm i)) + +(:: ->pen-color (-> Plot-Color (List Real Real Real))) +(define (->pen-color c) + (cond [(exact-integer? c) (->color-map-pen-color c)] + [else (->color c)])) + +(:: ->brush-color (-> Plot-Color (List Real Real Real))) +(define (->brush-color c) + (cond [(exact-integer? c) (->color-map-brush-color c)] + [else (->color c)])) + +(provide + color-map-names + color-map-size + register-color-map + ->pen-color + ->brush-color) + diff --git a/plot-lib/plot/private/common/contract.rkt b/plot-lib/plot/private/common/contract.rkt index 9a5b27a6..9a77894f 100644 --- a/plot-lib/plot/private/common/contract.rkt +++ b/plot-lib/plot/private/common/contract.rkt @@ -34,6 +34,14 @@ (define anchor/c (one-of/c 'top-left 'top 'top-right 'left 'center 'right 'bottom-left 'bottom 'bottom-right)) +(define legend-anchor/c (or/c anchor/c + (one-of/c + 'no-legend + 'outside-global-top + 'outside-top-left 'outside-top 'outside-top-right + 'outside-left-top 'outside-left 'outside-left-bottom + 'outside-right-top 'outside-right 'outside-right-bottom + 'outside-bottom-left 'outside-bottom 'outside-bottom-right))) (define color/c (or/c (list/c real? real? real?) string? symbol? @@ -45,11 +53,16 @@ (one-of/c 'transparent 'solid 'dot 'long-dash 'short-dash 'dot-dash))) +(define plot-pen-cap/c (one-of/c 'round 'butt 'projecting)) + (define plot-brush-style/c (or/c exact-integer? (one-of/c 'transparent 'solid 'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch 'horizontal-hatch 'vertical-hatch 'cross-hatch))) +(define plot-file-format/c + (or/c 'auto 'png 'jpeg 'xmb 'xpm 'bmp 'ps 'pdf 'svg)) + (module typed-defs typed/racket/base (require "type-doc.rkt") @@ -110,3 +123,6 @@ (define (treeof elem-contract) (or/c elem-contract (listof (recursive-contract (treeof elem-contract) #:flat)))) + +(require (submod "plotmetrics.rkt" untyped)) +(provide plot-metrics-object/c) diff --git a/plot-lib/plot/private/common/draw-attribs.rkt b/plot-lib/plot/private/common/draw-attribs.rkt index d492ebd5..680affc6 100644 --- a/plot-lib/plot/private/common/draw-attribs.rkt +++ b/plot-lib/plot/private/common/draw-attribs.rkt @@ -21,7 +21,8 @@ (case a [(top-left) 'bottom-right] [(top) 'bottom] [(top-right) 'bottom-left] [(right) 'left] [(bottom-right) 'top-left] [(bottom) 'top] [(bottom-left) 'top-right] [(left) 'right] - [(center) 'center])) + [(center) 'center] + [(auto) 'auto])) ;; =================================================================================================== ;; Draw paramter normalization @@ -153,8 +154,8 @@ (define r (assert (+ 127 (* 128 (expt (max 0 (- 1 (integer->gray-value i))) 3/4))) real?)) (list r r r)) -(: pen-colors (Vectorof (List Byte Byte Byte))) -(define pen-colors +(: default-pen-colors (Vectorof (List Byte Byte Byte))) +(define default-pen-colors (for/vector ([color (in-list (append (list (integer->gray-pen-color 0)) (build-list 120 integer->pen-color) (build-list 7 (λ ([n : Index]) @@ -165,8 +166,8 @@ (real->color-byte g) (real->color-byte b)))) -(: brush-colors (Vectorof (List Byte Byte Byte))) -(define brush-colors +(: default-brush-colors (Vectorof (List Byte Byte Byte))) +(define default-brush-colors (for/vector ([color (in-list (append (list (integer->gray-brush-color 0)) (build-list 120 integer->brush-color) (build-list 7 (λ ([n : Index]) @@ -177,16 +178,6 @@ (real->color-byte g) (real->color-byte b)))) -(:: ->pen-color (-> Plot-Color (List Real Real Real))) -(define (->pen-color c) - (cond [(exact-integer? c) (vector-ref pen-colors (modulo c 128))] - [else (->color c)])) - -(:: ->brush-color (-> Plot-Color (List Real Real Real))) -(define (->brush-color c) - (cond [(exact-integer? c) (vector-ref brush-colors (modulo c 128))] - [else (->color c)])) - (:: ->pen-style (-> Plot-Pen-Style Plot-Pen-Style-Sym)) (define (->pen-style s) (cond [(exact-integer? s) (case (remainder (abs s) 5) @@ -234,3 +225,31 @@ [gs (linear-seq* gs num #:start? start? #:end? end?)] [bs (linear-seq* bs num #:start? start? #:end? end?)]) (map (λ ([r : Real] [g : Real] [b : Real]) (list r g b)) rs gs bs))) + +(:: default-contour-colors (-> (Listof Real) (Listof Plot-Color))) +(define (default-contour-colors zs) + (color-seq* (list (vector-ref default-pen-colors 5) + (vector-ref default-pen-colors 0) + (vector-ref default-pen-colors 1)) + (length zs))) + +(:: default-contour-fill-colors (-> (Listof ivl) (Listof Plot-Color))) +(define (default-contour-fill-colors z-ivls) + (color-seq* (list (vector-ref default-brush-colors 5) + (vector-ref default-brush-colors 0) + (vector-ref default-brush-colors 1)) + (length z-ivls))) + +(:: default-isosurface-colors (-> (Listof Real) (Listof Plot-Color))) +(define (default-isosurface-colors zs) + (color-seq* (list (vector-ref default-brush-colors 5) + (vector-ref default-brush-colors 0) + (vector-ref default-brush-colors 1)) + (length zs))) + +(:: default-isosurface-line-colors (-> (Listof Real) (Listof Plot-Color))) +(define (default-isosurface-line-colors zs) + (color-seq* (list (vector-ref default-pen-colors 5) + (vector-ref default-pen-colors 0) + (vector-ref default-pen-colors 1)) + (length zs))) diff --git a/plot-lib/plot/private/common/draw.rkt b/plot-lib/plot/private/common/draw.rkt index 8cd874df..a072a5be 100644 --- a/plot-lib/plot/private/common/draw.rkt +++ b/plot-lib/plot/private/common/draw.rkt @@ -2,7 +2,7 @@ ;; Extra drawing functions. -(require typed/racket/draw typed/racket/class racket/match racket/list +(require typed/racket/draw typed/racket/class racket/match racket/list typed/pict (except-in math/base sum) (except-in math/flonum flsum) "math.rkt" @@ -16,21 +16,97 @@ (define sin45 (/ 1.0 (sqrt 2.0))) +(: get-box-corners/anchor (->* [Real Real Real Real] + [Anchor Real Real] + (Listof (Vector Real Real)))) +(define (get-box-corners/anchor x y width height [anchor 'top-left] [angle 0] [dist 0]) + (let ([dist (case anchor + [(top-left bottom-left top-right bottom-right) (* sin45 dist)] + [else dist])]) + (: dxs (Listof Real)) + (define dxs (case anchor + [(top-left left bottom-left) (list (- dist) (- width dist))] + [(top center bottom) (list (* -1/2 width) (* 1/2 width))] + [else (list (- dist width) dist)])) + (: dys (Listof Real)) + (define dys (case anchor + [(top-left top top-right) (list (- dist) (- height dist))] + [(left center right) (list (* -1/2 height) (* 1/2 height))] + [else (list (- dist height) dist)])) + + (for*/list : (Listof (Vector Real Real)) ([dx (in-list dxs)] [dy (in-list dys)]) + (define rdx (+ (* (sin angle) dy) (* (cos angle) dx))) + (define rdy (- (* (cos angle) dy) (* (sin angle) dx))) + (vector (+ x rdx) (+ y rdy))))) + +(: resolve-auto-anchor/str (-> (Instance DC<%>) String Real Real Real Real Anchor)) +(define (resolve-auto-anchor/str dc str x y angle dist) + (define region (send dc get-clipping-region)) + (define-values (width height _1 _2) (send dc get-text-extent str #f #t 0)) + (if region + (let loop ([anchors '(bottom-left bottom-right top-left top-right)] + [best : Anchor 'bottom-left] + [best-score -1]) + (if (null? anchors) + best + (let* ((anchor (car anchors)) + (corners (get-box-corners/anchor x y width height anchor angle dist)) + (center (let ((center-sum (foldl + (lambda ([corner : (Vector Real Real)] [sum : (Vector Real Real)]) + (match-define (vector x y) corner) + (match-define (vector sx sy) sum) + (vector (+ x sx) (+ y sy))) + (cast (vector 0 0) (Vector Real Real)) + corners))) + (match-define (vector x y) center-sum) + (define ncorners (length corners)) + (vector (/ x ncorners) (/ y ncorners)))) + (candidates (cons center corners)) + (score (foldl + (lambda ([corner : (Vector Real Real)] [score : Integer]) + (match-define (vector x y) corner) + (+ (if (send region in-region? x y) 1 0) score)) + 0 + candidates))) + (cond + ;; All candidate points are visible, don't bother checking + ;; other anchor locations + ((= score (length candidates)) anchor) + ((> score best-score) (loop (cdr anchors) anchor score)) + (#t (loop (cdr anchors) best best-score)))))) + 'bottom-left)) + +(: resolve-auto-anchor/pict (-> (Instance DC<%>) pict Real Real Real Anchor)) +(define (resolve-auto-anchor/pict dc pict x y dist) + (define region (send dc get-clipping-region)) + (if region + (let () + (define-values (left top width height) (send region get-bounding-box)) + (define anchor-right? (> (+ x dist (pict-width pict)) (+ left width))) + (define anchor-top? (< (- y dist (pict-height pict)) top)) + (if anchor-right? + (if anchor-top? 'top-right 'bottom-right) + (if anchor-top? 'top-left 'bottom-left))) + 'bottom-left)) + (: draw-text/anchor (->* [(Instance DC<%>) String Real Real] [Anchor Real Real] Void)) (define (draw-text/anchor dc str x y [anchor 'top-left] [angle 0] [dist 0]) (define-values (width height _1 _2) (send dc get-text-extent str #f #t 0)) - (let ([dist (case anchor + (define nanchor (if (eq? anchor 'auto) + (resolve-auto-anchor/str dc str x y angle dist) + anchor)) + (let ([dist (case nanchor [(top-left bottom-left top-right bottom-right) (* sin45 dist)] [else dist])]) - (define dx (case anchor - [(top-left left bottom-left) (- dist)] + (define dx (case nanchor + [(top-left left bottom-left auto) (- dist)] [(top center bottom) (* 1/2 width)] [(top-right right bottom-right) (+ width dist)] [else (raise-type-error 'draw-text/anchor "anchor/c" anchor)])) - (define dy (case anchor - [(top-left top top-right) (- dist)] + (define dy (case nanchor + [(top-left top top-right auto) (- dist)] [(left center right) (* 1/2 height)] [(bottom-left bottom bottom-right) (+ height dist)])) (define rdx (+ (* (sin angle) dy) (* (cos angle) dx))) @@ -38,29 +114,38 @@ (send dc draw-text str (- x rdx) (- y rdy) #t 0 angle))) -(: get-text-corners/anchor (->* [(Instance DC<%>) String Real Real] +(: get-text-corners/anchor (->* [(Instance DC<%>) (U String pict) Real Real] [Anchor Real Real] (Listof (Vector Real Real)))) (define (get-text-corners/anchor dc str x y [anchor 'top-left] [angle 0] [dist 0]) - (define-values (width height _1 _2) (send dc get-text-extent str #f #t 0)) - (let ([dist (case anchor - [(top-left bottom-left top-right bottom-right) (* sin45 dist)] - [else dist])]) - (: dxs (Listof Real)) - (define dxs (case anchor - [(top-left left bottom-left) (list (- dist) (- width dist))] - [(top center bottom) (list (* -1/2 width) (* 1/2 width))] - [else (list (- dist width) dist)])) - (: dys (Listof Real)) - (define dys (case anchor - [(top-left top top-right) (list (- dist) (- height dist))] - [(left center right) (list (* -1/2 height) (* 1/2 width))] - [else (list (- dist height) dist)])) - - (for*/list : (Listof (Vector Real Real)) ([dx (in-list dxs)] [dy (in-list dys)]) - (define rdx (+ (* (sin angle) dy) (* (cos angle) dx))) - (define rdy (- (* (cos angle) dy) (* (sin angle) dx))) - (vector (+ x rdx) (+ y rdy))))) + (define-values (width height _1 _2) + (if (string? str) + (send dc get-text-extent str #f #t 0) + (values (pict-width str) (pict-height str) 0 0))) + (define nanchor (if (eq? anchor 'auto) + (if (string? str) + (resolve-auto-anchor/str dc str x y angle dist) + (resolve-auto-anchor/pict dc str x y dist)) + anchor)) + (get-box-corners/anchor x y width height nanchor angle dist)) + +(: draw-pict/anchor (->* [(Instance DC<%>) pict Real Real] [Anchor Real] Void)) +(define (draw-pict/anchor dc pict x y [anchor 'top-left] [dist 0]) + (define width (pict-width pict)) + (define height (pict-height pict)) + (define nanchor (if (eq? anchor 'auto) + (resolve-auto-anchor/pict dc pict x y dist) + anchor)) + (define dx (case nanchor + [(top-left left bottom-left auto) (- dist)] + [(top center bottom) (* 1/2 width)] + [(top-right right bottom-right) (+ width dist)] + [else (raise-type-error 'draw-text/anchor "anchor/c" anchor)])) + (define dy (case nanchor + [(top-left top top-right auto) (- dist)] + [(left center right) (* 1/2 height)] + [(bottom-left bottom bottom-right) (+ height dist)])) + (draw-pict pict dc (- x dx) (- y dy))) ;; =================================================================================================== ;; Subdividing nonlinearly transformed shapes @@ -157,6 +242,10 @@ (define (margin-fixpoint x-min x-max y-min y-max init-left init-right init-top init-bottom get-vs) + (define x- (+ x-min init-left)) + (define x+ (- x-max init-right 1)) + (define y- (+ y-min init-top)) + (define y+ (- y-max init-bottom 1)) (let/ec return : (Values Real Real Real Real) (for/fold ([left : Real init-left] [right : Real init-right] @@ -165,15 +254,15 @@ ([i (in-range 3)]) (match-define (list (vector #{xs : (Listof Real)} #{ys : (Listof Real)}) ...) (get-vs left right top bottom)) - (define param-x-min (apply min x-min xs)) - (define param-x-max (apply max (sub1 x-max) xs)) - (define param-y-min (apply min y-min ys)) - (define param-y-max (apply max (sub1 y-max) ys)) + (define param-x-min (apply min x- xs)) + (define param-x-max (apply max x+ xs)) + (define param-y-min (apply min y- ys)) + (define param-y-max (apply max y+ ys)) - (define new-left (round (+ left (- x-min param-x-min)))) - (define new-right (round (- right (- (sub1 x-max) param-x-max)))) - (define new-top (round (+ top (- y-min param-y-min)))) - (define new-bottom (round (- bottom (- (sub1 y-max) param-y-max)))) + (define new-left (round (+ left (- x- param-x-min)))) + (define new-right (round (- right (- x+ param-x-max)))) + (define new-top (round (+ top (- y- param-y-min)))) + (define new-bottom (round (- bottom (- y+ param-y-max)))) ;; Not enough space? (define area-x-min (+ x-min new-left)) @@ -349,23 +438,3 @@ (define scale (max 1.0 (fl (send pen get-width)))) (define sty (scale-pen-style (symbol->style style-sym) scale)) (draw-lines* dc vs sty)]))])) - -;; =================================================================================================== -;; Drawing a bitmap using 2x supersampling - -(: draw-bitmap/supersampling (-> (-> (Instance DC<%>) Any) Positive-Integer Positive-Integer - (Instance Bitmap%))) -(define (draw-bitmap/supersampling draw width height) - (define bm (make-bitmap width height #:backing-scale 2)) - (define dc (make-object bitmap-dc% bm)) - (send dc set-alignment-scale 2) - (draw dc) - bm) - -(: draw-bitmap (-> (-> (Instance DC<%>) Any) Positive-Integer Positive-Integer - (Instance Bitmap%))) -(define (draw-bitmap draw width height) - (define bm (make-bitmap width height)) - (define dc (make-object bitmap-dc% bm)) - (draw dc) - bm) diff --git a/plot-lib/plot/private/common/kde.rkt b/plot-lib/plot/private/common/kde.rkt index 7de41ba5..bb5e5804 100644 --- a/plot-lib/plot/private/common/kde.rkt +++ b/plot-lib/plot/private/common/kde.rkt @@ -3,13 +3,14 @@ (require racket/list racket/promise math/base math/flonum - (only-in math/statistics sort-samples) + (only-in math/statistics sort-samples quantile stddev) "math.rkt" "utils.rkt" "sample.rkt" "type-doc.rkt") -(provide kde) +(provide kde + silverman-bandwidth) (: make-kde/windowed (-> (Vectorof Flonum) Flonum (Vectorof Flonum) Flonum (-> Flonum Flonum))) ;; Can assume that xs is sorted @@ -77,3 +78,11 @@ [(> y x-max) 0.0] [else (* c (kde/windowed y))])))) (values f x-min x-max))])) + +(:: silverman-bandwidth (-> (Listof Real) Real)) +(define (silverman-bandwidth xs) + (define iqr (- (quantile 3/4 < xs) (quantile 1/4 < xs))) + (define n (length xs)) + (define m (min (stddev xs) (/ iqr 1.349))) + (/ (* 0.9 m) + (expt n 1/5))) diff --git a/plot-lib/plot/private/common/legend.rkt b/plot-lib/plot/private/common/legend.rkt index 71583451..4d13b250 100644 --- a/plot-lib/plot/private/common/legend.rkt +++ b/plot-lib/plot/private/common/legend.rkt @@ -3,6 +3,7 @@ ;; Functions that create legend entries and lists of legend entries. (require racket/class racket/match racket/list racket/string + (only-in typed/pict pict) "type-doc.rkt" "math.rkt" "format.rkt" @@ -14,7 +15,7 @@ ;; =================================================================================================== ;; Line legends -(:: line-legend-entry (-> String Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry)) +(:: line-legend-entry (-> (U String pict) Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry)) (define (line-legend-entry label color width style) (legend-entry label (λ (pd x-size y-size) (define y (* 1/2 y-size)) @@ -22,7 +23,7 @@ (send pd set-alpha 1) (send pd draw-line (vector (ann 0 Real) y) (vector x-size y))))) -(:: line-legend-entries (-> String (Listof Real) (Listof String) +(:: line-legend-entries (-> (U String pict) (Listof Real) (Listof String) (Plot-Colors (Listof Real)) (Pen-Widths (Listof Real)) (Plot-Pen-Styles (Listof Real)) @@ -51,7 +52,7 @@ ;; =================================================================================================== ;; Rectangle legends -(:: rectangle-legend-entry (-> String +(:: rectangle-legend-entry (-> (U String pict) Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry)) @@ -63,7 +64,7 @@ (send pd draw-rect (vector (ivl 0 x-size) (ivl 0 y-size)))))) (:: rectangle-legend-entries - (-> String (Listof Real) + (-> (U String pict) (Listof Real) (Plot-Colors (Listof Real)) (Plot-Brush-Styles (Listof Real)) (Plot-Colors (Listof Real)) (Pen-Widths (Listof Real)) (Plot-Pen-Styles (Listof Real)) (Listof legend-entry))) @@ -97,7 +98,7 @@ ;; =================================================================================================== ;; Interval legends -(:: interval-legend-entry (-> String +(:: interval-legend-entry (-> (U String pict) Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Plot-Color Nonnegative-Real Plot-Pen-Style @@ -123,7 +124,7 @@ (vector x-size (ann 0 Real)))))) (:: interval-legend-entries - (-> String (Listof ivl) (Listof String) + (-> (U String pict) (Listof ivl) (Listof String) (Plot-Colors (Listof ivl)) (Plot-Brush-Styles (Listof ivl)) (Plot-Colors (Listof ivl)) (Pen-Widths (Listof ivl)) (Plot-Pen-Styles (Listof ivl)) (Plot-Colors (Listof ivl)) (Pen-Widths (Listof ivl)) (Plot-Pen-Styles (Listof ivl)) @@ -178,7 +179,7 @@ ;; =================================================================================================== ;; Point legends -(:: point-legend-entry (-> String Point-Sym Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real +(:: point-legend-entry (-> (U String pict) Point-Sym Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real legend-entry)) (define (point-legend-entry label sym color fill-color size line-width) (legend-entry label (λ (pd x-size y-size) @@ -188,7 +189,7 @@ (send pd draw-glyphs (list (vector (* 1/2 x-size) (* 1/2 y-size))) sym size)))) -(:: arrow-legend-entry (-> String Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry)) +(:: arrow-legend-entry (-> (U String pict) Plot-Color Nonnegative-Real Plot-Pen-Style legend-entry)) (define (arrow-legend-entry label color line-width line-style) (legend-entry label (λ (pd x-size y-size) (send pd set-pen color line-width line-style) diff --git a/plot-lib/plot/private/common/math.rkt b/plot-lib/plot/private/common/math.rkt index 199ba503..86e80ab4 100644 --- a/plot-lib/plot/private/common/math.rkt +++ b/plot-lib/plot/private/common/math.rkt @@ -146,11 +146,12 @@ ;; =================================================================================================== ;; Vectors +;; The final case was dead code and has been deleted. There are no instances of +;; vector-andmap thattake more than two vectors as arguments. (:: vector-andmap (All (A B C ...) (case-> (-> (-> A Boolean) (Vectorof A) Boolean) - (-> (-> A B Boolean) (Vectorof A) (Vectorof B) Boolean) - (-> (-> A B C ... C Boolean) (Vectorof A) (Vectorof B) (Vectorof C) ... C Boolean)))) + (-> (-> A B Boolean) (Vectorof A) (Vectorof B) Boolean)))) (define vector-andmap (case-lambda [([f : (-> A Boolean)] [as : (Vectorof A)]) @@ -162,27 +163,14 @@ (raise-argument-error 'vector-andmap (format "vector of length ~a" n) 2 f as bs)) (for/and ([a (in-vector as)] [b (in-vector bs)]) - (f a b))] - [(f as bs . vs) - (define n (vector-length as)) - (for ([v (in-list (cons bs vs))] - [i (in-naturals 2)]) - (unless (= (vector-length v) n) - (apply raise-argument-error 'vector-andmap (format "vector of length ~a" n) i f as bs vs))) - (let loop ([i : Nonnegative-Fixnum 0]) - (cond [(< i n) - (and (apply f (vector-ref as n) (vector-ref bs n) - (map (plambda: (C) ([v : (Vectorof C)]) - (vector-ref v n)) - vs)) - (loop (+ i 1)))] - [else #t]))])) + (f a b))])) + +;; As with vector-andmap, dead code has been deleted. (:: vector-ormap (All (A B C ...) (case-> (-> (-> A Boolean) (Vectorof A) Boolean) - (-> (-> A B Boolean) (Vectorof A) (Vectorof B) Boolean) - (-> (-> A B C ... C Boolean) (Vectorof A) (Vectorof B) (Vectorof C) ... C Boolean)))) + (-> (-> A B Boolean) (Vectorof A) (Vectorof B) Boolean)))) (define vector-ormap (case-lambda [([f : (-> A Boolean)] [as : (Vectorof A)]) @@ -194,21 +182,7 @@ (raise-argument-error 'vector-ormap (format "vector of length ~a" n) 2 f as bs)) (for/or ([a (in-vector as)] [b (in-vector bs)]) - (f a b))] - [(f as bs . vs) - (define n (vector-length as)) - (for ([v (in-list (cons bs vs))] - [i (in-naturals 2)]) - (unless (= (vector-length v) n) - (apply raise-argument-error 'vector-ormap (format "vector of length ~a" n) i f as bs vs))) - (let loop ([i : Nonnegative-Fixnum 0]) - (cond [(< i n) - (or (apply f (vector-ref as n) (vector-ref bs n) - (map (plambda: (C) ([v : (Vectorof C)]) - (vector-ref v n)) - vs)) - (loop (+ i 1)))] - [else #f]))])) + (f a b))])) (:: vcross (-> (Vectorof Real) (Vectorof Real) (Vector Real Real Real))) (define (vcross v1 v2) diff --git a/plot-lib/plot/private/common/parameter-groups.rkt b/plot-lib/plot/private/common/parameter-groups.rkt index 3c2ffad2..5e3bcd7f 100644 --- a/plot-lib/plot/private/common/parameter-groups.rkt +++ b/plot-lib/plot/private/common/parameter-groups.rkt @@ -3,24 +3,28 @@ (module untyped-defs racket/base (require "parameters.rkt" "parameter-group.rkt") - + (provide (all-defined-out)) - + (define-parameter-group plot-axes? (plot-x-axis? plot-x-far-axis? plot-y-axis? plot-y-far-axis? plot-z-axis? plot-z-far-axis?)) - + (define-parameter-group plot-tick-labels - (plot-x-tick-label-anchor + (plot-x-tick-labels? + plot-x-tick-label-anchor plot-x-tick-label-angle + plot-x-far-tick-labels? plot-x-far-tick-label-anchor plot-x-far-tick-label-angle + plot-y-tick-labels? plot-y-tick-label-anchor plot-y-tick-label-angle + plot-y-far-tick-labels? plot-y-far-tick-label-anchor plot-y-far-tick-label-angle)) - + (define-parameter-group plot-appearance (plot-width plot-height @@ -28,11 +32,20 @@ plot-background plot-background-alpha plot-line-width plot-tick-size plot-font-size plot-font-face plot-font-family - plot-legend-anchor plot-legend-box-alpha + plot-legend-font-size plot-legend-font-face plot-legend-font-family + plot-legend-anchor plot-legend-box-alpha plot-legend-layout plot-axes? plot-tick-labels plot-decorations? - plot-animating?)) - + plot-animating? + plot-pen-color-map + plot-brush-color-map + arrow-head-size-or-scale + arrow-head-angle + plot-line-cap + line-cap + plot-inset + plot-legend-padding)) + (define-parameter-group plot3d-appearance (plot3d-samples plot3d-angle @@ -40,20 +53,20 @@ plot3d-ambient-light plot3d-diffuse-light? plot3d-specular-light?)) - + (define-parameter-group plot-output (plot-new-window? plot-jpeg-quality plot-ps/pdf-interactive? plot-ps-setup)) - + (define-parameter-group plot-labels (plot-title plot-x-label plot-y-label plot-z-label plot-x-far-label plot-y-far-label plot-z-far-label)) - + (define-parameter-group plot-x-axis (plot-x-transform plot-x-ticks plot-x-far-ticks)) (define-parameter-group plot-y-axis (plot-y-transform plot-y-ticks plot-y-far-ticks)) (define-parameter-group plot-z-axis (plot-z-transform plot-z-ticks plot-z-far-ticks)) (define-parameter-group plot-axes (plot-x-axis plot-y-axis plot-z-axis plot-d-ticks plot-r-ticks)) - + (define-parameter-group plot-parameters (plot-appearance plot3d-appearance @@ -64,16 +77,18 @@ (module typed-defs typed/racket/base (require typed/racket/draw + (only-in typed/pict pict) (submod ".." untyped-defs) "type-doc.rkt" "types.rkt" "axis-transform.rkt" "ticks.rkt") - + (provide Plot-Parameters) - + (deftype Plot-Parameters (List + ;; plot-appearance (List Positive-Integer Positive-Integer @@ -86,29 +101,45 @@ Nonnegative-Real (U False String) Font-Family - Anchor + (U False Nonnegative-Real) + (U False String) + (U False Font-Family) + Legend-Anchor Nonnegative-Real + Legend-Layout (List Boolean Boolean Boolean Boolean Boolean Boolean) - (List Anchor Real Anchor Real Anchor Real Anchor Real) + (List Boolean Anchor Real (U Boolean 'auto) Anchor Real Boolean Anchor Real (U Boolean 'auto) Anchor Real) + Boolean Boolean - Boolean) + (U Symbol #f) + (U Symbol #f) + (U (List '= Nonnegative-Real) Nonnegative-Real) + Nonnegative-Real + Plot-Pen-Cap + Plot-Pen-Cap + (U Nonnegative-Real (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real)) + (U Nonnegative-Real (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real))) + ;;plot3d-appearance (List Positive-Integer Real Real Nonnegative-Real Boolean Boolean) + ;;plot-labels (List - (U False String) - (U False String) - (U False String) - (U False String) - (U False String) - (U False String) - (U False String)) + (U False String pict) + (U False String pict) + (U False String pict) + (U False String pict) + (U False String pict) + (U False String pict) + (U False String pict)) + ;;plot-output (List Boolean Nonnegative-Integer Boolean (Instance PS-Setup%)) + ;;plot-axes (List (List Axis-Transform ticks ticks) (List Axis-Transform ticks ticks) (List Axis-Transform ticks ticks) ticks ticks))) - + (define (test) (ann (plot-parameters) Plot-Parameters))) (require 'untyped-defs diff --git a/plot-lib/plot/private/common/parameters.rkt b/plot-lib/plot/private/common/parameters.rkt index d2f9cbc8..ebb65753 100644 --- a/plot-lib/plot/private/common/parameters.rkt +++ b/plot-lib/plot/private/common/parameters.rkt @@ -4,6 +4,7 @@ (require typed/racket/class typed/racket/draw + (only-in typed/pict pict) "type-doc.rkt" "types.rkt" "draw-attribs.rkt" @@ -62,17 +63,29 @@ (defparam2 plot-width Integer Positive-Integer 400 (integer>=1 'plot-width)) (defparam2 plot-height Integer Positive-Integer 400 (integer>=1 'plot-height)) -(defparam plot-foreground color Plot-Color 0) -(defparam plot-background color Plot-Color 0) +(defparam plot-foreground color Plot-Color "black") +(defparam plot-background color Plot-Color "white") (defparam2 plot-foreground-alpha alpha Real Nonnegative-Real 1 (unit-ivl 'plot-foreground-alpha)) (defparam2 plot-background-alpha alpha Real Nonnegative-Real 1 (unit-ivl 'plot-background-alpha)) (defparam2 plot-line-width width Real Nonnegative-Real 1 (nonnegative-rational 'plot-line-width)) +(defparam plot-line-cap Plot-Pen-Cap 'round) (defparam2 plot-tick-size size Real Nonnegative-Real 10 (nonnegative-rational 'plot-tick-size)) (defparam2 plot-font-size size Real Nonnegative-Real 11 (nonnegative-rational 'plot-font-size)) (defparam plot-font-face face (U String #f) #f) (defparam plot-font-family family Font-Family 'roman) -(defparam plot-legend-anchor anchor Anchor 'top-left) +(defparam plot-legend-font-size size (U Nonnegative-Real #f) #f) +(defparam plot-legend-font-face face (U String #f) #f) +(defparam plot-legend-font-family family (U Font-Family #f) #f) +(defparam plot-legend-anchor anchor Legend-Anchor 'top-left) +(defparam plot-legend-layout layout Legend-Layout '(columns 1 equal-size)) (defparam2 plot-legend-box-alpha alpha Real Nonnegative-Real 2/3 (unit-ivl 'plot-legend-box-alpha)) +(defparam plot-legend-padding + (U + ;; A single padding value for all sides + Nonnegative-Real + ;; Separate left, right, top, and bottom padding values + (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real)) + 0.0) (defparam plot-animating? Boolean #f) (defparam plot-x-axis? Boolean #t) @@ -83,6 +96,14 @@ (defparam plot-y-far-axis? Boolean #t) (defparam plot-z-far-axis? Boolean #t) +(defparam plot-x-tick-labels? Boolean #t) +(defparam plot-y-tick-labels? Boolean #t) +(defparam plot-z-tick-labels? Boolean #t) + +(defparam plot-x-far-tick-labels? (U Boolean 'auto) 'auto) +(defparam plot-y-far-tick-labels? (U Boolean 'auto) 'auto) +(defparam plot-z-far-tick-labels? (U Boolean 'auto) 'auto) + (defparam2 plot-x-tick-label-angle angle Real Real 0 (rational 'plot-x-tick-label-angle)) (defparam2 plot-y-tick-label-angle angle Real Real 0 (rational 'plot-y-tick-label-angle)) (defparam2 plot-x-far-tick-label-angle angle Real Real 0 (rational 'plot-x-far-tick-label-angle)) @@ -94,6 +115,15 @@ (defparam plot-y-far-tick-label-anchor anchor Anchor 'left) (defparam plot-decorations? Boolean #t) +(defparam plot-inset + (U + ;; A single inset value for all sides + Nonnegative-Real + ;; Separate left, right, top, and bottom inset values + (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real)) + 0.0) +(defparam plot-pen-color-map (U Symbol #f) #f) +(defparam plot-brush-color-map (U Symbol #f) #f) (:: pen-gap (-> Real)) (define (pen-gap) @@ -125,16 +155,18 @@ (defparam plot-ps/pdf-interactive? Boolean #f) (defparam plot-ps-setup (Instance PS-Setup%) default-plot-ps-setup) +(defparam plot-aspect-ratio (U Nonnegative-Real #f) #f) + ;; Labels -(defparam plot-title (U String #f) #f) -(defparam plot-x-label (U String #f) "x axis") -(defparam plot-y-label (U String #f) "y axis") -(defparam plot-z-label (U String #f) #f) +(defparam plot-title (U String pict #f) #f) +(defparam plot-x-label (U String pict #f) "x axis") +(defparam plot-y-label (U String pict #f) "y axis") +(defparam plot-z-label (U String pict #f) #f) -(defparam plot-x-far-label (U String #f) #f) -(defparam plot-y-far-label (U String #f) #f) -(defparam plot-z-far-label (U String #f) #f) +(defparam plot-x-far-label (U String pict #f) #f) +(defparam plot-y-far-label (U String pict #f) #f) +(defparam plot-z-far-label (U String pict #f) #f) ;; Axes: transform, ticks @@ -161,6 +193,7 @@ (defparam line-color Plot-Color 1) (defparam2 line-width Real Nonnegative-Real 1 (nonnegative-rational 'line-width)) (defparam line-style Plot-Pen-Style 'solid) +(defparam line-cap Plot-Pen-Cap 'round) (defparam2 line-alpha Real Nonnegative-Real 1 (unit-ivl 'line-alpha)) ;; Intervals @@ -179,9 +212,9 @@ (defparam point-sym Point-Sym 'circle) (defparam point-color Plot-Color 0) -(defparam point-x-jitter Real 0) -(defparam point-y-jitter Real 0) -(defparam point-z-jitter Real 0) +(defparam point-x-jitter Nonnegative-Real 0) +(defparam point-y-jitter Nonnegative-Real 0) +(defparam point-z-jitter Nonnegative-Real 0) (defparam2 point-size Real Nonnegative-Real 6 (nonnegative-rational 'point-size)) (defparam2 point-line-width Real Nonnegative-Real 1 (nonnegative-rational 'point-line-width)) (defparam2 point-alpha Real Nonnegative-Real 1 (unit-ivl 'point-alpha)) @@ -197,6 +230,16 @@ (defparam2 vector-field-alpha Real Nonnegative-Real 1 (unit-ivl 'vector-field-alpha)) (defparam vector-field3d-samples Positive-Integer 9) +;;arrow + +(defparam arrows-color Plot-Color 1) +(defparam2 arrows-line-width Real Nonnegative-Real 2/3 + (nonnegative-rational 'arrows-line-width)) +(defparam arrows-line-style Plot-Pen-Style 'solid) +(defparam2 arrows-alpha Real Nonnegative-Real 1 (unit-ivl 'arrows-alpha)) +(defparam arrow-head-size-or-scale (U Nonnegative-Real (List '= Nonnegative-Real)) 2/5) +(defparam arrow-head-angle Nonnegative-Real 0.5235987755982988);=pi/6=30° + ;; Error bars (defparam2 error-bar-width Real Nonnegative-Real 6 (nonnegative-rational 'error-bar-width)) @@ -214,17 +257,13 @@ (defparam candlestick-line-style Plot-Pen-Style 'solid) (defparam2 candlestick-alpha Real Nonnegative-Real 2/3 (unit-ivl 'candlestick-alpha)) -;; Contours -(:: default-contour-colors (-> (Listof Real) (Listof Plot-Color))) -(define (default-contour-colors zs) - (color-seq* (list (->pen-color 5) (->pen-color 0) (->pen-color 1)) - (length zs))) +;; color fields + +(defparam color-field-samples Positive-Integer 20) +(defparam2 color-field-alpha Real Nonnegative-Real 1 (unit-ivl 'color-field-alpha)) -(:: default-contour-fill-colors (-> (Listof ivl) (Listof Plot-Color))) -(define (default-contour-fill-colors z-ivls) - (color-seq* (list (->brush-color 5) (->brush-color 0) (->brush-color 1)) - (length z-ivls))) +;; Contours (defparam2 contour-samples Integer Positive-Integer 51 (integer>=2 'contour-samples)) (defparam contour-levels Contour-Levels 'auto) @@ -305,16 +344,6 @@ ;; Isosurfaces -(:: default-isosurface-colors (-> (Listof Real) (Listof Plot-Color))) -(define (default-isosurface-colors zs) - (color-seq* (list (->brush-color 5) (->brush-color 0) (->brush-color 1)) - (length zs))) - -(:: default-isosurface-line-colors (-> (Listof Real) (Listof Plot-Color))) -(define (default-isosurface-line-colors zs) - (color-seq* (list (->pen-color 5) (->pen-color 0) (->pen-color 1)) - (length zs))) - (defparam isosurface-levels Contour-Levels 'auto) (defparam isosurface-colors (Plot-Colors (Listof Real)) default-isosurface-colors) (defparam isosurface-styles (Plot-Brush-Styles (Listof Real)) '(solid)) diff --git a/plot-lib/plot/private/common/plot-device.rkt b/plot-lib/plot/private/common/plot-device.rkt index 75c174b5..f2b51287 100644 --- a/plot-lib/plot/private/common/plot-device.rkt +++ b/plot-lib/plot/private/common/plot-device.rkt @@ -8,8 +8,10 @@ (require typed/racket/draw typed/racket/class + (only-in typed/pict pict pict? pict-width pict-height pict-descent pict-ascent) racket/match racket/math racket/bool racket/list racket/vector "draw-attribs.rkt" + "color-map.rkt" "draw.rkt" "math.rkt" "sample.rkt" @@ -95,7 +97,7 @@ (full8star . 8star))) (define-type Tick-Params (List Boolean (Vectorof Real) Real Real)) -(define-type Label-Params (List (U #f String) (Vectorof Real) Anchor Real)) +(define-type Label-Params (List (U #f String pict) (Vectorof Real) Anchor Real)) (: plot-device% Plot-Device%) (define plot-device% @@ -170,7 +172,7 @@ ;; ----------------------------------------------------------------------------------------------- ;; Pen, brush, alpha parameters - (define pen-hash ((inst make-hash (Vector Integer Integer Integer Real) (Instance Pen%)))) + (define pen-hash ((inst make-hash (Vector Integer Integer Integer Real Symbol) (Instance Pen%)))) (define transparent-pen (make-pen% 0 0 0 1 'transparent 'round)) (: pen-color (List Real Real Real)) @@ -183,7 +185,7 @@ ;; Sets the pen, using a hash table to avoid making duplicate objects. At time of writing (and for ;; the forseeable future) this is much faster than using a pen-list%, because it doesn't have to ;; synchronize access. It's also not thread-safe. - (define/public (set-pen color width style [cap 'round]) + (define/public (set-pen color width style [cap (line-cap)]) (set! pen-style (->pen-style style)) (cond [(eq? pen-style 'transparent) (set! pen-color '(0 0 0)) @@ -196,16 +198,16 @@ (app real->color-byte g) (app real->color-byte b)) pen-color) - (send dc set-pen (hash-ref! pen-hash (vector r g b width) + (send dc set-pen (hash-ref! pen-hash (vector r g b width cap) (λ () (make-pen% r g b width 'solid cap))))])) ;; Sets the pen used to draw major ticks. (define/public (set-major-pen [style 'solid]) - (set-pen (plot-foreground) (plot-line-width) style)) + (set-pen (plot-foreground) (plot-line-width) style (plot-line-cap))) ;; Sets the pen used to draw minor ticks. (define/public (set-minor-pen [style 'solid]) - (set-pen (plot-foreground) (* 1/2 (plot-line-width)) style)) + (set-pen (plot-foreground) (* 1/2 (plot-line-width)) style (plot-line-cap))) (define brush-hash ((inst make-hash (Vector Integer Integer Integer Symbol) (Instance Brush%)))) (define transparent-brush (make-brush% 0 0 0 'transparent)) @@ -269,7 +271,7 @@ ;; Sets only the font size, not the face or family. (define/public (set-font-size size) - (set-font-attribs size + (set-font-attribs size (send (send dc get-font) get-face) (send (send dc get-font) get-family))) @@ -285,7 +287,13 @@ ;; Returns the extent of a string, as exact reals. (define/public (get-text-extent str) (define-values (w h b d) - (send dc get-text-extent str #f #t 0)) + (cond ((string? str) + (send dc get-text-extent str #f #t 0)) + ((pict? str) + (values (pict-width str) (pict-height str) + (pict-descent str) (pict-ascent str))) + (#t + (values 0 0 0 0)))) (values (inexact->exact w) (inexact->exact h) (inexact->exact b) (inexact->exact d))) @@ -298,6 +306,21 @@ (define/public (set-text-foreground color) (send dc set-text-foreground (color->color% (->pen-color color)))) + + ;; ----------------------------------------------------------------------------------------------- + ;; Arrows + + (: pd-arrow-head-size-or-scale (U (List '= Nonnegative-Real) Nonnegative-Real)) + (: pd-arrow-head-angle Nonnegative-Real) + (define pd-arrow-head-size-or-scale (arrow-head-size-or-scale)) + (define pd-arrow-head-angle (arrow-head-angle)) + + ;; Sets the arrow-head shape (for draw-arrow) + (define/public (set-arrow-head size-or-scale angle) + (set! pd-arrow-head-size-or-scale size-or-scale) + (set! pd-arrow-head-angle angle)) + + ;; ----------------------------------------------------------------------------------------------- ;; Clipping @@ -402,12 +425,15 @@ (define dy (- y2 y1)) (define angle (if (and (zero? dy) (zero? dx)) 0 (atan dy dx))) (define dist (sqrt (+ (sqr dx) (sqr dy)))) - (define head-r (* 2/5 dist)) - (define head-angle (* 1/6 pi)) - (define dx1 (* (cos (+ angle head-angle)) head-r)) - (define dy1 (* (sin (+ angle head-angle)) head-r)) - (define dx2 (* (cos (- angle head-angle)) head-r)) - (define dy2 (* (sin (- angle head-angle)) head-r)) + (define head-r + (let ([size-or-scale pd-arrow-head-size-or-scale]) + (if (list? size-or-scale) + (cadr size-or-scale) + (* size-or-scale dist)))) + (define dx1 (* (cos (+ angle pd-arrow-head-angle)) head-r)) + (define dy1 (* (sin (+ angle pd-arrow-head-angle)) head-r)) + (define dx2 (* (cos (- angle pd-arrow-head-angle)) head-r)) + (define dy2 (* (sin (- angle pd-arrow-head-angle)) head-r)) (send dc draw-line x1 y1 x2 y2) (send dc draw-line x2 y2 (- x2 dx1) (- y2 dy1)) (send dc draw-line x2 y2 (- x2 dx2) (- y2 dy2)))) @@ -419,7 +445,7 @@ (define/private ((make-draw-circle-glyph r) v) (when (vrational? v) (match-define (vector x y) v) - (send dc draw-ellipse (- x r -1/2) (- y r -1/2) (* 2 r) (* 2 r)))) + (send dc draw-ellipse (- x r) (- y r) (* 2 r) (* 2 r)))) (: make-draw-polygon-glyph (-> Nonnegative-Real Natural Real (-> (Vectorof Real) Void))) (define/private (make-draw-polygon-glyph r sides start-angle) @@ -520,13 +546,11 @@ (define r (* 1/2 size)) (define line-sym (cond [(hash-has-key? full-glyph-hash real-sym) - (when (eq? pen-color brush-color) - (set-pen pen-color 1 'transparent) - (set-brush brush-color 'solid)) (hash-ref full-glyph-hash real-sym)] [else (set-brush brush-color 'transparent) real-sym])) (case line-sym + [(none) void] ; circles [(circle) (make-draw-circle-glyph r)] ; squares @@ -575,87 +599,233 @@ (for ([v (in-list vs)]) (draw-glyph v)))) + (define/public (draw-pict pict v [anchor 'top-left] [dist 0]) + (when (vrational? v) + (match-define (vector x y) v) + (draw-pict/anchor dc pict x y anchor dist))) + ;; =============================================================================================== ;; Legend - (define/public (draw-legend legend-entries rect) + ;; the folowing functions take a (Listof legend-entry), a Rect and Anchor as argument. + ;; the understanding is that Rect will be the complete dc for a legend outside the plot-area + ;; and the plot-area otherwise + + (: calculate-legend-parameters (-> (Listof legend-entry) + Rect + Anchor + (U Nonnegative-Real + (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real)) + + (Values Rect (Listof Exact-Rational) + Nonnegative-Exact-Rational (Listof Real) (Listof Real) + Nonnegative-Exact-Rational (Listof Real) + Boolean Nonnegative-Integer))) + (define/private (calculate-legend-parameters legend-entries rect anchor padding) (define n (length legend-entries)) - (match-define (list (legend-entry #{labels : (Listof String)} - #{draw-procs : (Listof Legend-Draw-Proc)}) - ...) - legend-entries) - + (define labels (map legend-entry-label legend-entries)) (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) rect) - - (define-values (_1 label-y-size baseline _2) (get-text-extent (first labels))) - (define horiz-gap (get-text-width " ")) - (define top-gap baseline) - (define bottom-gap (* 1/2 baseline)) - (define baseline-skip (+ label-y-size baseline)) - - (define max-label-x-size (apply max (map (λ ([label : String]) (get-text-width label)) labels))) - (define labels-x-size (+ max-label-x-size horiz-gap)) - - (define draw-y-size (max 0 (- label-y-size baseline))) - (define draw-x-size (* 4 draw-y-size)) - - (define legend-x-size (+ horiz-gap - labels-x-size (* 2 horiz-gap) - draw-x-size horiz-gap)) - (define legend-y-size (+ top-gap (* n baseline-skip) bottom-gap)) - - (define legend-x-min - (cond - [(and x-min x-max) - (case (plot-legend-anchor) - [(top-left left bottom-left) x-min] + (cond + [(and x-min x-max y-min y-max) + (define-values (cols? rows cols compact?) + (match (plot-legend-layout) + [(list 'rows i compact) + (values #f (min n i) (ceiling (/ n i)) (equal? compact 'compact))] + [(list 'columns i compact) + (values #t (ceiling (/ n i)) (min n i) (equal? compact 'compact))])) + (define div (if cols? rows cols)) + + ;; get max widths and heights per row/column + (define-values (max-label-widths max-label-heights) + (let-values ([(width height) + (for/fold ([width : (Immutable-HashTable Integer Exact-Rational) #hash()] + [height : (Immutable-HashTable Integer Exact-Rational) #hash()]) + ([label (in-list labels)] + [k (in-naturals)]) + (define-values (i j) + (let-values ([(i j) (quotient/remainder k div)]) + (if cols? (values j i) (values i j)))) + (define-values (w h b a) (get-text-extent label)) + (values + (hash-update width j (λ ([v : Exact-Rational]) (max w v)) (λ () 0)) + (hash-update height i (λ ([v : Exact-Rational]) (max h v)) (λ () 0))))]) + (define widths + ((inst map Exact-Rational (Pairof Integer Exact-Rational)) + cdr ((inst sort (Pairof Integer Exact-Rational) Integer) + (hash->list width) < #:key car))) + (define heights + ((inst map Exact-Rational (Pairof Integer Exact-Rational)) + cdr ((inst sort (Pairof Integer Exact-Rational) Integer) + (hash->list height) < #:key car))) + (cond + [compact? (values widths heights)] + [else + (define max-width (apply max widths)) + (define max-heights (apply max heights)) + (values (map (λ (_) max-width) widths) + (map (λ (_) max-heights) heights))]))) + + ;; different gaps + (define-values (horiz-gap min-label-height baseline _1) + (get-text-extent " ")) + + (define top-gap baseline) + (define bottom-gap (* 1/2 baseline)) + (define in-label-gap (* 3 horiz-gap)) + (define column-gap (* 3 in-label-gap)) + + ;; size of legend line/square + (define draw-y-size (max 0 (- min-label-height baseline))) + (define draw-x-size (* 4 draw-y-size)) + + ;; size of complete legend-entry + (define x-skips (for/list : (Listof Exact-Rational) + ([w (in-list max-label-widths)]) + (+ w in-label-gap draw-x-size column-gap))) + (define y-skips (for/list : (Listof Exact-Rational) + ([h (in-list max-label-heights)]) + (+ h baseline))) + + ;; size of complete legend + (define legend-x-size (+ horiz-gap (- column-gap) horiz-gap + (for/sum : Exact-Rational ([w (in-list x-skips)]) w))) + (define legend-y-size (+ top-gap bottom-gap + (for/sum : Exact-Rational ([h (in-list y-skips)]) h))) + + ;; top-left corner of legend + (define legend-x-min + (case anchor + [(top-left left bottom-left auto) x-min] [(top-right right bottom-right) (- x-max legend-x-size)] [(center bottom top) (- (* 1/2 (+ x-min x-max)) - (* 1/2 legend-x-size))])] - [else - (raise-argument-error 'draw-legend "rect-known?" 1 legend-entries rect)])) - - (define legend-y-min - (cond - [(and y-min y-max) - (case (plot-legend-anchor) - [(top-left top top-right) y-min] + (* 1/2 legend-x-size))])) + + (define legend-y-min + (case anchor + [(top-left top top-right auto) y-min] [(bottom-left bottom bottom-right) (- y-max legend-y-size)] [(center left right) (- (* 1/2 (+ y-min y-max)) - (* 1/2 legend-y-size))])] - [else - (raise-argument-error 'draw-legend "rect-known?" 1 legend-entries rect)])) - - (define legend-rect (vector (ivl legend-x-min (+ legend-x-min legend-x-size)) - (ivl legend-y-min (+ legend-y-min legend-y-size)))) - - (define label-x-min (+ legend-x-min horiz-gap)) - (define draw-x-min (+ legend-x-min (* 2 horiz-gap) labels-x-size horiz-gap)) + (* 1/2 legend-y-size))])) + + (define legend-rect + (let-values ([(pad-left pad-right pad-top pad-bottom) + (if (list? padding) + (values (list-ref padding 0) (list-ref padding 1) (list-ref padding 2) (list-ref padding 3)) + (values padding padding padding padding))]) + (vector (ivl (- legend-x-min pad-left) + (+ legend-x-min legend-x-size pad-right)) + (ivl (- legend-y-min pad-top) + (+ legend-y-min legend-y-size pad-bottom))))) + + ;; per entry x/y left/top corners + (define label-x-mins (for/fold ([mins : (Listof Real) (list (+ legend-x-min horiz-gap))] + [prev : Real (+ legend-x-min horiz-gap)] + #:result (reverse mins)) + ([x (in-list x-skips)]) + (define nxt (+ prev x)) + (values (cons nxt mins) nxt))) + (define label-y-mins (for/fold ([mins : (Listof Real) (list (+ legend-y-min top-gap))] + [prev : Real (+ legend-y-min top-gap)] + #:result (reverse mins)) + ([y (in-list y-skips)]) + (define nxt (+ prev y)) + (values (cons nxt mins) nxt))) + (define draw-x-mins (for/list : (Listof Real) + ([x (in-list label-x-mins)] + [w (in-list max-label-widths)]) (+ x w in-label-gap))) + + (values legend-rect max-label-heights + draw-x-size label-x-mins draw-x-mins + draw-y-size label-y-mins + cols? div)] + [else + (raise-argument-error 'draw-legend "rect-known?" 1 legend-entries rect)])) + + (define/public (calculate-legend-rect legend-entries rect anchor padding) + ;; Change font for correct size calculation in calculate-legend-parameters + (define old-size (send (send dc get-font) get-point-size)) + (define old-face (send (send dc get-font) get-face)) + (define old-family (send (send dc get-font) get-family)) + (set-font-attribs + (or (plot-legend-font-size) old-size) + (or (plot-legend-font-face) old-face) + (or (plot-legend-font-family) old-family)) + + (define-values (legend-rect max-label-heights + draw-x-size label-x-mins draw-x-mins + draw-y-size label-y-mins + cols? div) + (calculate-legend-parameters legend-entries rect anchor padding)) + + ;; Undo change font + (set-font-attribs old-size old-face old-family) + + legend-rect) - ;; legend background - (set-pen (plot-foreground) 1 'transparent) - (set-brush (plot-background) 'solid) - (set-alpha (plot-legend-box-alpha)) - (draw-rect legend-rect) - - ;; legend border - (set-minor-pen) - (set-brush (plot-background) 'transparent) - (set-alpha 3/4) - (draw-rect legend-rect) - - (set-alpha (plot-foreground-alpha)) - (set-clipping-rect legend-rect) - (for ([label (in-list labels)] [draw-proc (in-list draw-procs)] [i (in-naturals)]) - (define label-y-min (+ legend-y-min top-gap (* i baseline-skip))) - (draw-text label (vector (ann label-x-min Real) (ann label-y-min Real)) 'top-left 0 0 #t) - - (define draw-y-min (+ label-y-min (* 1/2 baseline))) - - (define entry-pd (make-object plot-device% dc draw-x-min draw-y-min draw-x-size draw-y-size)) - (send entry-pd reset-drawing-params #f) - (draw-proc this draw-x-size draw-y-size) - (send entry-pd restore-drawing-params)) - - (clear-clipping-rect)) - )) ; end class + (define/public (draw-legend legend-entries rect) + (define legend-anchor (plot-legend-anchor)) + (define legend-padding (plot-legend-padding)) + (when (not (eq? legend-anchor 'no-legend)) + (match-define (list (legend-entry #{labels : (Listof (U String pict))} + #{draw-procs : (Listof Legend-Draw-Proc)}) + ...) + legend-entries) + + ;; Change font early for correct size calculation in calculate-legend-parameters + (define old-size (send (send dc get-font) get-point-size)) + (define old-face (send (send dc get-font) get-face)) + (define old-family (send (send dc get-font) get-family)) + (set-font-attribs + (or (plot-legend-font-size) old-size) + (or (plot-legend-font-face) old-face) + (or (plot-legend-font-family) old-family)) + + (define-values (legend-rect max-label-heights + draw-x-size label-x-mins draw-x-mins + draw-y-size label-y-mins + cols? div) + (calculate-legend-parameters legend-entries rect (legend-anchor->anchor legend-anchor) legend-padding)) + + ;; legend background + (set-pen (plot-foreground) 1 'transparent) + (set-brush (plot-background) 'solid) + (set-alpha (plot-legend-box-alpha)) + (draw-rect legend-rect) + + ;; legend border + (set-minor-pen) + (set-brush (plot-background) 'transparent) + (set-alpha 3/4) + (draw-rect legend-rect) + + (set-alpha (plot-foreground-alpha)) + (set-clipping-rect legend-rect) + (for ([label (in-list labels)] [draw-proc (in-list draw-procs)] [k (in-naturals)]) + (define-values (i j) + (let-values ([(i j) (quotient/remainder k div)]) + (if cols? (values j i) (values i j)))) + + (define-values (_1 label-height _2 _3) (get-text-extent label)) + (define label-x-min (list-ref label-x-mins j)) + (define legend-entry-y-min (list-ref label-y-mins i)) + (define max-label-height (list-ref max-label-heights i)) + (define label-y-min (+ legend-entry-y-min + (* 1/2 (- max-label-height label-height)))) + + (if (pict? label) + (draw-pict label (vector label-x-min label-y-min) 'top-left 0) + (draw-text label (vector label-x-min label-y-min) 'top-left 0 0 #t)) + + (define draw-y-min (+ legend-entry-y-min (* 1/2 (- max-label-height draw-y-size)))) + (define draw-x-min (list-ref draw-x-mins j)) + + (define entry-pd (make-object plot-device% dc draw-x-min draw-y-min draw-x-size draw-y-size)) + (send entry-pd reset-drawing-params #f) + (draw-proc this draw-x-size draw-y-size) + (send entry-pd restore-drawing-params)) + + ;; reset plot font attributes + (set-font-attribs old-size old-face old-family) + + (clear-clipping-rect)) + ))) ; end class diff --git a/plot-lib/plot/private/common/plotmetrics.rkt b/plot-lib/plot/private/common/plotmetrics.rkt new file mode 100644 index 00000000..b6ace8f7 --- /dev/null +++ b/plot-lib/plot/private/common/plotmetrics.rkt @@ -0,0 +1,96 @@ +#lang typed/racket/base + +;; Untyped interface / contract +(module untyped racket/base + (require racket/class + racket/contract) + + (provide plot-metrics<%> + plot-metrics-object/c + interface?) + + (define plot-metrics<%> + (interface () + get-plot-bounds + dc->plot + plot->dc + plane-vector + get-plot-metrics-functions)) + + (define plot-metrics-object/c + (object/c [get-plot-bounds (->m (vectorof (vector/c real? real?)))] + [plot->dc (->m (vectorof real?) (vectorof real?))] + [dc->plot (->m (vectorof real?) (vectorof real?))] + [plane-vector (->m (vectorof real?))] + [get-plot-metrics-functions (->m (list/c (-> (vectorof (vector/c real? real?))) + (-> (vectorof real?) (vectorof real?)) + (-> (vectorof real?) (vectorof real?)) + (-> (vectorof real?))))])) + ) + +;; Typed Types / mixin / structures +(require typed/pict + typed/racket/class + racket/match) + +(provide plot-metrics-mixin Plot-Metrics-Functions Plot-Metrics<%> plot-metrics% + (struct-out plot-pict) Plot-Pict pict->pp) + +(define-type Metrics-Object (Object [get-plot-metrics-functions (-> Plot-Metrics-Functions)])) +(define-type Plot-Metrics-Functions (List (-> (Vectorof (Vectorof Real))) + (-> (Vectorof Real) (Vectorof Real)) + (-> (Vectorof Real) (Vectorof Real)) + (-> (Vectorof Real)))) +(define-type Plot-Metrics<%> + (Class + [get-plot-bounds (-> (Vectorof (Vectorof Real)))] + [plot->dc (-> (Vectorof Real) (Vectorof Real))] + [dc->plot (-> (Vectorof Real) (Vectorof Real))] + [plane-vector (-> (Vectorof Real))] + [get-plot-metrics-functions (-> Plot-Metrics-Functions)])) + +(: plot-metrics-mixin (All (A #:row) (-> (Class #:row-var A) + (Class [init [->metrics-object (-> Metrics-Object)]] + #:row-var A + #:implements Plot-Metrics<%>)))) +(define (plot-metrics-mixin %) + (class % + (init ->metrics-object) + (define (load) : Void + (match-define (list new-bounds new-->dc new-->plot new-plane) + (send (->metrics-object) get-plot-metrics-functions)) + (set! bounds new-bounds) + (set! ->dc new-->dc) + (set! ->plot new-->plot) + (set! plane new-plane) + (set! getall (λ () (list bounds ->dc ->plot plane))) + (set! load void)) + + (define (bounds) : (Vectorof (Vectorof Real)) (load)(bounds)) + (define (plane) : (Vectorof Real) (load)(plane)) + (define (getall) : Plot-Metrics-Functions (load)(list bounds ->dc ->plot plane)) + (define (->dc [v : (Vectorof Real)]) : (Vectorof Real) (load)(->dc v)) + (define (->plot [v : (Vectorof Real)]) : (Vectorof Real) (load)(->plot v)) + + (super-make-object) + (define/public (get-plot-bounds) (bounds)) + (define/public (dc->plot coords) (->plot coords)) + (define/public (plot->dc coords) (->dc coords)) + (define/public (plane-vector) (plane)) + (define/public (get-plot-metrics-functions) (getall)))) + +(define plot-metrics% (plot-metrics-mixin object%)) + +(struct plot-pict pict ([bounds : (Vectorof (Vectorof Real))] + [plot->dc : (-> (Vectorof Real) (Vectorof Real))] + [dc->plot : (-> (Vectorof Real) (Vectorof Real))] + [plane-vector : (Vectorof Real)])) +(define-type Plot-Pict plot-pict) +(define (pict->pp [P : pict] + [metrics-object : Metrics-Object]) : plot-pict + (match-define (list bounds ->dc ->plot plane) + (send metrics-object get-plot-metrics-functions)) + + (plot-pict (pict-draw P) (pict-width P) (pict-height P) (pict-ascent P) + (pict-descent P) (pict-children P) (pict-panbox P) (pict-last P) + (bounds) ->dc ->plot (plane))) diff --git a/plot-lib/plot/private/common/ticks.rkt b/plot-lib/plot/private/common/ticks.rkt index e2020e10..681d3a1d 100644 --- a/plot-lib/plot/private/common/ticks.rkt +++ b/plot-lib/plot/private/common/ticks.rkt @@ -38,7 +38,18 @@ (match-define (ticks layout format) t) (define ts (map pre-tick-inexact->exact (layout x-min x-max))) (match-define (list (pre-tick #{xs : (Listof Real)} #{majors : (Listof Boolean)}) ...) ts) - (map tick xs majors (format x-min x-max ts))) + (define labels (format x-min x-max ts)) + (unless (= (length labels) (length ts)) + (raise-arguments-error + 'ticks-generate + "ticks-format must return one label for each pre-tick" + "num. expected" (length ts) + "num. returned" (length labels) + "pre-ticks" ts + "labels" labels + "ticks-layout" layout + "ticks-format" format)) + (map tick xs majors labels)) (defparam ticks-default-number Positive-Integer 4) @@ -149,26 +160,30 @@ (define-values (major-xs minor-xs) (linear-tick-values x-min x-max number base divisors)) (tick-values->pre-ticks major-xs minor-xs))])) -(:: linear-ticks-format (-> Ticks-Format)) -(define (linear-ticks-format) +(:: linear-ticks-format (->* [] + [#:scientific? Boolean] + Ticks-Format)) +(define (linear-ticks-format #:scientific? [scientific? #t]) (λ (x-min x-max ts) (with-exact-bounds x-min x-max (define digits (digits-for-range x-min x-max)) (for/list ([t (in-list ts)]) - (real->plot-label (pre-tick-value t) digits))))) + (real->plot-label (pre-tick-value t) digits scientific?))))) (:: linear-ticks (->* [] [#:number Positive-Integer #:base Positive-Integer - #:divisors (Listof Positive-Integer)] + #:divisors (Listof Positive-Integer) + #:scientific? Boolean] ticks)) (define (linear-ticks #:number [number (ticks-default-number)] #:base [base 10] - #:divisors [divisors '(1 2 4 5)]) + #:divisors [divisors '(1 2 4 5)] + #:scientific? [scientific? #t]) (ticks (linear-ticks-layout #:number number #:base base #:divisors divisors) - (linear-ticks-format))) + (linear-ticks-format #:scientific? scientific?))) ;; =================================================================================================== ;; No ticks @@ -212,37 +227,41 @@ (and (zero? i) (zero? m))))] [else (list (pre-tick x (zero? m)))]))))]))])) -(:: log-ticks-format (->* [] [#:base Positive-Integer] Ticks-Format)) -(define (log-ticks-format #:base [base 10]) +(:: log-ticks-format (->* [] [#:base Positive-Integer #:scientific? Boolean] Ticks-Format)) +(define (log-ticks-format #:base [base 10] #:scientific? [scientific? #t]) (cond [(< base 2) (error 'log-ticks-format "expected base >= 2; given ~e" base)] [else (define base-str (number->string base)) (λ (x-min x-max ts) (with-exact-bounds x-min x-max - (define epsilon (expt 10 (- (digits-for-range x-min x-max)))) (define base-digits (digits-for-range 0 base)) (for/list ([t (in-list ts)]) (define x (pre-tick-value t)) (cond [(<= x 0) (raise-argument-error 'log-ticks-format "(Listof pre-tick) with positive positions" 2 x-min x-max ts)] + [(not scientific?) + (real->plot-label x base-digits scientific?)] [else + (define epsilon (expt 10 (- (digits-for-range x-min x)))) (define log-x (floor-log/base base x)) (define (major-str) (if (zero? log-x) "1" (format "~a~a" base-str (integer->superscript log-x)))) (cond [((abs (- x (expt base log-x))) . < . epsilon) (major-str)] [(zero? log-x) (real->plot-label x base-digits)] - [else (format "~a×~a" - (real->plot-label (/ x (expt base log-x)) base-digits) - (major-str))])]))))])) - -(:: log-ticks (->* [] [#:number Positive-Integer #:base Positive-Integer] ticks)) -(define (log-ticks #:number [number (ticks-default-number)] #:base [base 10]) + [else + (let ([p (real->plot-label (/ x (expt base log-x)) base-digits)]) + (if (string=? p "1") + (major-str) + (format "~a×~a" p (major-str))))])]))))])) + +(:: log-ticks (->* [] [#:number Positive-Integer #:base Positive-Integer #:scientific? Boolean] ticks)) +(define (log-ticks #:number [number (ticks-default-number)] #:base [base 10] #:scientific? [scientific? #t]) (cond [(< base 2) (error 'log-ticks "expected base >= 2; given ~e" base)] [else (ticks (log-ticks-layout #:number number #:base base) - (log-ticks-format #:base base))])) + (log-ticks-format #:base base #:scientific? scientific?))])) ;; =================================================================================================== ;; Date/time helpers diff --git a/plot-lib/plot/private/common/types.rkt b/plot-lib/plot/private/common/types.rkt index 2e5cb3e8..41f0b13a 100644 --- a/plot-lib/plot/private/common/types.rkt +++ b/plot-lib/plot/private/common/types.rkt @@ -3,9 +3,11 @@ (require (for-syntax racket/base) typed/racket/draw typed/racket/class + typed/pict "type-doc.rkt" "math.rkt") + (provide (all-defined-out)) (deftype (Treeof A) (U A (Listof (Treeof A)))) @@ -13,7 +15,9 @@ (deftype Anchor (U 'top-left 'top 'top-right 'left 'center 'right - 'bottom-left 'bottom 'bottom-right)) + 'bottom-left 'bottom 'bottom-right + 'auto)) +(define-predicate anchor? Anchor) (deftype Color (U (List Real Real Real) @@ -24,6 +28,8 @@ (deftype Plot-Color (U Integer Color)) +(deftype Color-Map (Vectorof (List Byte Byte Byte))) + (deftype Plot-Pen-Style-Sym (U 'transparent 'solid 'dot 'long-dash 'short-dash 'dot-dash)) @@ -31,6 +37,9 @@ (deftype Plot-Pen-Style (U Integer Plot-Pen-Style-Sym)) +(deftype Plot-Pen-Cap + (U 'round 'projecting 'butt)) + (deftype Plot-Brush-Style-Sym (U 'transparent 'solid 'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch @@ -60,7 +69,7 @@ 'circle7 'circle8 'bullet 'fullcircle1 'fullcircle2 'fullcircle3 'fullcircle4 'fullcircle5 'fullcircle6 - 'fullcircle7 'fullcircle8))) + 'fullcircle7 'fullcircle8 'none))) (deftype (List-Generator A B) (U (Listof B) (-> A (Listof B)))) @@ -74,18 +83,44 @@ (deftype (Pen-Widths A) (List-Generator A Nonnegative-Real)) (deftype (Plot-Brush-Styles A) (List-Generator A Plot-Brush-Style)) (deftype (Alphas A) (List-Generator A Nonnegative-Real)) -(deftype (Labels A) (List-Generator A (U String #f))) +(deftype (Labels A) (List-Generator A (U String pict #f))) (deftype Contour-Levels (U 'auto Positive-Integer (Listof Real))) (define-type Image-File-Format - (U 'png 'jpeg - 'xbm 'xpm 'bmp + (U 'png 'jpeg + 'xbm 'xpm 'bmp 'ps 'pdf 'svg)) (deftype Legend-Draw-Proc (-> (Instance Plot-Device%) Real Real Void)) -(struct legend-entry ([label : String] [draw : Legend-Draw-Proc]) #:transparent) +(struct legend-entry ([label : (U String pict)] [draw : Legend-Draw-Proc]) #:transparent) + +(deftype Legend-Anchor (U Anchor + 'no-legend + 'outside-global-top + 'outside-top-left 'outside-top 'outside-top-right + 'outside-left-top 'outside-left 'outside-left-bottom + 'outside-right-top 'outside-right 'outside-right-bottom + 'outside-bottom-left 'outside-bottom 'outside-bottom-right)) +(define (inside-anchor? [a : Legend-Anchor]) (anchor? a)) +(define (outside-anchor? [a : Legend-Anchor]) + (and (not (anchor? a)) (not (eq? a 'no-legend)))) +(define (legend-anchor->anchor [a : Legend-Anchor]) : Anchor + (if (anchor? a) + a + (case a + [(outside-top-left outside-left-top) 'top-left] + [(outside-top outside-global-top) 'top] + [(outside-top-right outside-right-top) 'top-right] + [(outside-right) 'right] + [(outside-bottom-right outside-right-bottom) 'bottom-right] + [(outside-bottom) 'bottom] + [(outside-bottom-left outside-left-bottom) 'bottom-left] + [(outside-left) 'left] + [else 'auto]))) + +(deftype Legend-Layout (List (U 'rows 'columns) Positive-Integer (U 'equal-size 'compact))) (define-type Plot-Device% (Class @@ -108,9 +143,10 @@ [set-font-size (-> Real Void)] [get-char-height (-> Exact-Rational)] [get-char-baseline (-> Exact-Rational)] - [get-text-extent (-> String (Values Exact-Rational Exact-Rational Exact-Rational Exact-Rational))] - [get-text-width (-> String Exact-Rational)] + [get-text-extent (-> (U String pict) (Values Exact-Rational Exact-Rational Exact-Rational Exact-Rational))] + [get-text-width (-> (U String pict) Exact-Rational)] [set-text-foreground (-> Plot-Color Void)] + [set-arrow-head (-> (U (List '= Nonnegative-Real) Nonnegative-Real) Nonnegative-Real Void)] [set-clipping-rect (-> Rect Void)] [clear-clipping-rect (-> Void)] [clear (-> Void)] @@ -120,10 +156,20 @@ [draw-lines (-> (Listof (Vectorof Real)) Void)] [draw-line (-> (Vectorof Real) (Vectorof Real) Void)] [draw-text (->* [String (Vectorof Real)] [Anchor Real Real Boolean] Void)] - [get-text-corners (->* [String (Vectorof Real)] [Anchor Real Real] (Listof (Vectorof Real)))] + [get-text-corners (->* [(U String pict) (Vectorof Real)] [Anchor Real Real] (Listof (Vectorof Real)))] [draw-arrow (-> (Vectorof Real) (Vectorof Real) Void)] [get-tick-endpoints (-> (Vectorof Real) Real Real (List (Vectorof Real) (Vectorof Real)))] [draw-tick (-> (Vectorof Real) Real Real Void)] [draw-arrow-glyph (-> (Vectorof Real) Real Real Void)] [draw-glyphs (-> (Listof (Vectorof Real)) Point-Sym Nonnegative-Real Void)] + [draw-pict (->* [pict (Vectorof Real)] (Anchor Real) Void)] + [calculate-legend-rect (-> (Listof legend-entry) + Rect + Anchor + (U Nonnegative-Real + (List Nonnegative-Real Nonnegative-Real Nonnegative-Real Nonnegative-Real)) + Rect)] [draw-legend (-> (Listof legend-entry) Rect Void)])) + +(require "plotmetrics.rkt") +(provide Plot-Metrics<%> Plot-Pict Plot-Metrics-Functions) diff --git a/plot-lib/plot/private/common/untyped-utils.rkt b/plot-lib/plot/private/common/untyped-utils.rkt index 356b851d..67027f1a 100644 --- a/plot-lib/plot/private/common/untyped-utils.rkt +++ b/plot-lib/plot/private/common/untyped-utils.rkt @@ -10,6 +10,10 @@ [else (λ (x y) (sequence-head-vector name (f (vector x y)) 2))])) +(define (fix-a-field-fun name f) + (cond [(procedure-arity-includes? f 2 #t) f] + [else (λ (x y) (f (vector x y)))])) + (define (fix-vector-field3d-fun name f) (cond [(procedure-arity-includes? f 3 #t) (λ (x y z) (sequence-head-vector name (f x y z) 3))] diff --git a/plot-lib/plot/private/no-gui/evil-types.rkt b/plot-lib/plot/private/no-gui/evil-types.rkt index 99ab96e9..650d85a1 100644 --- a/plot-lib/plot/private/no-gui/evil-types.rkt +++ b/plot-lib/plot/private/no-gui/evil-types.rkt @@ -1,7 +1,7 @@ #lang typed/racket +(require typed/pict) + (provide Pict pict?) -(require/typed - pict - [#:opaque Pict pict?]) +(define-type Pict pict) diff --git a/plot-lib/plot/private/no-gui/plot-bitmap.rkt b/plot-lib/plot/private/no-gui/plot-bitmap.rkt index d71bbb30..ee8cd68c 100644 --- a/plot-lib/plot/private/no-gui/plot-bitmap.rkt +++ b/plot-lib/plot/private/no-gui/plot-bitmap.rkt @@ -8,9 +8,10 @@ "../plot2d/renderer.rkt" "../plot3d/renderer.rkt" "plot2d.rkt" - "plot3d.rkt") + "plot3d.rkt" + typed/racket/unsafe) -(provide (all-defined-out)) +(unsafe-provide plot plot3d) (:: plot (->* [(Treeof (U renderer2d nonrenderer))] @@ -21,10 +22,11 @@ #:title (U String #f) #:x-label (U String #f) #:y-label (U String #f) + #:aspect-ratio (U Nonnegative-Real #f) #:legend-anchor Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format)] - (Instance Bitmap%))) + (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)))) (define (plot renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -33,17 +35,20 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto]) (when out-file (plot-file renderer-tree out-file out-kind #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (plot-bitmap renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (:: plot3d (->* [(Treeof (U renderer3d nonrenderer))] @@ -57,10 +62,11 @@ #:x-label (U String #f) #:y-label (U String #f) #:z-label (U String #f) + #:aspect-ratio (U Nonnegative-Real #f) #:legend-anchor Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format)] - (Instance Bitmap%))) + (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)))) (define (plot3d renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -73,6 +79,7 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto]) @@ -81,10 +88,12 @@ #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (plot3d-bitmap renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) diff --git a/plot-lib/plot/private/no-gui/plot-pict.rkt b/plot-lib/plot/private/no-gui/plot-pict.rkt index c6adceaa..5f2f7c5d 100644 --- a/plot-lib/plot/private/no-gui/plot-pict.rkt +++ b/plot-lib/plot/private/no-gui/plot-pict.rkt @@ -21,10 +21,11 @@ #:title (U String #f) #:x-label (U String #f) #:y-label (U String #f) - #:legend-anchor Anchor + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format)] - Pict)) + Plot-Pict)) (define (plot renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -33,17 +34,20 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto]) (when out-file (plot-file renderer-tree out-file out-kind #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (plot-pict renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (:: plot3d (->* [(Treeof (U renderer3d nonrenderer))] @@ -57,10 +61,11 @@ #:x-label (U String #f) #:y-label (U String #f) #:z-label (U String #f) - #:legend-anchor Anchor + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor #:out-file (U Path-String Output-Port #f) #:out-kind (U 'auto Image-File-Format)] - Pict)) + Plot-Pict)) (define (plot3d renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -73,6 +78,7 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)] #:out-file [out-file #f] #:out-kind [out-kind 'auto]) @@ -81,10 +87,13 @@ #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (plot3d-pict renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:title title #:angle (or angle (plot3d-angle)) #:altitude (or altitude (plot3d-altitude)) - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) + diff --git a/plot-lib/plot/private/no-gui/plot2d-untyped.rkt b/plot-lib/plot/private/no-gui/plot2d-untyped.rkt index 15da031b..5cf0ee06 100644 --- a/plot-lib/plot/private/no-gui/plot2d-untyped.rkt +++ b/plot-lib/plot/private/no-gui/plot2d-untyped.rkt @@ -3,7 +3,7 @@ (require racket/contract racket/class racket/draw - (for-syntax racket/base "plot2d-evil-box.rkt") + pict "../../utils.rkt" "../common/contract.rkt" "../common/nonrenderer.rkt" @@ -12,7 +12,7 @@ (provide (contract-out - [untyped-plot/dc + [plot/dc (->* [(treeof (or/c renderer2d? nonrenderer?)) (is-a?/c dc<%>) real? @@ -23,11 +23,38 @@ #:x-max (or/c real? #f) #:y-min (or/c real? #f) #:y-max (or/c real? #f) - #:title (or/c string? #f) - #:x-label (or/c string? #f) - #:y-label (or/c string? #f) - #:legend-anchor anchor/c] - void?)])) + #:title (or/c string? pict? #f) + #:x-label (or/c string? pict? #f) + #:y-label (or/c string? pict? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor legend-anchor/c] + plot-metrics-object/c)] + [plot-bitmap + (->* [(treeof (or/c renderer2d? nonrenderer?))] + [#:x-min (or/c real? #f) + #:x-max (or/c real? #f) + #:y-min (or/c real? #f) + #:y-max (or/c real? #f) + #:title (or/c string? pict? #f) + #:height (or/c real? #f) + #:width (or/c real? #f) + #:x-label (or/c string? pict? #f) + #:y-label (or/c string? pict? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor legend-anchor/c] + (and/c (is-a?/c bitmap%) plot-metrics-object/c))] + [plot-pict + (->* [(treeof (or/c renderer2d? nonrenderer?))] + [#:x-min (or/c real? #f) + #:x-max (or/c real? #f) + #:y-min (or/c real? #f) + #:y-max (or/c real? #f) + #:title (or/c string? pict? #f) + #:x-label (or/c string? pict? #f) + #:height (or/c real? #f) + #:width (or/c real? #f) + #:y-label (or/c string? pict? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor legend-anchor/c] + plot-pict?)])) -(define-syntax untyped-plot/dc - (make-rename-transformer (unbox plot/dc-box))) diff --git a/plot-lib/plot/private/no-gui/plot2d-utils.rkt b/plot-lib/plot/private/no-gui/plot2d-utils.rkt index 6570458c..e1255a37 100644 --- a/plot-lib/plot/private/no-gui/plot2d-utils.rkt +++ b/plot-lib/plot/private/no-gui/plot2d-utils.rkt @@ -9,18 +9,22 @@ "../common/ticks.rkt" "../plot2d/plot-area.rkt" "../plot2d/renderer.rkt" - "utils.rkt") + "utils.rkt" + typed/racket/unsafe) -(provide (all-defined-out)) +(provide get-renderer-list get-bounds-rect get-ticks get-legend-entry-list) +(unsafe-provide plot-area) -(: get-renderer-list (-> (Treeof (U renderer2d nonrenderer)) (Listof renderer2d))) +(: get-renderer-list (-> Any (Listof renderer2d))) (define (get-renderer-list renderer-tree) (cond [(list? renderer-tree) (append* (map get-renderer-list renderer-tree))] [(nonrenderer? renderer-tree) (match-define (nonrenderer bounds-rect bounds-fun ticks-fun) renderer-tree) - (list (renderer2d bounds-rect bounds-fun ticks-fun #f))] + (list (renderer2d bounds-rect bounds-fun ticks-fun #f #f))] + [(renderer2d? renderer-tree) + (list renderer-tree)] [else - (list renderer-tree)])) + (raise-argument-error 'get-renderer-list "(or/c list? nonrenderer? renderer2d?)" renderer-tree)])) (: get-bounds-rect (-> (Listof renderer2d) (U #f Real) (U #f Real) (U #f Real) (U #f Real) Rect)) (define (get-bounds-rect renderer-list x-min x-max y-min y-max) @@ -64,18 +68,28 @@ (define (plot-area area renderer-list) (send area start-plot) - (define legend-entries - (flatten-legend-entries - (for/list : (Listof (Treeof legend-entry)) ([rend (in-list renderer-list)]) - (match-define (renderer2d rend-bounds-rect _bf _tf render-proc) rend) - (send area start-renderer (if rend-bounds-rect - (rect-inexact->exact rend-bounds-rect) - (unknown-rect 2))) - (if render-proc (render-proc area) empty)))) + (for ([rend (in-list renderer-list)]) + (match-define (renderer2d rend-bounds-rect _bf _tf label-proc render-proc) rend) + (when render-proc + (send area start-renderer (if rend-bounds-rect + (rect-inexact->exact rend-bounds-rect) + (unknown-rect 2))) + (render-proc area))) (send area end-renderers) - - (when (not (empty? legend-entries)) - (send area draw-legend legend-entries)) - (send area end-plot)) + +(: get-legend-entry-list (-> (Listof renderer2d) Rect (Listof legend-entry))) +(define (get-legend-entry-list renderer-list outer-rect) + (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) outer-rect) + + (cond + [(and x-min x-max y-min y-max) + (flatten-legend-entries + (for*/list : (Listof (Treeof legend-entry)) + ([rend (in-list renderer-list)] + [label-proc (in-value (renderer2d-label rend))] + #:when label-proc) + ;; clipping not necessary, levels are always calculated on the complete bounds-rect + (label-proc outer-rect)))] + [else '()])) diff --git a/plot-lib/plot/private/no-gui/plot2d.rkt b/plot-lib/plot/private/no-gui/plot2d.rkt index 0a73eb1e..51aff28b 100644 --- a/plot-lib/plot/private/no-gui/plot2d.rkt +++ b/plot-lib/plot/private/no-gui/plot2d.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/draw typed/racket/class + typed/pict "../common/type-doc.rkt" "../common/types.rkt" "../common/draw.rkt" @@ -11,33 +12,41 @@ "../common/nonrenderer.rkt" "../common/file-type.rkt" "../common/utils.rkt" + "../common/plotmetrics.rkt" "../plot2d/plot-area.rkt" "../plot2d/renderer.rkt" "plot2d-utils.rkt" - "evil.rkt") + (except-in "evil.rkt" dc) + typed/racket/unsafe) -(provide (all-defined-out)) +(unsafe-provide plot/dc + plot-bitmap + plot-pict + plot-file) ;; =================================================================================================== ;; Plot to a given device context + (:: plot/dc (->* [(Treeof (U renderer2d nonrenderer)) (Instance DC<%>) Real Real Nonnegative-Real Nonnegative-Real] [#:x-min (U Real #f) #:x-max (U Real #f) #:y-min (U Real #f) #:y-max (U Real #f) - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] - Void)) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance Plot-Metrics<%>))) (define (plot/dc renderer-tree dc x y width height #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/pos (make-raise-argument-error 'plot/dc renderer-tree dc x y width height)) (define fail/kw (make-raise-keyword-error 'plot/dc)) @@ -50,25 +59,24 @@ [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] [else (define renderer-list (get-renderer-list renderer-tree)) (define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max)) (define-values (x-ticks x-far-ticks y-ticks y-far-ticks) (get-ticks renderer-list bounds-rect)) - + (define legend (get-legend-entry-list renderer-list bounds-rect)) + (parameterize ([plot-title title] [plot-x-label x-label] [plot-y-label y-label] [plot-legend-anchor legend-anchor]) (define area (make-object 2d-plot-area% - bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks dc x y width height)) - (plot-area area renderer-list))])) + bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks legend dc x y width height aspect-ratio)) + (plot-area area renderer-list) -(require (for-syntax racket/base - "plot2d-evil-box.rkt")) - -(begin-for-syntax - (set-box! plot/dc-box #'plot/dc)) + (new plot-metrics% [->metrics-object (λ () area)]))])) ;; =================================================================================================== ;; Plot to a bitmap @@ -79,11 +87,12 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] - (Instance Bitmap%))) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)))) (define (plot-bitmap renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -92,13 +101,17 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) - ((if (plot-animating?) draw-bitmap draw-bitmap/supersampling) - (λ (dc) - (plot/dc renderer-tree dc 0 0 width height - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) - width height)) + (define bm : (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)) + (make-object (plot-metrics-mixin bitmap%) (λ () pm) width height #f #t)) + (define dc : (Instance DC<%>) (make-object bitmap-dc% bm)) + (define pm : (Instance Plot-Metrics<%>) + (plot/dc renderer-tree dc 0 0 width height + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) + bm) ;; =================================================================================================== ;; Plot to a pict @@ -109,11 +122,12 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] - Pict)) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + Plot-Pict)) (define (plot-pict renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -122,14 +136,20 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define saved-values (plot-parameters)) - (dc (λ (dc x y) - (parameterize/group ([plot-parameters saved-values]) - (plot/dc renderer-tree dc x y width height - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor))) - width height)) + (define pm : (Option (Instance Plot-Metrics<%>)) #f) + (define P : pict + (dc (λ (dc x y) + (parameterize/group ([plot-parameters saved-values]) + (set! pm + (plot/dc renderer-tree dc x y width height + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)))) + width height)) + (pict->pp P (assert pm))) ;; =================================================================================================== ;; Plot to a file @@ -142,10 +162,11 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:width Positive-Integer #:height Positive-Integer - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:legend-anchor Anchor] + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] Void)) (define (plot-file renderer-tree output [kind 'auto] #:x-min [x-min #f] #:x-max [x-max #f] @@ -155,6 +176,7 @@ #:title [title (plot-title)] #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define real-kind (cond [(eq? kind 'auto) @@ -167,7 +189,8 @@ (plot-bitmap renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:width width #:height height - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor)) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (send bm save-file output real-kind (plot-jpeg-quality))] [(ps pdf svg) (define dc @@ -181,7 +204,8 @@ (plot/dc renderer-tree dc 0 0 (/ width (inexact->exact x-scale)) (/ height (inexact->exact y-scale)) #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max - #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor) + #:title title #:x-label x-label #:y-label y-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio) (send dc end-page) (send dc end-doc)]) (void)) diff --git a/plot-lib/plot/private/no-gui/plot3d-untyped.rkt b/plot-lib/plot/private/no-gui/plot3d-untyped.rkt index 2d411f98..b0d33f6a 100644 --- a/plot-lib/plot/private/no-gui/plot3d-untyped.rkt +++ b/plot-lib/plot/private/no-gui/plot3d-untyped.rkt @@ -4,6 +4,7 @@ racket/contract racket/class racket/draw + (only-in pict pict?) (for-syntax racket/base "plot3d-evil-box.rkt") "../../utils.rkt" "../common/contract.rkt" @@ -27,12 +28,13 @@ #:z-max (or/c real? #f) #:angle real? #:altitude real? - #:title (or/c string? #f) - #:x-label (or/c string? #f) - #:y-label (or/c string? #f) - #:z-label (or/c string? #f) - #:legend-anchor anchor/c] - void?)])) + #:title (or/c string? pict? #f) + #:x-label (or/c string? pict? #f) + #:y-label (or/c string? pict? #f) + #:z-label (or/c string? pict? #f) + #:aspect-ratio (or/c (and/c rational? positive?) #f) + #:legend-anchor legend-anchor/c] + plot-metrics-object/c)])) (define-syntax untyped-plot3d/dc (make-rename-transformer (unbox plot3d/dc-box))) diff --git a/plot-lib/plot/private/no-gui/plot3d-utils.rkt b/plot-lib/plot/private/no-gui/plot3d-utils.rkt index ff73adb5..8521be61 100644 --- a/plot-lib/plot/private/no-gui/plot3d-utils.rkt +++ b/plot-lib/plot/private/no-gui/plot3d-utils.rkt @@ -9,18 +9,22 @@ "../common/ticks.rkt" "../plot3d/plot-area.rkt" "../plot3d/renderer.rkt" - "utils.rkt") + "utils.rkt" + typed/racket/unsafe) -(provide (all-defined-out)) +(provide get-renderer-list get-bounds-rect get-ticks get-legend-entry-list) +(unsafe-provide plot-area) -(: get-renderer-list (-> (Treeof (U renderer3d nonrenderer)) (Listof renderer3d))) +(: get-renderer-list (-> Any (Listof renderer3d))) (define (get-renderer-list renderer-tree) (cond [(list? renderer-tree) (append* (map get-renderer-list renderer-tree))] [(nonrenderer? renderer-tree) (match-define (nonrenderer bounds-rect bounds-fun ticks-fun) renderer-tree) - (list (renderer3d bounds-rect bounds-fun ticks-fun #f))] + (list (renderer3d bounds-rect bounds-fun ticks-fun #f #f))] + [(renderer3d? renderer-tree) + (list renderer-tree)] [else - (list renderer-tree)])) + (raise-argument-error 'get-renderer-list "(or/c list? nonrenderer? renderer3d?)" renderer-tree)])) (: get-bounds-rect (-> (Listof renderer3d) (U #f Real) (U #f Real) @@ -74,18 +78,27 @@ (define (plot-area area renderer-list) (send area start-plot) - (define legend-entries - (flatten-legend-entries - (for/list : (Listof (Treeof legend-entry)) ([rend (in-list renderer-list)]) - (match-define (renderer3d rend-bounds-rect _bf _tf render-proc) rend) - (send area start-renderer (if rend-bounds-rect - (rect-inexact->exact rend-bounds-rect) - (unknown-rect 3))) - (if render-proc (render-proc area) empty)))) + (for ([rend (in-list renderer-list)]) + (match-define (renderer3d rend-bounds-rect _bf _tf label-proc render-proc) rend) + (when render-proc + (send area start-renderer (if rend-bounds-rect + (rect-inexact->exact rend-bounds-rect) + (unknown-rect 3))) + (render-proc area))) (send area end-renderers) - - (when (not (empty? legend-entries)) - (send area draw-legend legend-entries)) - (send area end-plot)) + +(: get-legend-entry-list (-> (Listof renderer3d) Rect (Listof legend-entry))) +(define (get-legend-entry-list renderer-list outer-rect) + (match-define (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) outer-rect) + + (cond + [(and x-min x-max y-min y-max z-min z-max) + (flatten-legend-entries + (for*/list : (Listof (Treeof legend-entry)) + ([rend (in-list renderer-list)] + [label-proc (in-value (renderer3d-label rend))] + #:when label-proc) + (label-proc outer-rect)))] + [else '()])) diff --git a/plot-lib/plot/private/no-gui/plot3d.rkt b/plot-lib/plot/private/no-gui/plot3d.rkt index c52ab2bc..46887e0d 100644 --- a/plot-lib/plot/private/no-gui/plot3d.rkt +++ b/plot-lib/plot/private/no-gui/plot3d.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/draw typed/racket/class + typed/pict "../common/type-doc.rkt" "../common/types.rkt" "../common/draw.rkt" @@ -11,12 +12,20 @@ "../common/nonrenderer.rkt" "../common/file-type.rkt" "../common/utils.rkt" + "../common/plotmetrics.rkt" "../plot3d/plot-area.rkt" "../plot3d/renderer.rkt" "plot3d-utils.rkt" - "evil.rkt") + "../common/math.rkt" + (except-in "evil.rkt" dc) + typed/racket/unsafe) -(provide (all-defined-out)) + + +(unsafe-provide plot3d/dc + plot3d-bitmap + plot3d-pict + plot3d-file) ;; =================================================================================================== ;; Plot to a given device context @@ -29,12 +38,13 @@ #:y-min (U Real #f) #:y-max (U Real #f) #:z-min (U Real #f) #:z-max (U Real #f) #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] - Void)) + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance Plot-Metrics<%>))) (define (plot3d/dc renderer-tree dc x y width height #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -45,6 +55,7 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define fail/pos (make-raise-argument-error 'plot3d/dc renderer-tree dc x y width height)) (define fail/kw (make-raise-keyword-error 'plot3d/dc)) @@ -59,6 +70,8 @@ [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(and aspect-ratio (not (and (rational? aspect-ratio) (positive? aspect-ratio)))) + (fail/kw "#f or positive real" '#:aspect-ratio aspect-ratio)] [(not (rational? angle)) (fail/kw "rational?" '#:angle angle)] [(not (rational? altitude)) (fail/kw "rational?" '#:altitude altitude)] [else @@ -66,7 +79,8 @@ (define bounds-rect (get-bounds-rect renderer-list x-min x-max y-min y-max z-min z-max)) (define-values (x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks) (get-ticks renderer-list bounds-rect)) - + (define legend-list (get-legend-entry-list renderer-list bounds-rect)) + (parameterize ([plot3d-angle angle] [plot3d-altitude altitude] [plot-title title] @@ -76,8 +90,11 @@ [plot-legend-anchor legend-anchor]) (define area (make-object 3d-plot-area% bounds-rect x-ticks x-far-ticks y-ticks y-far-ticks z-ticks z-far-ticks - dc x y width height)) - (plot-area area renderer-list))])) + legend-list + dc x y width height aspect-ratio)) + (plot-area area renderer-list) + + (new plot-metrics% [->metrics-object (λ () area)]))])) (require (for-syntax racket/base "plot3d-evil-box.rkt")) @@ -96,13 +113,14 @@ #:width Positive-Integer #:height Positive-Integer #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] - (Instance Bitmap%))) -(define (plot3d-bitmap renderer-tree + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)))) +(define (plot3d-bitmap renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] #:z-min [z-min #f] #:z-max [z-max #f] @@ -114,14 +132,17 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) - ((if (plot-animating?) draw-bitmap draw-bitmap/supersampling) - (λ (dc) - (plot3d/dc renderer-tree dc 0 0 width height - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max - #:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label - #:z-label z-label #:legend-anchor legend-anchor)) - width height)) + (define bm : (Instance (Class #:implements Bitmap% #:implements Plot-Metrics<%>)) + (make-object (plot-metrics-mixin (class bitmap% (super-new))) (λ () pm) width height #f #t)) + (define dc : (Instance DC<%>) (make-object bitmap-dc% bm)) + (define pm : (Instance Plot-Metrics<%>) + (plot3d/dc renderer-tree dc 0 0 width height + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max + #:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label + #:z-label z-label #:legend-anchor legend-anchor #:aspect-ratio aspect-ratio)) + bm) ;; =================================================================================================== ;; Plot to a pict @@ -134,13 +155,14 @@ #:width Positive-Integer #:height Positive-Integer #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] - Pict)) -(define (plot3d-pict renderer-tree + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] + Plot-Pict)) +(define (plot3d-pict renderer-tree #:x-min [x-min #f] #:x-max [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] #:z-min [z-min #f] #:z-max [z-max #f] @@ -152,15 +174,21 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define saved-plot-parameters (plot-parameters)) - (dc (λ (dc x y) - (parameterize/group ([plot-parameters saved-plot-parameters]) - (plot3d/dc renderer-tree dc x y width height - #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min - #:z-max z-max #:angle angle #:altitude altitude #:title title #:x-label x-label - #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor))) - width height)) + (define pm : (Option (Instance Plot-Metrics<%>)) #f) + (define P : Pict + (dc (λ (dc x y) + (parameterize/group ([plot-parameters saved-plot-parameters]) + (set! pm + (plot3d/dc renderer-tree dc x y width height + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min + #:z-max z-max #:angle angle #:altitude altitude #:title title #:x-label x-label + #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)))) + width height)) + (pict->pp P (assert pm))) ;; =================================================================================================== ;; Plot to any supported kind of file @@ -175,11 +203,12 @@ #:width Positive-Integer #:height Positive-Integer #:angle Real #:altitude Real - #:title (U String #f) - #:x-label (U String #f) - #:y-label (U String #f) - #:z-label (U String #f) - #:legend-anchor Anchor] + #:title (U String pict #f) + #:x-label (U String pict #f) + #:y-label (U String pict #f) + #:z-label (U String pict #f) + #:aspect-ratio (U Nonnegative-Real #f) + #:legend-anchor Legend-Anchor] Void)) (define (plot3d-file renderer-tree output [kind 'auto] #:x-min [x-min #f] #:x-max [x-max #f] @@ -193,6 +222,7 @@ #:x-label [x-label (plot-x-label)] #:y-label [y-label (plot-y-label)] #:z-label [z-label (plot-z-label)] + #:aspect-ratio [aspect-ratio (plot-aspect-ratio)] #:legend-anchor [legend-anchor (plot-legend-anchor)]) (define real-kind (cond [(eq? kind 'auto) @@ -206,7 +236,8 @@ renderer-tree #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:width width #:height height #:angle angle #:altitude altitude #:title title - #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor)) + #:x-label x-label #:y-label y-label #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio)) (send bm save-file output real-kind (plot-jpeg-quality))] [(ps pdf svg) (define dc @@ -221,7 +252,8 @@ (/ width (inexact->exact x-scale)) (/ height (inexact->exact y-scale)) #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max #:z-min z-min #:z-max z-max #:angle angle #:altitude altitude #:title title #:x-label x-label #:y-label y-label - #:z-label z-label #:legend-anchor legend-anchor) + #:z-label z-label #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio) (send dc end-page) (send dc end-doc)]) (void)) diff --git a/plot-lib/plot/private/plot2d/arrows.rkt b/plot-lib/plot/private/plot2d/arrows.rkt new file mode 100644 index 00000000..6c0adfae --- /dev/null +++ b/plot-lib/plot/private/plot2d/arrows.rkt @@ -0,0 +1,144 @@ +#lang typed/racket/base + +(require typed/racket/class racket/match racket/math racket/list racket/sequence + plot/utils + (only-in typed/pict pict) + "../common/type-doc.rkt" + "../common/utils.rkt") + +(provide arrows-render-fun + arrows) + +;; =================================================================================================== +;; Arrows + +(: arrows-render-fun + (-> (Listof (Pair (Vectorof Real) (Vectorof Real))) + Plot-Color Nonnegative-Real Plot-Pen-Style + Nonnegative-Real + (U (List '= Nonnegative-Real) Nonnegative-Real) Nonnegative-Real + 2D-Render-Proc)) +(define ((arrows-render-fun vs + color line-width line-style + alpha + arrow-head-size-or-scale arrow-head-angle) area) + (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) (send area get-bounds-rect)) + (when (and x-min x-max y-min y-max) + (send area put-alpha alpha) + (send area put-pen color line-width line-style) + (send area put-arrow-head arrow-head-size-or-scale arrow-head-angle) + (for ([x (in-list vs)]) + (match-define (cons (vector v1x v1y) (vector v2x v2y)) x) + (define (f [x : Real][y : Real]) + (- (* (- v2x v1x) (- y v1y)) + (* (- v2y v1y) (- x v1x)))) + (cond + ;only draw the arrow head if the endpoint is visible + ;other option makes little sense since size and angle can be/is plot units-absolute + [(and (<= x-min v2x x-max) (<= y-min v2y y-max)) + (send area put-arrow (car x) (cdr x) #t)] + ;only draw the vector line if it is visible + [(or (<= (* (f x-min y-min) (f x-max y-max)) 0) + (<= (* (f x-min y-max) (f x-max y-min)) 0)) + (send area put-lines (list (car x) (cdr x)))])))) + +;(Sequenceof (Sequence (Sequenceof Real))) does not work because (sequence? 5) = #t +;and so the contract can not know if '((2 2)) is three or two nested sequences +(define-type (LVof A) + (U (Listof A) (Vectorof A))) + +(:: arrows + (->* [(U (LVof (LVof Real)) + (LVof (LVof (LVof Real))))] + [#:x-min (U Real #f) #:x-max (U Real #f) + #:y-min (U Real #f) #:y-max (U Real #f) + #:color Plot-Color + #:width Nonnegative-Real + #:style Plot-Pen-Style + #:alpha Nonnegative-Real + #:arrow-head-size-or-scale (U (List '= Nonnegative-Real) Nonnegative-Real) + #:arrow-head-angle Nonnegative-Real + #:label (U String pict #f)] + renderer2d)) +(define (arrows vs + #:x-min [x-min #f] #:x-max [x-max #f] + #:y-min [y-min #f] #:y-max [y-max #f] + #:color [color (arrows-color)] + #:width [width (arrows-line-width)] + #:style [style (arrows-line-style)] + #:alpha [alpha (arrows-alpha)] + #:arrow-head-size-or-scale [arrow-head-size-or-scale (arrow-head-size-or-scale)] + #:arrow-head-angle [arrow-head-angle (arrow-head-angle)] + #:label [label #f]) + (define fail/kw (make-raise-keyword-error 'lines)) + (cond + [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] + [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] + [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] + [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(not (rational? width)) (fail/kw "rational?" '#:width width)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + + [else + (define (argument-error) + (raise-argument-error + 'arrows + "(U (Sequenceof (Sequence Real Real)) (Sequenceof (Sequence (Sequence Real Real) (Sequence Real Real))))" + vs)) + ;; check if we have head/tail or pair vectors, and put in standard format + (define-values (S1 S2) + (for/fold ([S1 : (Listof (Vectorof Real)) '()] + [S2 : (Listof (Pair (Vectorof Real) (Vectorof Real))) '()]) + ([s vs]) + (define l (sequence->list s)) + (cond + [(not (= (length l) 2)) + (argument-error)] + ;order important because integers are sequence? + [(andmap real? l) + (values (cons (sequence-head-vector 'arrows l 2) S1) S2)] + [(andmap sequence? l) + (define v1 (sequence-head-vector 'arrows (car l) 2)) + (define v2 (sequence-head-vector 'arrows (cadr l) 2)) + (define v3 (vector (+ (vector-ref v1 0) (vector-ref v2 0)) + (+ (vector-ref v1 1) (vector-ref v2 1)))) + (values S1 + (cons (cons v1 v3) S2))] + [else (argument-error)]))) + + (define vs* + (cond + [(empty? S2) + (define S1* (reverse S1)) + (for/list : (Listof (Pair (Vectorof Real) (Vectorof Real))) + ([v1 (in-list S1*)] + [v2 (in-list (cdr S1*))]) + (cons v1 v2))] + [else S2])) + + ;; calculate bound and pick right render-fun + (define rvs + (let () + (match-define (list (cons #{p1 : (Listof (Vectorof Real))} + #{p2 : (Listof (Vectorof Real))}) ...) + vs*) + (filter vrational? (append p1 p2)))) + + (cond + [(empty? rvs) empty-renderer2d] + [else + (define-values (x- x+ y- y+) (get-bounds x-min x-max y-min y-max rvs)) + (renderer2d (vector (ivl x- x+) (ivl y- y+)) #f default-ticks-fun + (and label (λ (_) (arrow-legend-entry label color width style))) + (arrows-render-fun vs* + color width style alpha + arrow-head-size-or-scale arrow-head-angle))])])) + +(define (get-bounds [x-min : (Option Real)][x-max : (Option Real)] + [y-min : (Option Real)][y-max : (Option Real)] + [rvs : (Listof (Vectorof Real))]) + (match-define (list (vector #{rxs : (Listof Real)} #{rys : (Listof Real)}) ...) rvs) + (values (if x-min x-min (apply min* rxs)) + (if x-max x-max (apply max* rxs)) + (if y-min y-min (apply min* rys)) + (if y-max y-max (apply max* rys)))) diff --git a/plot-lib/plot/private/plot2d/box-and-whisker.rkt b/plot-lib/plot/private/plot2d/box-and-whisker.rkt new file mode 100644 index 00000000..e9679ab2 --- /dev/null +++ b/plot-lib/plot/private/plot2d/box-and-whisker.rkt @@ -0,0 +1,307 @@ +#lang typed/racket/base + +(require (only-in math/statistics quantile) + racket/sequence + racket/match + racket/class + (only-in typed/pict pict) + plot/utils + (only-in "../common/utils.rkt" make-raise-keyword-error) + (only-in "rectangle.rkt" discrete-histogram-ticks-fun)) + +(provide box-and-whisker + make-one-axis-default-ticks-fun) + +;; Box and whisker renderer, https://en.wikipedia.org/wiki/Box_plot + +;; See also https://en.wikipedia.org/wiki/Box_plot, and the Matplotlib +;; reference +;; https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.boxplot.html + +;; Hold the quantile and other information for the box and whiskers plot: Q1 +;; is the 1st quantile, 25% of the points in the data set are less than this +;; value. MEDIAN is the median, 50% of the points in the data set are less +;; than this, while Q3 is the 3rd quantile (75%). The LOWER-WHISKER and +;; UPPWER-WHISKER are lower and upper limits below and above which points are +;; considered outliers, see `samples->bnw-data`. Finally, OUTLIERS represents +;; a list of outlier points. +(struct bnw-data + ([q1 : Real] + [median : Real] + [q3 : Real] + [lower-whisker : Real] + [upper-whisker : Real] + [outliers : (Listof Real)]) + #:transparent) + +;; Construct a BNW-DATA object from the data points VS. If WS is present, it +;; represents the weights of each data point (if missing, each point has the +;; same weight), see `quantile` from the `racket/math` package on how WS is +;; used. +;; +;; IQR-SCALE is the multiplier used to determine the lower an upper limits +;; below and above which points are considered outliers. These limits are +;; calculated as (* IQR-SCALE (- Q3 Q1)) above and below the median, with the +;; caveat that the limits are adjusted to represent the highest (or lowest) +;; actual data point at that limit. +(: samples->bnw-data (->* ((Sequenceof Real)) ((U #f (Sequenceof Real)) #:iqr-scale Real) bnw-data)) +(define (samples->bnw-data vs [ws #f] #:iqr-scale [iqr-scale 1.5]) + (let* ([q1 (quantile 0.25 < vs ws)] + [median (quantile 0.5 < vs ws)] + [q3 (quantile 0.75 < vs ws)] + [iqr (- q3 q1)] + [lower-limit (- q1 (* iqr-scale iqr))] + [upper-limit (+ q3 (* iqr-scale iqr))] + [lower-whisker (cast (sequence-fold + (lambda ([a : Real] [sample : Real]) + (if (>= sample lower-limit) (min a sample) a)) + q1 vs) + Real)] + [upper-whisker (cast (sequence-fold + (lambda ([a : Real] [sample : Real]) + (if (<= sample upper-limit) (max a sample) a)) + q3 vs) + Real)] + [outliers (sequence-filter + (lambda ([sample : Real]) + (or (> sample upper-whisker) + (< sample lower-whisker))) vs)]) + (bnw-data q1 median q3 lower-whisker upper-whisker (sequence->list outliers)))) + +;; Wrapper around `default-ticks-fun` to return ticks for one axis only. If +;; INVERT? is #f, the Y axis (far and near) ticks are returned, if INVERT? is +;; #t, the X axis (far and near) ticks are returned. This can be used by +;; one-dimensional plots, such as box-and-whisker and violin to avoid placing +;; ticks on the axis that has no dimensions. +(: make-one-axis-default-ticks-fun (-> Boolean Ticks-Fun)) +(define ((make-one-axis-default-ticks-fun invert?) rect) + (match-define (list x-near x-far y-near y-far) + (default-ticks-fun rect)) + (if invert? + (list x-near x-far '() '()) + (list '() '() y-near y-far))) + +;; Rendering procedure for the box-and-whisker plot. This does the actual +;; rendering of the plot data, but all information is already preprocessed and +;; passed to it. For plot snips, this function can be invoked each time the +;; snip is drawn, so the function should be reasonably fast and all things +;; that can be precomputed should be. +(: renderer-proc + (-> Real Real Real Real Real (Listof (Vectorof Real)) + Real Nonnegative-Real Boolean + Plot-Color Plot-Brush-Style Plot-Color Plot-Pen-Style Nonnegative-Real Nonnegative-Real + Boolean Plot-Color Plot-Pen-Style Nonnegative-Real Nonnegative-Real + Boolean Plot-Color Plot-Pen-Style Nonnegative-Real Nonnegative-Real + Boolean Plot-Color Point-Sym Plot-Color Nonnegative-Real Nonnegative-Real Nonnegative-Real + 2D-Render-Proc)) +(define ((renderer-proc + q1 median q3 lower-whisker upper-whisker outliers + x width invert? + box-color box-style box-line-color box-line-style box-line-width box-alpha + show-median? median-color median-style median-width median-alpha + show-whiskers? whisker-color whisker-style whisker-width whisker-alpha + show-outliers? outlier-color outlier-sym outlier-fill-color outlier-size outlier-line-width outlier-alpha) + area) + (define half-width (* 1/2 width)) + (define quater-width (* 1/4 width)) + (: maybe-invert (All (A) (-> A A (Vectorof A)))) + (define maybe-invert (if invert? (lambda (x y) (vector y x)) vector)) + (send area put-pen box-line-color box-line-width box-line-style) + (send area put-brush box-color box-style) + (send area put-alpha box-alpha) + (send area put-rect + (maybe-invert (ivl (- x half-width) (+ x half-width)) (ivl q1 q3))) + (when show-median? + (send area put-pen median-color median-width median-style) + (send area put-alpha median-alpha) + (send area put-line + (maybe-invert (- x half-width) median) + (maybe-invert (+ x half-width) median))) + (when show-whiskers? + (send area put-pen whisker-color whisker-width whisker-style) + (send area put-alpha whisker-alpha) + (send area put-line (maybe-invert x lower-whisker) (maybe-invert x q1)) + (send area put-line (maybe-invert x q3) (maybe-invert x upper-whisker)) + (send area put-line + (maybe-invert (- x quater-width) lower-whisker) + (maybe-invert (+ x quater-width) lower-whisker)) + (send area put-line + (maybe-invert (- x quater-width) upper-whisker) + (maybe-invert (+ x quater-width) upper-whisker))) + (when show-outliers? + (send area put-alpha outlier-alpha) + (send area put-pen outlier-color outlier-line-width 'solid) + (send area put-brush outlier-fill-color 'solid) + (send area put-glyphs outliers outlier-sym outlier-size))) + +;; Create a box-and-whisker plot from data obtained from a call to +;; `samples->bnw-data`. X represents the x axis position where the box and +;; whiskers plot should be placed (by default the plot is drawn in a vertical +;; position). Various X values allows multiple box plots to be drawn side by +;; side. If INVERT? is #t, the plot is drawn horizontally, and X represents a +;; value on the Y axis. GAP represents the "width" of the box plot (but the +;; actual plot will be narrower than GAP. If multiple box plots are +;; displayed, they should be placed GAP interval between each other, in order +;; to look good. +(: box-and-whisker (->* [(Sequenceof Real)] + [#:weights (U (Sequenceof Real) #f) + #:x Real + #:invert? Boolean + #:label (U String pict #f) + #:iqr-scale Nonnegative-Real + #:width Nonnegative-Real + + #:box-color Plot-Color + #:box-style Plot-Brush-Style + #:box-line-color Plot-Color + #:box-line-width Nonnegative-Real + #:box-line-style Plot-Pen-Style + #:box-alpha Nonnegative-Real + + #:show-outliers? Boolean + #:outlier-color Plot-Color + #:outlier-sym Point-Sym + #:outlier-fill-color (U Plot-Color 'auto) + #:outlier-size Nonnegative-Real + #:outlier-line-width Nonnegative-Real + #:outlier-alpha Nonnegative-Real + + #:show-whiskers? Boolean + #:whisker-color Plot-Color + #:whisker-width Nonnegative-Real + #:whisker-style Plot-Pen-Style + #:whisker-alpha Nonnegative-Real + + #:show-median? Boolean + #:median-color Plot-Color + #:median-width Nonnegative-Real + #:median-style Plot-Pen-Style + #:median-alpha Nonnegative-Real + + #:add-ticks? Boolean + #:far-ticks? Boolean] + renderer2d)) +(define (box-and-whisker + vs + #:weights [ws #f] + #:x [x 0] + #:invert? (invert? #f) + #:label (label #f) + #:iqr-scale (iqr-scale 1.5) + + #:width (width 1) + + #:box-color (box-color (rectangle-color)) + #:box-style (box-style (rectangle-style)) + #:box-line-color (box-line-color (rectangle-line-color)) + #:box-line-width (box-line-width (rectangle-line-width)) + #:box-line-style (box-line-style (rectangle-line-style)) + #:box-alpha (box-alpha (rectangle-alpha)) + + #:show-outliers? (show-outliers? #t) + #:outlier-color (outlier-color (point-color)) + #:outlier-sym (outlier-sym (point-sym)) + #:outlier-fill-color (outlier-fill-color 'auto) + #:outlier-size (outlier-size (point-size)) + #:outlier-line-width (outlier-line-width (point-line-width)) + #:outlier-alpha (outlier-alpha (point-alpha)) + + #:show-whiskers? (show-whiskers? #t) + #:whisker-color (whisker-color (line-color)) + #:whisker-width (whisker-width (line-width)) + #:whisker-style (whisker-style (line-style)) + #:whisker-alpha (whisker-alpha (line-alpha)) + + #:show-median? (show-median? #t) + #:median-color (median-color (line-color)) + #:median-width (median-width (line-width)) + #:median-style (median-style (line-style)) + #:median-alpha (median-alpha (line-alpha)) + + #:add-ticks? [add-ticks? #t] + #:far-ticks? [far-ticks? #f]) + + (define fail/kw (make-raise-keyword-error 'box-and-whisker)) + (cond + [(not (and (rational? width) (positive? width))) (fail/kw "positive rational" '#:width width)] + [(not (rational? box-line-width)) (fail/kw "rational?" '#:box-line-width box-line-width)] + [(or (not (rational? box-alpha)) (> box-alpha 1) (< box-alpha 0)) + (fail/kw "real in [0,1]" '#:box-alpha box-alpha)] + + [(not (rational? outlier-size)) (fail/kw "rational?" '#:outlier-size outlier-size)] + [(or (not (rational? outlier-alpha)) (> outlier-alpha 1) (< outlier-alpha 0)) + (fail/kw "real in [0,1]" '#:outlier-alpha outlier-alpha)] + [(not (rational? outlier-line-width)) + (fail/kw "rational?" '#:outlier-line-width outlier-line-width)] + + [(or (not (rational? whisker-alpha)) (> whisker-alpha 1) (< whisker-alpha 0)) + (fail/kw "real in [0,1]" '#:whisker-alpha whisker-alpha)] + [(not (rational? whisker-width)) + (fail/kw "rational?" '#:whisker-width whisker-width)] + + [(or (not (rational? median-alpha)) (> median-alpha 1) (< median-alpha 0)) + (fail/kw "real in [0,1]" '#:median-alpha median-alpha)] + [(not (rational? median-width)) + (fail/kw "rational?" '#:median-width median-width)]) + + (match-define (bnw-data q1 median q3 lower-whisker upper-whisker outliers) + (samples->bnw-data vs ws #:iqr-scale iqr-scale)) + (define y-min* + (if (null? outliers) + lower-whisker + (min lower-whisker (apply min outliers)))) + (define y-max* + (if (null? outliers) + upper-whisker + (max upper-whisker (apply max outliers)))) + + ;; Make the Y range slightly larger to make sure outliers fit in nicely at + ;; the edges. + (define y-room (* (- y-max* y-min*) 0.07)) + (define y-min (- y-min* y-room)) + (define y-max (+ y-max* y-room)) + + (define x-min* (- x (/ width 2))) + (define x-max* (+ x (/ width 2))) + (define x-room (* (- x-max* x-min*) 0.07)) + (define x-min (- x-min* x-room)) + (define x-max (+ x-max* x-room)) + + (: maybe-invert (All (A) (-> A A (Vectorof A)))) + (define maybe-invert (if invert? (lambda (x y) (vector y x)) vector)) + + (define outlier-fill-color* + (if (eq? outlier-fill-color 'auto) (->pen-color outlier-color) outlier-fill-color)) + + (define outlier-vs + (map (lambda ([y : Real]) (maybe-invert x y)) outliers)) + + (renderer2d + ;; bounds-rect + (if invert? + (vector (ivl y-min y-max) (ivl x-min x-max)) + (vector (ivl x-min x-max) (ivl y-min y-max))) + ;; bounds-fun + #f + ;; ticks-fun + + ;; NOTE: for a box and whiskers plot, it does not make sense to put ticks + ;; on the X axis unless they are the actual box and whiskers labels, so we + ;; don't use default-ticks-fun here. + (if (and (string? label) add-ticks?) + (discrete-histogram-ticks-fun + (list label) (list x) add-ticks? far-ticks? maybe-invert) + (make-one-axis-default-ticks-fun invert?)) + ;; label + (and label + (lambda (_) + (rectangle-legend-entry + label box-color box-style box-line-color box-line-width box-line-style))) + ;; render-proc + (renderer-proc + q1 median q3 lower-whisker upper-whisker outlier-vs + x width invert? + box-color box-style box-line-color box-line-style box-line-width box-alpha + show-median? median-color median-style median-width median-alpha + show-whiskers? whisker-color whisker-style whisker-width whisker-alpha + show-outliers? outlier-color outlier-sym outlier-fill-color* outlier-size outlier-line-width outlier-alpha))) diff --git a/plot-lib/plot/private/plot2d/color-field.rkt b/plot-lib/plot/private/plot2d/color-field.rkt new file mode 100644 index 00000000..03d28709 --- /dev/null +++ b/plot-lib/plot/private/plot2d/color-field.rkt @@ -0,0 +1,73 @@ +#lang typed/racket/base + +;; Renderers for points and other point-like things. + +(require typed/racket/class racket/match racket/list + plot/utils + "../common/type-doc.rkt" + "../common/utils.rkt") + +(require/typed + "../common/untyped-utils.rkt" + [fix-a-field-fun (All (A) + (-> Symbol + (U (-> Real Real A) + (-> (Vector Real Real) A)) + (-> Real Real A)))]) + +(provide (all-defined-out)) + +;; =================================================================================================== +;; color-field +;; similar to point.rkt/vector-field, but draws a square area with a color + +(: color-field-render-fun + (-> (-> Real Real Plot-Color) + Positive-Integer + Nonnegative-Real + 2D-Render-Proc)) +(define ((color-field-render-fun f samples alpha) area) + (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) (send area get-bounds-rect)) + + (when (and x-min x-max y-min y-max) + (define xs (linear-seq x-min x-max (+ samples 1) #:start? #t #:end? #t)) + (define ys (linear-seq y-min y-max (+ samples 1) #:start? #t #:end? #t)) + + (send area put-alpha alpha) + (send area put-pen 'black 0 'transparent) + (for ([x- (in-list xs)] + [x+ (in-list (cdr xs))]) + (define x (/ (+ x- x+) 2)) + (for ([y- (in-list ys)] + [y+ (in-list (cdr ys))]) + (define y (/ (+ y- y+) 2)) + (define c (f x y)) + (send area put-brush c 'solid) + (send area put-rect (vector (ivl x- x+) + (ivl y- y+))))))) + +(:: color-field + (->* [(U (-> Real Real Plot-Color) + (-> (Vector Real Real) Plot-Color))] + [(U Real #f) (U Real #f) + (U Real #f) (U Real #f) + #:samples Positive-Integer + #:alpha Nonnegative-Real] + renderer2d)) +(define (color-field f [x-min #f] [x-max #f] [y-min #f] [y-max #f] + #:samples [samples (color-field-samples)] + #:alpha [alpha (color-field-alpha)]) + (define fail/pos (make-raise-argument-error 'vector-field3d f x-min x-max y-min y-max)) + (define fail/kw (make-raise-keyword-error 'vector-field3d)) + (cond + [(and x-min (not (rational? x-min))) (fail/pos "#f or rational" 1)] + [(and x-max (not (rational? x-max))) (fail/pos "#f or rational" 2)] + [(and y-min (not (rational? y-min))) (fail/pos "#f or rational" 3)] + [(and y-max (not (rational? y-max))) (fail/pos "#f or rational" 4)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [else + (let ([f ((inst fix-a-field-fun Plot-Color) 'color-field f)]) + (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun #f + (color-field-render-fun + f samples alpha)))])) + diff --git a/plot-lib/plot/private/plot2d/contour.rkt b/plot-lib/plot/private/plot2d/contour.rkt index 1a05bc86..6c685352 100644 --- a/plot-lib/plot/private/plot2d/contour.rkt +++ b/plot-lib/plot/private/plot2d/contour.rkt @@ -3,6 +3,7 @@ ;; Renderers for contour lines and contour intervals (require typed/racket/class racket/match racket/list racket/vector + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -15,12 +16,9 @@ (: isoline-render-proc (-> 2D-Sampler Real Positive-Integer Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) -(define ((isoline-render-proc g z samples color width style alpha label) area) +(define ((isoline-render-proc g z samples color width style alpha) area) (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) (define num (animated-samples samples)) (define sample (g (vector x-ivl y-ivl) (vector num num))) (match-define (2d-sample xs ys zss z-min z-max) sample) @@ -33,9 +31,7 @@ (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) (match-define (list v1 v2) (map (λ ([v : (Vectorof Real)]) (vector-take v 2)) line)) (send area put-line v1 v2)))) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (void)) (:: isoline (->* [(-> Real Real Real) Real] @@ -46,7 +42,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (isoline f z [x-min #f] [x-max #f] [y-min #f] [y-max #f] #:samples [samples (contour-samples)] @@ -71,54 +67,67 @@ (define y-ivl (ivl y-min y-max)) (define g (2d-function->sampler f (vector x-ivl y-ivl))) (renderer2d (vector x-ivl y-ivl) #f default-ticks-fun - (isoline-render-proc g z samples color width style alpha label))])) + (and label (λ (_) (line-legend-entry label color width style))) + (isoline-render-proc g z samples color width style alpha))])) ;; =================================================================================================== ;; Contour lines -(: contours-render-proc (-> 2D-Sampler Contour-Levels Positive-Integer - (Plot-Colors (Listof Real)) - (Pen-Widths (Listof Real)) - (Plot-Pen-Styles (Listof Real)) - (Alphas (Listof Real)) - (U String #f) - 2D-Render-Proc)) -(define ((contours-render-proc g levels samples colors widths styles alphas label) area) - (let/ec return : (Treeof legend-entry) - (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) +(: make-contour-labels-and-renderer (-> 2D-Sampler Contour-Levels Positive-Integer + (Plot-Colors (Listof Real)) + (Pen-Widths (Listof Real)) + (Plot-Pen-Styles (Listof Real)) + (Alphas (Listof Real)) + (U String pict #f) + (Values (U #f (-> Rect (Treeof legend-entry))) + 2D-Render-Proc))) +(define (make-contour-labels-and-renderer g levels samples colors widths styles alphas label) + ;; g is a 2D-sampler, which is a memoized proc. Recalculation here should be cheap + (define (calculate-zs/labels [rect : Rect]) : (Values 2d-sample (Listof Real) (Listof String)) + (match-define (vector x-ivl y-ivl) rect) (define num (animated-samples samples)) (define sample (g (vector x-ivl y-ivl) (vector num num))) (match-define (2d-sample xs ys zss z-min z-max) sample) - - (unless (and z-min z-max) (return empty)) - - (match-define (list (tick #{zs : (Listof Real)} - #{_ : (Listof Boolean)} - #{labels : (Listof String)}) - ...) - (contour-ticks (plot-z-ticks) (assert z-min values) (assert z-max values) levels #f)) - - (let* ([colors (generate-list colors zs)] - [widths (generate-list widths zs)] - [styles (generate-list styles zs)] - [alphas (generate-list alphas zs)]) - (for ([z (in-list zs)] - [color (in-cycle* colors)] - [width : Nonnegative-Real (in-cycle* widths)] - [style (in-cycle* styles)] - [alpha : Nonnegative-Real (in-cycle* alphas)]) - (send area put-alpha alpha) - (send area put-pen color width style) - (for-2d-sample - (xa xb ya yb z1 z2 z3 z4) sample - (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) - (match-define (list v1 v2) (map (λ ([v : (Vectorof Real)]) (vector-take v 2)) line)) - (send area put-line v1 v2))))) - - (cond [(and label (not (empty? zs))) (line-legend-entries label zs labels colors widths styles)] - [else empty]))) + (cond + [(and z-min z-max) + (match-define (list (tick #{zs : (Listof Real)} + #{_ : (Listof Boolean)} + #{labels : (Listof String)}) + ...) + (contour-ticks (plot-z-ticks) (assert z-min values) (assert z-max values) levels #f)) + (values sample zs labels)] + [else + (values (2d-sample '() '() #() #f #f) empty empty)])) + + (define label-proc + (and label (λ ([rect : Rect]) + (define-values (_ zs labels) (calculate-zs/labels rect)) + (if (empty? zs) + '() + (line-legend-entries label zs labels colors widths styles))))) + + (: render-proc 2D-Render-Proc) + (define (render-proc area) + (define-values (sample zs _) (calculate-zs/labels (send area get-bounds-rect))) + (unless (empty? zs) + (let* ([colors (generate-list colors zs)] + [widths (generate-list widths zs)] + [styles (generate-list styles zs)] + [alphas (generate-list alphas zs)]) + (for ([z (in-list zs)] + [color (in-cycle* colors)] + [width : Nonnegative-Real (in-cycle* widths)] + [style (in-cycle* styles)] + [alpha : Nonnegative-Real (in-cycle* alphas)]) + (send area put-alpha alpha) + (send area put-pen color width style) + (for-2d-sample + (xa xb ya yb z1 z2 z3 z4) sample + (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) + (match-define (list v1 v2) (map (λ ([v : (Vectorof Real)]) (vector-take v 2)) line)) + (send area put-line v1 v2))))))) + + (values label-proc render-proc)) (:: contours (->* [(-> Real Real Real)] @@ -130,7 +139,7 @@ #:widths (Pen-Widths (Listof Real)) #:styles (Plot-Pen-Styles (Listof Real)) #:alphas (Alphas (Listof Real)) - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (contours f [x-min #f] [x-max #f] [y-min #f] [y-max #f] #:samples [samples (contour-samples)] @@ -152,81 +161,107 @@ (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) (define g (2d-function->sampler f (vector x-ivl y-ivl))) + (define-values (label-proc render-proc) + (make-contour-labels-and-renderer + g levels samples colors widths styles alphas label)) (renderer2d (vector x-ivl y-ivl) #f default-ticks-fun - (contours-render-proc g levels samples colors widths styles alphas label))])) + label-proc render-proc)])) ;; =================================================================================================== ;; Contour intervals -(: contour-intervals-render-proc +(: make-contour-intervals-labels-and-renderer (-> 2D-Sampler Contour-Levels Positive-Integer (Plot-Colors (Listof ivl)) (Plot-Brush-Styles (Listof ivl)) (Plot-Colors (Listof Real)) (Pen-Widths (Listof Real)) (Plot-Pen-Styles (Listof Real)) (Alphas (Listof ivl)) - (U String #f) - 2D-Render-Proc)) -(define ((contour-intervals-render-proc - g levels samples colors styles contour-colors contour-widths contour-styles alphas label) - area) - (let/ec return : (Treeof legend-entry) - (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) + (U String pict #f) + (Values (U #f (-> Rect (Treeof legend-entry))) + 2D-Render-Proc))) +(define (make-contour-intervals-labels-and-renderer + g levels samples colors styles contour-colors contour-widths contour-styles alphas label) + ;; g is a 2D-sampler, which is a memoized proc. Recalculation here should be cheap + (define (calculate-zivls/labels [rect : Rect]) : (Values 2d-sample (Listof ivl) (Listof Real) (Listof String)) + (match-define (vector x-ivl y-ivl) rect) (define num (animated-samples samples)) (define sample (g (vector x-ivl y-ivl) (vector num num))) (match-define (2d-sample xs ys zss z-min z-max) sample) - - (unless (and z-min z-max) (return empty)) - - (match-define (list (tick #{zs : (Listof Real)} - #{_ : (Listof Boolean)} - #{labels : (Listof String)}) - ...) - (contour-ticks (plot-z-ticks) (assert z-min values) (assert z-max values) levels #t)) - - (define-values (z-ivls ivl-labels) - (for/lists ([z-ivls : (Listof ivl)] - [ivl-labels : (Listof String)] - ) ([za (in-list zs)] - [zb (in-list (rest zs))] - [la (in-list labels)] - [lb (in-list (rest labels))]) - (values (ivl za zb) (format "[~a,~a]" la lb)))) - - (send area put-pen 0 1 'transparent) - (let* ([colors (map ->brush-color (generate-list colors z-ivls))] - [styles (map ->brush-style (generate-list styles z-ivls))] - [alphas (generate-list alphas z-ivls)]) - (for ([za (in-list zs)] - [zb (in-list (rest zs))] - [color : (List Real Real Real) (in-cycle* colors)] - [style : Plot-Brush-Style (in-cycle* styles)] - [alpha : Nonnegative-Real (in-cycle* alphas)]) - (send area put-brush color style) - (send area put-alpha alpha) - (for-2d-sample - (xa xb ya yb z1 z2 z3 z4) sample - (for ([poly (in-list (heights->polys xa xb ya yb za zb z1 z2 z3 z4))]) - (send area put-polygon (map (λ ([v : (Vectorof Real)]) (vector-take v 2)) poly))))) - - ((contours-render-proc g levels samples contour-colors contour-widths contour-styles alphas #f) - area) - - (define n (- (length zs) 2)) - (define contour-colors* - (append (list 0) (sequence-take (in-cycle* (generate-list contour-colors zs)) 0 n) (list 0))) - (define contour-widths* - (append (list 0) (sequence-take (in-cycle* (generate-list contour-widths zs)) 0 n) (list 0))) - (define contour-styles* - (append '(transparent) (sequence-take (in-cycle* (generate-list contour-styles zs)) 0 n) - '(transparent))) - - (cond [label (interval-legend-entries - label z-ivls ivl-labels - colors styles colors '(1) '(transparent) - contour-colors* contour-widths* contour-styles* - (rest contour-colors*) (rest contour-widths*) (rest contour-styles*))] - [else empty])))) + (cond + [(and z-min z-max) + (match-define (list (tick #{zs : (Listof Real)} + #{_ : (Listof Boolean)} + #{labels : (Listof String)}) + ...) + (contour-ticks (plot-z-ticks) (assert z-min values) (assert z-max values) levels #t)) + + (define-values (z-ivls ivl-labels) + (for/lists ([z-ivls : (Listof ivl)] + [ivl-labels : (Listof String)] + ) ([za (in-list zs)] + [zb (in-list (rest zs))] + [la (in-list labels)] + [lb (in-list (rest labels))]) + (values (ivl za zb) (format "[~a,~a]" la lb)))) + + (values sample z-ivls zs ivl-labels)] + [else + (values (2d-sample '() '() #() #f #f) empty empty empty)])) + + (define label-proc + (and label + (λ ([rect : Rect]) + (define-values (_ z-ivls zs ivl-labels) + (calculate-zivls/labels rect)) + + (cond + [(empty? zs) empty] + [else + (let* ([colors (map ->brush-color (generate-list colors z-ivls))] + [styles (map ->brush-style (generate-list styles z-ivls))]) + (define n (- (length zs) 2)) + (define contour-colors* + (append (list 0) (sequence-take (in-cycle* (generate-list contour-colors zs)) 0 n) (list 0))) + (define contour-widths* + (append (list 0) (sequence-take (in-cycle* (generate-list contour-widths zs)) 0 n) (list 0))) + (define contour-styles* + (append '(transparent) (sequence-take (in-cycle* (generate-list contour-styles zs)) 0 n) + '(transparent))) + + (interval-legend-entries + label z-ivls ivl-labels + colors styles colors '(1) '(transparent) + contour-colors* contour-widths* contour-styles* + (rest contour-colors*) (rest contour-widths*) (rest contour-styles*)))])))) + + (: render-proc 2D-Render-Proc) + (define (render-proc area) + (define-values (sample z-ivls zs _) + (calculate-zivls/labels (send area get-bounds-rect))) + (unless (empty? zs) + (let* ([colors (map ->brush-color (generate-list colors z-ivls))] + [styles (map ->brush-style (generate-list styles z-ivls))] + [alphas (generate-list alphas z-ivls)]) + + (send area put-pen 0 1 'transparent) + (for ([za (in-list zs)] + [zb (in-list (rest zs))] + [color : (List Real Real Real) (in-cycle* colors)] + [style : Plot-Brush-Style (in-cycle* styles)] + [alpha : Nonnegative-Real (in-cycle* alphas)]) + (send area put-brush color style) + (send area put-alpha alpha) + (for-2d-sample + (xa xb ya yb z1 z2 z3 z4) sample + (for ([poly (in-list (heights->polys xa xb ya yb za zb z1 z2 z3 z4))]) + (send area put-polygon (map (λ ([v : (Vectorof Real)]) (vector-take v 2)) poly))))) + + (define-values (_ contour-render-proc) + (make-contour-labels-and-renderer + g levels samples contour-colors contour-widths contour-styles alphas #f)) + + (contour-render-proc area)))) + + (values label-proc render-proc)) (:: contour-intervals (->* [(-> Real Real Real)] @@ -240,7 +275,7 @@ #:contour-widths (Pen-Widths (Listof Real)) #:contour-styles (Plot-Pen-Styles (Listof Real)) #:alphas (Alphas (Listof ivl)) - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (contour-intervals f [x-min #f] [x-max #f] [y-min #f] [y-max #f] @@ -265,7 +300,9 @@ (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) (define g (2d-function->sampler f (vector x-ivl y-ivl))) + (define-values (label-proc render-proc) + (make-contour-intervals-labels-and-renderer + g levels samples colors styles + contour-colors contour-widths contour-styles alphas label)) (renderer2d (vector x-ivl y-ivl) #f default-ticks-fun - (contour-intervals-render-proc g levels samples colors styles - contour-colors contour-widths contour-styles - alphas label))])) + label-proc render-proc)])) diff --git a/plot-lib/plot/private/plot2d/decoration.rkt b/plot-lib/plot/private/plot2d/decoration.rkt index c2a322fa..be8a4e95 100644 --- a/plot-lib/plot/private/plot2d/decoration.rkt +++ b/plot-lib/plot/private/plot2d/decoration.rkt @@ -2,14 +2,14 @@ ;; Renderers for plot decorations: axes, grids, labeled points, etc. -(require typed/racket/class typed/racket/draw racket/match racket/math racket/list +(require typed/racket/class typed/racket/draw racket/match racket/math racket/list typed/pict plot/utils "../common/type-doc.rkt" "../common/utils.rkt" "clip.rkt" "plot-area.rkt") -(provide (all-defined-out)) +(provide (except-out (all-defined-out) draw-polar-axis-lines draw-polar-axis-ticks)) ;; =================================================================================================== ;; X and Y axes @@ -35,9 +35,7 @@ (define dist (+ radius (pen-gap))) (for ([t (in-list x-ticks)] #:when (pre-tick-major? t)) (match-define (tick x _ label) t) - (send area put-text label (vector x y) (if far? 'bottom 'top) 0 dist))) - - empty) + (send area put-text label (vector x y) (if far? 'bottom 'top) 0 dist)))) (:: x-axis (->* [] [Real #:ticks? Boolean #:labels? Boolean #:far? Boolean #:alpha Nonnegative-Real] @@ -52,7 +50,7 @@ [(or (> alpha 1) (not (rational? alpha))) (raise-keyword-error 'x-axis "real in [0,1]" '#:alpha alpha)] [else - (renderer2d #f #f #f (x-axis-render-proc y ticks? labels? far? alpha))])) + (renderer2d #f #f #f #f (x-axis-render-proc y ticks? labels? far? alpha))])) ;; --------------------------------------------------------------------------------------------------- @@ -77,9 +75,7 @@ (define dist (+ radius (pen-gap))) (for ([t (in-list y-ticks)] #:when (pre-tick-major? t)) (match-define (tick y _ label) t) - (send area put-text label (vector x y) (if far? 'left 'right) 0 dist))) - - empty) + (send area put-text label (vector x y) (if far? 'left 'right) 0 dist)))) (:: y-axis (->* [] [Real #:ticks? Boolean #:labels? Boolean #:far? Boolean #:alpha Nonnegative-Real] @@ -94,7 +90,7 @@ [(or (> alpha 1) (not (rational? alpha))) (raise-keyword-error 'y-axis "real in [0,1]" '#:alpha alpha)] [else - (renderer2d #f #f #f (y-axis-render-proc x ticks? labels? far? alpha))])) + (renderer2d #f #f #f #f (y-axis-render-proc x ticks? labels? far? alpha))])) (:: axes (->* [] @@ -195,8 +191,7 @@ (define ((polar-axes-render-proc num ticks? labels? alpha) area) (send area put-alpha alpha) (when (num . > . 0) (draw-polar-axis-lines num area)) - (when ticks? (draw-polar-axis-ticks (if (num . > . 0) num 12) labels? area)) - empty) + (when ticks? (draw-polar-axis-ticks (if (num . > . 0) num 12) labels? area))) (:: polar-axes (->* [] [#:number Natural #:ticks? Boolean #:labels? Boolean #:alpha Nonnegative-Real] @@ -209,7 +204,7 @@ [(or (> alpha 1) (not (rational? alpha))) (raise-keyword-error 'polar-axes "real in [0,1]" '#:alpha alpha)] [else - (renderer2d #f #f #f (polar-axes-render-proc num ticks? labels? alpha))])) + (renderer2d #f #f #f #f (polar-axes-render-proc num ticks? labels? alpha))])) ;; =================================================================================================== ;; Grid @@ -223,8 +218,7 @@ (for ([t (in-list x-ticks)]) (match-define (tick x major? _) t) (if major? (send area put-minor-pen) (send area put-minor-pen 'long-dash)) - (send area put-line (vector x y-min) (vector x y-max)))) - empty) + (send area put-line (vector x y-min) (vector x y-max))))) (: y-tick-lines-render-proc (-> 2D-Render-Proc)) (define ((y-tick-lines-render-proc) area) @@ -235,16 +229,15 @@ (for ([t (in-list y-ticks)]) (match-define (tick y major? _) t) (if major? (send area put-minor-pen) (send area put-minor-pen 'long-dash)) - (send area put-line (vector x-min y) (vector x-max y)))) - empty) + (send area put-line (vector x-min y) (vector x-max y))))) (:: x-tick-lines (-> renderer2d)) (define (x-tick-lines) - (renderer2d #f #f #f (x-tick-lines-render-proc))) + (renderer2d #f #f #f #f (x-tick-lines-render-proc))) (:: y-tick-lines (-> renderer2d)) (define (y-tick-lines) - (renderer2d #f #f #f (y-tick-lines-render-proc))) + (renderer2d #f #f #f #f (y-tick-lines-render-proc))) (:: tick-grid (-> (Listof renderer2d))) (define (tick-grid) @@ -284,9 +277,24 @@ ; point (send area put-pen point-color point-line-width 'solid) (send area put-brush point-fill-color 'solid) - (send area put-glyphs (list v) point-sym point-size)) - - empty) + (send area put-glyphs (list v) point-sym point-size))) + +(: pict-render-proc (-> pict (Vectorof Real) + Anchor + Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real Point-Sym + Nonnegative-Real + 2D-Render-Proc)) +(define ((pict-render-proc pict v anchor + point-color point-fill-color point-size point-line-width point-sym + alpha) + area) + (send area put-alpha alpha) + ; pict + (send area put-pict pict v anchor (* 1/2 point-size)) + ; point + (send area put-pen point-color point-line-width 'solid) + (send area put-brush point-fill-color 'solid) + (send area put-glyphs (list v) point-sym point-size)) (:: point-label (->* [(Sequenceof Real)] @@ -327,7 +335,7 @@ [else (let ([v (sequence-head-vector 'point-label v 2)]) (match-define (vector x y) v) - (renderer2d (vector (ivl x x) (ivl y y)) #f #f + (renderer2d (vector (ivl x x) (ivl y y)) #f #f #f (label-render-proc label v color size face family anchor angle point-color (cond [(eq? point-fill-color 'auto) (->pen-color point-color)] @@ -335,6 +343,40 @@ point-size point-line-width point-sym alpha)))])) +(:: point-pict + (->* [(Sequenceof Real) pict] + [#:anchor Anchor + #:point-color Plot-Color + #:point-fill-color (U Plot-Color 'auto) + #:point-size Nonnegative-Real + #:point-line-width Nonnegative-Real + #:point-sym Point-Sym + #:alpha Nonnegative-Real] + renderer2d)) +(define (point-pict v pict + #:anchor [anchor (label-anchor)] + #:point-color [point-color (point-color)] + #:point-fill-color [point-fill-color 'auto] + #:point-size [point-size (label-point-size)] + #:point-line-width [point-line-width (point-line-width)] + #:point-sym [point-sym 'fullcircle] + #:alpha [alpha (label-alpha)]) + (define fail/kw (make-raise-keyword-error 'point-pict)) + (cond + [(not (rational? point-size)) (fail/kw "rational?" '#:point-size point-size)] + [(not (rational? point-line-width)) (fail/kw "rational?" '#:point-line-width point-line-width)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [else + (let ([v (sequence-head-vector 'point-pict v 2)]) + (match-define (vector x y) v) + (renderer2d (vector (ivl x x) (ivl y y)) #f #f #f + (pict-render-proc pict v anchor + point-color (cond [(eq? point-fill-color 'auto) (->pen-color point-color)] + [else point-fill-color]) + point-size point-line-width point-sym + alpha)))])) + + (:: parametric-label (->* [(-> Real (Sequenceof Real)) Real] [(U String #f) @@ -376,6 +418,37 @@ #:point-line-width point-line-width #:point-sym point-sym #:alpha alpha)])) +(:: parametric-pict + (->* [(-> Real (Sequenceof Real)) Real pict] + [#:anchor Anchor + #:point-color Plot-Color + #:point-fill-color (U Plot-Color 'auto) + #:point-size Nonnegative-Real + #:point-line-width Nonnegative-Real + #:point-sym Point-Sym + #:alpha Nonnegative-Real] + renderer2d)) +(define (parametric-pict + f t pict + #:anchor [anchor (label-anchor)] + #:point-color [point-color (point-color)] + #:point-fill-color [point-fill-color 'auto] + #:point-size [point-size (label-point-size)] + #:point-line-width [point-line-width (point-line-width)] + #:point-sym [point-sym 'fullcircle] + #:alpha [alpha (label-alpha)]) + (cond + [(not (rational? t)) (raise-argument-error 'parametric-pict "rational?" 1 f t)] + [else + (point-pict + (sequence-head-vector 'parametric-pict (f t) 2) + pict + #:anchor anchor + #:point-color point-color #:point-fill-color point-fill-color #:point-size point-size + #:point-line-width point-line-width #:point-sym point-sym + #:alpha alpha)])) + + (:: polar-label (->* [(-> Real Real) Real] [(U String #f) @@ -416,6 +489,35 @@ #:point-line-width point-line-width #:point-sym point-sym #:alpha alpha)])) +(:: polar-pict + (->* [(-> Real Real) Real pict] + [#:anchor Anchor + #:point-color Plot-Color + #:point-fill-color (U Plot-Color 'auto) + #:point-size Nonnegative-Real + #:point-line-width Nonnegative-Real + #:point-sym Point-Sym + #:alpha Nonnegative-Real] + renderer2d)) +(define (polar-pict + f θ pict + #:anchor [anchor (label-anchor)] + #:point-color [point-color (point-color)] + #:point-fill-color [point-fill-color 'auto] + #:point-size [point-size (label-point-size)] + #:point-line-width [point-line-width (point-line-width)] + #:point-sym [point-sym 'fullcircle] + #:alpha [alpha (label-alpha)]) + (cond + [(not (rational? θ)) (raise-argument-error 'polar-pict "rational?" 1 f θ)] + [else + (point-pict + (polar->cartesian θ (f θ)) pict + #:anchor anchor + #:point-color point-color #:point-fill-color point-fill-color #:point-size point-size + #:point-line-width point-line-width #:point-sym point-sym + #:alpha alpha)])) + (:: function-label (->* [(-> Real Real) Real] [(U String #f) @@ -456,6 +558,35 @@ #:point-line-width point-line-width #:point-sym point-sym #:alpha alpha)])) +(:: function-pict + (->* [(-> Real Real) Real pict] + [#:anchor Anchor + #:point-color Plot-Color + #:point-fill-color (U Plot-Color 'auto) + #:point-size Nonnegative-Real + #:point-line-width Nonnegative-Real + #:point-sym Point-Sym + #:alpha Nonnegative-Real] + renderer2d)) +(define (function-pict + f x pict + #:anchor [anchor (label-anchor)] + #:point-color [point-color (point-color)] + #:point-fill-color [point-fill-color 'auto] + #:point-size [point-size (label-point-size)] + #:point-line-width [point-line-width (point-line-width)] + #:point-sym [point-sym 'fullcircle] + #:alpha [alpha (label-alpha)]) + (cond + [(not (rational? x)) (raise-argument-error 'function-pict "rational" 1 f x)] + [else + (point-pict + (vector x (f x)) pict + #:anchor anchor + #:point-color point-color #:point-fill-color point-fill-color #:point-size point-size + #:point-line-width point-line-width #:point-sym point-sym + #:alpha alpha)])) + (:: inverse-label (->* [(-> Real Real) Real] [(U String #f) @@ -495,3 +626,32 @@ #:point-color point-color #:point-fill-color point-fill-color #:point-size point-size #:point-line-width point-line-width #:point-sym point-sym #:alpha alpha)])) + +(:: inverse-pict + (->* [(-> Real Real) Real pict] + [#:anchor Anchor + #:point-color Plot-Color + #:point-fill-color (U Plot-Color 'auto) + #:point-size Nonnegative-Real + #:point-line-width Nonnegative-Real + #:point-sym Point-Sym + #:alpha Nonnegative-Real] + renderer2d)) +(define (inverse-pict + f y pict + #:anchor [anchor (label-anchor)] + #:point-color [point-color (point-color)] + #:point-fill-color [point-fill-color 'auto] + #:point-size [point-size (label-point-size)] + #:point-line-width [point-line-width (point-line-width)] + #:point-sym [point-sym 'fullcircle] + #:alpha [alpha (label-alpha)]) + (cond + [(not (rational? y)) (raise-argument-error 'inverse-pict "rational?" 1 f y)] + [else + (point-pict + (vector (f y) y) pict + #:anchor anchor + #:point-color point-color #:point-fill-color point-fill-color #:point-size point-size + #:point-line-width point-line-width #:point-sym point-sym + #:alpha alpha)])) diff --git a/plot-lib/plot/private/plot2d/interval.rkt b/plot-lib/plot/private/plot2d/interval.rkt index d43d80f9..c0efa6d4 100644 --- a/plot-lib/plot/private/plot2d/interval.rkt +++ b/plot-lib/plot/private/plot2d/interval.rkt @@ -2,10 +2,14 @@ ;; Renderers for intervals between functions. -(require typed/racket/class racket/match racket/math racket/list +(require typed/racket/class racket/match racket/math racket/list racket/sequence + (only-in math/statistics stddev quantile) + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" - "../common/utils.rkt") + "../common/utils.rkt" + (only-in "rectangle.rkt" discrete-histogram-ticks-fun) + (only-in "box-and-whisker.rkt" make-one-axis-default-ticks-fun)) (provide (all-defined-out)) @@ -17,12 +21,11 @@ Plot-Color Nonnegative-Real Plot-Pen-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) (define ((lines-interval-render-proc v1s v2s color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label) + alpha) area) (send area put-alpha alpha) (send area put-pen 0 0 'transparent) @@ -33,12 +36,7 @@ (send area put-lines v1s) (send area put-pen line2-color line2-width line2-style) - (send area put-lines v2s) - - (cond [label (interval-legend-entry label color style 0 0 'transparent - line1-color line1-width line1-style - line2-color line2-width line2-style)] - [else empty])) + (send area put-lines v2s)) (:: lines-interval (->* [(Sequenceof (Sequenceof Real)) @@ -54,7 +52,7 @@ #:line2-width Nonnegative-Real #:line2-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (lines-interval v1s v2s #:x-min [x-min #f] #:x-max [x-max #f] @@ -77,13 +75,13 @@ [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(not (rational? line1-width)) (fail/kw "rational?" '#:line1-width line1-width)] [(not (rational? line2-width)) (fail/kw "rational?" '#:line2-width line2-width)] - [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (let ([v1s (sequence->listof-vector 'lines-interval v1s 2)] [v2s (sequence->listof-vector 'lines-interval v2s 2)]) (define rvs (filter vrational? (append v1s v2s))) (cond - [(empty? rvs) (renderer2d #f #f #f #f)] + [(empty? rvs) empty-renderer2d] [else (match-define (list (vector #{rxs : (Listof Real)} #{rys : (Listof Real)}) ...) rvs) (let ([x-min (if x-min x-min (apply min* rxs))] @@ -91,10 +89,14 @@ [y-min (if y-min y-min (apply min* rys))] [y-max (if y-max y-max (apply max* rys))]) (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun + (and label (λ (_) + (interval-legend-entry label color style 0 0 'transparent + line1-color line1-width line1-style + line2-color line2-width line2-style))) (lines-interval-render-proc v1s v2s color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label)))]))])) + alpha)))]))])) (:: parametric-interval (->* [(-> Real (Sequenceof Real)) (-> Real (Sequenceof Real)) Real Real] @@ -110,7 +112,7 @@ #:line2-width Nonnegative-Real #:line2-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (parametric-interval f1 f2 t-min t-max @@ -139,7 +141,7 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? line1-width)) (fail/kw "rational?" '#:line1-width line1-width)] [(not (rational? line2-width)) (fail/kw "rational?" '#:line2-width line2-width)] - [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (let ([f1 (λ ([t : Real]) (sequence-head-vector 'parametric-interval (f1 t) 2))] [f2 (λ ([t : Real]) (sequence-head-vector 'parametric-interval (f2 t) 2))]) @@ -167,7 +169,7 @@ #:line2-width Nonnegative-Real #:line2-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (polar-interval f1 f2 [θ-min 0] [θ-max (* 2 pi)] @@ -196,7 +198,7 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? line1-width)) (fail/kw "rational?" '#:line1-width line1-width)] [(not (rational? line2-width)) (fail/kw "rational?" '#:line2-width line2-width)] - [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (define θs (linear-seq θ-min θ-max samples)) (lines-interval @@ -216,12 +218,11 @@ Plot-Color Nonnegative-Real Plot-Pen-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) (define ((function-interval-render-proc f1 f2 samples color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label) + alpha) area) (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) (match-define (sample x1s y1s _ _) (f1 x-ivl samples)) @@ -232,7 +233,7 @@ ((lines-interval-render-proc v1s v2s color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label) + alpha) area)) (:: function-interval @@ -249,7 +250,7 @@ #:line2-width Nonnegative-Real #:line2-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (function-interval f1 f2 [x-min #f] [x-max #f] @@ -275,7 +276,7 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? line1-width)) (fail/kw "rational?" '#:line1-width line1-width)] [(not (rational? line2-width)) (fail/kw "rational?" '#:line2-width line2-width)] - [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) @@ -284,10 +285,14 @@ (renderer2d (vector x-ivl y-ivl) (function-interval-bounds-fun g1 g2 samples) default-ticks-fun + (and label (λ (_) + (interval-legend-entry label color style 0 0 'transparent + line1-color line1-width line1-style + line2-color line2-width line2-style))) (function-interval-render-proc g1 g2 samples color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label))])) + alpha))])) ;; =================================================================================================== ;; Inverse function @@ -297,12 +302,11 @@ Plot-Color Nonnegative-Real Plot-Pen-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) (define ((inverse-interval-render-proc f1 f2 samples color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label) + alpha) area) (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) (match-define (sample y1s x1s _ _) (f1 y-ivl samples)) @@ -313,7 +317,7 @@ ((lines-interval-render-proc v1s v2s color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label) + alpha) area)) (:: inverse-interval @@ -330,7 +334,7 @@ #:line2-width Nonnegative-Real #:line2-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (inverse-interval f1 f2 [y-min #f] [y-max #f] @@ -356,7 +360,7 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? line1-width)) (fail/kw "rational?" '#:line1-width line1-width)] [(not (rational? line2-width)) (fail/kw "rational?" '#:line2-width line2-width)] - [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) @@ -365,7 +369,100 @@ (renderer2d (vector x-ivl y-ivl) (inverse-interval-bounds-fun g1 g2 samples) default-ticks-fun + (and label (λ (_) + (interval-legend-entry label color style 0 0 'transparent + line1-color line1-width line1-style + line2-color line2-width line2-style))) (inverse-interval-render-proc g1 g2 samples color style line1-color line1-width line1-style line2-color line2-width line2-style - alpha label))])) + alpha))])) + +;; =================================================================================================== +;; Violin + +(:: violin + (->* [(Sequenceof Real)] + [#:x Real + #:y-min (U Real #f) #:y-max (U Real #f) + #:width Nonnegative-Real + #:samples Positive-Integer + #:color Plot-Color + #:style Plot-Brush-Style + #:line-color Plot-Color + #:line-width Nonnegative-Real + #:line-style Plot-Pen-Style + #:alpha Nonnegative-Real + #:label (U String pict #f) + #:add-ticks? Boolean + #:far-ticks? Boolean + #:bandwidth (U Real #f) + #:invert? Boolean] + renderer2d)) +(define (violin + ys + #:x [x 0] + #:y-min [y-min #f] #:y-max [y-max #f] + #:width [width 1] + #:samples [samples (line-samples)] + #:color [color (interval-color)] + #:style [style (interval-style)] + #:line-color [line-color (interval-line1-color)] + #:line-width [line-width (interval-line1-width)] + #:line-style [line-style (interval-line1-style)] + #:alpha [alpha (interval-alpha)] + #:label [label #f] + #:add-ticks? [add-ticks? #t] + #:far-ticks? [far-ticks? #f] + #:bandwidth [bandwidth #f] + #:invert? [invert? #f]) + (define fail/kw (make-raise-keyword-error 'violin)) + (cond + [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] + [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(not (and (rational? width) (positive? width))) (fail/kw "positive rational" '#:width width)] + [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] + [(not (rational? line-width)) (fail/kw "rational?" '#:line-width line-width)] + [(or (not (rational? alpha)) (> alpha 1) (< alpha 0)) (fail/kw "real in [0,1]" '#:alpha alpha)] + [else + (define ys* (sequence->list ys)) + (define-values (f1 y-low y-high) + (kde ys* (or bandwidth (silverman-bandwidth ys*)))) + (define y-min* (or y-min y-low)) + (define y-max* (or y-max y-high)) + (define half-width (/ width 2)) + (define x-ivl (ivl (- x half-width) (+ x half-width))) + (define y-ivl (ivl y-min* y-max*)) + (define (f1* [y : Real]) (+ (* width (f1 y)) x)) + (define (f2* [y : Real]) (+ (* width (- (f1 y))) x)) + + (define-values (g1 g2 bounds bounds-fun render-proc) + (if invert? + (values (function->sampler f1* y-ivl) + (function->sampler f2* y-ivl) + (vector y-ivl x-ivl) + function-interval-bounds-fun + function-interval-render-proc) + (values (inverse->sampler f1* y-ivl) + (inverse->sampler f2* y-ivl) + (vector x-ivl y-ivl) + inverse-interval-bounds-fun + inverse-interval-render-proc))) + + (: maybe-invert (All (A) (-> A A (Vectorof A)))) + (define maybe-invert (if invert? (λ (x y) (vector y x)) vector)) + + (renderer2d bounds + (bounds-fun g1 g2 samples) + (if (and (string? label) add-ticks?) + (discrete-histogram-ticks-fun + (list label) (list x) add-ticks? far-ticks? maybe-invert) + (make-one-axis-default-ticks-fun invert?)) + (and label (λ (_) + (interval-legend-entry label color style 0 0 'transparent + line-color line-width line-style + line-color line-width line-style))) + (render-proc g1 g2 samples color style + line-color line-width line-style + line-color line-width line-style + alpha))])) diff --git a/plot-lib/plot/private/plot2d/line.rkt b/plot-lib/plot/private/plot2d/line.rkt index d92bb173..34962569 100644 --- a/plot-lib/plot/private/plot2d/line.rkt +++ b/plot-lib/plot/private/plot2d/line.rkt @@ -4,6 +4,7 @@ (require typed/racket/class racket/match racket/math racket/list racket/sequence plot/utils + (only-in typed/pict pict) (only-in math/statistics stddev) "../common/type-doc.rkt" "../common/utils.rkt") @@ -14,17 +15,33 @@ ;; Lines, parametric, polar (: lines-render-proc (-> (Listof (Vectorof Real)) - Plot-Color Nonnegative-Real Plot-Pen-Style + Plot-Color Nonnegative-Real - (U String #f) + Plot-Pen-Style + Nonnegative-Real + Point-Sym + Plot-Color + Plot-Color + Nonnegative-Real + Nonnegative-Real + Nonnegative-Real + Boolean 2D-Render-Proc)) -(define ((lines-render-proc vs color width style alpha label) area) +(define ((lines-render-proc + vs + color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha + ignore-axis-transforms?) + area) (send area put-alpha alpha) (send area put-pen color width style) - (send area put-lines vs) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (send area put-lines vs ignore-axis-transforms?) + + (unless (eq? marker 'none) + (send area put-alpha marker-alpha) + (send area put-pen marker-color marker-line-width 'solid) + (send area put-brush marker-fill-color 'solid) + (send area put-glyphs vs marker marker-size))) (:: lines (->* [(Sequenceof (Sequenceof Real))] @@ -34,7 +51,14 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f) + #:marker Point-Sym + #:marker-color (U Plot-Color 'auto) + #:marker-fill-color (U Plot-Color 'auto) + #:marker-size Nonnegative-Real + #:marker-line-width Nonnegative-Real + #:marker-alpha Nonnegative-Real + #:ignore-axis-transforms? Boolean] renderer2d)) (define (lines vs #:x-min [x-min #f] #:x-max [x-max #f] @@ -43,7 +67,14 @@ #:width [width (line-width)] #:style [style (line-style)] #:alpha [alpha (line-alpha)] - #:label [label #f]) + #:label [label #f] + #:marker [marker 'none] + #:marker-color [marker-color 'auto] + #:marker-fill-color [marker-fill-color 'auto] + #:marker-size [marker-size (point-size)] + #:marker-line-width [marker-line-width (point-line-width)] + #:marker-alpha [marker-alpha (point-alpha)] + #:ignore-axis-transforms? [ignore-axis-transforms? #f]) (define fail/kw (make-raise-keyword-error 'lines)) (cond [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] @@ -52,18 +83,55 @@ [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] [(not (rational? width)) (fail/kw "rational?" '#:width width)] [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(not (rational? marker-size)) (fail/kw "rational?" '#:marker-size marker-size)] + [(not (rational? marker-line-width)) (fail/kw "rational?" '#:marker-line-width marker-line-width)] + [(or (> marker-alpha 1) (not (rational? marker-alpha))) (fail/kw "real in [0,1]" '#:marker-alpha marker-alpha)] [else (let ([vs (sequence->listof-vector 'lines vs 2)]) (define rvs (filter vrational? vs)) - (cond [(empty? rvs) (renderer2d #f #f #f #f)] + (cond [(empty? rvs) empty-renderer2d] [else (match-define (list (vector #{rxs : (Listof Real)} #{rys : (Listof Real)}) ...) rvs) - (let ([x-min (if x-min x-min (apply min* rxs))] - [x-max (if x-max x-max (apply max* rxs))] - [y-min (if y-min y-min (apply min* rys))] - [y-max (if y-max y-max (apply max* rys))]) - (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun - (lines-render-proc vs color width style alpha label)))]))])) + (let* ([x-min (if x-min x-min (apply min* rxs))] + [x-max (if x-max x-max (apply max* rxs))] + [y-min (if y-min y-min (apply min* rys))] + [y-max (if y-max y-max (apply max* rys))] + [marker-color (if (eq? marker-color 'auto) + (->pen-color color) + marker-color)] + [marker-fill-color (if (eq? marker-fill-color 'auto) + (->pen-color marker-color) + marker-fill-color)]) + (define render-fun + (lines-render-proc + vs + color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha + ignore-axis-transforms?)) + + (: legend-entries (U #f (-> Rect (Treeof legend-entry)))) + (define legend-entries + (and label + (let ([lle (line-legend-entry label color width style)]) + (if (eq? marker 'none) + (lambda (_) lle) + (let ([mle (point-legend-entry + label marker marker-color marker-fill-color marker-size + marker-line-width)]) + (lambda (_) + (legend-entry + label + (lambda ([pd : (Instance Plot-Device%)] + [w : Real] + [h : Real]) + ((legend-entry-draw lle) pd w h) + ((legend-entry-draw mle) pd w h))))))))) + + (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) + #f + default-ticks-fun + legend-entries + render-fun))]))])) (:: parametric (->* [(-> Real (Sequenceof Real)) Real Real] @@ -74,7 +142,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (parametric f t-min t-max #:x-min [x-min #f] #:x-max [x-max #f] @@ -114,7 +182,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (polar f [θ-min 0] [θ-max (* 2 pi)] #:x-min [x-min #f] #:x-max [x-max #f] @@ -153,9 +221,8 @@ Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) -(define ((rule-render-proc v v-min v-max h/v color width style alpha label) area) +(define ((rule-render-proc v v-min v-max h/v color width style alpha) area) (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) (send area get-bounds-rect)) ;; This is the error that `get-bounds-rect` should raise (unless (and x-min x-max y-min y-max) @@ -163,13 +230,10 @@ (ivl->plot-label (ivl x-min x-max)) (ivl->plot-label (ivl y-min y-max)))) (send area put-alpha alpha) - (send area put-pen color width style 'butt) + (send area put-pen color width style) (case h/v [(h) (send area put-line (vector (or v-min x-min) v) (vector (or v-max x-max) v))] - [(v) (send area put-line (vector v (or v-min y-min)) (vector v (or v-max y-max)))]) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + [(v) (send area put-line (vector v (or v-min y-min)) (vector v (or v-max y-max)))])) (:: vrule (->* [Real] @@ -178,7 +242,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (vrule x [y-min #f] [y-max #f] #:color [color (line-color)] @@ -195,7 +259,8 @@ [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (renderer2d #f #f default-ticks-fun - (rule-render-proc x y-min y-max 'v color width style alpha label))])) + (and label (λ (_) (line-legend-entry label color width style))) + (rule-render-proc x y-min y-max 'v color width style alpha))])) (:: hrule (->* [Real] @@ -204,7 +269,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (hrule y [x-min #f] [x-max #f] #:color [color (line-color)] @@ -221,26 +286,61 @@ [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] [else (renderer2d #f #f default-ticks-fun - (rule-render-proc y x-min x-max 'h color width style alpha label))])) + (and label (λ (_) (line-legend-entry label color width style))) + (rule-render-proc y x-min x-max 'h color width style alpha))])) ;; =================================================================================================== ;; Function -(: function-render-proc (-> Sampler Positive-Integer - Plot-Color Nonnegative-Real Plot-Pen-Style +(: function-render-proc (-> Sampler + Positive-Integer + Plot-Color + Nonnegative-Real + Plot-Pen-Style + Nonnegative-Real + Point-Sym + Plot-Color + Plot-Color + Nonnegative-Real Nonnegative-Real - (U String #f) + Nonnegative-Real + Positive-Integer 2D-Render-Proc)) -(define ((function-render-proc f samples color width style alpha label) area) +(define ((function-render-proc + f samples + color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha marker-count) + area) (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) (match-define (sample xs ys y-min y-max) (f x-ivl samples)) + (define vs (map (λ ([x : Real] [y : Real]) (vector x y)) xs ys)) (send area put-alpha alpha) - (send area put-pen color width style) - (send area put-lines (map (λ ([x : Real] [y : Real]) (vector x y)) xs ys)) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (send area put-pen color width style) + (send area put-lines vs) + + (unless (eq? marker 'none) + + ;; Get a subset of the points from the samples to draw markers on. + ;; Normally `samples` is a large number (500 by default) and, without + ;; reducing their number, this draws too many markers on the plot. + (define mvs + (let ([vs-count (length vs)]) + (if (<= vs-count marker-count) + vs + (let ([segment-length : Integer (exact-round (/ vs-count (sub1 marker-count)))]) + (for/list : (Listof (Vector Real Real)) + ([v : (Vector Real Real) (in-list vs)] + [n : Integer (in-naturals)] + #:when (or (= 0 (remainder n segment-length)) + ;; Always get the last point + (= n (sub1 vs-count)))) + v))))) + + (send area put-alpha marker-alpha) + (send area put-pen marker-color marker-line-width 'solid) + (send area put-brush marker-fill-color 'solid) + (send area put-glyphs mvs marker marker-size))) (:: function (->* [(-> Real Real)] @@ -251,7 +351,14 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f) + #:marker Point-Sym + #:marker-color (U Plot-Color 'auto) + #:marker-fill-color (U Plot-Color 'auto) + #:marker-size Nonnegative-Real + #:marker-line-width Nonnegative-Real + #:marker-alpha Nonnegative-Real + #:marker-count Positive-Integer] renderer2d)) (define (function f [x-min #f] [x-max #f] #:y-min [y-min #f] #:y-max [y-max #f] @@ -260,7 +367,14 @@ #:width [width (line-width)] #:style [style (line-style)] #:alpha [alpha (line-alpha)] - #:label [label #f]) + #:label [label #f] + #:marker [marker 'none] + #:marker-color [marker-color 'auto] + #:marker-fill-color [marker-fill-color 'auto] + #:marker-size [marker-size (point-size)] + #:marker-line-width [marker-line-width (point-line-width)] + #:marker-alpha [marker-alpha (point-alpha)] + #:marker-count [marker-count 20]) (define fail/pos (make-raise-argument-error 'function f x-min x-max)) (define fail/kw (make-raise-keyword-error 'function)) (cond @@ -271,33 +385,104 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? width)) (fail/kw "rational?" '#:width width)] [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(not (rational? marker-size)) (fail/kw "rational?" '#:marker-size marker-size)] + [(not (rational? marker-line-width)) (fail/kw "rational?" '#:marker-line-width marker-line-width)] + [(or (> marker-alpha 1) (not (rational? marker-alpha))) (fail/kw "real in [0,1]" '#:marker-alpha marker-alpha)] + [(not (positive-integer? marker-count)) (fail/kw "positive-integer?" '#:marker-count marker-count)] [else (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) - (let ([f (function->sampler f x-ivl)]) + (let* ([f (function->sampler f x-ivl)] + [marker-color + (if (eq? marker-color 'auto) + (->pen-color color) + marker-color)] + [marker-fill-color + (if (eq? marker-fill-color 'auto) + (->pen-color marker-color) + marker-fill-color)]) + + (define render-fun + (function-render-proc f samples color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha marker-count)) + + (: legend-entries (U #f (-> Rect (Treeof legend-entry)))) + (define legend-entries + (and label + (let ([lle (line-legend-entry label color width style)]) + (if (eq? marker 'none) + (lambda (_) lle) + (let ([mle (point-legend-entry + label marker marker-color marker-fill-color marker-size + marker-line-width)]) + (lambda (_) + (legend-entry + label + (lambda ([pd : (Instance Plot-Device%)] + [w : Real] + [h : Real]) + ((legend-entry-draw lle) pd w h) + ((legend-entry-draw mle) pd w h))))))))) + (renderer2d (vector x-ivl y-ivl) (function-bounds-fun f samples) default-ticks-fun - (function-render-proc f samples color width style alpha label)))])) + legend-entries + render-fun))])) ;; =================================================================================================== ;; Inverse function -(: inverse-render-proc (-> Sampler Positive-Integer - Plot-Color Nonnegative-Real Plot-Pen-Style +(: inverse-render-proc (-> Sampler + Positive-Integer + Plot-Color + Nonnegative-Real + Plot-Pen-Style + Nonnegative-Real + Point-Sym + Plot-Color + Plot-Color + Nonnegative-Real + Nonnegative-Real Nonnegative-Real - (U String #f) + Positive-Integer 2D-Render-Proc)) -(define ((inverse-render-proc f samples color width style alpha label) area) +(define ((inverse-render-proc + f samples + color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha marker-count) + area) (match-define (vector x-ivl y-ivl) (send area get-bounds-rect)) (match-define (sample ys xs x-min x-max) (f y-ivl samples)) + (define vs (map (λ ([x : Real] [y : Real]) (vector x y)) xs ys)) (send area put-alpha alpha) (send area put-pen color width style) - (send area put-lines (map (λ ([x : Real] [y : Real]) (vector x y)) xs ys)) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (send area put-lines vs) + + (unless (eq? marker 'none) + + ;; Get a subset of the points from the samples to draw markers on. + ;; Normally `samples` is a large number (500 by default) and, without + ;; reducing their number, this draws too many markers on the plot. + (define mvs + (let ([vs-count (length vs)]) + (if (<= vs-count marker-count) + vs + (let ([segment-length : Integer (exact-round (/ vs-count (sub1 marker-count)))]) + (for/list : (Listof (Vector Real Real)) + ([v : (Vector Real Real) (in-list vs)] + [n : Integer (in-naturals)] + #:when (or (= 0 (remainder n segment-length)) + ;; Always get the last point + (= n (sub1 vs-count)))) + v))))) + + (send area put-alpha marker-alpha) + (send area put-pen marker-color marker-line-width 'solid) + (send area put-brush marker-fill-color 'solid) + (send area put-glyphs mvs marker marker-size))) (: inverse (->* [(-> Real Real)] @@ -308,7 +493,14 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:marker Point-Sym + #:marker-color (U Plot-Color 'auto) + #:marker-fill-color (U Plot-Color 'auto) + #:marker-size Nonnegative-Real + #:marker-line-width Nonnegative-Real + #:marker-alpha Nonnegative-Real + #:marker-count Positive-Integer + #:label (U String pict #f)] renderer2d)) (define (inverse f [y-min #f] [y-max #f] #:x-min [x-min #f] #:x-max [x-max #f] @@ -317,6 +509,13 @@ #:width [width (line-width)] #:style [style (line-style)] #:alpha [alpha (line-alpha)] + #:marker [marker 'none] + #:marker-color [marker-color 'auto] + #:marker-fill-color [marker-fill-color 'auto] + #:marker-size [marker-size (point-size)] + #:marker-line-width [marker-line-width (point-line-width)] + #:marker-alpha [marker-alpha (point-alpha)] + #:marker-count [marker-count 20] #:label [label #f]) (define fail/pos (make-raise-argument-error 'inverse f y-min y-max)) (define fail/kw (make-raise-keyword-error 'inverse)) @@ -328,14 +527,52 @@ [(< samples 2) (fail/kw "Integer >= 2" '#:samples samples)] [(not (rational? width)) (fail/kw "rational?" '#:width width)] [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [(not (rational? marker-size)) (fail/kw "rational?" '#:marker-size marker-size)] + [(not (rational? marker-line-width)) (fail/kw "rational?" '#:marker-line-width marker-line-width)] + [(or (> marker-alpha 1) (not (rational? marker-alpha))) (fail/kw "real in [0,1]" '#:marker-alpha marker-alpha)] + [(not (positive-integer? marker-count)) (fail/kw "positive-integer?" '#:marker-count marker-count)] [else (define x-ivl (ivl x-min x-max)) (define y-ivl (ivl y-min y-max)) - (define g (inverse->sampler f y-ivl)) - (renderer2d (vector x-ivl y-ivl) - (inverse-bounds-fun g samples) - default-ticks-fun - (inverse-render-proc g samples color width style alpha label))])) + + (let* ([g (inverse->sampler f y-ivl)] + [marker-color + (if (eq? marker-color 'auto) + (->pen-color color) + marker-color)] + [marker-fill-color + (if (eq? marker-fill-color 'auto) + (->pen-color marker-color) + marker-fill-color)]) + + (define render-fun + (inverse-render-proc + g samples color width style alpha + marker marker-color marker-fill-color marker-size marker-line-width marker-alpha marker-count)) + + (: legend-entries (U #f (-> Rect (Treeof legend-entry)))) + (define legend-entries + (and label + (let ([lle (line-legend-entry label color width style)]) + (if (eq? marker 'none) + (lambda (_) lle) + (let ([mle (point-legend-entry + label marker marker-color marker-fill-color marker-size + marker-line-width)]) + (lambda (_) + (legend-entry + label + (lambda ([pd : (Instance Plot-Device%)] + [w : Real] + [h : Real]) + ((legend-entry-draw lle) pd w h) + ((legend-entry-draw mle) pd w h))))))))) + + (renderer2d (vector x-ivl y-ivl) + (inverse-bounds-fun g samples) + default-ticks-fun + legend-entries + render-fun))])) ;; =================================================================================================== ;; Kernel density estimation @@ -351,7 +588,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (density xs [bw-adjust 1] [orig-ws #f] #:x-min [x-min #f] #:x-max [x-max #f] diff --git a/plot-lib/plot/private/plot2d/plot-area.rkt b/plot-lib/plot/private/plot2d/plot-area.rkt index af3fc23b..4ca8b86e 100644 --- a/plot-lib/plot/private/plot2d/plot-area.rkt +++ b/plot-lib/plot/private/plot2d/plot-area.rkt @@ -1,6 +1,6 @@ #lang typed/racket/base -(require typed/racket/class typed/racket/draw racket/match racket/math racket/list racket/flonum +(require typed/racket/class typed/racket/draw racket/match racket/math racket/list racket/flonum typed/pict (only-in math/flonum fl) "../common/type-doc.rkt" "../common/types.rkt" @@ -26,11 +26,13 @@ [rx-far-ticks (Listof tick)] [ry-ticks (Listof tick)] [ry-far-ticks (Listof tick)] + [legend (Listof legend-entry)] [dc (Instance DC<%>)] [dc-x-min Real] [dc-y-min Real] [dc-x-size Nonnegative-Real] - [dc-y-size Nonnegative-Real]) + [dc-y-size Nonnegative-Real] + [aspect-ratio (U Nonnegative-Real #f)]) [put-clip-rect (-> Rect Void)] [clear-clip-rect (-> Void)] [get-x-ticks (-> (Listof tick))] @@ -39,6 +41,7 @@ [get-y-far-ticks (-> (Listof tick))] [get-bounds-rect (-> Rect)] [get-clip-rect (-> Rect)] + [get-aspect-ratio (-> (U Nonnegative-Real #f))] [get-area-bounds-rect (-> Rect)] [plot->dc (-> (Vectorof Real) (Vectorof Real))] [dc->plot (-> (Vectorof Real) (Vectorof Real))] @@ -57,21 +60,24 @@ [put-font-attribs (-> Nonnegative-Real (U #f String) Font-Family Void)] [put-text-foreground (-> Plot-Color Void)] [reset-drawing-params (-> Void)] - [put-lines (-> (Listof (Vectorof Real)) Void)] + [put-arrow-head (-> (U (List '= Nonnegative-Real) Nonnegative-Real) Nonnegative-Real Void)] + [put-lines (->* [(Listof (Vectorof Real))] [Boolean] Void)] [put-line (-> (Vectorof Real) (Vectorof Real) Void)] [put-polygon (-> (Listof (Vectorof Real)) Void)] [put-rect (-> Rect Void)] [put-text (->* [String (Vectorof Real)] [Anchor Real Real Boolean] Void)] [put-glyphs (-> (Listof (Vectorof Real)) Point-Sym Nonnegative-Real Void)] - [put-arrow (-> (Vectorof Real) (Vectorof Real) Void)] + [put-arrow (->* ((Vectorof Real) (Vectorof Real)) (Boolean) Void)] [put-tick (-> (Vectorof Real) Real Real Void)] + [put-pict (->* [pict (Vectorof Real)] [Anchor Real] Void)] + [get-plot-metrics-functions (-> Plot-Metrics-Functions)] )) (: 2d-plot-area% 2D-Plot-Area%) (define 2d-plot-area% (class object% - (init-field bounds-rect rx-ticks rx-far-ticks ry-ticks ry-far-ticks) - (init-field dc dc-x-min dc-y-min dc-x-size dc-y-size) + (init-field bounds-rect rx-ticks rx-far-ticks ry-ticks ry-far-ticks legend) + (init-field dc dc-x-min dc-y-min dc-x-size dc-y-size aspect-ratio) (super-new) (: pd (Instance Plot-Device%)) @@ -192,7 +198,11 @@ [(vector x y) (vector +nan.0 +nan.0)]))) - (define/public (plot->dc v) (view->dc (plot->view v))) + (: plot->dc (-> (Vectorof Real) (Vectorof Real))) + (define (plot->dc v) (view->dc (plot->view v))) + (begin + (public [public-plot->dc plot->dc]) + (define (public-plot->dc [v : (Vectorof Real)]) (plot->dc v))) (define: view-x-size : Real 0) (define: view-y-size : Real 0) @@ -223,14 +233,100 @@ (vector (+ area-x-min (* x area-per-view-x)) (- area-y-max (* y area-per-view-y)))))) + + (: title-margin Real) + (define title-margin + (let ([title (plot-title)]) + (cond [(and (plot-decorations?) title) + (if (pict? title) + (+ (pict-height title) (* 1/2 char-height)) + (* 3/2 char-height))] + [else 0]))) + + ;; legend margin calculation and preparation of draw function + (: legend-print (-> (Listof legend-entry) Void)) + (: init-left-margin Real) + (: init-right-margin Real) (: init-top-margin Real) - (define init-top-margin - (cond [(and (plot-decorations?) (plot-title)) (* 3/2 char-height)] - [else 0])) + (: init-bottom-margin Real) + (define-values (legend-print init-left-margin init-right-margin init-top-margin init-bottom-margin) + (let* ([legend-anchor (plot-legend-anchor)] + [legend-rect (and (outside-anchor? legend-anchor) + (not (empty? legend)) + (send pd calculate-legend-rect + legend + (vector (ivl dc-x-min (+ dc-x-min dc-x-size)) + (ivl dc-y-min (+ dc-y-min dc-y-size))) + (legend-anchor->anchor legend-anchor) + (plot-legend-padding)))] + [gap (pen-gap)] + [make-print + (λ ([get-bounds : (-> (Listof Real))]) + (λ ([legend-entries : (Listof legend-entry)]) + (match-define (list x-min x-max y-min y-max gap-size) (get-bounds)) + (send pd draw-legend legend-entries + (vector (ivl (+ x-min gap-size) (- x-max gap-size)) + (ivl (+ y-min gap-size) (- y-max gap-size))))))] + [make-none (λ ([get-bounds : (-> (Listof Real))]) + (values (make-print get-bounds) 0 0 title-margin 0))] + [none (λ () (make-none (λ () (list area-x-min area-x-max area-y-min area-y-max + (+ gap tick-radius)))))]) + (cond + [legend-rect + (define double-gap (* 2 gap)) + (define tripple-gap (* 3 gap)) + + ;; legend with and height + (match-define (vector (ivl x- x+) (ivl y- y+)) legend-rect) + (define width (if (and x- x+) (+ double-gap (- x+ x-)) 0)) + (define height (if (and y- y+) (+ double-gap (- y+ y-)) 0)) + + ;; the maximum width/height for the plot+axis-labels + (define remaining-x-size (- dc-x-size width)) + (define remaining-y-size (- dc-y-size title-margin height)) + + ;; Align with dc/title + (define t-print + (make-print + (λ () + (list dc-x-min (+ dc-x-min dc-x-size) + (+ title-margin dc-y-min) (+ dc-y-min dc-y-size) gap)))) + ;; Align with plot-area + (define v-print + (make-print + (λ () + (list dc-x-min (+ dc-x-min dc-x-size) + (- area-y-min gap) (+ area-y-max gap) gap)))) + (define h-print + (make-print + (λ () + (list (- area-x-min gap) (+ area-x-max gap) + (+ title-margin dc-y-min) (+ dc-y-min dc-y-size) gap)))) + + (case legend-anchor + [(outside-global-top) + (values t-print 0 0 + (+ title-margin (if (< remaining-y-size 0) 0 height) tripple-gap) 0)] + [(outside-top-left outside-top outside-top-right) + (values h-print 0 0 + (+ title-margin (if (< remaining-y-size 0) 0 height) tripple-gap) 0)] + [(outside-left-top outside-left outside-left-bottom) + (values v-print (+ (if (< remaining-x-size 0) 0 width) tripple-gap) 0 + title-margin 0)] + [(outside-right-top outside-right outside-right-bottom) + (values v-print 0 (+ (if (< remaining-x-size 0) 0 width) tripple-gap) + title-margin 0)] + [(outside-bottom-left outside-bottom outside-bottom-right) + (values h-print 0 0 + title-margin (+ (if (< remaining-y-size 0) 0 height) tripple-gap))] + ;; unreachable code, but TR complains about 1 vs 5 values if not present + [else (none)])] + [else (none)]))) (: view->dc (-> (Vectorof Real) (Vectorof Real))) ;; Initial view->dc (draws labels and half of every tick off the allotted space on the dc) - (define view->dc (make-view->dc 0 0 init-top-margin 0)) + (define view->dc (make-view->dc init-left-margin init-right-margin + init-top-margin init-bottom-margin)) ;; =============================================================================================== ;; Tick and label constants @@ -330,10 +426,22 @@ ;; ----------------------------------------------------------------------------------------------- ;; Tick label parameters + (: draw-x-tick-labels? Boolean) + (: draw-y-tick-labels? Boolean) (: draw-x-far-tick-labels? Boolean) (: draw-y-far-tick-labels? Boolean) - (define draw-x-far-tick-labels? (not (and (plot-x-axis?) (equal? x-ticks x-far-ticks)))) - (define draw-y-far-tick-labels? (not (and (plot-y-axis?) (equal? y-ticks y-far-ticks)))) + (define draw-x-tick-labels? (plot-x-tick-labels?)) + (define draw-y-tick-labels? (plot-y-tick-labels?)) + (define draw-x-far-tick-labels? + (let ((flag (plot-x-far-tick-labels?))) + (if (eq? flag 'auto) + (not (and (plot-x-axis?) (equal? x-ticks x-far-ticks))) + flag))) + (define draw-y-far-tick-labels? + (let ((flag (plot-y-far-tick-labels?))) + (if (eq? flag 'auto) + (not (and (plot-y-axis?) (equal? y-ticks y-far-ticks))) + flag))) (: x-tick-label-offset (Vectorof Real)) (: y-tick-label-offset (Vectorof Real)) @@ -354,7 +462,7 @@ (: get-x-tick-label-params (-> (Listof Label-Params))) (define (get-x-tick-label-params) - (if (plot-x-axis?) + (if (and (plot-x-axis?) draw-x-tick-labels?) (get-tick-label-params x-ticks x-tick-label-offset (λ ([x : Real]) (x-tick-value->dc x)) @@ -364,7 +472,7 @@ (: get-y-tick-label-params (-> (Listof Label-Params))) (define (get-y-tick-label-params) - (if (plot-y-axis?) + (if (and (plot-y-axis?) draw-y-tick-labels?) (get-tick-label-params y-ticks y-tick-label-offset (λ ([y : Real]) (y-tick-value->dc y)) @@ -422,14 +530,14 @@ (: max-x-tick-label-height Real) (define max-x-tick-label-height - (if (plot-x-axis?) + (if (and (plot-x-axis?) draw-x-tick-labels?) (apply max 0 (map (λ ([corner : (Vectorof Real)]) (vector-ref corner 1)) (get-relative-corners (get-x-tick-label-params)))) 0)) (: max-y-tick-label-width Real) (define max-y-tick-label-width - (if (plot-y-axis?) + (if (and (plot-y-axis?) draw-y-tick-labels?) (- (apply min 0 (map (λ ([corner : (Vectorof Real)]) (vector-ref corner 0)) (get-relative-corners (get-y-tick-label-params))))) 0)) @@ -456,9 +564,15 @@ (: get-y-label-params (-> Label-Params)) (define (get-y-label-params) - (define offset (vector (+ max-y-tick-offset max-y-tick-label-width half-char-height) + (define label (plot-y-label)) + (define half-label-width (if (pict? label) + (* 1/2 (pict-width label)) + half-char-height)) + (define offset (vector (+ max-y-tick-offset max-y-tick-label-width half-label-width) (ann 0 Real))) - (list (plot-y-label) (v- (view->dc (vector 0.0 0.5)) offset) 'bottom (/ pi 2))) + (if (string? label) + (list label (v- (view->dc (vector 0.0 0.5)) offset) 'bottom (/ pi 2)) + (list label (v- (view->dc (vector 0.0 0.5)) offset) 'center 0))) (: get-x-far-label-params (-> Label-Params)) (define (get-x-far-label-params) @@ -468,9 +582,15 @@ (: get-y-far-label-params (-> Label-Params)) (define (get-y-far-label-params) - (define offset (vector (+ max-y-far-tick-offset max-y-far-tick-label-width half-char-height) + (define label (plot-y-far-label)) + (define half-label-width (if (pict? label) + (* 1/2 (pict-width label)) + half-char-height)) + (define offset (vector (+ max-y-far-tick-offset max-y-far-tick-label-width half-label-width) (ann 0 Real))) - (list (plot-y-far-label) (v+ (view->dc (vector 1.0 0.5)) offset) 'top (/ pi 2))) + (if (string? label) + (list label (v+ (view->dc (vector 1.0 0.5)) offset) 'top (/ pi 2)) + (list label (v+ (view->dc (vector 1.0 0.5)) offset) 'center 0))) ;; ----------------------------------------------------------------------------------------------- @@ -521,14 +641,41 @@ (define: right : Real 0) (define: top : Real 0) (define: bottom : Real 0) - (let-values ([(left-val right-val top-val bottom-val) - (margin-fixpoint 0 dc-x-size init-top-margin dc-y-size 0 0 init-top-margin 0 - (λ ([left : Real] [right : Real] [top : Real] [bottom : Real]) - (get-param-vs/set-view->dc! left right top bottom)))]) - (set! left left-val) - (set! right right-val) - (set! top top-val) - (set! bottom bottom-val)) + (let ([inset (plot-inset)]) + (let-values ([(left-inset right-inset top-inset bottom-inset) + (if (list? inset) + (values (list-ref inset 0) (list-ref inset 1) (list-ref inset 2) (list-ref inset 3)) + (values inset inset inset inset))]) + (let-values ([(left-val right-val top-val bottom-val) + (margin-fixpoint + left-inset (- dc-x-size right-inset) + top-inset (- dc-y-size bottom-inset) + init-left-margin init-right-margin + init-top-margin init-bottom-margin + (λ ([left : Real] [right : Real] [top : Real] [bottom : Real]) + (get-param-vs/set-view->dc! left right top bottom)))]) + (set! left left-val) + (set! right right-val) + (set! top top-val) + (set! bottom bottom-val)))) + + ;; When an aspect ratio has been defined, adjust the margins so that the + ;; actual plot area maintains this ratio. + (when (real? aspect-ratio) + (let* ([area-width (- dc-x-size left right)] + [area-height (- dc-y-size top bottom)] + [desired-height (/ area-width (cast aspect-ratio Real))]) + (if (<= desired-height area-height) + (let ([adjust (/ (- area-height desired-height) 2)]) + (set! top (+ top adjust)) + (set! bottom (+ bottom adjust))) + (let* ([desired-width (* area-height (cast aspect-ratio Real))] + [adjust (/ (- area-width desired-width) 2)]) + (set! left (+ left adjust)) + (set! right (+ right adjust))))) + (set! view->dc (make-view->dc left right top bottom))) + + (define/public (get-aspect-ratio) aspect-ratio) (: area-x-min Real) (: area-x-max Real) @@ -570,9 +717,14 @@ (vector (/ (- x area-x-min) area-per-view-x) (/ (- area-y-max y) area-per-view-y))) - (define/public (dc->plot v) + (: dc->plot (-> (Vectorof Real) (Vectorof Real))) + (define (dc->plot v) (view->plot (dc->view v))) + (begin + (public [public-dc->plot dc->plot]) + (define (public-dc->plot [v : (Vectorof Real)]) (dc->plot v))) + ;; =============================================================================================== ;; Plot decoration @@ -580,7 +732,9 @@ (define (draw-title) (define title (plot-title)) (when (and (plot-decorations?) title) - (send pd draw-text title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top))) + (if (string? title) + (send pd draw-text title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top) + (send pd draw-pict title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top)))) (: draw-axes (-> Void)) (define (draw-axes) @@ -614,8 +768,10 @@ (define (draw-labels) (for ([p (in-list (get-all-label-params))]) (match-define (list label v anchor angle) p) - (when label - (send pd draw-text label v anchor angle 0 #t)))) + (cond ((pict? label) + (send pd draw-pict label v anchor 0)) + ((string? label) + (send pd draw-text label v anchor angle 0 #t))))) ;; =============================================================================================== ;; Public drawing control (used by plot/dc) @@ -623,6 +779,8 @@ (define/public (start-plot) (send pd reset-drawing-params) (send pd clear) + (when (and (not (empty? legend)) (outside-anchor? (plot-legend-anchor))) + (draw-legend legend)) (draw-title) (draw-axes) (draw-ticks) @@ -638,13 +796,12 @@ (define/public (end-renderers) (clear-clip-rect) - (send pd reset-drawing-params)) + (send pd reset-drawing-params) + (when (and (not (empty? legend)) (inside-anchor? (plot-legend-anchor))) + (draw-legend legend))) (define/public (draw-legend legend-entries) - (define gap-size (+ (pen-gap) tick-radius)) - (send pd draw-legend legend-entries - (vector (ivl (+ area-x-min gap-size) (- area-x-max gap-size)) - (ivl (+ area-y-min gap-size) (- area-y-max gap-size))))) + (legend-print legend-entries)) (define/public (end-plot) (send pd restore-drawing-params)) @@ -654,7 +811,7 @@ (define/public (put-alpha alpha) (send pd set-alpha alpha)) - (define/public (put-pen color width style [cap 'round]) (send pd set-pen color width style cap)) + (define/public (put-pen color width style [cap (line-cap)]) (send pd set-pen color width style cap)) (define/public (put-major-pen [style 'solid]) (send pd set-major-pen style)) (define/public (put-minor-pen [style 'solid]) (send pd set-minor-pen style)) @@ -666,6 +823,8 @@ (define/public (put-font-attribs size face family) (send pd set-font-attribs size face family)) (define/public (put-text-foreground color) (send pd set-text-foreground color)) + (define/public (put-arrow-head size-or-scale angle) (send pd set-arrow-head size-or-scale angle)) + (define/public (reset-drawing-params) (put-alpha (plot-foreground-alpha)) (put-pen (plot-foreground) (plot-line-width) 'solid) @@ -676,7 +835,12 @@ ;; Shapes - (define/public (put-lines vs) + ;; When ignore-axis-transforms? is #t, we don't sub-divide lines based on + ;; axis transforms. This allows drawing a straight line regardless of the + ;; axis transforms used, such as a log-log plot. This is used to + ;; replicate "lines" functionality form other plotting libraries. See + ;; also #110. + (define/public (put-lines vs [ignore-axis-transforms? #f]) (for ([vs (in-list (exact-vector2d-sublists vs))]) (let ([vss (if clipping? (clip-lines/bounds vs @@ -685,9 +849,11 @@ (list vs))]) (for ([vs (in-list vss)]) (unless (empty? vs) - (let* ([vs (if identity-transforms? vs (subdivide-lines (λ ([v : (Vectorof Real)]) - (plot->dc v)) - vs))] + (let* ([vs (if (or identity-transforms? ignore-axis-transforms?) + vs + (subdivide-lines (λ ([v : (Vectorof Real)]) + (plot->dc v)) + vs))] [vs (map (λ ([v : (Vectorof Real)]) (plot->dc v)) vs)]) @@ -751,14 +917,33 @@ vs) symbol size)))) - (define/public (put-arrow v1 v2) + (define/public (put-arrow v1 v2 [draw-outside? #f]) (let ([v1 (exact-vector2d v1)] [v2 (exact-vector2d v2)]) - (when (and v1 v2 (in-bounds? v1)) + (when (and v1 v2 (or draw-outside? (in-bounds? v1))) (send pd draw-arrow (plot->dc v1) (plot->dc v2))))) (define/public (put-tick v r angle) (let ([v (exact-vector2d v)]) (when (and v (in-bounds? v)) (send pd draw-tick (plot->dc v) r angle)))) + + (define/public (put-pict pict v [anchor 'top-left] [dist 0]) + (let ([v (exact-vector2d v)]) + (when (and v (in-bounds? v)) + (send pd draw-pict pict (plot->dc v) anchor dist)))) + + (define/public (get-plot-metrics-functions) + (list (let ([bounds bounds-rect] + [vect : (Option (Immutable-Vector (Immutable-Vector Real Real) (Immutable-Vector Real Real))) #f]) + (λ () (or vect + (let ([new (vector-immutable (vector-immutable (assert (ivl-min (vector-ref bounds 0)) real?) + (assert (ivl-max (vector-ref bounds 0)) real?)) + (vector-immutable (assert (ivl-min (vector-ref bounds 1)) real?) + (assert (ivl-max (vector-ref bounds 1)) real?)))]) + (set! vect new) + new)))) + plot->dc + dc->plot + (λ () #(0 0 1)))) )) diff --git a/plot-lib/plot/private/plot2d/point.rkt b/plot-lib/plot/private/plot2d/point.rkt index f6678e5f..a742f039 100644 --- a/plot-lib/plot/private/plot2d/point.rkt +++ b/plot-lib/plot/private/plot2d/point.rkt @@ -3,6 +3,7 @@ ;; Renderers for points and other point-like things. (require typed/racket/class racket/match racket/math racket/list + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -22,15 +23,12 @@ (: points-render-fun (-> (Listof (Vectorof Real)) Point-Sym Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real Nonnegative-Real - (U String #f) 2D-Render-Proc)) -(define ((points-render-fun vs sym color fill-color size line-width alpha label) area) +(define ((points-render-fun vs sym color fill-color size line-width alpha) area) (send area put-alpha alpha) (send area put-pen color line-width 'solid) (send area put-brush fill-color 'solid) - (send area put-glyphs vs sym size) - - (if label (point-legend-entry label sym color fill-color size line-width) empty)) + (send area put-glyphs vs sym size)) (:: points (->* [(Sequenceof (Sequenceof Real))] @@ -44,7 +42,7 @@ #:size Nonnegative-Real #:line-width Nonnegative-Real #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (points vs #:x-min [x-min #f] #:x-max [x-max #f] @@ -70,10 +68,10 @@ (let* ([vs (sequence->listof-vector 'points vs 2)] [vs (filter vrational? vs)]) (cond - [(empty? vs) (renderer2d #f #f #f #f)] + [(empty? vs) empty-renderer2d] [else (unless (= 0 x-jitter y-jitter) - (points-apply-jitters vs (vector x-jitter y-jitter) #:ivls (vector (ivl x-min x-max) (ivl y-min y-max)))) + (points-apply-jitters vs ((inst vector Nonnegative-Real) x-jitter y-jitter) #:ivls (vector (ivl x-min x-max) (ivl y-min y-max)))) (match-define (list (vector #{xs : (Listof Real)} #{ys : (Listof Real)}) ...) vs) (let ([x-min (if x-min x-min (apply min* xs))] [x-max (if x-max x-max (apply max* xs))] @@ -82,8 +80,9 @@ [fill-color (if (eq? fill-color 'auto) (->pen-color color) fill-color)]) (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun + (and label (λ (_) (point-legend-entry label sym color fill-color size line-width))) (points-render-fun vs sym color fill-color - size line-width alpha label)))]))])) + size line-width alpha)))]))])) ;; =================================================================================================== ;; Vector fields @@ -93,57 +92,56 @@ Positive-Integer (U Real 'auto 'normalized) Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) -(define ((vector-field-render-fun f samples scale color line-width line-style alpha label) area) +(define ((vector-field-render-fun f samples scale color line-width line-style alpha) area) (match-define (vector (ivl x-min x-max) (ivl y-min y-max)) (send area get-bounds-rect)) - (cond - [(and x-min x-max y-min y-max) - (define xs0 (linear-seq x-min x-max samples #:start? #t #:end? #t)) - (define ys0 (linear-seq y-min y-max samples #:start? #t #:end? #t)) + (when (and x-min x-max y-min y-max) + (define xs0 (linear-seq x-min x-max samples #:start? #t #:end? #t)) + (define ys0 (linear-seq y-min y-max samples #:start? #t #:end? #t)) - (define-values (xs ys dxs dys angles mags) - (for*/lists ([xs : (Listof Real)] - [ys : (Listof Real)] - [dxs : (Listof Real)] - [dys : (Listof Real)] - [angles : (Listof Real)] - [mags : (Listof Nonnegative-Real)] - ) ([x (in-list xs0)] - [y (in-list ys0)] - [dv (in-value (f x y))] #:when (vrational? dv)) - (match-define (vector dx dy) dv) - (values x y dx dy (atan2 dy dx) (sqrt (+ (sqr dx) (sqr dy)))))) + (define-values (xs ys dxs dys angles mags) + (for*/lists ([xs : (Listof Real)] + [ys : (Listof Real)] + [dxs : (Listof Real)] + [dys : (Listof Real)] + [angles : (Listof Real)] + [mags : (Listof Nonnegative-Real)] + ) ([x (in-list xs0)] + [y (in-list ys0)] + [dv (in-value (f x y))] #:when (vrational? dv)) + (match-define (vector dx dy) dv) + (values x y dx dy (atan2 dy dx) (sqrt (+ (sqr dx) (sqr dy)))))) - (cond [(empty? xs) empty] - [else (define box-x-size (/ (- x-max x-min) samples)) - (define box-y-size (/ (- y-max y-min) samples)) + (unless (empty? xs) + (define box-x-size (/ (- x-max x-min) samples)) + (define box-y-size (/ (- y-max y-min) samples)) - (define new-mags - (match scale - [(? real?) (map (λ ([mag : Real]) (* scale mag)) mags)] - ['normalized (define box-size (min box-x-size box-y-size)) - (build-list (length dxs) (λ _ box-size))] - ['auto (define dx-max (apply max (map abs dxs))) - (define dy-max (apply max (map abs dys))) - (define scale (min (/ box-x-size dx-max) - (/ box-y-size dy-max))) - (map (λ ([mag : Real]) (* scale mag)) mags)])) + (define new-mags + (match scale + [(? real?) (map (λ ([mag : Real]) (* scale mag)) mags)] + ['normalized (define box-size (min box-x-size box-y-size)) + (build-list (length dxs) (λ _ box-size))] + ['auto + ;; When all dxs or dys are (exact) zero, the calculation of scale + ;; will raise a 'division by zero' error. If we convert the values + ;; to flonums, the partial result will be +inf.0, and the correct + ;; scale can be calculated. + (define dx-max (real->double-flonum (apply max (map abs dxs)))) + (define dy-max (real->double-flonum (apply max (map abs dys)))) + (define scale (min (/ box-x-size dx-max) + (/ box-y-size dy-max))) + (map (λ ([mag : Real]) (* scale mag)) mags)])) - (send area put-alpha alpha) - (send area put-pen color line-width line-style) - (for ([x (in-list xs)] - [y (in-list ys)] - [angle (in-list angles)] - [mag (in-list new-mags)]) - (send area put-arrow - (vector x y) - (vector (+ x (* mag (cos angle))) (+ y (* mag (sin angle)))))) - - (cond [label (arrow-legend-entry label color line-width line-style)] - [else empty])])] - [else empty])) + (send area put-alpha alpha) + (send area put-pen color line-width line-style) + (for ([x (in-list xs)] + [y (in-list ys)] + [angle (in-list angles)] + [mag (in-list new-mags)]) + (send area put-arrow + (vector x y) + (vector (+ x (* mag (cos angle))) (+ y (* mag (sin angle))))))))) (:: vector-field (->* [(U (-> Real Real (Sequenceof Real)) @@ -156,7 +154,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (vector-field f [x-min #f] [x-max #f] [y-min #f] [y-max #f] #:samples [samples (vector-field-samples)] @@ -180,31 +178,32 @@ [else (let ([f (fix-vector-field-fun 'vector-field f)]) (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun + (and label (λ (_) (arrow-legend-entry label color line-width line-style))) (vector-field-render-fun - f samples scale color line-width line-style alpha label)))])) + f samples scale color line-width line-style alpha)))])) ;; =================================================================================================== ;; Error bars (: error-bars-render-fun (-> (Listof Real) (Listof Real) (Listof Real) Plot-Color Nonnegative-Real Plot-Pen-Style - Nonnegative-Real Nonnegative-Real + Nonnegative-Real Nonnegative-Real Boolean 2D-Render-Proc)) -(define ((error-bars-render-fun xs ys hs color line-width line-style width alpha) area) - (define clip-rect (send area get-clip-rect)) +(define ((error-bars-render-fun xs ys hs color line-width line-style width alpha invert?) area) (define radius (* 1/2 width)) + (define angle (if invert? (/ pi 2) 0)) + + (: maybe-invert (All (A) (-> A A (Vectorof A)))) + (define maybe-invert (if invert? (λ (x y) (vector y x)) vector)) (send area put-alpha alpha) (send area put-pen color line-width line-style) (for ([x (in-list xs)] [y (in-list ys)] [h (in-list hs)]) - (when (rect-contains? clip-rect (vector x y)) - (define v1 (vector x (- y h))) - (define v2 (vector x (+ y h))) - (send area put-line v1 v2) - (send area put-tick v1 radius 0) - (send area put-tick v2 radius 0))) - - empty) + (define v1 (maybe-invert x (- y h))) + (define v2 (maybe-invert x (+ y h))) + (send area put-line v1 v2) + (send area put-tick v1 radius angle) + (send area put-tick v2 radius angle))) (:: error-bars (->* [(Sequenceof (Sequenceof Real))] @@ -214,7 +213,8 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:width Nonnegative-Real - #:alpha Nonnegative-Real] + #:alpha Nonnegative-Real + #:invert? Boolean] renderer2d)) (define (error-bars bars #:x-min [x-min #f] #:x-max [x-max #f] @@ -223,7 +223,8 @@ #:line-width [line-width (error-bar-line-width)] #:line-style [line-style (error-bar-line-style)] #:width [width (error-bar-width)] - #:alpha [alpha (error-bar-alpha)]) + #:alpha [alpha (error-bar-alpha)] + #:invert? [invert? #f]) (define fail/kw (make-raise-keyword-error 'error-bars)) (cond [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] @@ -235,7 +236,7 @@ [else (let* ([bars (sequence->listof-vector 'error-bars bars 3)] [bars (filter vrational? bars)]) - (cond [(empty? bars) (renderer2d #f #f #f #f)] + (cond [(empty? bars) empty-renderer2d] [else (match-define (list (vector #{xs : (Listof Real)} #{ys : (Listof Real)} @@ -246,9 +247,13 @@ [x-max (if x-max x-max (apply max* xs))] [y-min (if y-min y-min (apply min* (map - ys hs)))] [y-max (if y-max y-max (apply max* (map + ys hs)))]) - (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun - (error-bars-render-fun xs ys hs - color line-width line-style width alpha)))]))])) + (: maybe-invert (All (A) (-> A A (Vectorof A)))) + (define maybe-invert (if invert? (λ (x y) (vector y x)) vector)) + (renderer2d + (maybe-invert (ivl x-min x-max) (ivl y-min y-max)) + #f default-ticks-fun #f + (error-bars-render-fun xs ys hs + color line-width line-style width alpha invert?)))]))])) ;; =================================================================================================== ;; Candlesticks @@ -278,8 +283,7 @@ (send area put-line v2 v4) (send area put-line v1 v3) (send area put-brush up-color 'solid) - (send area put-rect r1)])) - empty) + (send area put-rect r1)]))) (:: candlesticks (->* [(Sequenceof (Sequenceof Real))] @@ -312,7 +316,7 @@ [else (let* ([candles (sequence->listof-vector 'candlesticks candles 5)] [candles (filter vrational? candles)]) - (cond [(empty? candles) (renderer2d #f #f #f #f)] + (cond [(empty? candles) empty-renderer2d] [else (match-define (list (vector #{xs : (Listof Real)} #{opens : (Listof Real)} @@ -325,6 +329,6 @@ [x-max (if x-max x-max (+ (apply max* xs) width))] [y-min (if y-min y-min (apply min* lows))] [y-max (if y-max y-max (apply max* highs))]) - (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun + (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun #f (candlesticks-render-fun xs opens highs lows closes up-color down-color line-width line-style width alpha)))]))])) diff --git a/plot-lib/plot/private/plot2d/rectangle.rkt b/plot-lib/plot/private/plot2d/rectangle.rkt index de8c02b4..dc54e5c9 100644 --- a/plot-lib/plot/private/plot2d/rectangle.rkt +++ b/plot-lib/plot/private/plot2d/rectangle.rkt @@ -1,6 +1,8 @@ #lang typed/racket/base (require racket/match typed/racket/class racket/list racket/sequence + (only-in typed/pict pict) + (only-in racket/math infinite?) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -14,18 +16,20 @@ Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 2D-Render-Proc)) -(define ((rectangles-render-proc rects color style line-color line-width line-style alpha label) +(define ((rectangles-render-proc rects color style line-color line-width line-style alpha) area) + (match-define (vector (ivl bx-min bx-max) (ivl by-min by-max)) (send area get-bounds-rect)) (send area put-pen line-color line-width line-style) (send area put-brush color style) (send area put-alpha alpha) (for ([rect (in-list rects)]) - (send area put-rect rect)) - - (cond [label (rectangle-legend-entry label color style line-color line-width line-style)] - [else empty])) + (match-define (vector (ivl vx-min vx-max) (ivl vy-min vy-max)) rect) + (define x-min (if (and vx-min (infinite? vx-min)) bx-min vx-min)) + (define x-max (if (and vx-max (infinite? vx-max)) bx-max vx-max)) + (define y-min (if (and vy-min (infinite? vy-min)) by-min vy-min)) + (define y-max (if (and vy-max (infinite? vy-max)) by-max vy-max)) + (send area put-rect (vector (ivl x-min x-max) (ivl y-min y-max))))) (:: rectangles (->* [(Sequenceof (Sequenceof ivl))] @@ -37,7 +41,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (rectangles rects #:x-min [x-min #f] #:x-max [x-max #f] @@ -65,18 +69,32 @@ #{y2s : (Listof (U Real #f))})) ...) rects) - (define rxs (filter rational? (append x1s x2s))) - (define rys (filter rational? (append y1s y2s))) + (define (valid? num) + (and (real? num) (not (eqv? num +nan.0)) (not (eqv? num +nan.f)))) + (define rxs (filter valid? (append x1s x2s))) + (define rys (filter valid? (append y1s y2s))) (cond - [(or (empty? rxs) (empty? rys)) (renderer2d #f #f #f #f)] + [(or (empty? rxs) (empty? rys)) empty-renderer2d] [else (let ([x-min (if x-min x-min (apply min* rxs))] [x-max (if x-max x-max (apply max* rxs))] [y-min (if y-min y-min (apply min* rys))] [y-max (if y-max y-max (apply max* rys))]) - (renderer2d (vector (ivl x-min x-max) (ivl y-min y-max)) #f default-ticks-fun + ;; Only provide bounds if all rectangle dimensions are finite. + ;; Infinite limits mean "extend to the edge of the plot". + ;; + ;; We cannot simply discard infinite limits, as these bounds will + ;; be used for clipping the rectangles and this might result in + ;; rectangles that don't extend all the way to the edge. + (define bounds + (and (rational? x-min) (rational? x-max) + (rational? y-min) (rational? y-max) + (vector (ivl x-min x-max) (ivl y-min y-max)))) + (renderer2d bounds #f default-ticks-fun + (and label (λ (_) (rectangle-legend-entry label color style + line-color line-width line-style))) (rectangles-render-proc rects color style line-color line-width line-style - alpha label)))]))])) + alpha)))]))])) ;; =================================================================================================== ;; Real histograms (or histograms on the real line) @@ -92,7 +110,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer2d)) (define (area-histogram f bin-bounds #:x-min [x-min #f] #:x-max [x-max #f] @@ -119,7 +137,7 @@ [bin-bounds (filter rational? bin-bounds)] [bin-bounds (sort bin-bounds <)]) (cond - [((length bin-bounds) . < . 2) (renderer2d #f #f #f #f)] + [((length bin-bounds) . < . 2) empty-renderer2d] [else (define xs (linear-seq (apply min* bin-bounds) (apply max* bin-bounds) samples #:start? #f #:end? #f)) @@ -182,7 +200,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f) + #:label (U String pict #f) #:add-ticks? Boolean #:far-ticks? Boolean] renderer2d)) @@ -228,7 +246,7 @@ (list y1 y2)] [else (list y)]))))) (cond - [(empty? rys) (renderer2d #f #f #f #f)] + [(empty? rys) empty-renderer2d] [else (define n (length cats)) (let* ([x-min (if x-min x-min 0)] @@ -245,10 +263,12 @@ (renderer2d (maybe-invert (ivl x-min x-max) (ivl y-min y-max)) #f (discrete-histogram-ticks-fun cats tick-xs add-ticks? far-ticks? maybe-invert) + (and label (λ (_) (rectangle-legend-entry label color style + line-color line-width line-style))) (rectangles-render-proc (map (λ ([x-ivl : ivl] [y-ivl : ivl]) (maybe-invert x-ivl y-ivl)) x-ivls y-ivls) - color style line-color line-width line-style alpha label)))]))])) + color style line-color line-width line-style alpha)))]))])) (:: stacked-histogram (->* [(Sequenceof (U (Vector Any (Sequenceof Real)) diff --git a/plot-lib/plot/private/plot2d/renderer.rkt b/plot-lib/plot/private/plot2d/renderer.rkt index a438a3a9..65a2029b 100644 --- a/plot-lib/plot/private/plot2d/renderer.rkt +++ b/plot-lib/plot/private/plot2d/renderer.rkt @@ -3,10 +3,15 @@ (require "../common/plot-element.rkt" "../common/types.rkt" "../common/type-doc.rkt" + "../common/math.rkt" "plot-area.rkt") (provide (all-defined-out)) -(deftype 2D-Render-Proc (-> (Instance 2D-Plot-Area%) (Treeof legend-entry))) +(deftype 2D-Render-Proc (-> (Instance 2D-Plot-Area%) Void)) -(struct renderer2d plot-element ([render-proc : (U #f 2D-Render-Proc)]) #:transparent) +(struct renderer2d plot-element ([label : (U #f (-> Rect (Treeof legend-entry)))] + [render-proc : (U #f 2D-Render-Proc)]) + #:transparent) + +(define empty-renderer2d (renderer2d #f #f #f #f #f)) diff --git a/plot-lib/plot/private/plot3d/arrows.rkt b/plot-lib/plot/private/plot3d/arrows.rkt new file mode 100644 index 00000000..ccfcd3f2 --- /dev/null +++ b/plot-lib/plot/private/plot3d/arrows.rkt @@ -0,0 +1,140 @@ +#lang typed/racket/base + +(require typed/racket/class racket/match racket/list racket/sequence + (only-in typed/pict pict) + plot/utils + "../common/type-doc.rkt" + "../common/utils.rkt") + +(provide arrows3d-render-fun + arrows3d) +;; =================================================================================================== +;; Arrows + +(: arrows3d-render-fun + (-> (Listof (Pair (Vectorof Real) (Vectorof Real))) + Plot-Color Nonnegative-Real Plot-Pen-Style + Nonnegative-Real + (U (List '= Nonnegative-Real) Nonnegative-Real) Nonnegative-Real + 3D-Render-Proc)) +(define ((arrows3d-render-fun vs + color line-width line-style + alpha + arrow-head-size-or-scale arrow-head-angle) area) + (match-define (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) (send area get-bounds-rect)) + + (when (and x-min x-max y-min y-max z-min z-max) + (send area put-alpha alpha) + (send area put-pen color line-width line-style) + (send area put-arrow-head arrow-head-size-or-scale arrow-head-angle) + (for ([x (in-list vs)]) + (send area put-arrow (car x) (cdr x) #t)))) + + +(define-type (LVof A) + (U (Listof A) (Vectorof A))) + +(:: arrows3d + (->* [(U (LVof (LVof Real)) + (LVof (LVof (LVof Real))))] + [#:x-min (U Real #f) #:x-max (U Real #f) + #:y-min (U Real #f) #:y-max (U Real #f) + #:z-min (U Real #f) #:z-max (U Real #f) + #:color Plot-Color + #:width Nonnegative-Real + #:style Plot-Pen-Style + #:alpha Nonnegative-Real + #:arrow-head-size-or-scale (U (List '= Nonnegative-Real) Nonnegative-Real) + #:arrow-head-angle Nonnegative-Real + #:label (U String pict #f)] + renderer3d)) +(define (arrows3d vs + #:x-min [x-min #f] #:x-max [x-max #f] + #:y-min [y-min #f] #:y-max [y-max #f] + #:z-min [z-min #f] #:z-max [z-max #f] + #:color [color (arrows-color)] + #:width [width (arrows-line-width)] + #:style [style (arrows-line-style)] + #:alpha [alpha (arrows-alpha)] + #:arrow-head-size-or-scale [arrow-head-size-or-scale (arrow-head-size-or-scale)] + #:arrow-head-angle [arrow-head-angle (arrow-head-angle)] + #:label [label #f]) + (define fail/kw (make-raise-keyword-error 'lines3d)) + (cond + [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] + [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] + [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] + [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(not (rational? width)) (fail/kw "rational" '#:width width)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + + [else + (define (argument-error) + (raise-argument-error + 'arrows3d + "(U (Sequenceof (Sequence Real Real Real)) (Sequenceof (Sequence (Sequence Real Real Real) (Sequence Real Real Real))))" + vs)) + + ;; check if we have head/tail or pair vectors, and put in standard format + (define-values (S1 S2) + (for/fold ([S1 : (Listof (Vectorof Real)) '()] + [S2 : (Listof (Pair (Vectorof Real) (Vectorof Real))) '()]) + ([s vs]) + (define l (sequence->list s)) + (cond + [(andmap real? l) + (values (cons (sequence-head-vector 'arrows3d l 3) S1) S2)] + [(and (andmap sequence? l) (= (length l) 2)) + (define v1 (sequence-head-vector 'arrows3d (car l) 3)) + (define v2 (sequence-head-vector 'arrows3d (cadr l) 3)) + (define v3 (vector (+ (vector-ref v1 0) (vector-ref v2 0)) + (+ (vector-ref v1 1) (vector-ref v2 1)) + (+ (vector-ref v1 2) (vector-ref v2 2)))) + (values S1 + (cons (cons v1 v3) S2))] + [else (argument-error)]))) + + (define vs* + (cond + [(empty? S2) + (define S1* (reverse S1)) + (for/list : (Listof (Pair (Vectorof Real) (Vectorof Real))) + ([v1 (in-list S1*)] + [v2 (in-list (cdr S1*))]) + (cons v1 v2))] + [else S2])) + + ;; calculate bound and pick right render-fun + (define rvs + (let () + (match-define (list (cons #{p1 : (Listof (Vectorof Real))} + #{p2 : (Listof (Vectorof Real))}) ...) + vs*) + (filter vrational? (append p1 p2)))) + + (cond + [(empty? rvs) empty-renderer3d] + [else + (define-values (x- x+ y- y+ z- z+) (get-bounds x-min x-max y-min y-max z-min z-max rvs)) + (renderer3d (vector (ivl x- x+) (ivl y- y+) (ivl z- z+)) #f default-ticks-fun + (and label (λ (_) (arrow-legend-entry label color width style))) + (arrows3d-render-fun vs* + color width style alpha + arrow-head-size-or-scale arrow-head-angle))])])) + + +(define (get-bounds [x-min : (Option Real)][x-max : (Option Real)] + [y-min : (Option Real)][y-max : (Option Real)] + [z-min : (Option Real)][z-max : (Option Real)] + [rvs : (Listof (Vectorof Real))]) + (match-define (list (vector #{rxs : (Listof Real)} + #{rys : (Listof Real)} + #{rzs : (Listof Real)}) ...) rvs) + (values (if x-min x-min (apply min* rxs)) + (if x-max x-max (apply max* rxs)) + (if y-min y-min (apply min* rys)) + (if y-max y-max (apply max* rys)) + (if z-min z-min (apply min* rzs)) + (if z-max z-max (apply max* rzs)))) diff --git a/plot-lib/plot/private/plot3d/bsp-trees.rkt b/plot-lib/plot/private/plot3d/bsp-trees.rkt index d34b3842..52c5b997 100644 --- a/plot-lib/plot/private/plot3d/bsp-trees.rkt +++ b/plot-lib/plot/private/plot3d/bsp-trees.rkt @@ -7,26 +7,26 @@ (provide (all-defined-out)) -(: build-bsp-trees (-> (HashTable Integer (Listof BSP-Shape)) - (HashTable Integer BSP-Tree))) +(: build-bsp-trees (-> (Immutable-HashTable Integer (Listof BSP-Shape)) + (Immutable-HashTable Integer BSP-Tree))) (define (build-bsp-trees structural-shapes) - (for/hasheq : (HashTable Integer BSP-Tree) ([(layer ss) (in-hash structural-shapes)]) + (for/hasheq : (Immutable-HashTable Integer BSP-Tree) ([(layer ss) (in-hash structural-shapes)]) (values layer (build-bsp-tree ss)))) -(: walk-bsp-trees (-> (HashTable Integer BSP-Tree) +(: walk-bsp-trees (-> (Immutable-HashTable Integer BSP-Tree) FlVector - (HashTable Integer (Listof BSP-Shape)) - (HashTable Integer (Listof BSP-Shape)))) + (Immutable-HashTable Integer (Listof BSP-Shape)) + (Immutable-HashTable Integer (Listof BSP-Shape)))) (define (walk-bsp-trees bsp-trees view-dir detail-shapes) (define vx (flvector-ref view-dir 0)) (define vy (flvector-ref view-dir 1)) (define vz (flvector-ref view-dir 2)) - + (define layers (sort (append (hash-keys bsp-trees) (hash-keys detail-shapes)) >)) - (for/hasheq : (HashTable Integer (Listof BSP-Shape)) ([layer (in-list layers)]) + (for/hasheq : (Immutable-HashTable Integer (Listof BSP-Shape)) ([layer (in-list layers)]) (define bsp (hash-ref bsp-trees layer (λ () (bsp-leaf empty)))) (define ss (hash-ref detail-shapes layer (λ () empty))) - + (: in-order-ss (Listof BSP-Shape)) (define in-order-ss (let loop ([bsp (bsp-tree-insert bsp ss)]) @@ -40,5 +40,5 @@ (if (cos-angle . > . -1e-16) (append (loop neg) (loop pos)) (append (loop pos) (loop neg)))]))) - + (values layer in-order-ss))) diff --git a/plot-lib/plot/private/plot3d/bsp.rkt b/plot-lib/plot/private/plot3d/bsp.rkt index 89920188..72587691 100644 --- a/plot-lib/plot/private/plot3d/bsp.rkt +++ b/plot-lib/plot/private/plot3d/bsp.rkt @@ -143,7 +143,7 @@ [(n . = . 2) (list (line data (first vs) (second vs)))] [else (list (lines data vs))])) vss))) - + (define-values (vss1 vss2) (split-lines3d vs plane)) (values (vertices->lines vss2) (vertices->lines vss1))])) @@ -254,7 +254,7 @@ (define n (length ivls)) (define-values (ivls1 ivls2) (split-at ivls (quotient n 2))) (interval-list-union (loop ivls1) (loop ivls2))]))) - + (cond [(empty? ivls) #f] [(empty? (rest ivls)) #f] [else @@ -408,7 +408,7 @@ (match s [(points _ vs) (if (empty? vs) empty (list s))] - [(line _ v1 v2) + [(line _ v1 v2) (if (equal? v1 v2) empty (list s))] [(poly data vs ls norm) (let-values ([(vs ls) (canonical-polygon3d vs ls)]) @@ -513,17 +513,17 @@ [else (define axes (vertices->axes (bsp-polys->vertices ps))) (define center (list->flvector (map axis-mid axes))) - + ;; Planes defined by neighboring polygon vertices (define polygon-planes (delay (sort-planes (append* (map bsp-poly-planes ps)) center))) - + (: try-bsp-split/polygon-planes (-> Boolean (U #f BSP-Tree))) ;; Tries splitting using polygon-planes (define (try-bsp-split/polygon-planes disjoint?) (define planes (force polygon-planes)) (cond [(and disjoint? ((length planes) . > . 10)) #f] [else (try-bsp-split/planes ss planes disjoint?)])) - + (let* ([bsp #f] [bsp (if bsp bsp (try-bsp-split/axial-planes ss axes))] [bsp (if bsp bsp (try-bsp-split/bounding-planes ss ps center))] @@ -543,17 +543,17 @@ [else (define axes (vertices->axes (bsp-lines->vertices ls))) (define center (list->flvector (map axis-mid axes))) - + ;; Planes defined by line segments and basis vectors (i.e. one basis in normal is zero) (define line-planes (delay (sort-planes (append* (map bsp-line-planes ls)) center))) - + (: try-bsp-split/line-planes (-> Boolean (U #f BSP-Tree))) ;; Tries splitting using line-planes (define (try-bsp-split/line-planes disjoint?) (define planes (force line-planes)) (cond [(and disjoint? ((length planes) . > . 10)) #f] [else (try-bsp-split/planes ss planes disjoint?)])) - + (let* ([bsp #f] [bsp (if bsp bsp (try-bsp-split/axial-planes ss axes))] [bsp (if bsp bsp (try-bsp-split/line-planes #t))] @@ -573,7 +573,7 @@ (define axes (vertices->axes (append (append* (map lines-vertices ls)) (append* (map points-vertices ps))))) (define center (list->flvector (map axis-mid axes))) - + (: try-nondisjoint-split (-> (U #f BSP-Tree))) (define (try-nondisjoint-split) (match-define (axis i size _mn _mx mid) (argmax axis-size axes)) @@ -581,7 +581,7 @@ [else (define plane (axial-plane i mid)) (try-bsp-split ss plane #f (λ () #f))])) - + (let* ([bsp #f] [bsp (if bsp bsp (try-bsp-split/axial-planes ss axes))] [bsp (if bsp bsp (try-nondisjoint-split))]) diff --git a/plot-lib/plot/private/plot3d/contour.rkt b/plot-lib/plot/private/plot3d/contour.rkt index 3f0808b1..3bf50e62 100644 --- a/plot-lib/plot/private/plot3d/contour.rkt +++ b/plot-lib/plot/private/plot3d/contour.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/class racket/match racket/list + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -13,9 +14,8 @@ (: isoline3d-render-proc (-> 2D-Sampler Real Positive-Integer Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U #f String) 3D-Render-Proc)) -(define ((isoline3d-render-proc f z samples color width style alpha label) area) +(define ((isoline3d-render-proc f z samples color width style alpha) area) (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) (match-define (ivl z-min z-max) z-ivl) (define num (animated-samples samples)) @@ -29,9 +29,7 @@ (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) (match-define (list v1 v2) line) (send area put-line v1 v2)))) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (void)) (:: isoline3d (->* [(-> Real Real Real) Real] @@ -43,7 +41,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (isoline3d f z [x-min #f] [x-max #f] @@ -76,54 +74,80 @@ (define g (2d-function->sampler f (vector x-ivl y-ivl))) (renderer3d (vector x-ivl y-ivl z-ivl) #f default-ticks-fun - (isoline3d-render-proc g z samples color width style alpha label)))])) + (and label (λ (_) (line-legend-entry label color width style))) + (isoline3d-render-proc g z samples color width style alpha)))])) ;; =================================================================================================== ;; Contour lines in 3D (using marching squares) -(: contours3d-render-proc (-> 2D-Sampler Contour-Levels Positive-Integer - (Plot-Colors (Listof Real)) - (Pen-Widths (Listof Real)) - (Plot-Pen-Styles (Listof Real)) - (Alphas (Listof Real)) - (U String #f) - 3D-Render-Proc)) -(define ((contours3d-render-proc f levels samples colors widths styles alphas label) area) - (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) - (match-define (ivl z-min z-max) z-ivl) - (cond - [(and z-min z-max) - (define num (animated-samples samples)) - (define sample (f (vector x-ivl y-ivl) (vector num num))) - ;; can't use the actual z ticks because some or all could be collapsed - (match-define (list (tick #{zs : (Listof Real)} - #{_ : (Listof Boolean)} - #{labels : (Listof String)}) - ...) - (contour-ticks (plot-z-ticks) z-min z-max levels #f)) - - (let* ([colors (generate-list colors zs)] - [widths (generate-list widths zs)] - [styles (generate-list styles zs)] - [alphas (generate-list alphas zs)]) - (for ([z (in-list zs)] - [color (in-cycle* (in-list colors))] - [width : Nonnegative-Real (in-cycle* (in-list widths))] - [style (in-cycle* (in-list styles))] - [alpha : Nonnegative-Real (in-cycle* (in-list alphas))]) - (send area put-alpha alpha) - (send area put-pen color width style) - (for-2d-sample - (xa xb ya yb z1 z2 z3 z4) sample - (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) - (match-define (list v1 v2) line) - (send area put-line v1 v2)))) - - (cond [label (line-legend-entries label zs labels colors widths styles)] - [else empty]))] - [else empty])) +(: make-contours3d-label-and-render (-> 2D-Sampler Contour-Levels Positive-Integer + (Plot-Colors (Listof Real)) + (Pen-Widths (Listof Real)) + (Plot-Pen-Styles (Listof Real)) + (Alphas (Listof Real)) + (U String pict #f) + (Values (U #f (-> Rect (Treeof legend-entry))) + 3D-Render-Proc))) +(define (make-contours3d-label-and-render f levels samples colors widths styles alphas label) + ;; g is a 2D-sampler, which is a memoized proc. Recalculation here should be cheap. + ;; if we memoize here based on rect, smooth interactions are disabled (because of the call to `plot-z-ticks`) + (define (calculate-zs/labels [rect : Rect]) : (Values 2d-sample (Listof Real) (Listof String)) + (match-define (vector x-ivl y-ivl z-ivl) rect) + (match-define (ivl x-min x-max) x-ivl) + (match-define (ivl y-min y-max) y-ivl) + (match-define (ivl z-min z-max) z-ivl) + (cond + [(and z-min z-max) + (define num (animated-samples samples)) + (define sample (f (vector x-ivl y-ivl) (vector num num))) + ;; can't use the actual z ticks because some or all could be collapsed + (match-define (list (tick #{zs : (Listof Real)} + #{_ : (Listof Boolean)} + #{labels : (Listof String)}) + ...) + (contour-ticks (plot-z-ticks) z-min z-max levels #f)) + (values sample zs labels)] + [else + (values (2d-sample '() '() #() #f #f) empty empty)])) + + (define label-proc + (and label + (λ ([rect : Rect]) + (define-values (_ zs labels) (calculate-zs/labels rect)) + (cond + [(empty? zs) empty] + [else + (let* ([colors (generate-list colors zs)] + [widths (generate-list widths zs)] + [styles (generate-list styles zs)]) + (line-legend-entries label zs labels colors widths styles))])))) + + (: render-proc 3D-Render-Proc) + (define (render-proc area) + (define-values (sample zs _) (calculate-zs/labels (send area get-bounds-rect))) + (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) + (match-define (ivl x-min x-max) x-ivl) + (match-define (ivl y-min y-max) y-ivl) + (match-define (ivl z-min z-max) z-ivl) + (unless (empty? zs) + (let* ([colors (generate-list colors zs)] + [widths (generate-list widths zs)] + [styles (generate-list styles zs)] + [alphas (generate-list alphas zs)]) + (for ([z (in-list zs)] + [color (in-cycle* (in-list colors))] + [width : Nonnegative-Real (in-cycle* (in-list widths))] + [style (in-cycle* (in-list styles))] + [alpha : Nonnegative-Real (in-cycle* (in-list alphas))]) + (send area put-alpha alpha) + (send area put-pen color width style) + (for-2d-sample + (xa xb ya yb z1 z2 z3 z4) sample + (for ([line (in-list (heights->lines xa xb ya yb z z1 z2 z3 z4))]) + (match-define (list v1 v2) line) + (send area put-line v1 v2))))))) + + (values label-proc render-proc)) (:: contours3d (->* [(-> Real Real Real)] @@ -136,7 +160,7 @@ #:widths (Pen-Widths (Listof Real)) #:styles (Plot-Pen-Styles (Listof Real)) #:alphas (Alphas (Listof Real)) - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (contours3d f [x-min #f] [x-max #f] @@ -164,103 +188,132 @@ (define y-ivl (ivl y-min y-max)) (define z-ivl (ivl z-min z-max)) (define g (2d-function->sampler f (vector x-ivl y-ivl))) + (define-values (label-proc render-proc) + (make-contours3d-label-and-render g levels samples colors widths styles alphas label)) (renderer3d (vector x-ivl y-ivl z-ivl) (surface3d-bounds-fun g samples) default-ticks-fun - (contours3d-render-proc g levels samples colors widths styles alphas label))])) + label-proc render-proc)])) ;; =================================================================================================== ;; Contour intervals in 3D (using marching squares) -(: contour-intervals3d-render-proc (-> 2D-Sampler Contour-Levels Positive-Integer - (Plot-Colors (Listof ivl)) - (Plot-Brush-Styles (Listof ivl)) - (Plot-Colors (Listof ivl)) - (Pen-Widths (Listof ivl)) - (Plot-Pen-Styles (Listof ivl)) - (Plot-Colors (Listof Real)) - (Pen-Widths (Listof Real)) - (Plot-Pen-Styles (Listof Real)) - (Alphas (Listof ivl)) - (U String #f) - 3D-Render-Proc)) -(define ((contour-intervals3d-render-proc +(: make-contour-intervals3d-label-and-renderer + (-> 2D-Sampler Contour-Levels Positive-Integer + (Plot-Colors (Listof ivl)) + (Plot-Brush-Styles (Listof ivl)) + (Plot-Colors (Listof ivl)) + (Pen-Widths (Listof ivl)) + (Plot-Pen-Styles (Listof ivl)) + (Plot-Colors (Listof Real)) + (Pen-Widths (Listof Real)) + (Plot-Pen-Styles (Listof Real)) + (Alphas (Listof ivl)) + (U String pict #f) + (Values (U #f (-> Rect (Treeof legend-entry))) + 3D-Render-Proc))) +(define (make-contour-intervals3d-label-and-renderer f levels samples colors styles line-colors line-widths line-styles contour-colors contour-widths contour-styles alphas label) - area) - (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) - (match-define (ivl z-min z-max) z-ivl) - (cond - [(and z-min z-max) - (define num (animated-samples samples)) - (define sample (f (vector x-ivl y-ivl) (vector num num))) - ;; can't use the actual z ticks because some or all could be collapsed - (match-define (list (tick #{zs : (Listof Real)} - #{_ : (Listof Boolean)} - #{labels : (Listof String)}) - ...) - (contour-ticks (plot-z-ticks) z-min z-max levels #t)) + ;; g is a 2D-sampler, which is a memoized proc. Recalculation here should be cheap. + ;; if we memoize here based on rect, smooth interactions are disabled (because of the call to `plot-z-ticks`) + (define (calculate-zivls/labels [rect : Rect]) : (Values 2d-sample (Listof ivl) (Listof Real) (Listof String)) + (match-define (vector x-ivl y-ivl z-ivl) rect) + (match-define (ivl x-min x-max) x-ivl) + (match-define (ivl y-min y-max) y-ivl) + (match-define (ivl z-min z-max) z-ivl) + (cond + [(and z-min z-max) + (define num (animated-samples samples)) + (define sample (f (vector x-ivl y-ivl) (vector num num))) + ;; can't use the actual z ticks because some or all could be collapsed + (match-define (list (tick #{zs : (Listof Real)} + #{_ : (Listof Boolean)} + #{labels : (Listof String)}) + ...) + (contour-ticks (plot-z-ticks) z-min z-max levels #t)) - (define-values (z-ivls ivl-labels) - (for/lists ([z-ivls : (Listof ivl)] - [ivl-labels : (Listof String)] - ) ([za (in-list zs)] - [zb (in-list (rest zs))] - [la (in-list labels)] - [lb (in-list (rest labels))]) - (values (ivl za zb) (format "[~a,~a]" la lb)))) - - (let* ([colors (generate-list colors z-ivls)] - [styles (generate-list styles z-ivls)] - [alphas (generate-list alphas z-ivls)] - [line-colors (generate-list line-colors z-ivls)] - [line-widths (generate-list line-widths z-ivls)] - [line-styles (generate-list line-styles z-ivls)]) - (for ([za (in-list zs)] - [zb (in-list (rest zs))] - [color (in-cycle* (in-list colors))] - [style (in-cycle* (in-list styles))] - [alpha : Nonnegative-Real (in-cycle* (in-list alphas))] - [line-color (in-cycle* (in-list line-colors))] - [line-width : Nonnegative-Real (in-cycle* (in-list line-widths))] - [line-style (in-cycle* (in-list line-styles))]) - (send area put-alpha alpha) - (send area put-pen line-color line-width line-style) - (send area put-brush color style) - (for-2d-sample - (xa xb ya yb z1 z2 z3 z4) sample - (for ([vs (in-list (heights->polys xa xb ya yb za zb z1 z2 z3 z4))]) - (define ls - (for/list : (Listof Boolean) ([v1 (in-list (cons (last vs) vs))] - [v2 (in-list vs)]) - (define z1 (vector-ref v1 2)) - (define z2 (vector-ref v2 2)) - (not (or (and (= z1 za) (= z2 za)) - (and (= z1 zb) (= z2 zb)))))) - (send area put-polygon vs 'both ls)))) + (define-values (z-ivls ivl-labels) + (for/lists ([z-ivls : (Listof ivl)] + [ivl-labels : (Listof String)] + ) ([za (in-list zs)] + [zb (in-list (rest zs))] + [la (in-list labels)] + [lb (in-list (rest labels))]) + (values (ivl za zb) (format "[~a,~a]" la lb)))) + + (values sample z-ivls zs ivl-labels)] + [else + (values (2d-sample '() '() #() #f #f) empty empty empty)])) + + (define label-proc + (and label + (λ ([rect : Rect]) + (define-values (_ z-ivls zs ivl-labels) (calculate-zivls/labels rect)) + (let* ([colors (generate-list colors z-ivls)] + [styles (generate-list styles z-ivls)] + [line-colors (generate-list line-colors z-ivls)] + [line-widths (generate-list line-widths z-ivls)] + [line-styles (generate-list line-styles z-ivls)]) + (define n (- (length zs) 2)) + (define contour-colors* + (append (list 0) (sequence-take (in-cycle* (generate-list contour-colors zs)) 0 n) (list 0))) + (define contour-widths* + (append (list 0) (sequence-take (in-cycle* (generate-list contour-widths zs)) 0 n) (list 0))) + (define contour-styles* + (append '(transparent) (sequence-take (in-cycle* (generate-list contour-styles zs)) 0 n) + '(transparent))) - ((contours3d-render-proc f levels samples contour-colors contour-widths contour-styles - alphas #f) - area) + (cond [label (interval-legend-entries + label z-ivls ivl-labels + colors styles line-colors line-widths line-styles + contour-colors* contour-widths* contour-styles* + (rest contour-colors*) (rest contour-widths*) (rest contour-styles*))] + [else empty]))))) + + (: render-proc 3D-Render-Proc) + (define (render-proc area) + (define-values (sample z-ivls zs _) (calculate-zivls/labels (send area get-bounds-rect))) + (unless (empty? zs) - (define n (- (length zs) 2)) - (define contour-colors* - (append (list 0) (sequence-take (in-cycle* (generate-list contour-colors zs)) 0 n) (list 0))) - (define contour-widths* - (append (list 0) (sequence-take (in-cycle* (generate-list contour-widths zs)) 0 n) (list 0))) - (define contour-styles* - (append '(transparent) (sequence-take (in-cycle* (generate-list contour-styles zs)) 0 n) - '(transparent))) + + (let* ([colors (generate-list colors z-ivls)] + [styles (generate-list styles z-ivls)] + [alphas (generate-list alphas z-ivls)] + [line-colors (generate-list line-colors z-ivls)] + [line-widths (generate-list line-widths z-ivls)] + [line-styles (generate-list line-styles z-ivls)]) + (for ([za (in-list zs)] + [zb (in-list (rest zs))] + [color (in-cycle* (in-list colors))] + [style (in-cycle* (in-list styles))] + [alpha : Nonnegative-Real (in-cycle* (in-list alphas))] + [line-color (in-cycle* (in-list line-colors))] + [line-width : Nonnegative-Real (in-cycle* (in-list line-widths))] + [line-style (in-cycle* (in-list line-styles))]) + (send area put-alpha alpha) + (send area put-pen line-color line-width line-style) + (send area put-brush color style) + (for-2d-sample + (xa xb ya yb z1 z2 z3 z4) sample + (for ([vs (in-list (heights->polys xa xb ya yb za zb z1 z2 z3 z4))]) + (define ls + (for/list : (Listof Boolean) ([v1 (in-list (cons (last vs) vs))] + [v2 (in-list vs)]) + (define z1 (vector-ref v1 2)) + (define z2 (vector-ref v2 2)) + (not (or (and (= z1 za) (= z2 za)) + (and (= z1 zb) (= z2 zb)))))) + (send area put-polygon vs 'both ls)))) + + (define-values (_ render-proc) + (make-contours3d-label-and-render f levels samples contour-colors contour-widths contour-styles + alphas #f)) + (render-proc area) - (cond [label (interval-legend-entries - label z-ivls ivl-labels - colors styles line-colors line-widths line-styles - contour-colors* contour-widths* contour-styles* - (rest contour-colors*) (rest contour-widths*) (rest contour-styles*))] - [else empty]))] - [else empty])) + ))) + + (values label-proc render-proc)) (:: contour-intervals3d (->* [(-> Real Real Real)] @@ -278,7 +331,7 @@ #:contour-widths (Pen-Widths (Listof Real)) #:contour-styles (Plot-Pen-Styles (Listof Real)) #:alphas (Alphas (Listof ivl)) - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (contour-intervals3d f [x-min #f] [x-max #f] @@ -311,10 +364,12 @@ (define y-ivl (ivl y-min y-max)) (define z-ivl (ivl z-min z-max)) (define g (2d-function->sampler f (vector x-ivl y-ivl))) + (define-values (label-proc render-proc) + (make-contour-intervals3d-label-and-renderer g levels samples colors styles + line-colors line-widths line-styles + contour-colors contour-widths contour-styles + alphas label)) (renderer3d (vector x-ivl y-ivl z-ivl) (surface3d-bounds-fun g samples) default-ticks-fun - (contour-intervals3d-render-proc g levels samples colors styles - line-colors line-widths line-styles - contour-colors contour-widths contour-styles - alphas label))])) + label-proc render-proc)])) diff --git a/plot-lib/plot/private/plot3d/decoration.rkt b/plot-lib/plot/private/plot3d/decoration.rkt index 21b0381a..4c1f33b3 100644 --- a/plot-lib/plot/private/plot3d/decoration.rkt +++ b/plot-lib/plot/private/plot3d/decoration.rkt @@ -46,9 +46,7 @@ ; point (send area put-pen point-color point-line-width 'solid) (send area put-brush point-fill-color 'solid) - (send area put-glyphs (list v) point-sym point-size plot3d-front-layer)) - - empty) + (send area put-glyphs (list v) point-sym point-size plot3d-front-layer))) (:: point-label3d (->* [(Sequenceof Real)] @@ -89,7 +87,7 @@ [else (let ([v (sequence-head-vector 'point-label3d v 3)]) (match-define (vector x y z) v) - (renderer3d (vector (ivl x x) (ivl y y) (ivl z z)) #f #f + (renderer3d (vector (ivl x x) (ivl y y) (ivl z z)) #f #f #f (label3d-render-proc label v color size face family anchor angle point-color (cond [(eq? point-fill-color 'auto) (->pen-color point-color)] diff --git a/plot-lib/plot/private/plot3d/isosurface.rkt b/plot-lib/plot/private/plot3d/isosurface.rkt index 0a5dbb00..8a18f0aa 100644 --- a/plot-lib/plot/private/plot3d/isosurface.rkt +++ b/plot-lib/plot/private/plot3d/isosurface.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/class racket/match racket/list math/flonum racket/math + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -14,10 +15,9 @@ Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 3D-Render-Proc)) (define ((isosurface3d-render-proc - f d samples color style line-color line-width line-style alpha label) + f d samples color style line-color line-width line-style alpha) area) (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) (match-define (ivl x-min x-max) x-ivl) @@ -34,10 +34,7 @@ (xa xb ya yb za zb d1 d2 d3 d4 d5 d6 d7 d8) sample (for ([vs (in-list (heights->cube-polys xa xb ya yb za zb d d1 d2 d3 d4 d5 d6 d7 d8))]) (send area put-polygon vs))) - - (cond [label (rectangle-legend-entry - label color style line-color line-width line-style)] - [else empty])) + (void)) (:: isosurface3d (->* [(-> Real Real Real Real) Real] @@ -51,7 +48,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (isosurface3d f d [x-min #f] [x-max #f] [y-min #f] [y-max #f] [z-min #f] [z-max #f] #:samples [samples (plot3d-samples)] @@ -81,65 +78,82 @@ (define z-ivl (ivl z-min z-max)) (define g (3d-function->sampler f (vector x-ivl y-ivl z-ivl))) (renderer3d (vector x-ivl y-ivl z-ivl) #f default-ticks-fun + (and label (λ (_) (rectangle-legend-entry + label color style line-color line-width line-style))) (isosurface3d-render-proc - g d samples color style line-color line-width line-style alpha label))])) + g d samples color style line-color line-width line-style alpha))])) ;; =================================================================================================== ;; Nested isosurfaces -(: isosurfaces3d-render-proc +(: make-isosurfaces3d-label-and-renderer (-> 3D-Sampler (U Real #f) (U Real #f) Contour-Levels Positive-Integer (Plot-Colors (Listof Real)) (Plot-Brush-Styles (Listof Real)) (Plot-Colors (Listof Real)) (Pen-Widths (Listof Real)) (Plot-Pen-Styles (Listof Real)) (Alphas (Listof Real)) - (U String #f) - 3D-Render-Proc)) -(define ((isosurfaces3d-render-proc f rd-min rd-max levels samples colors styles + (U String pict #f) + (Values (U #f (-> Rect (Treeof legend-entry))) + 3D-Render-Proc))) +(define (make-isosurfaces3d-label-and-renderer f rd-min rd-max levels samples colors styles line-colors line-widths line-styles alphas label) - area) - (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) - (match-define (ivl x-min x-max) x-ivl) - (match-define (ivl y-min y-max) y-ivl) - (match-define (ivl z-min z-max) z-ivl) - (define num (animated-samples samples)) - (define sample (f (vector x-ivl y-ivl z-ivl) (vector num num num))) - (match-define (3d-sample xs ys zs dsss fd-min fd-max) sample) + ;; g is a 3D-sampler, which is a memoized proc. Recalculation here should be cheap. + ;; if we memoize here based on rect, smooth interactions are disabled (because of the call to `plot-z-ticks`) + (define (calculate-ds/labels [rect : Rect]) : (Values 3d-sample (Listof Real) (Listof String)) + (match-define (vector x-ivl y-ivl z-ivl) rect) + (match-define (ivl x-min x-max) x-ivl) + (match-define (ivl y-min y-max) y-ivl) + (match-define (ivl z-min z-max) z-ivl) + (define num (animated-samples samples)) + (define sample (f (vector x-ivl y-ivl z-ivl) (vector num num num))) + (match-define (3d-sample xs ys zs dsss fd-min fd-max) sample) + + (define d-min (if rd-min rd-min fd-min)) + (define d-max (if rd-max rd-max fd-max)) - (define d-min (if rd-min rd-min fd-min)) - (define d-max (if rd-max rd-max fd-max)) + (match-define (list (tick #{ds : (Listof Real)} + #{_ : (Listof Bolean)} + #{labels : (Listof String)}) + ...) + (cond [(and d-min d-max) (contour-ticks (plot-d-ticks) d-min d-max levels #f)] + [else empty])) + + (values sample ds labels)) + + (define label-proc + (and label + (λ ([rect : Rect]) + (define-values (_ ds labels) (calculate-ds/labels rect)) + (cond + [(empty? ds) empty] + [else (rectangle-legend-entries + label ds colors styles line-colors line-widths line-styles)])))) - (match-define (list (tick #{ds : (Listof Real)} - #{_ : (Listof Bolean)} - #{labels : (Listof String)}) - ...) - (cond [(and d-min d-max) (contour-ticks (plot-d-ticks) d-min d-max levels #f)] - [else empty])) + (: render-proc 3D-Render-Proc) + (define (render-proc area) + (define-values (sample ds _) (calculate-ds/labels (send area get-bounds-rect))) - (let* ([colors (generate-list colors ds)] - [styles (generate-list styles ds)] - [alphas (generate-list alphas ds)] - [line-colors (generate-list line-colors ds)] - [line-widths (generate-list line-widths ds)] - [line-styles (generate-list line-styles ds)]) - (for ([d (in-list ds)] - [color (in-cycle* colors)] - [style (in-cycle* styles)] - [alpha : Nonnegative-Real (in-cycle* alphas)] - [line-color (in-cycle* line-colors)] - [line-width : Nonnegative-Real (in-cycle* line-widths)] - [line-style (in-cycle* line-styles)]) - (send area put-alpha alpha) - (send area put-brush color style) - (send area put-pen line-color line-width line-style) - (for-3d-sample - (xa xb ya yb za zb d1 d2 d3 d4 d5 d6 d7 d8) sample - (for ([vs (in-list (heights->cube-polys xa xb ya yb za zb d d1 d2 d3 d4 d5 d6 d7 d8))]) - (send area put-polygon vs))))) + (let* ([colors (generate-list colors ds)] + [styles (generate-list styles ds)] + [alphas (generate-list alphas ds)] + [line-colors (generate-list line-colors ds)] + [line-widths (generate-list line-widths ds)] + [line-styles (generate-list line-styles ds)]) + (for ([d (in-list ds)] + [color (in-cycle* colors)] + [style (in-cycle* styles)] + [alpha : Nonnegative-Real (in-cycle* alphas)] + [line-color (in-cycle* line-colors)] + [line-width : Nonnegative-Real (in-cycle* line-widths)] + [line-style (in-cycle* line-styles)]) + (send area put-alpha alpha) + (send area put-brush color style) + (send area put-pen line-color line-width line-style) + (for-3d-sample + (xa xb ya yb za zb d1 d2 d3 d4 d5 d6 d7 d8) sample + (for ([vs (in-list (heights->cube-polys xa xb ya yb za zb d d1 d2 d3 d4 d5 d6 d7 d8))]) + (send area put-polygon vs)))))) - (cond - [(and label (not (empty? ds))) (rectangle-legend-entries - label ds colors styles line-colors line-widths line-styles)] - [else empty])) + (values label-proc render-proc)) (:: isosurfaces3d (->* [(-> Real Real Real Real)] @@ -155,7 +169,7 @@ #:line-widths (Pen-Widths (Listof Real)) #:line-styles (Plot-Pen-Styles (Listof Real)) #:alphas (Alphas (Listof Real)) - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (isosurfaces3d f [x-min #f] [x-max #f] [y-min #f] [y-max #f] [z-min #f] [z-max #f] #:d-min [d-min #f] #:d-max [d-max #f] @@ -185,10 +199,12 @@ (define y-ivl (ivl y-min y-max)) (define z-ivl (ivl z-min z-max)) (define g (3d-function->sampler f (vector x-ivl y-ivl z-ivl))) + (define-values (label-proc render-proc) + (make-isosurfaces3d-label-and-renderer g d-min d-max levels samples colors styles + line-colors line-widths line-styles alphas + label)) (renderer3d (vector x-ivl y-ivl z-ivl) #f default-ticks-fun - (isosurfaces3d-render-proc g d-min d-max levels samples colors styles - line-colors line-widths line-styles alphas - label))])) + label-proc render-proc)])) ;; =================================================================================================== @@ -196,9 +212,8 @@ Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 3D-Render-Proc)) -(define ((polar3d-render-proc f g samples color style line-color line-width line-style alpha label) +(define ((polar3d-render-proc f g samples color style line-color line-width line-style alpha) area) (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) (match-define (ivl x-min x-max) x-ivl) @@ -234,10 +249,7 @@ (draw-cube xa xb ya yb za zb d d1 d2 d3 d4 d5 d6 d7 d8))] [else (draw-cube xa xb ya yb za zb d d1 d2 d3 d4 d5 d6 d7 d8)])) - - (cond [label (rectangle-legend-entry - label color style line-color line-width line-style)] - [else empty])) + (void)) (define 2pi (* 2 pi)) @@ -268,7 +280,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (polar3d f #:x-min [x-min #f] #:x-max [x-max #f] @@ -297,10 +309,10 @@ (define vs (for*/list : (Listof (Vectorof Real)) ([θ (in-list (linear-seq 0.0 2pi (* 4 samples)))] - [ρ (in-list (linear-seq (* -1/2 pi) (* 1/2 pi) (* 2 samples)))]) - (3d-polar->3d-cartesian θ ρ (f θ ρ)))) + [ϕ (in-list (linear-seq (* -1/2 pi) (* 1/2 pi) (* 2 samples)))]) + (3d-polar->3d-cartesian θ ϕ (f θ ϕ)))) (define rvs (filter vrational? vs)) - (cond [(empty? rvs) (renderer3d #f #f #f #f)] + (cond [(empty? rvs) empty-renderer3d] [else (match-define (list (vector #{rxs : (Listof Real)} #{rys : (Listof Real)} @@ -320,5 +332,7 @@ (define g (3d-function->sampler new-f (vector x-ivl y-ivl z-ivl))) (renderer3d (vector x-ivl y-ivl z-ivl) #f default-ticks-fun + (and label (λ (_) (rectangle-legend-entry + label color style line-color line-width line-style))) (polar3d-render-proc new-f g samples color style - line-color line-width line-style alpha label)))])])) + line-color line-width line-style alpha)))])])) diff --git a/plot-lib/plot/private/plot3d/line.rkt b/plot-lib/plot/private/plot3d/line.rkt index 04ad85ac..686a48dd 100644 --- a/plot-lib/plot/private/plot3d/line.rkt +++ b/plot-lib/plot/private/plot3d/line.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/class racket/match racket/list + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -12,26 +13,22 @@ (: lines3d-render-proc (-> (-> (Listof (Vectorof Real))) Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 3D-Render-Proc)) -(define ((lines3d-render-proc vs-fun color width style alpha label) area) +(define ((lines3d-render-proc vs-fun color width style alpha) area) (send area put-alpha alpha) (send area put-pen color width style) - (send area put-lines (vs-fun)) - - (cond [label (line-legend-entry label color width style)] - [else empty])) + (send area put-lines (vs-fun))) (: lines3d-renderer (-> (-> (Listof (Vectorof Real))) (U #f Real) (U #f Real) (U #f Real) (U #f Real) (U #f Real) (U #f Real) Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) + (U String pict #f) renderer3d)) (define (lines3d-renderer vs-thnk x-min x-max y-min y-max z-min z-max color width style alpha label) (define rvs (filter vrational? (vs-thnk))) - (cond [(empty? rvs) (renderer3d #f #f #f #f)] + (cond [(empty? rvs) empty-renderer3d] [else (match-define (list (vector #{rxs : (Listof Real)} #{rys : (Listof Real)} @@ -46,7 +43,8 @@ [z-max (if z-max z-max (apply max* rzs))]) (renderer3d (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun - (lines3d-render-proc vs-thnk color width style alpha label)))])) + (and label (λ (_) (line-legend-entry label color width style))) + (lines3d-render-proc vs-thnk color width style alpha)))])) (:: lines3d (->* [(Sequenceof (Sequenceof Real))] @@ -57,7 +55,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (lines3d vs #:x-min [x-min #f] #:x-max [x-max #f] @@ -95,7 +93,7 @@ #:width Nonnegative-Real #:style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (parametric3d f t-min t-max #:x-min [x-min #f] #:x-max [x-max #f] diff --git a/plot-lib/plot/private/plot3d/param-surf.rkt b/plot-lib/plot/private/plot3d/param-surf.rkt new file mode 100644 index 00000000..89ffd8d4 --- /dev/null +++ b/plot-lib/plot/private/plot3d/param-surf.rkt @@ -0,0 +1,164 @@ +#lang typed/racket/base + +(require typed/racket/class racket/match racket/list + (only-in typed/pict pict) + plot/utils + "../common/type-doc.rkt" + "../common/utils.rkt") + +(provide (all-defined-out)) + +;; =================================================================================================== +(: polygons3d-render-proc (-> (-> (Listof (Listof (Vectorof Real)))) + Plot-Color Plot-Brush-Style + Plot-Color Nonnegative-Real Plot-Pen-Style + Nonnegative-Real + 3D-Render-Proc)) +(define ((polygons3d-render-proc vs-fun color style line-color line-width line-style alpha) + area) + (send area put-alpha alpha) + (send area put-brush color style) + (send area put-pen line-color line-width line-style) + (for ([v (in-list (vs-fun))]) + (send area put-polygon v))) + +(: polygons3d-renderer (-> (-> (Listof (Listof (Vectorof Real)))) + (U #f Real) (U #f Real) (U #f Real) (U #f Real) (U #f Real) (U #f Real) + Plot-Color Plot-Brush-Style + Plot-Color Nonnegative-Real Plot-Pen-Style + Nonnegative-Real + (U String pict #f) + renderer3d)) +(define (polygons3d-renderer vs-thnk x-min x-max y-min y-max z-min z-max + color style line-color line-width line-style alpha label) + (define rvs (filter vrational? (apply append (vs-thnk)))) + (cond + [(empty? rvs) empty-renderer3d] + [else + (match-define (list (vector #{rxs : (Listof Real)} + #{rys : (Listof Real)} + #{rzs : (Listof Real)}) + ...) + rvs) + (let ([x-min (or x-min (apply min* rxs))] + [x-max (or x-max (apply max* rxs))] + [y-min (or y-min (apply min* rys))] + [y-max (or y-max (apply max* rys))] + [z-min (or z-min (apply min* rzs))] + [z-max (or z-max (apply max* rzs))]) + (renderer3d (vector (ivl x-min x-max)(ivl y-min y-max)(ivl z-min z-max)) + #f ;surface3d-bounds-fun + default-ticks-fun + (and label (λ (_) (rectangle-legend-entry label color style line-color line-width line-style))) + (polygons3d-render-proc vs-thnk + color style line-color line-width line-style alpha)))])) +(:: polygons3d + (->* [(Sequenceof (Sequenceof (Sequenceof Real)))] + [#:x-min (U #f Real) #:x-max (U #f Real) + #:y-min (U #f Real) #:y-max (U #f Real) + #:z-min (U #f Real) #:z-max (U #f Real) + #:color Plot-Color + #:style Plot-Brush-Style + #:line-color Plot-Color + #:line-width Nonnegative-Real + #:line-style Plot-Pen-Style + #:alpha Nonnegative-Real + #:label (U String pict #f)] + renderer3d)) +(define (polygons3d vs + #:x-min [x-min #f] #:x-max [x-max #f] + #:y-min [y-min #f] #:y-max [y-max #f] + #:z-min [z-min #f] #:z-max [z-max #f] + #:color [color (surface-color)] + #:style [style (surface-style)] + #:line-color [line-color (surface-line-color)] + #:line-width [line-width (surface-line-width)] + #:line-style [line-style (surface-line-style)] + #:alpha [alpha (surface-alpha)] + #:label [label #f]) + (define fail/kw (make-raise-keyword-error 'polygons3d)) + (cond + [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] + [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] + [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] + [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [else + (let ([vs (for/list : (Listof (Listof (Vectorof Real))) + ([v vs]) + (sequence->listof-vector 'polygons3d v 3))]) + (polygons3d-renderer (λ () vs) + x-min x-max y-min y-max z-min z-max + color style line-color line-width line-style alpha label))])) + +(:: parametric-surface3d + (->* [(-> Real Real (Sequenceof Real)) (U #f Real) (U #f Real) (U #f Real) (U #f Real)] + [#:x-min (U #f Real) #:x-max (U #f Real) + #:y-min (U #f Real) #:y-max (U #f Real) + #:z-min (U #f Real) #:z-max (U #f Real) + #:samples Positive-Integer + #:s-samples Positive-Integer + #:t-samples Positive-Integer + #:color Plot-Color + #:style Plot-Brush-Style + #:line-color Plot-Color + #:line-width Nonnegative-Real + #:line-style Plot-Pen-Style + #:alpha Nonnegative-Real + #:label (U String pict #f)] + renderer3d)) +(define (parametric-surface3d f s-min s-max t-min t-max + #:x-min [x-min #f] #:x-max [x-max #f] + #:y-min [y-min #f] #:y-max [y-max #f] + #:z-min [z-min #f] #:z-max [z-max #f] + #:samples [samples (plot3d-samples)] + #:s-samples [s-samples samples] + #:t-samples [t-samples samples] + #:color [color (surface-color)] + #:style [style (surface-style)] + #:line-color [line-color (surface-line-color)] + #:line-width [line-width (surface-line-width)] + #:line-style [line-style (surface-line-style)] + #:alpha [alpha (surface-alpha)] + #:label [label #f]) + (define fail/pos (make-raise-argument-error 'parametric-surface3d f x-min x-max y-min y-max)) + (define fail/kw (make-raise-keyword-error 'parametric-surface3d)) + (cond + [(not (rational? t-min)) (fail/pos "rational?" 1)] + [(not (rational? t-max)) (fail/pos "rational?" 2)] + [(not (rational? s-min)) (fail/pos "rational?" 3)] + [(not (rational? s-max)) (fail/pos "rational?" 4)] + [(and x-min (not (rational? x-min))) (fail/kw "#f or rational" '#:x-min x-min)] + [(and x-max (not (rational? x-max))) (fail/kw "#f or rational" '#:x-max x-max)] + [(and y-min (not (rational? y-min))) (fail/kw "#f or rational" '#:y-min y-min)] + [(and y-max (not (rational? y-max))) (fail/kw "#f or rational" '#:y-max y-max)] + [(and z-min (not (rational? z-min))) (fail/kw "#f or rational" '#:z-min z-min)] + [(and z-max (not (rational? z-max))) (fail/kw "#f or rational" '#:z-max z-max)] + [(< samples 2) (fail/kw "integer >= 2" '#:samples samples)] + [(< s-samples 2) (fail/kw "integer >= 2" '#:s-samples s-samples)] + [(< t-samples 2) (fail/kw "integer >= 2" '#:t-samples t-samples)] + [(or (> alpha 1) (not (rational? alpha))) (fail/kw "real in [0,1]" '#:alpha alpha)] + [else + (define vs (for/list : (Listof (Listof (Vectorof Real))) + ([s (in-list (linear-seq s-min s-max s-samples))]) + (for/list : (Listof (Vectorof Real)) + ([t (in-list (linear-seq t-min t-max t-samples))]) + (sequence-head-vector 'parametric-surface3d (f s t) 3)))) + (define vs+ + (apply + append + (for/list : (Listof (Listof (Listof (Vectorof Real)))) + ([s0 (in-list vs)] + [s1 (in-list (cdr vs))]) + (for/list : (Listof (Listof (Vectorof Real))) + ([t0 (in-list s0)] + [t1 (in-list s1)] + [t2 (in-list (cdr s0))] + [t3 (in-list (cdr s1))]) + (list t0 t1 t3 t2))))) + (polygons3d-renderer + (λ () vs+) + x-min x-max y-min y-max z-min z-max + color style line-color line-width line-style alpha label)])) diff --git a/plot-lib/plot/private/plot3d/plot-area.rkt b/plot-lib/plot/private/plot3d/plot-area.rkt index 7cf8bb40..d87fba23 100644 --- a/plot-lib/plot/private/plot3d/plot-area.rkt +++ b/plot-lib/plot/private/plot3d/plot-area.rkt @@ -2,12 +2,14 @@ (require typed/racket/class typed/racket/draw racket/match racket/list racket/math racket/flonum (only-in math fl vector->flvector) + (only-in typed/pict pict? pict-height) "../common/type-doc.rkt" "../common/types.rkt" "../common/math.rkt" "../common/plot-device.rkt" "../common/ticks.rkt" "../common/draw-attribs.rkt" + "../common/color-map.rkt" "../common/draw.rkt" "../common/axis-transform.rkt" "../common/parameters.rkt" @@ -17,11 +19,13 @@ "bsp-trees.rkt" "bsp.rkt") -(provide (all-defined-out) +(provide plot3d-subdivisions plot3d-back-layer plot3d-area-layer plot3d-front-layer - ) + 3D-Plot-Area% + 3d-plot-area% + (struct-out render-tasks)) (define plot3d-back-layer 2) (define plot3d-area-layer 1) @@ -30,9 +34,9 @@ (: plot3d-subdivisions (Parameterof Natural)) (define plot3d-subdivisions (make-parameter 0)) -(struct render-tasks ([structural-shapes : (HashTable Integer (Listof BSP-Shape))] - [detail-shapes : (HashTable Integer (Listof BSP-Shape))] - [bsp-trees : (HashTable Integer BSP-Tree)])) +(struct render-tasks ([structural-shapes : (Immutable-HashTable Integer (Listof BSP-Shape))] + [detail-shapes : (Immutable-HashTable Integer (Listof BSP-Shape))] + [bsp-trees : (Immutable-HashTable Integer BSP-Tree)])) (struct data ([alpha : Nonnegative-Real]) #:transparent) @@ -74,7 +78,9 @@ [outline-color : (List Real Real Real)] [pen-color : (List Real Real Real)] [pen-width : Nonnegative-Real] - [pen-style : Plot-Pen-Style-Sym]) + [pen-style : Plot-Pen-Style-Sym] + [size-or-scale : (U (List '= Nonnegative-Real) Nonnegative-Real)] + [angle : Nonnegative-Real]) #:transparent) @@ -91,12 +97,14 @@ [ry-ticks (Listof tick)] [ry-far-ticks (Listof tick)] [rz-ticks (Listof tick)] - [rz-far-ticks (Listof tick)]) + [rz-far-ticks (Listof tick)] + [legend (Listof legend-entry)]) (init-field [dc (Instance DC<%>)] [dc-x-min Real] [dc-y-min Real] [dc-x-size Nonnegative-Real] - [dc-y-size Nonnegative-Real]) + [dc-y-size Nonnegative-Real] + [aspect-ratio (U Nonnegative-Real #f)]) [put-clip-rect (-> Rect Void)] [clear-clip-rect (-> Void)] [get-x-ticks (-> (Listof tick))] @@ -107,6 +115,8 @@ [get-z-far-ticks (-> (Listof tick))] [get-bounds-rect (-> Rect)] [get-clip-rect (-> Rect)] + [get-aspect-ratio (-> (U Nonnegative-Real #f))] + [get-area-bounds-rect (-> Rect)] [get-render-tasks (-> render-tasks)] [set-render-tasks (-> render-tasks Void)] [start-plot (-> Void)] @@ -125,6 +135,7 @@ [put-font-family (-> Font-Family Void)] [put-font-attribs (-> Nonnegative-Real (U #f String) Font-Family Void)] [put-text-foreground (-> Plot-Color Void)] + [put-arrow-head (-> (U (List '= Nonnegative-Real) Nonnegative-Real) Nonnegative-Real Void)] [reset-drawing-params (-> Void)] [put-lines (-> (Listof (Vectorof Real)) Void)] [put-line (-> (Vectorof Real) (Vectorof Real) Void)] @@ -132,25 +143,26 @@ [put-rect (-> Rect Void)] [put-text (->* [String (Vectorof Real)] [Anchor Real Real Boolean Integer] Void)] [put-glyphs (->* [(Listof (Vectorof Real)) Point-Sym Nonnegative-Real] [Integer] Void)] - [put-arrow (-> (Vectorof Real) (Vectorof Real) Void)] + [put-arrow (->* ((Vectorof Real) (Vectorof Real)) (Boolean) Void)] + [get-plot-metrics-functions (-> Plot-Metrics-Functions)] )) (: 3d-plot-area% 3D-Plot-Area%) (define 3d-plot-area% (class object% - (init-field bounds-rect rx-ticks rx-far-ticks ry-ticks ry-far-ticks rz-ticks rz-far-ticks) - (init-field dc dc-x-min dc-y-min dc-x-size dc-y-size) + (init-field bounds-rect rx-ticks rx-far-ticks ry-ticks ry-far-ticks rz-ticks rz-far-ticks legend) + (init-field dc dc-x-min dc-y-min dc-x-size dc-y-size aspect-ratio) (super-new) - + (: pd (Instance Plot-Device%)) (define pd (make-object plot-device% dc dc-x-min dc-y-min dc-x-size dc-y-size)) (send pd reset-drawing-params) - + (: char-height Exact-Rational) (: half-char-height Exact-Rational) (define char-height (send pd get-char-height)) (define half-char-height (* 1/2 char-height)) - + (define: x-min : Real 0) (define: x-max : Real 0) (define: y-min : Real 0) @@ -158,7 +170,7 @@ (define: z-min : Real 0) (define: z-max : Real 0) (let () - (match-define (vector (ivl x-min-val x-max-val) + (match-define (vector (ivl x-min-val x-max-val) (ivl y-min-val y-max-val) (ivl z-min-val z-max-val)) bounds-rect) @@ -171,7 +183,7 @@ (set! z-max z-max-val)] [else (raise-argument-error '3d-plot-area% "rect-known?" bounds-rect)])) - + (: x-size Real) (: y-size Real) (: z-size Real) @@ -184,7 +196,7 @@ (define x-mid (* 1/2 (+ x-min x-max))) (define y-mid (* 1/2 (+ y-min y-max))) (define z-mid (* 1/2 (+ z-min z-max))) - + (: clipping? Boolean) (: clip-x-min Real) (: clip-x-max Real) @@ -199,7 +211,7 @@ (define clip-y-max y-max) (define clip-z-min z-min) (define clip-z-max z-max) - + (define/public (put-clip-rect rect) (match-define (vector (ivl rx-min rx-max) (ivl ry-min ry-max) (ivl rz-min rz-max)) rect) (define cx-min (if rx-min (max* x-min rx-min) x-min)) @@ -221,30 +233,30 @@ (set! clip-z-min cz-min) (set! clip-z-max cz-max)) (set! clipping? #t)) - + (define/public (clear-clip-rect) (set! clipping? #f)) - + (: in-bounds? (-> (Vectorof Real) Boolean)) (define/private (in-bounds? v) (or (not clipping?) (point-in-bounds? v clip-x-min clip-x-max clip-y-min clip-y-max clip-z-min clip-z-max))) - + (define/public (get-x-ticks) x-ticks) (define/public (get-y-ticks) y-ticks) (define/public (get-z-ticks) z-ticks) (define/public (get-x-far-ticks) x-far-ticks) (define/public (get-y-far-ticks) y-far-ticks) (define/public (get-z-far-ticks) z-far-ticks) - + (define/public (get-bounds-rect) bounds-rect) - + (define/public (get-clip-rect) (if clipping? (vector (ivl clip-x-min clip-x-max) (ivl clip-y-min clip-y-max) (ivl clip-z-min clip-z-max)) bounds-rect)) - + (: angle Real) (: altitude Real) (: theta Real) @@ -255,57 +267,67 @@ ;; or 270, the x/y/z tick labels are drawn on the left side. (define theta (+ (degrees->radians angle) 0.00001)) (define rho (degrees->radians altitude)) - + ;; There are four coordinate systems: ;; 1. Plot coordinates (original, user-facing coordinate system) ;; 2. Normalized coordinates (from plot coordinates: for each axis: transform, center, and scale ;; to [-0.5,0.5]) - these are always flvectors ;; 3. View coordinates (from normalized coordinates: rotate) ;; 4. Device context coordinates (from view coordinates: project to 2D) - + (define: fx : (-> Real Real) (λ ([x : Real]) x)) + (define: gx : (-> Real Real) (λ ([x : Real]) x)) (define: fy : (-> Real Real) (λ ([y : Real]) y)) + (define: gy : (-> Real Real) (λ ([y : Real]) y)) (define: fz : (-> Real Real) (λ ([z : Real]) z)) + (define: gz : (-> Real Real) (λ ([z : Real]) z)) (match-let - ([(invertible-function fx-val _) (apply-axis-transform (plot-x-transform) x-min x-max)] - [(invertible-function fy-val _) (apply-axis-transform (plot-y-transform) y-min y-max)] - [(invertible-function fz-val _) (apply-axis-transform (plot-z-transform) z-min z-max)]) + ([(invertible-function fx-val gx-val) (apply-axis-transform (plot-x-transform) x-min x-max)] + [(invertible-function fy-val gy-val) (apply-axis-transform (plot-y-transform) y-min y-max)] + [(invertible-function fz-val gz-val) (apply-axis-transform (plot-z-transform) z-min z-max)]) (set! fx fx-val) + (set! gx gx-val) (set! fy fy-val) - (set! fz fz-val)) - + (set! gy gy-val) + (set! fz fz-val) + (set! gz gz-val)) + (: identity-transforms? Boolean) (define identity-transforms? (and (equal? (plot-x-transform) id-transform) (equal? (plot-y-transform) id-transform) (equal? (plot-z-transform) id-transform))) - + (: plot->norm (-> (Vectorof Real) FlVector)) (define/private (plot->norm v) - (if identity-transforms? - (match v - [(vector (? rational? x) (? rational? y) (? rational? z)) + (match v + [(vector (? rational? x) (? rational? y) (? rational? z)) + (if identity-transforms? (flvector (fl (/ (- x x-mid) x-size)) (fl (/ (- y y-mid) y-size)) - (fl (/ (- z z-mid) z-size)))] - [(vector x y z) - (flvector +nan.0 +nan.0 +nan.0)]) - (match v - [(vector (? rational? x) (? rational? y) (? rational? z)) + (fl (/ (- z z-mid) z-size))) (let ([x (fx x)] [y (fy y)] [z (fz z)]) (flvector (if (rational? x) (fl (/ (- (inexact->exact x) x-mid) x-size)) +nan.0) (if (rational? y) (fl (/ (- (inexact->exact y) y-mid) y-size)) +nan.0) - (if (rational? z) (fl (/ (- (inexact->exact z) z-mid) z-size)) +nan.0)))] - [(vector x y z) - (flvector +nan.0 +nan.0 +nan.0)]))) - + (if (rational? z) (fl (/ (- (inexact->exact z) z-mid) z-size)) +nan.0))))] + [(vector x y z) + (flvector +nan.0 +nan.0 +nan.0)])) + (: norm->plot (-> FlVector (Vectorof Real))) + (define (norm->plot v) + (for/vector : (Vectorof Real) + ([c (in-flvector v)] + [m (in-list (list x-mid y-mid z-mid))] + [s (in-list (list x-size y-size z-size))] + [g (in-list (list gx gy gz))]) + (g (+ (* c s) m)))) + (: rotate-theta-matrix M3) (: rotate-rho-matrix M3) (: rotation-matrix M3) (define rotate-theta-matrix (m3-rotate-z theta)) (define rotate-rho-matrix (m3-rotate-x rho)) (define rotation-matrix (m3* rotate-rho-matrix rotate-theta-matrix)) - + (: norm->view (-> FlVector FlVector)) (: plot->view (-> (Vectorof Real) FlVector)) (: plot->view/no-rho (-> (Vectorof Real) FlVector)) @@ -316,17 +338,17 @@ (define/private (plot->view/no-rho v) (m3-apply rotate-theta-matrix (plot->norm v))) (define/private (norm->view/no-rho v) (m3-apply rotate-theta-matrix v)) (define/private (rotate/rho v) (m3-apply rotate-rho-matrix v)) - + (: unrotation-matrix M3) (: view->norm (-> FlVector FlVector)) (define unrotation-matrix (m3-transpose rotation-matrix)) (define/private (view->norm v) (m3-apply unrotation-matrix v)) - + (: plot->dc (-> (Vectorof Real) (Vectorof Real))) - (: norm->dc (-> FlVector (Vectorof Real))) - (define/private (plot->dc v) (view->dc (plot->view v))) + (: norm->dc (-> FlVector (Vectorof Real))) + (define (plot->dc v) (view->dc (plot->view v))) (define/private (norm->dc v) (view->dc (norm->view v))) - + (define: view-x-size : Real 0) (define: view-y-size : Real 0) (define: view-z-size : Real 0) @@ -343,7 +365,7 @@ (set! view-x-size view-x-size-val) (set! view-y-size view-y-size-val) (set! view-z-size view-z-size-val)) - + (: make-view->dc (-> Real Real Real Real (-> FlVector (Vectorof Real)))) (define/private (make-view->dc left right top bottom) (define area-x-min left) @@ -363,49 +385,107 @@ (define z (flvector-ref v 2)) (vector (fl+ area-x-mid (fl* x area-per-view-x)) (fl- area-y-mid (fl* z area-per-view-z)))))) - + + (: dc->view (-> (Vectorof Real) FlVector)) + (define (dc->view v) + (match-define (vector x y) v) + (define area-x-mid (* 1/2 (+ area-x-min area-x-max))) + (define area-y-mid (* 1/2 (+ area-y-min area-y-max))) + (define area-per-view-x (/ (- area-x-max area-x-min) view-x-size)) + (define area-per-view-z (/ (- area-y-max area-y-min) view-z-size)) + (flvector (fl (/ (- x area-x-mid) area-per-view-x)) + 0.0 + (fl (/ (- area-y-mid y) area-per-view-z)))) + + (: dc->plot (-> (Vectorof Real) (Vectorof Real))) + (define (dc->plot v) + (norm->plot (view->norm (dc->view v)))) + + (: title-margin Real) + (define title-margin + (let ([title (plot-title)]) + (cond [(and (plot-decorations?) title) + (if (pict? title) + (+ (pict-height title) (* 1/2 char-height)) + (* 3/2 char-height))] + [else 0]))) + + (: init-left-margin Real) + (: init-right-margin Real) (: init-top-margin Real) - (define init-top-margin (if (and (plot-decorations?) (plot-title)) (* 3/2 char-height) 0)) - + (: init-bottom-margin Real) + (define-values (init-left-margin init-right-margin init-top-margin init-bottom-margin) + (let* ([legend-anchor (plot-legend-anchor)] + [legend-rect (and (outside-anchor? legend-anchor) + (not (empty? legend)) + (send pd calculate-legend-rect + legend + (vector (ivl dc-x-min (+ dc-x-min dc-x-size)) + (ivl dc-y-min (+ dc-y-min dc-y-size))) + (legend-anchor->anchor legend-anchor) + (plot-legend-padding)))] + [none (λ () (values 0 0 title-margin 0))]) + (cond + [legend-rect + (match-define (vector (ivl x- x+) (ivl y- y+)) legend-rect) + (define gap (* 2 (pen-gap))) + (define width (if (and x- x+) (+ gap (- x+ x-)) 0)) + (define height (if (and y- y+) (+ gap (- y+ y-)) 0)) + (define remaining-x-size (- dc-x-size width)) + (define remaining-y-size (- dc-y-size title-margin height)) + (case legend-anchor + [(outside-top-left outside-top outside-top-right outside-global-top) + (if (< remaining-y-size 0) (none) (values 0 0 (+ title-margin height) 0))] + [(outside-left-top outside-left outside-left-bottom) + (if (< remaining-x-size 0) (none) (values width 0 title-margin 0))] + [(outside-right-top outside-right outside-right-bottom) + (if (< remaining-x-size 0) (none) (values 0 width title-margin 0))] + [(outside-bottom-left outside-bottom outside-bottom-right) + (if (< remaining-y-size 0) (none) (values 0 0 title-margin height))] + ;; unreachable code ... + [else (none)])] + [else (none)]))) + ;; Initial view->dc (: view->dc (-> FlVector (Vectorof Real))) - (define view->dc (make-view->dc 0 0 init-top-margin 0)) - + (define view->dc (make-view->dc init-left-margin init-right-margin + init-top-margin init-bottom-margin)) + (: x-axis-angle (-> Real)) (define (x-axis-angle) (match-define (vector dx dy) (v- (norm->dc (flvector 0.5 0.0 0.0)) (norm->dc (flvector -0.5 0.0 0.0)))) (- (atan2 (- dy) dx))) - + (: y-axis-angle (-> Real)) (define (y-axis-angle) (match-define (vector dx dy) (v- (norm->dc (flvector 0.0 0.5 0.0)) (norm->dc (flvector 0.0 -0.5 0.0)))) (- (atan2 (- dy) dx))) - + (: x-axis-dir (-> (Vectorof Real))) (define (x-axis-dir) (vnormalize (v- (norm->dc (flvector 0.5 0.0 0.0)) (norm->dc (flvector -0.5 0.0 0.0))))) - + (: y-axis-dir (-> (Vectorof Real))) (define (y-axis-dir) (vnormalize (v- (norm->dc (flvector 0.0 0.5 0.0)) (norm->dc (flvector 0.0 -0.5 0.0))))) - + ;; =============================================================================================== ;; Tick and label constants - + (: tick-radius Real) (: half-tick-radius Real) (define tick-radius (* 1/2 (plot-tick-size))) (define half-tick-radius (* 1/2 tick-radius)) - + (: x-axis-y-min? Boolean) (: y-axis-x-min? Boolean) (define x-axis-y-min? ((cos theta) . >= . 0)) ; #t iff x near labels should be drawn at y-min (define y-axis-x-min? ((sin theta) . >= . 0)) ; #t iff y near labels should be drawn at x-min - + (: x-axis-y Real) (: y-axis-x Real) (: z-axis-x Real) @@ -414,7 +494,7 @@ (define y-axis-x (if y-axis-x-min? x-min x-max)) (define z-axis-x (if x-axis-y-min? x-min x-max)) (define z-axis-y (if y-axis-x-min? y-max y-min)) - + (: x-far-axis-y Real) (: y-far-axis-x Real) (: z-far-axis-x Real) @@ -423,7 +503,7 @@ (define y-far-axis-x (if y-axis-x-min? x-max x-min)) (define z-far-axis-x (if x-axis-y-min? x-max x-min)) (define z-far-axis-y (if y-axis-x-min? y-min y-max)) - + (: x-axis-norm-y Flonum) (: y-axis-norm-x Flonum) (: z-axis-norm-x Flonum) @@ -432,7 +512,7 @@ (define y-axis-norm-x (if y-axis-x-min? -0.5 0.5)) (define z-axis-norm-x (if x-axis-y-min? -0.5 0.5)) (define z-axis-norm-y (if y-axis-x-min? 0.5 -0.5)) - + (: x-far-axis-norm-y Flonum) (: y-far-axis-norm-x Flonum) (: z-far-axis-norm-x Flonum) @@ -441,29 +521,29 @@ (define y-far-axis-norm-x (if y-axis-x-min? 0.5 -0.5)) (define z-far-axis-norm-x (if x-axis-y-min? 0.5 -0.5)) (define z-far-axis-norm-y (if y-axis-x-min? -0.5 0.5)) - + (: near-dist^2 Real) (define near-dist^2 (sqr (* 3 (plot-line-width)))) - + (: vnear? (-> (Vectorof Real) (Vectorof Real) Boolean)) (define/private (vnear? v1 v2) ((vmag^2 (v- (plot->dc v1) (plot->dc v2))) . <= . near-dist^2)) - + (: x-ticks-near? (-> Real (-> pre-tick pre-tick Boolean))) (define/private ((x-ticks-near? y) t1 t2) (vnear? (vector (pre-tick-value t1) y z-min) (vector (pre-tick-value t2) y z-min))) - + (: y-ticks-near? (-> Real (-> pre-tick pre-tick Boolean))) (define/private ((y-ticks-near? x) t1 t2) (vnear? (vector x (pre-tick-value t1) z-min) (vector x (pre-tick-value t2) z-min))) - + (: z-ticks-near? (-> Real Real (-> pre-tick pre-tick Boolean))) (define/private ((z-ticks-near? x y) t1 t2) (vnear? (vector x y (pre-tick-value t1)) (vector x y (pre-tick-value t2)))) - + (: x-ticks (Listof tick)) (: y-ticks (Listof tick)) (: z-ticks (Listof tick)) @@ -479,7 +559,7 @@ (collapse-ticks (filter (λ ([t : tick]) (<= z-min (pre-tick-value t) z-max)) (map tick-inexact->exact rz-ticks)) (z-ticks-near? z-axis-x z-axis-y))) - + (: x-far-ticks (Listof tick)) (: y-far-ticks (Listof tick)) (: z-far-ticks (Listof tick)) @@ -495,18 +575,18 @@ (collapse-ticks (filter (λ ([t : tick]) (<= z-min (pre-tick-value t) z-max)) (map tick-inexact->exact rz-far-ticks)) (z-ticks-near? z-far-axis-x z-far-axis-y))) - + ;; =============================================================================================== ;; Tick and label parameters, and fixpoint margin computation - + ;; From here through "All parameters" are functions that compute *just the parameters* of ticks ;; and labels that will be drawn on the plot. We have to separate computing parameters from ;; actually drawing the ticks and labels so we can solve for the plot margins using a fixpoint ;; computation. See ../common/draw.rkt for more explanation. (Search for 'margin-fixpoint'.) - + ;; ----------------------------------------------------------------------------------------------- ;; Tick parameters - + (: x-tick-value->view (-> Real FlVector)) (: y-tick-value->view (-> Real FlVector)) (: x-far-tick-value->view (-> Real FlVector)) @@ -515,7 +595,7 @@ (define/private (y-tick-value->view y) (plot->view (vector y-axis-x y z-min))) (define/private (x-far-tick-value->view x) (plot->view (vector x x-far-axis-y z-min))) (define/private (y-far-tick-value->view y) (plot->view (vector y-far-axis-x y z-min))) - + (: x-tick-value->dc (-> Real (Vectorof Real))) (: y-tick-value->dc (-> Real (Vectorof Real))) (: z-tick-value->dc (-> Real (Vectorof Real))) @@ -528,65 +608,83 @@ (define/private (x-far-tick-value->dc x) (view->dc (x-far-tick-value->view x))) (define/private (y-far-tick-value->dc y) (view->dc (y-far-tick-value->view y))) (define/private (z-far-tick-value->dc z) (plot->dc (vector z-far-axis-x z-far-axis-y z))) - + (: get-tick-params (-> (Listof tick) (-> Real (Vectorof Real)) Real (Listof Tick-Params))) (define/private (get-tick-params ts tick-value->dc angle) (for/list : (Listof Tick-Params) ([t (in-list ts)]) (match-define (tick p major? _) t) (list major? (tick-value->dc p) (if major? tick-radius half-tick-radius) angle))) - + (: get-x-tick-params (-> (Listof Tick-Params))) (define (get-x-tick-params) (if (plot-x-axis?) (get-tick-params x-ticks (λ ([x : Real]) (x-tick-value->dc x)) (y-axis-angle)) empty)) - + (: get-y-tick-params (-> (Listof Tick-Params))) (define (get-y-tick-params) (if (plot-y-axis?) (get-tick-params y-ticks (λ ([y : Real]) (y-tick-value->dc y)) (x-axis-angle)) empty)) - + (: get-z-tick-params (-> (Listof Tick-Params))) (define (get-z-tick-params) (if (plot-z-axis?) (get-tick-params z-ticks (λ ([z : Real]) (z-tick-value->dc z)) 0) empty)) - + (: get-x-far-tick-params (-> (Listof Tick-Params))) (define (get-x-far-tick-params) (if (plot-x-far-axis?) (get-tick-params x-far-ticks (λ ([x : Real]) (x-far-tick-value->dc x)) (y-axis-angle)) empty)) - + (: get-y-far-tick-params (-> (Listof Tick-Params))) (define (get-y-far-tick-params) (if (plot-y-far-axis?) (get-tick-params y-far-ticks (λ ([y : Real]) (y-far-tick-value->dc y)) (x-axis-angle)) empty)) - + (: get-z-far-tick-params (-> (Listof Tick-Params))) (define (get-z-far-tick-params) (if (plot-z-far-axis?) (get-tick-params z-far-ticks (λ ([z : Real]) (z-far-tick-value->dc z)) 0) empty)) - + ;; ----------------------------------------------------------------------------------------------- ;; Tick label parameters - + + (: draw-x-tick-labels? Boolean) + (: draw-y-tick-labels? Boolean) + (: draw-z-tick-labels? Boolean) (: draw-x-far-tick-labels? Boolean) (: draw-y-far-tick-labels? Boolean) (: draw-z-far-tick-labels? Boolean) - (define draw-x-far-tick-labels? (not (and (plot-x-axis?) (equal? x-ticks x-far-ticks)))) - (define draw-y-far-tick-labels? (not (and (plot-y-axis?) (equal? y-ticks y-far-ticks)))) - (define draw-z-far-tick-labels? (not (and (plot-z-axis?) (equal? z-ticks z-far-ticks)))) - + (define draw-x-tick-labels? (plot-x-tick-labels?)) + (define draw-y-tick-labels? (plot-y-tick-labels?)) + (define draw-z-tick-labels? (plot-z-tick-labels?)) + (define draw-x-far-tick-labels? + (let ((flag (plot-x-far-tick-labels?))) + (if (eq? flag 'auto) + (and (plot-x-axis?) (equal? x-ticks x-far-ticks)) + flag))) + (define draw-y-far-tick-labels? + (let ((flag (plot-y-far-tick-labels?))) + (if (eq? flag 'auto) + (and (plot-y-axis?) (equal? y-ticks y-far-ticks)) + flag))) + (define draw-z-far-tick-labels? + (let ((flag (plot-z-far-tick-labels?))) + (if (eq? flag 'auto) + (and (plot-z-axis?) (equal? z-ticks z-far-ticks)) + flag))) + (: sort-ticks (-> (Listof tick) (-> Real FlVector) (Listof tick))) (define/private (sort-ticks ts tick-value->view) ((inst sort tick Flonum) ts fl> #:key (λ ([t : tick]) (flvector-ref (tick-value->view (pre-tick-value t)) 2)) #:cache-keys? #t)) - + (: x-tick-label-anchor Anchor) (define x-tick-label-anchor (let ([s (sin theta)]) @@ -595,7 +693,7 @@ [(s . < . (sin (degrees->radians 22.5))) 'top] [(s . < . (sin (degrees->radians 67.5))) (if x-axis-y-min? 'top-left 'top-right)] [else (if x-axis-y-min? 'top-left 'top-right)]))) - + (: y-tick-label-anchor Anchor) (define y-tick-label-anchor (let ([c (cos theta)]) @@ -604,17 +702,17 @@ [(c . > . (cos (degrees->radians 112.5))) 'top] [(c . > . (cos (degrees->radians 157.5))) (if y-axis-x-min? 'top-left 'top-right)] [else (if y-axis-x-min? 'top-left 'top-right)]))) - + (: z-tick-label-anchor Anchor) (define z-tick-label-anchor 'right) - + (: x-far-tick-label-anchor Anchor) (: y-far-tick-label-anchor Anchor) (: z-far-tick-label-anchor Anchor) (define x-far-tick-label-anchor (opposite-anchor x-tick-label-anchor)) (define y-far-tick-label-anchor (opposite-anchor y-tick-label-anchor)) (define z-far-tick-label-anchor 'left) - + (: get-tick-label-params (-> (Listof tick) (-> Real (Vectorof Real)) (Vectorof Real) Anchor (Listof Label-Params))) (define/private (get-tick-label-params ts tick-value->dc offset-dir anchor) @@ -622,36 +720,36 @@ (for/list : (Listof Label-Params) ([t (in-list ts)] #:when (pre-tick-major? t)) (match-define (tick x _ label) t) (list label (v+ (tick-value->dc x) (v* offset-dir dist)) anchor 0))) - + (: get-x-tick-label-params (-> (Listof Label-Params))) (define (get-x-tick-label-params) - (if (plot-x-axis?) + (if (and (plot-x-axis?) draw-x-tick-labels?) (let ([offset (if x-axis-y-min? (vneg (y-axis-dir)) (y-axis-dir))]) (get-tick-label-params (sort-ticks x-ticks (λ ([x : Real]) (x-tick-value->view x))) (λ ([x : Real]) (x-tick-value->dc x)) offset x-tick-label-anchor)) empty)) - + (: get-y-tick-label-params (-> (Listof Label-Params))) (define (get-y-tick-label-params) - (if (plot-y-axis?) + (if (and (plot-y-axis?) draw-y-tick-labels?) (let ([offset (if y-axis-x-min? (vneg (x-axis-dir)) (x-axis-dir))]) (get-tick-label-params (sort-ticks y-ticks (λ ([y : Real]) (y-tick-value->view y))) (λ ([y : Real]) (y-tick-value->dc y)) offset y-tick-label-anchor)) empty)) - + (: get-z-tick-label-params (-> (Listof Label-Params))) (define (get-z-tick-label-params) - (if (plot-z-axis?) + (if (and (plot-z-axis?) draw-z-tick-labels?) (get-tick-label-params z-ticks (λ ([z : Real]) (z-tick-value->dc z)) #(-1 0) z-tick-label-anchor) empty)) - + (: get-x-far-tick-label-params (-> (Listof Label-Params))) (define (get-x-far-tick-label-params) (if (and (plot-x-far-axis?) draw-x-far-tick-labels?) @@ -662,7 +760,7 @@ offset x-far-tick-label-anchor)) empty)) - + (: get-y-far-tick-label-params (-> (Listof Label-Params))) (define (get-y-far-tick-label-params) (if (and (plot-y-far-axis?) draw-y-far-tick-labels?) @@ -673,7 +771,7 @@ offset y-far-tick-label-anchor)) empty)) - + (: get-z-far-tick-label-params (-> (Listof Label-Params))) (define (get-z-far-tick-label-params) (if (and (plot-z-far-axis?) draw-z-far-tick-labels?) @@ -682,16 +780,16 @@ #(1 0) z-far-tick-label-anchor) empty)) - + ;; ----------------------------------------------------------------------------------------------- ;; Axis label parameters - + (: max-tick-offset (-> (Listof tick) Real)) (define/private (max-tick-offset ts) (cond [(empty? ts) 0] [(ormap pre-tick-major? ts) (+ (pen-gap) tick-radius)] [else (+ (pen-gap) (* 1/4 (plot-tick-size)))])) - + (: max-x-tick-offset Real) (: max-y-tick-offset Real) (: max-x-far-tick-offset Real) @@ -700,16 +798,16 @@ (define max-y-tick-offset (if (plot-y-axis?) (max-tick-offset y-ticks) 0)) (define max-x-far-tick-offset (if (plot-x-far-axis?) (max-tick-offset x-far-ticks) 0)) (define max-y-far-tick-offset (if (plot-y-far-axis?) (max-tick-offset y-far-ticks) 0)) - + (: max-tick-label-height (-> (Listof tick) Real)) (define/private (max-tick-label-height ts) (if (ormap pre-tick-major? ts) char-height 0)) - + (: max-tick-label-width (-> (Listof tick) Real)) (define/private (max-tick-label-width ts) (apply max 0 (for/list : (Listof Real) ([t (in-list ts)] #:when (pre-tick-major? t)) (send pd get-text-width (tick-label t))))) - + (: max-x-tick-label-width Real) (: max-y-tick-label-width Real) (: max-z-tick-label-width Real) @@ -722,7 +820,7 @@ (define max-x-tick-label-height (max-tick-label-height x-ticks)) (define max-y-tick-label-height (max-tick-label-height y-ticks)) (define max-z-tick-label-height (max-tick-label-height z-ticks)) - + (: max-x-far-tick-label-width Real) (: max-y-far-tick-label-width Real) (: max-z-far-tick-label-width Real) @@ -735,81 +833,81 @@ (define max-x-far-tick-label-height (max-tick-label-height x-far-ticks)) (define max-y-far-tick-label-height (max-tick-label-height y-far-ticks)) (define max-z-far-tick-label-height (max-tick-label-height z-far-ticks)) - + (: max-tick-label-diag (-> (Vectorof Real) Real Real Real)) (define/private (max-tick-label-diag axis-dc-dir max-tick-label-width max-tick-label-height) (match-define (vector dx dy) axis-dc-dir) (+ (* (abs dx) max-tick-label-width) (* (abs dy) max-tick-label-height))) - + (: max-x-tick-label-diag (-> Real)) (define (max-x-tick-label-diag) - (if (plot-x-axis?) + (if (and (plot-x-axis?) draw-x-tick-labels?) (max-tick-label-diag (y-axis-dir) max-x-tick-label-width max-x-tick-label-height) 0)) - + (: max-y-tick-label-diag (-> Real)) (define (max-y-tick-label-diag) - (if (plot-y-axis?) + (if (and (plot-y-axis?) draw-y-far-tick-labels?) (max-tick-label-diag (x-axis-dir) max-y-tick-label-width max-y-tick-label-height) 0)) - + (: max-x-far-tick-label-diag (-> Real)) (define (max-x-far-tick-label-diag) (if (and (plot-x-far-axis?) draw-x-far-tick-labels?) (max-tick-label-diag (y-axis-dir) max-x-far-tick-label-width max-x-far-tick-label-height) 0)) - + (: max-y-far-tick-label-diag (-> Real)) (define (max-y-far-tick-label-diag) (if (and (plot-y-far-axis?) draw-y-far-tick-labels?) (max-tick-label-diag (x-axis-dir) max-y-far-tick-label-width max-y-far-tick-label-height) 0)) - + (: get-x-label-params (-> Label-Params)) (define (get-x-label-params) (define v0 (norm->dc (flvector 0.0 x-axis-norm-y -0.5))) (define dist (+ max-x-tick-offset (max-x-tick-label-diag) half-char-height)) (list (plot-x-label) (v+ v0 (v* (y-axis-dir) (if x-axis-y-min? (- dist) dist))) 'top (- (if x-axis-y-min? 0 pi) (x-axis-angle)))) - + (: get-y-label-params (-> Label-Params)) (define (get-y-label-params) (define v0 (norm->dc (flvector y-axis-norm-x 0.0 -0.5))) (define dist (+ max-y-tick-offset (max-y-tick-label-diag) half-char-height)) (list (plot-y-label) (v+ v0 (v* (x-axis-dir) (if y-axis-x-min? (- dist) dist))) 'top (- (if y-axis-x-min? pi 0) (y-axis-angle)))) - + (: get-z-label-params (-> Label-Params)) (define (get-z-label-params) (list (plot-z-label) (v+ (plot->dc (vector z-axis-x z-axis-y z-max)) (vector 0 (- half-char-height))) 'bottom-left 0)) - + (: get-x-far-label-params (-> Label-Params)) (define (get-x-far-label-params) (define v0 (norm->dc (flvector 0.0 x-far-axis-norm-y -0.5))) (define dist (+ max-x-far-tick-offset (max-x-far-tick-label-diag) half-char-height)) (list (plot-x-far-label) (v+ v0 (v* (y-axis-dir) (if x-axis-y-min? dist (- dist)))) 'bottom (- (if x-axis-y-min? 0 pi) (x-axis-angle)))) - + (: get-y-far-label-params (-> Label-Params)) (define (get-y-far-label-params) (define v0 (norm->dc (flvector y-far-axis-norm-x 0.0 -0.5))) (define dist (+ max-y-far-tick-offset (max-y-far-tick-label-diag) half-char-height)) (list (plot-y-far-label) (v+ v0 (v* (x-axis-dir) (if y-axis-x-min? dist (- dist)))) 'bottom (- (if y-axis-x-min? pi 0) (y-axis-angle)))) - + (: get-z-far-label-params (-> Label-Params)) (define (get-z-far-label-params) (list (plot-z-far-label) (v+ (plot->dc (vector z-far-axis-x z-far-axis-y z-max)) (vector 0 (- half-char-height))) 'bottom-right 0)) - + ;; ----------------------------------------------------------------------------------------------- ;; All parameters - + ;; Within each get-back-* or get-front-*, the parameters are ordered (roughly) back-to-front - + (: get-back-label-params (-> (Listof Label-Params))) (define (get-back-label-params) (if (plot-decorations?) @@ -818,7 +916,7 @@ (get-x-far-tick-label-params) (get-y-far-tick-label-params)) empty)) - + (: get-front-label-params (-> (Listof Label-Params))) (define (get-front-label-params) (if (plot-decorations?) @@ -831,11 +929,11 @@ (if (plot-z-label) (list (get-z-label-params)) empty) (if (plot-z-far-label) (list (get-z-far-label-params)) empty)) empty)) - + (: get-all-label-params (-> (Listof Label-Params))) (define (get-all-label-params) (append (get-back-label-params) (get-front-label-params))) - + (: get-back-tick-params (-> (Listof Tick-Params))) (define (get-back-tick-params) (if (plot-decorations?) @@ -844,22 +942,22 @@ (if (plot-x-axis?) (get-x-tick-params) empty) (if (plot-y-axis?) (get-y-tick-params) empty)) empty)) - + (: get-front-tick-params (-> (Listof Tick-Params))) (define (get-front-tick-params) (if (plot-decorations?) (append (if (plot-z-axis?) (get-z-tick-params) empty) (if (plot-z-far-axis?) (get-z-far-tick-params) empty)) empty)) - + (: get-all-tick-params (-> (Listof Tick-Params))) (define (get-all-tick-params) (append (get-back-tick-params) (get-front-tick-params))) - - + + ;; ----------------------------------------------------------------------------------------------- ;; Fixpoint margin computation - + (: get-param-vs/set-view->dc! (-> Real Real Real Real (Listof (Vectorof Real)))) (define/private (get-param-vs/set-view->dc! left right top bottom) ;(printf "margins: ~v ~v ~v ~v~n" left right top bottom) @@ -876,20 +974,47 @@ (match-define (list _ v radius angle) p) (send pd get-tick-endpoints v radius angle)) (get-all-tick-params))))) - + (define: left : Real 0) (define: right : Real 0) (define: top : Real 0) (define: bottom : Real 0) - (let-values ([(left-val right-val top-val bottom-val) - (margin-fixpoint 0 dc-x-size 0 dc-y-size 0 0 init-top-margin 0 - (λ ([left : Real] [right : Real] [top : Real] [bottom : Real]) - (get-param-vs/set-view->dc! left right top bottom)))]) - (set! left left-val) - (set! right right-val) - (set! top top-val) - (set! bottom bottom-val)) - + (let ([inset (plot-inset)]) + (let-values ([(left-inset right-inset top-inset bottom-inset) + (if (list? inset) + (values (list-ref inset 0) (list-ref inset 1) (list-ref inset 2) (list-ref inset 3)) + (values inset inset inset inset))]) + (let-values ([(left-val right-val top-val bottom-val) + (margin-fixpoint + left-inset (- dc-x-size right-inset) + top-inset (- dc-y-size bottom-inset) + init-left-margin init-right-margin + init-top-margin init-bottom-margin + (λ ([left : Real] [right : Real] [top : Real] [bottom : Real]) + (get-param-vs/set-view->dc! left right top bottom)))]) + (set! left left-val) + (set! right right-val) + (set! top top-val) + (set! bottom bottom-val)))) + + ;; When an aspect ratio has been defined, adjust the margins so that the + ;; actual plot area maintains this ratio. + (when (real? aspect-ratio) + (let* ([area-width (- dc-x-size left right)] + [area-height (- dc-y-size top bottom)] + [desired-height (/ area-width (cast aspect-ratio Real))]) + (if (<= desired-height area-height) + (let ([adjust (/ (- area-height desired-height) 2)]) + (set! top (+ top adjust)) + (set! bottom (+ bottom adjust))) + (let* ([desired-width (* area-height (cast aspect-ratio Real))] + [adjust (/ (- area-width desired-width) 2)]) + (set! left (+ left adjust)) + (set! right (+ right adjust))))) + (set! view->dc (make-view->dc left right top bottom))) + + (define/public (get-aspect-ratio) aspect-ratio) + (: area-x-min Real) (: area-x-max Real) (: area-y-min Real) @@ -898,16 +1023,21 @@ (define area-x-max (- dc-x-size right)) (define area-y-min top) (define area-y-max (- dc-y-size bottom)) - + + (define/public (get-area-bounds-rect) + (vector (ivl area-x-min area-x-max) (ivl area-y-min area-y-max))) + ;; =============================================================================================== ;; Plot decoration - + (: draw-title (-> Void)) (define/private (draw-title) (define title (plot-title)) (when (and (plot-decorations?) title) - (send pd draw-text title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top))) - + (if (string? title) + (send pd draw-text title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top) + (send pd draw-pict title (vector (* 1/2 dc-x-size) (ann 0 Real)) 'top 0)))) + (: draw-back-axes (-> Void)) (define/private (draw-back-axes) (when (plot-decorations?) @@ -928,7 +1058,7 @@ (send pd draw-line (norm->dc (flvector y-far-axis-norm-x -0.5 -0.5)) (norm->dc (flvector y-far-axis-norm-x 0.5 -0.5)))))) - + (: draw-front-axes (-> Void)) (define/private (draw-front-axes) (when (plot-decorations?) @@ -941,37 +1071,39 @@ (send pd draw-line (norm->dc (flvector z-far-axis-norm-x z-far-axis-norm-y -0.5)) (norm->dc (flvector z-far-axis-norm-x z-far-axis-norm-y 0.5)))))) - + (: draw-ticks (-> (Listof Tick-Params) Void)) (define/private (draw-ticks ps) (for ([p (in-list ps)]) (match-define (list major? v r angle) p) (if major? (send pd set-major-pen) (send pd set-minor-pen)) (send pd draw-tick v r angle))) - + (: draw-labels (-> (Listof Label-Params) Void)) (define/private (draw-labels ps) (for ([p (in-list ps)]) (match-define (list label v anchor angle) p) - (when label - (send pd draw-text label v anchor angle 0 #t)))) - + (cond ((string? label) + (send pd draw-text label v anchor angle 0 #t)) + ((pict? label) + (send pd draw-pict label v anchor 0))))) + ;; =============================================================================================== ;; Render list and its BSP representation - - (: structural-shapes (HashTable Integer (Listof BSP-Shape))) + + (: structural-shapes (Immutable-HashTable Integer (Listof BSP-Shape))) ;; View-independent shapes, used to built initial BSP trees (define structural-shapes ((inst make-immutable-hash Integer (Listof BSP-Shape)))) - - (: detail-shapes (HashTable Integer (Listof BSP-Shape))) + + (: detail-shapes (Immutable-HashTable Integer (Listof BSP-Shape))) ;; View-dependent shapes, inserted into BSP trees before each refresh (define detail-shapes ((inst make-immutable-hash Integer (Listof BSP-Shape)))) - - (: bsp-trees (U #f (HashTable Integer BSP-Tree))) + + (: bsp-trees (Option (Immutable-HashTable Integer BSP-Tree))) ;; Structural shapes partitioned in BSP trees, indexed by drawing layer ;; #f means not in sync with structural-shapes (define bsp-trees #f) - + (: add-shape! (-> Integer BSP-Shape Void)) (define/private (add-shape! layer s) (cond [(structural-shape? s) @@ -981,38 +1113,38 @@ [else (define ss detail-shapes) (set! detail-shapes (hash-set ss layer (cons s (hash-ref ss layer (λ () empty)))))])) - + (: add-shapes! (-> Integer (Listof BSP-Shape) Void)) (define/private (add-shapes! layer ss) (for ([s (in-list ss)]) (add-shape! layer s))) - + (: clear-shapes! (-> Void)) (define/private (clear-shapes!) (set! structural-shapes ((inst make-immutable-hash Integer (Listof BSP-Shape)))) (set! detail-shapes ((inst make-immutable-hash Integer (Listof BSP-Shape)))) (set! bsp-trees #f)) - + (define/public (get-render-tasks) (define bsp-trees (sync-bsp-trees)) (render-tasks structural-shapes detail-shapes bsp-trees)) - + (define/public (set-render-tasks tasks) (match-define (render-tasks sts dts bsps) tasks) (set! structural-shapes sts) (set! detail-shapes dts) (set! bsp-trees bsps)) - - (: sync-bsp-trees (-> (HashTable Integer BSP-Tree))) + + (: sync-bsp-trees (-> (Immutable-HashTable Integer BSP-Tree))) (define/private (sync-bsp-trees) (define bsp-trees-val bsp-trees) (cond - [bsp-trees-val bsp-trees-val] + [bsp-trees-val bsp-trees-val] [else (define bsp-trees-val (build-bsp-trees structural-shapes)) (set! bsp-trees bsp-trees-val) bsp-trees-val])) - + (: adjust-detail-shapes (-> (Listof BSP-Shape) (Listof BSP-Shape))) (define/private (adjust-detail-shapes ss) (define d (view->norm view-dir)) @@ -1021,7 +1153,7 @@ (define dz (flvector-ref d 2)) (define area-size (fl (min (- area-x-max area-x-min) (- area-y-max area-y-min)))) - + (for/list : (Listof BSP-Shape) ([s (in-list ss)]) (match s [(points data vs) @@ -1034,7 +1166,7 @@ [(line data v1 v2) ;; Bring line forward by about half its apparent thickness (define frac (* 0.5 (/ pen-width area-size))) - (line data + (line data (flvector (+ (flvector-ref v1 0) (* dx frac)) (+ (flvector-ref v1 1) (* dy frac)) (+ (flvector-ref v1 2) (* dz frac))) @@ -1049,54 +1181,54 @@ (+ (flvector-ref v 1) (* dy frac)) (+ (flvector-ref v 2) (* dz frac)))))] [_ s]))) - + (: draw-all-shapes (-> Void)) (define/private (draw-all-shapes) (define bsp-trees (sync-bsp-trees)) - + (define adj-detail-shapes - (for/hasheq : (HashTable Integer (Listof BSP-Shape)) ([(layer ss) (in-hash detail-shapes)]) + (for/hasheq : (Immutable-HashTable Integer (Listof BSP-Shape)) ([(layer ss) (in-hash detail-shapes)]) (values layer (adjust-detail-shapes ss)))) - + (define all-shapes (walk-bsp-trees bsp-trees (view->norm view-dir) adj-detail-shapes)) - + (for* ([layer (in-list (sort (hash-keys all-shapes) >))] [s (in-list (hash-ref all-shapes layer))]) (draw-shape s))) - + ;; =============================================================================================== ;; Lighting - + (: light FlVector) ;; Light position, in normalized view coordinates: 5 units up, ~3 units back and to the left ;; (simulates non-noon daylight conditions) (define light (m3-apply rotate-rho-matrix (flvector (- -0.5 2.0) (- -0.5 2.0) (+ 0.5 5.0)))) - + ;; Do lighting only by direction so we can precalculate light-dir and half-dir ;; Conceptually, the viewer and light are at infinity - + (: light-dir FlVector) ;; Light direction (define light-dir (vector->flvector (vnormalize (flv3->v light)))) - + (: view-dir FlVector) ;; View direction, in normalized view coordinates (define view-dir (flvector 0.0 -1.0 0.0)) - + (: half-dir FlVector) ;; Blinn-Phong "half angle" direction (define half-dir (vector->flvector (vnormalize (v* (v+ (flv3->v light-dir) (flv3->v view-dir)) 0.5)))) - + (: diffuse-light? Boolean) (: specular-light? Boolean) (: ambient-light Flonum) (define diffuse-light? (plot3d-diffuse-light?)) (define specular-light? (plot3d-specular-light?)) (define ambient-light (fl (plot3d-ambient-light))) - + (: get-light-values (-> FlVector (Values Flonum Flonum))) (define/private (get-light-values normal) (cond @@ -1114,17 +1246,17 @@ ;; Blend ambient light with diffuse light, return specular as it is ;; As ambient-light -> 1.0, contribution of diffuse -> 0.0 (values (fl+ ambient-light (fl* (fl- 1.0 ambient-light) diff)) spec)])) - + (: illuminate (-> (List Real Real Real) Real Real (List Real Real Real))) (define/private (illuminate c diff spec) (match-define (list r g b) c) (list (+ (* r diff) spec) (+ (* g diff) spec) (+ (* b diff) spec))) - + ;; =============================================================================================== ;; Drawing - + (: draw-polygon (-> poly Void)) (define/private (draw-polygon s) (match-define (poly (poly-data alpha center @@ -1159,21 +1291,21 @@ [v2 (in-list vs)] [l (in-list ls)]) (when l (send pd draw-line v1 v2)))]))])) - + (: draw-line (-> line Void)) (define/private (draw-line s) (match-define (line (line-data alpha pen-color pen-width pen-style) v1 v2) s) (send pd set-alpha alpha) (send pd set-pen pen-color pen-width pen-style) (send pd draw-line (norm->dc v1) (norm->dc v2))) - + (: draw-lines (-> lines Void)) (define/private (draw-lines s) (match-define (lines (line-data alpha pen-color pen-width pen-style) vs) s) (send pd set-alpha alpha) (send pd set-pen pen-color pen-width pen-style) (send pd draw-lines (map (λ ([v : FlVector]) (norm->dc v)) vs))) - + (: draw-glyph (-> glyph-data (Listof FlVector) Void)) (define/private (draw-glyph data vs) (match-define (glyph-data alpha symbol size @@ -1184,7 +1316,7 @@ (send pd set-pen pen-color pen-width pen-style) (send pd set-brush brush-color brush-style) (send pd draw-glyphs (map (λ ([v : FlVector]) (norm->dc v)) vs) symbol size)) - + (: draw-text (-> text-data (Listof FlVector) Void)) (define/private (draw-text data vs) (match-define (text-data alpha anchor angle dist str font-size font-family color outline?) data) @@ -1193,25 +1325,26 @@ (send pd set-text-foreground color) (for ([v (in-list vs)]) (send pd draw-text str (norm->dc v) anchor angle dist outline?))) - + (: draw-arrow (-> arrow-data Void)) (define/private (draw-arrow data) - (match-define (arrow-data alpha v1 v2 outline-color pen-color pen-width pen-style) data) + (match-define (arrow-data alpha v1 v2 outline-color pen-color pen-width pen-style size-or-scale angle) data) (let ([v1 (norm->dc v1)] [v2 (norm->dc v2)]) (send pd set-alpha alpha) (send pd set-pen outline-color (+ 2 pen-width) 'solid) (send pd draw-arrow v1 v2) (send pd set-pen pen-color pen-width pen-style) + (send pd set-arrow-head size-or-scale angle) (send pd draw-arrow v1 v2))) - + (: draw-points (-> points Void)) (define/private (draw-points s) (match-define (points data vs) s) (cond [(glyph-data? data) (draw-glyph data vs)] [(text-data? data) (draw-text data vs)] [(arrow-data? data) (draw-arrow data)])) - + (: draw-shape (-> BSP-Shape Void)) (define/private (draw-shape s) (cond [(poly? s) (draw-polygon s)] @@ -1219,13 +1352,15 @@ [(lines? s) (draw-lines s)] [(points? s) (draw-points s)] [else (raise-argument-error 'draw-shape "known shape" s)])) - + ;; =============================================================================================== ;; Public drawing control (used by plot3d/dc) - + (define/public (start-plot) (send pd reset-drawing-params) (send pd clear) + (when (and (not (empty? legend)) (outside-anchor? (plot-legend-anchor))) + (draw-legend legend)) (draw-title) (draw-labels (get-back-label-params)) (draw-ticks (get-back-tick-params)) @@ -1234,95 +1369,113 @@ (vector (ivl (+ 1/2 (- area-x-min (plot-line-width))) (+ area-x-max (plot-line-width))) (ivl (+ 1/2 (- area-y-min (plot-line-width))) (+ area-y-max (plot-line-width))))) (clear-shapes!)) - + (define/public (start-renderer rend-bounds-rect) (reset-drawing-params) (put-clip-rect rend-bounds-rect)) - + (define/public (end-renderers) (clear-clip-rect) (draw-all-shapes) (send pd reset-drawing-params) (draw-front-axes) (draw-ticks (get-front-tick-params)) - (draw-labels (get-front-label-params))) - + (draw-labels (get-front-label-params)) + (when (and (not (empty? legend)) (inside-anchor? (plot-legend-anchor))) + (draw-legend legend))) + (define/public (draw-legend legend-entries) - (define gap-size (+ (pen-gap) tick-radius)) + (define outside? (outside-anchor? (plot-legend-anchor))) + (define gap-size (+ (pen-gap) (if outside? 0 tick-radius))) + (define-values (x-min x-max y-min y-max) + (if outside? + (values dc-x-min (+ dc-x-min dc-x-size) + (+ title-margin dc-y-min) (+ dc-y-min dc-y-size)) + (values area-x-min area-x-max area-y-min area-y-max))) (send pd draw-legend legend-entries - (vector (ivl (+ area-x-min gap-size) (- area-x-max gap-size)) - (ivl (+ area-y-min gap-size) (- area-y-max gap-size))))) - + (vector (ivl (+ x-min gap-size) (- x-max gap-size)) + (ivl (+ y-min gap-size) (- y-max gap-size))))) + (define/public (end-plot) (send pd restore-drawing-params)) - + ;; =============================================================================================== ;; Public drawing interface (used by renderers) - + ;; Drawing parameters - + (: alpha Nonnegative-Real) (define alpha 1) - + (: pen-color (List Real Real Real)) (: pen-width Nonnegative-Real) (: pen-style Plot-Pen-Style-Sym) (define pen-color '(0 0 0)) (define pen-width 1) (define pen-style 'solid) - + (: brush-color (List Real Real Real)) (: brush-style Plot-Brush-Style-Sym) (define brush-color '(255 255 255)) (define brush-style 'solid) - + (: background-color (List Real Real Real)) (define background-color '(255 255 255)) - + (: font-size Nonnegative-Real) (: font-face (U #f String)) (: font-family Font-Family) (define font-size 11) (define font-face #f) (define font-family 'roman) - + (: text-foreground (List Real Real Real)) (define text-foreground '(0 0 0)) - + + (: pa-arrow-head-size-or-scale (U (List '= Nonnegative-Real) Nonnegative-Real)) + (: pa-arrow-head-angle Nonnegative-Real) + (define pa-arrow-head-size-or-scale (arrow-head-size-or-scale)) + (define pa-arrow-head-angle (arrow-head-angle)) + + ;; Drawing parameter accessors - + (define/public (put-alpha a) (set! alpha a)) - + (define/public (put-pen color width style) (set! pen-color (->pen-color color)) (set! pen-width width) (set! pen-style (->pen-style style))) - + (define/public (put-major-pen [style 'solid]) (put-pen (plot-foreground) (plot-line-width) style)) - + (define/public (put-minor-pen [style 'solid]) (put-pen (plot-foreground) (* 1/2 (plot-line-width)) style)) - + (define/public (put-brush color style) (set! brush-color (->brush-color color)) (set! brush-style (->brush-style style))) - + (define/public (put-background color) (set! background-color (->brush-color color))) - + (define/public (put-font-size size) (set! font-size size)) (define/public (put-font-face face) (set! font-face face)) (define/public (put-font-family family) (set! font-family family)) - + (define/public (put-font-attribs size face family) (put-font-size size) (put-font-face face) (put-font-family family)) - + (define/public (put-text-foreground c) (set! text-foreground (->pen-color c))) - + + (define/public (put-arrow-head size-or-scale angle) + (set! pa-arrow-head-size-or-scale size-or-scale) + (set! pa-arrow-head-angle angle)) + (define/public (reset-drawing-params) (put-alpha (plot-foreground-alpha)) (put-pen (plot-foreground) (plot-line-width) 'solid) @@ -1330,9 +1483,9 @@ (put-background (plot-background)) (put-font-attribs (plot-font-size) (plot-font-face) (plot-font-family)) (put-text-foreground (plot-foreground))) - + ;; Drawing shapes - + (define/public (put-line v1 v2) (let ([v1 (exact-vector3d v1)] [v2 (exact-vector3d v2)]) @@ -1354,7 +1507,7 @@ (add-shape! plot3d-area-layer (lines (line-data alpha pen-color pen-width pen-style) (map (λ ([v : (Vectorof Real)]) (plot->norm v)) vs)))])))))) - + (define/public (put-lines vs) (for ([vs (in-list (exact-vector3d-sublists vs))]) (let ([vss (if clipping? @@ -1374,7 +1527,7 @@ (add-shape! plot3d-area-layer (lines (line-data alpha pen-color pen-width pen-style) (map (λ ([v : (Vectorof Real)]) (plot->norm v)) vs)))))])))) - + (define/public (put-polygon vs [face 'both] [ls (make-list (length vs) #t)]) (let-values ([(vs ls) (exact-polygon3d vs ls)]) (unless (empty? vs) @@ -1397,7 +1550,7 @@ pen-color pen-width pen-style brush-color brush-style face) norm-vs ls normal))))))) - + (define/public (put-rect r) (let ([r (if (rect-rational? r) (rect-meet r bounds-rect) r)]) (when (rect-rational? r) @@ -1420,7 +1573,7 @@ (define z-mid (* 0.5 (+ z-max z-min))) ;; Faces are a list of center, normal, then vertices (define faces - (list + (list ;; Bottom (z-min) face (list (flvector x-mid y-mid z-min) (flvector 0.0 0.0 -1.0) (flvector x-min y-min z-min) (flvector x-max y-min z-min) @@ -1453,7 +1606,7 @@ pen-color pen-width pen-style brush-color brush-style 'front) vs ls normal))))))) - + (define/public (put-text str v [anchor 'center] [angle 0] [dist 0] [outline? #f] [layer plot3d-area-layer]) (let ([v (exact-vector3d v)]) @@ -1461,7 +1614,7 @@ (add-shape! layer (points (text-data alpha anchor angle dist str font-size font-family text-foreground outline?) (list (plot->norm v))))))) - + (define/public (put-glyphs vs symbol size [layer plot3d-area-layer]) (let ([vs (filter (λ ([v : (U #f (Vectorof Real))]) (and v (in-bounds? v))) (map exact-vector3d vs))]) @@ -1472,18 +1625,49 @@ (map (λ ([v : (U #f (Vectorof Real))]) (plot->norm (assert v values))) vs)))))) - - (define/public (put-arrow v1 v2) + + (define/public (put-arrow v1 v2 [draw-outside? #f]) (let ([v1 (exact-vector3d v1)] [v2 (exact-vector3d v2)]) - (when (and v1 v2 (in-bounds? v1)) + (when (and v1 v2 (or draw-outside? (in-bounds? v1))) (cond [(in-bounds? v2) (define c (v* (v+ v1 v2) 1/2)) (define outline-color (->brush-color (plot-background))) (add-shape! plot3d-area-layer (points (arrow-data alpha (plot->norm v1) (plot->norm v2) - outline-color pen-color pen-width pen-style) + outline-color pen-color pen-width pen-style + pa-arrow-head-size-or-scale pa-arrow-head-angle) (list (plot->norm c))))] [else (put-line v1 v2)])))) + + (define/public (get-plot-metrics-functions) + (list (let ([bounds bounds-rect] + [vect : (Option (Immutable-Vector (Immutable-Vector Real Real) (Immutable-Vector Real Real) (Immutable-Vector Real Real))) #f]) + (λ () (or vect + (let ([new (vector-immutable (vector-immutable (assert (ivl-min (vector-ref bounds 0)) real?) + (assert (ivl-max (vector-ref bounds 0)) real?)) + (vector-immutable (assert (ivl-min (vector-ref bounds 1)) real?) + (assert (ivl-max (vector-ref bounds 1)) real?)) + (vector-immutable (assert (ivl-min (vector-ref bounds 2)) real?) + (assert (ivl-max (vector-ref bounds 2)) real?)))]) + (set! vect new) + new)))) + plot->dc + dc->plot + (let ([v : (Option (Vectorof Real)) #f]) + (λ () + (or v + (let* ([v1 (norm->plot (view->norm (flvector 0.0 0.0 0.0)))] + [v2 (norm->plot (view->norm (flvector 0.0 1.0 0.0)))] + [v3 (for/vector : (Vectorof Real) + ([i (in-vector v1)] + [j (in-vector v2)]) + (- j i))] + [norm (sqrt (assert (for/sum : Real ([i (in-vector v3)]) (* i i)) positive?))] + [ans (for/vector : (Vectorof Real) + ([i (in-vector v3)]) + (/ i norm))]) + (set! v ans) + ans)))))) )) ; end class diff --git a/plot-lib/plot/private/plot3d/point.rkt b/plot-lib/plot/private/plot3d/point.rkt index 53af4957..f66286ea 100644 --- a/plot-lib/plot/private/plot3d/point.rkt +++ b/plot-lib/plot/private/plot3d/point.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/class racket/list racket/match + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -20,16 +21,12 @@ Plot-Color Plot-Color Nonnegative-Real Nonnegative-Real Nonnegative-Real - (U String #f) 3D-Render-Proc)) -(define ((points3d-render-proc vs sym color fill-color size line-width alpha label) area) +(define ((points3d-render-proc vs sym color fill-color size line-width alpha) area) (send area put-alpha alpha) (send area put-pen color line-width 'solid) (send area put-brush fill-color 'solid) - (send area put-glyphs vs sym size) - - (cond [label (point-legend-entry label sym color fill-color size line-width)] - [else empty])) + (send area put-glyphs vs sym size)) (:: points3d (->* [(Sequenceof (Sequenceof Real))] @@ -45,7 +42,7 @@ #:size Nonnegative-Real #:line-width Nonnegative-Real #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (points3d vs #:x-min [x-min #f] #:x-max [x-max #f] @@ -74,10 +71,10 @@ [else (let* ([vs (sequence->listof-vector 'points3d vs 3)] [vs (filter vrational? vs)]) - (cond [(empty? vs) (renderer3d #f #f #f #f)] + (cond [(empty? vs) empty-renderer3d] [else (unless (= 0 x-jitter y-jitter z-jitter) - (points-apply-jitters vs (vector x-jitter y-jitter z-jitter) + (points-apply-jitters vs ((inst vector Nonnegative-Real) x-jitter y-jitter z-jitter) #:ivls (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)))) @@ -95,8 +92,9 @@ [fill-color (if (eq? fill-color 'auto) (->pen-color color) fill-color)]) (renderer3d (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun + (and label (λ (_) (point-legend-entry label sym color fill-color size line-width))) (points3d-render-proc vs sym color fill-color - size line-width alpha label)))]))])) + size line-width alpha)))]))])) ;; =================================================================================================== @@ -105,59 +103,53 @@ Positive-Integer (U Real 'auto 'normalized) Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 3D-Render-Proc)) -(define ((vector-field3d-render-fun f samples scale color line-width line-style alpha label) area) +(define ((vector-field3d-render-fun f samples scale color line-width line-style alpha) area) (match-define (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) (send area get-bounds-rect)) - (cond - [(and x-min x-max y-min y-max z-min z-max) - (define xs0 (linear-seq x-min x-max samples #:start? #t #:end? #t)) - (define ys0 (linear-seq y-min y-max samples #:start? #t #:end? #t)) - (define zs0 (linear-seq z-min z-max samples #:start? #t #:end? #t)) + (when (and x-min x-max y-min y-max z-min z-max) + (define xs0 (linear-seq x-min x-max samples #:start? #t #:end? #t)) + (define ys0 (linear-seq y-min y-max samples #:start? #t #:end? #t)) + (define zs0 (linear-seq z-min z-max samples #:start? #t #:end? #t)) - (define-values (vs dxs dys dzs norms mags) - (for*/lists ([vs : (Listof (Vectorof Real))] - [dxs : (Listof Real)] - [dys : (Listof Real)] - [dzs : (Listof Real)] - [norms : (Listof (Vectorof Real))] - [mags : (Listof Nonnegative-Real)] - ) ([x (in-list xs0)] - [y (in-list ys0)] - [z (in-list zs0)] - [dv (in-value (f x y z))] #:when (vrational? dv)) - (match-define (vector dx dy dz) dv) - (values (vector x y z) dx dy dz (vnormalize dv) (vmag dv)))) + (define-values (vs dxs dys dzs norms mags) + (for*/lists ([vs : (Listof (Vectorof Real))] + [dxs : (Listof Real)] + [dys : (Listof Real)] + [dzs : (Listof Real)] + [norms : (Listof (Vectorof Real))] + [mags : (Listof Nonnegative-Real)] + ) ([x (in-list xs0)] + [y (in-list ys0)] + [z (in-list zs0)] + [dv (in-value (f x y z))] #:when (vrational? dv)) + (match-define (vector dx dy dz) dv) + (values (vector x y z) dx dy dz (vnormalize dv) (vmag dv)))) - (cond [(empty? vs) empty] - [else (define box-x-size (/ (- x-max x-min) samples)) - (define box-y-size (/ (- y-max y-min) samples)) - (define box-z-size (/ (- z-max z-min) samples)) - - (define new-mags - (match scale - [(? real?) (map (λ ([mag : Real]) (* scale mag)) mags)] - ['normalized (make-list (length dxs) (min box-x-size box-y-size box-z-size))] - ['auto (define dx-max (real->double-flonum (apply max (map abs dxs)))) - (define dy-max (real->double-flonum (apply max (map abs dys)))) - (define dz-max (real->double-flonum (apply max (map abs dzs)))) - (define scale (min (/ box-x-size dx-max) - (/ box-y-size dy-max) - (/ box-z-size dz-max))) - (map (λ ([mag : Real]) (* scale mag)) mags)])) + (unless (empty? vs) + (define box-x-size (/ (- x-max x-min) samples)) + (define box-y-size (/ (- y-max y-min) samples)) + (define box-z-size (/ (- z-max z-min) samples)) - (send area put-alpha alpha) - (send area put-pen color line-width line-style) - (for ([v (in-list vs)] - [norm (in-list norms)] - [mag (in-list new-mags)]) - (send area put-arrow v (v+ v (v* norm mag)))) + (define new-mags + (match scale + [(? real?) (map (λ ([mag : Real]) (* scale mag)) mags)] + ['normalized (make-list (length dxs) (min box-x-size box-y-size box-z-size))] + ['auto (define dx-max (real->double-flonum (apply max (map abs dxs)))) + (define dy-max (real->double-flonum (apply max (map abs dys)))) + (define dz-max (real->double-flonum (apply max (map abs dzs)))) + (define scale (min (/ box-x-size dx-max) + (/ box-y-size dy-max) + (/ box-z-size dz-max))) + (map (λ ([mag : Real]) (* scale mag)) mags)])) - (cond [label (arrow-legend-entry label color line-width line-style)] - [else empty])])] - [else empty])) + (send area put-alpha alpha) + (send area put-pen color line-width line-style) + (for ([v (in-list vs)] + [norm (in-list norms)] + [mag (in-list new-mags)]) + (send area put-arrow v (v+ v (v* norm mag))))))) (:: vector-field3d (->* [(U (-> Real Real Real (Sequenceof Real)) @@ -171,7 +163,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (vector-field3d f [x-min #f] [x-max #f] [y-min #f] [y-max #f] [z-min #f] [z-max #f] #:samples [samples (vector-field3d-samples)] @@ -197,5 +189,6 @@ [else (let ([f (fix-vector-field3d-fun 'vector-field3d f)]) (renderer3d (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun + (and label (λ (_) (arrow-legend-entry label color line-width line-style))) (vector-field3d-render-fun - f samples scale color line-width line-style alpha label)))])) + f samples scale color line-width line-style alpha)))])) diff --git a/plot-lib/plot/private/plot3d/rectangle.rkt b/plot-lib/plot/private/plot3d/rectangle.rkt index 215af340..aa90d5ac 100644 --- a/plot-lib/plot/private/plot3d/rectangle.rkt +++ b/plot-lib/plot/private/plot3d/rectangle.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require racket/match racket/list typed/racket/class racket/sequence + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -14,18 +15,14 @@ Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U String #f) 3D-Render-Proc)) -(define ((rectangles3d-render-proc rects color style line-color line-width line-style alpha label) +(define ((rectangles3d-render-proc rects color style line-color line-width line-style alpha) area) (send area put-pen line-color line-width line-style) (send area put-brush color style) (send area put-alpha alpha) (for ([rect (in-list rects)]) - (send area put-rect rect)) - - (cond [label (rectangle-legend-entry label color style line-color line-width line-style)] - [else empty])) + (send area put-rect rect))) (:: rectangles3d (->* [(Sequenceof (Sequenceof ivl))] @@ -38,7 +35,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f)] + #:label (U String pict #f)] renderer3d)) (define (rectangles3d rects #:x-min [x-min #f] #:x-max [x-max #f] @@ -75,7 +72,7 @@ (define rys (filter rational? (append y1s y2s))) (define rzs (filter rational? (append z1s z2s))) (cond - [(or (empty? rxs) (empty? rys) (empty? rzs)) (renderer3d #f #f #f #f)] + [(or (empty? rxs) (empty? rys) (empty? rzs)) empty-renderer3d] [else (let ([x-min (if x-min x-min (apply min* rxs))] [x-max (if x-max x-max (apply max* rxs))] @@ -85,8 +82,10 @@ [z-max (if z-max z-max (apply max* rzs))]) (renderer3d (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f default-ticks-fun + (and label (λ (_) (rectangle-legend-entry + label color style line-color line-width line-style))) (rectangles3d-render-proc rects color style line-color line-width line-style - alpha label)))]))])) + alpha)))]))])) ;; =================================================================================================== ;; Discrete histograms @@ -132,7 +131,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U String #f) + #:label (U String pict #f) #:add-x-ticks? Boolean #:add-y-ticks? Boolean #:x-far-ticks? Boolean @@ -184,7 +183,7 @@ (list z1 z2)] [else (list z)]))))) (cond - [(empty? rzs) (renderer3d #f #f #f #f)] + [(empty? rzs) empty-renderer3d] [else (define c1s (remove-duplicates cat1s)) (define c2s (remove-duplicates cat2s)) @@ -233,8 +232,10 @@ (vector (ivl x-min x-max) (ivl y-min y-max) (ivl z-min z-max)) #f (discrete-histogram3d-ticks-fun c1s c2s tick-xs tick-ys add-x-ticks? add-y-ticks? x-far-ticks? y-far-ticks?) + (and label (λ (_) (rectangle-legend-entry + label color style line-color line-width line-style))) (rectangles3d-render-proc rects color style line-color line-width line-style - alpha label)))]))])) + alpha)))]))])) (:: stacked-histogram3d (->* [(Sequenceof (U (Vector Any Any (Sequenceof Real)) diff --git a/plot-lib/plot/private/plot3d/renderer.rkt b/plot-lib/plot/private/plot3d/renderer.rkt index 9326307f..e1a26b70 100644 --- a/plot-lib/plot/private/plot3d/renderer.rkt +++ b/plot-lib/plot/private/plot3d/renderer.rkt @@ -3,10 +3,15 @@ (require "../common/plot-element.rkt" "../common/types.rkt" "../common/type-doc.rkt" + "../common/math.rkt" "plot-area.rkt") (provide (all-defined-out)) -(deftype 3D-Render-Proc (-> (Instance 3D-Plot-Area%) (Treeof legend-entry))) +(deftype 3D-Render-Proc (-> (Instance 3D-Plot-Area%) Void)) -(struct renderer3d plot-element ([render-proc : (U #f 3D-Render-Proc)]) #:transparent) +(struct renderer3d plot-element ([label : (U #f (-> Rect (Treeof legend-entry)))] + [render-proc : (U #f 3D-Render-Proc)]) + #:transparent) + +(define empty-renderer3d (renderer3d #f #f #f #f #f)) diff --git a/plot-lib/plot/private/plot3d/surface.rkt b/plot-lib/plot/private/plot3d/surface.rkt index 1a1f4d29..1aa37991 100644 --- a/plot-lib/plot/private/plot3d/surface.rkt +++ b/plot-lib/plot/private/plot3d/surface.rkt @@ -1,6 +1,7 @@ #lang typed/racket/base (require typed/racket/class racket/match racket/list + (only-in typed/pict pict) plot/utils "../common/type-doc.rkt" "../common/utils.rkt") @@ -14,9 +15,8 @@ Plot-Color Plot-Brush-Style Plot-Color Nonnegative-Real Plot-Pen-Style Nonnegative-Real - (U #f String) 3D-Render-Proc)) -(define ((surface3d-render-proc f samples color style line-color line-width line-style alpha label) +(define ((surface3d-render-proc f samples color style line-color line-width line-style alpha) area) (match-define (vector x-ivl y-ivl z-ivl) (send area get-bounds-rect)) (define num (animated-samples samples)) @@ -29,9 +29,7 @@ (xa xb ya yb z1 z2 z3 z4) sample (define vs (list (vector xa ya z1) (vector xb ya z2) (vector xb yb z3) (vector xa yb z4))) (send area put-polygon vs)) - - (cond [label (rectangle-legend-entry label color style line-color line-width line-style)] - [else empty])) + (void)) (:: surface3d (->* [(-> Real Real Real)] @@ -44,7 +42,7 @@ #:line-width Nonnegative-Real #:line-style Plot-Pen-Style #:alpha Nonnegative-Real - #:label (U #f String)] + #:label (U String pict #f)] renderer3d)) (define (surface3d f [x-min #f] [x-max #f] [y-min #f] [y-max #f] #:z-min [z-min #f] #:z-max [z-max #f] #:samples [samples (plot3d-samples)] @@ -74,5 +72,6 @@ (renderer3d (vector x-ivl y-ivl z-ivl) (surface3d-bounds-fun g samples) default-ticks-fun + (and label (λ (_) (rectangle-legend-entry label color style line-color line-width line-style))) (surface3d-render-proc g samples color style - line-color line-width line-style alpha label))])) + line-color line-width line-style alpha))])) diff --git a/plot-lib/plot/private/utils-and-no-gui.rkt b/plot-lib/plot/private/utils-and-no-gui.rkt index 6351b6de..dfda6897 100644 --- a/plot-lib/plot/private/utils-and-no-gui.rkt +++ b/plot-lib/plot/private/utils-and-no-gui.rkt @@ -7,6 +7,7 @@ Anchor Plot-Color Plot-Pen-Style + Plot-Pen-Cap Plot-Brush-Style Point-Sym List-Generator @@ -17,7 +18,21 @@ Alphas Labels Contour-Levels - Image-File-Format) + Image-File-Format + Legend-Anchor) + +(require "common/plotmetrics.rkt") +(require (only-in (submod "common/plotmetrics.rkt" untyped) plot-metrics<%>)) + +(provide + Plot-Metrics<%> + plot-metrics<%> + plot-pict? + Plot-Pict + plot-pict-bounds + plot-pict-plot->dc + plot-pict-dc->plot + plot-pict-plane-vector) (require "common/math.rkt") @@ -47,7 +62,8 @@ stretch-transform collapse-transform) -(require "common/parameters.rkt") +(require "common/parameters.rkt" + "common/draw-attribs.rkt") (provide plot-deprecation-warnings? @@ -58,6 +74,12 @@ plot-x-far-axis? plot-y-far-axis? plot-z-far-axis? + plot-x-tick-labels? + plot-y-tick-labels? + plot-z-tick-labels? + plot-x-far-tick-labels? + plot-y-far-tick-labels? + plot-z-far-tick-labels? plot-x-tick-label-anchor plot-y-tick-label-anchor plot-x-far-tick-label-anchor @@ -72,14 +94,23 @@ plot-background plot-background-alpha plot-line-width + plot-line-cap plot-tick-size plot-font-size plot-font-face plot-font-family + plot-legend-font-size + plot-legend-font-face + plot-legend-font-family plot-legend-anchor plot-legend-box-alpha + plot-legend-layout + plot-legend-padding plot-decorations? + plot-inset plot-animating? + plot-pen-color-map + plot-brush-color-map plot3d-samples plot3d-angle plot3d-altitude @@ -91,6 +122,7 @@ plot-ps/pdf-interactive? plot-ps-setup plot-title + plot-aspect-ratio plot-x-label plot-y-label plot-z-label @@ -113,6 +145,7 @@ line-color line-width line-style + line-cap line-alpha interval-color interval-style @@ -138,6 +171,12 @@ vector-field-scale vector-field-alpha vector-field3d-samples + arrows-color + arrows-line-width + arrows-line-style + arrows-alpha + arrow-head-size-or-scale + arrow-head-angle error-bar-width error-bar-color error-bar-line-width @@ -149,6 +188,8 @@ candlestick-line-width candlestick-line-style candlestick-alpha + color-field-samples + color-field-alpha contour-samples contour-levels contour-colors @@ -293,4 +334,6 @@ (struct-out plot-element) (struct-out nonrenderer) (struct-out renderer2d) - (struct-out renderer3d)) + empty-renderer2d + (struct-out renderer3d) + empty-renderer3d) diff --git a/plot-lib/plot/utils.rkt b/plot-lib/plot/utils.rkt index 7b950233..e3bec406 100644 --- a/plot-lib/plot/utils.rkt +++ b/plot-lib/plot/utils.rkt @@ -2,6 +2,7 @@ (require "private/utils-and-no-gui.rkt") (provide (all-from-out "private/utils-and-no-gui.rkt")) +(provide plot-metrics<%>) (require "private/common/contract.rkt" "private/common/leftover-contracts.rkt" @@ -142,16 +143,25 @@ parse-format-string apply-formatter) -(require "private/common/draw-attribs.rkt") +(require (only-in "private/common/draw-attribs.rkt" + ->color + ->pen-style + ->brush-style + color-seq + color-seq*) + "private/common/color-map.rkt") (provide ->color - ->pen-color - ->brush-color ->pen-style ->brush-style color-seq - color-seq*) + color-seq* + ->pen-color + ->brush-color + color-map-names + color-map-size + register-color-map) (require "private/common/sample.rkt") @@ -207,4 +217,5 @@ (require "private/common/kde.rkt") (provide - kde) + kde + silverman-bandwidth) diff --git a/plot-test/LICENSE.txt b/plot-test/LICENSE.txt deleted file mode 100644 index dbb89375..00000000 --- a/plot-test/LICENSE.txt +++ /dev/null @@ -1,11 +0,0 @@ -plot -Copyright (c) 2010-2014 PLT Design Inc. - -This package is distributed under the GNU Lesser General Public -License (LGPL). This means that you can link this package into proprietary -applications, provided you follow the rules stated in the LGPL. You -can also modify this package; if you distribute a modified version, -you must distribute it under the terms of the LGPL, which in -particular means that you must release the source code for the -modified software. See http://www.gnu.org/copyleft/lesser.html -for more information. diff --git a/plot-test/info.rkt b/plot-test/info.rkt index fbe441ba..5f4595a8 100644 --- a/plot-test/info.rkt +++ b/plot-test/info.rkt @@ -7,12 +7,13 @@ "plot-gui-lib" "plot-lib" "plot-doc" - "draw-lib" + ["draw-lib" #:version "1.19"] "pict-lib" "rackunit-lib" "slideshow-lib" "typed-racket-lib" - "typed-racket-more")) + "typed-racket-more" + "contract-profile")) (define build-deps '()) (define update-implies '("plot-lib")) @@ -20,3 +21,8 @@ (define pkg-desc "Plot tests") (define pkg-authors '(ntoronto)) + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT)) diff --git a/plot-test/plot/info.rkt b/plot-test/plot/info.rkt index 38d2700d..ad11124a 100644 --- a/plot-test/plot/info.rkt +++ b/plot-test/plot/info.rkt @@ -1,2 +1,3 @@ #lang info (define compile-omit-paths '("tests")) +(define test-responsibles '((all AlexHarsanyi@gmail.com))) diff --git a/plot-test/plot/tests/PRs/107.rkt b/plot-test/plot/tests/PRs/107.rkt new file mode 100644 index 00000000..f6acd78e --- /dev/null +++ b/plot-test/plot/tests/PRs/107.rkt @@ -0,0 +1,83 @@ +#lang racket +(require rackunit + plot pict racket/runtime-path + math/distributions + "../helpers.rkt") + +(random-seed 42) + +(define (rnorm sample-count mean stddev) + (sample (normal-dist mean stddev) sample-count)) + +(define a (rnorm 500 10 5)) +(define b (append (rnorm 500 13 1) (rnorm 500 18 1))) +(define c (rnorm 20 25 4)) +(define d (rnorm 100 12 1)) + +(plot-pen-color-map 'tab20) +(plot-brush-color-map 'tab20) + +(define ((do-plot-box-and-whisker invert? show-label? width) output-fn) + (parameterize ([plot-x-label #f] + [plot-y-label #f]) + (output-fn + (for/list ([data-set (list a b c d)] + [label (list "a" "b" "c" "d")] + [index (in-naturals)]) + (box-and-whisker data-set + #:label (and show-label? label) + #:invert? invert? + #:x index + #:width width + #:box-color (+ (* index 2) 1) + #:box-alpha 0.8 + #:box-line-color (* index 2) + #:whisker-color (* index 2) + #:median-color "red" + )) + #:legend-anchor 'no-legend))) + +(define ((do-plot-violin invert? show-label? width) output-fn) + (parameterize ([plot-x-label #f] + [plot-y-label #f]) + (output-fn + (for/list ([data-set (list a b c d)] + [label (list "a" "b" "c" "d")] + [index (in-naturals)]) + (violin data-set + #:label (and show-label? label) + #:invert? invert? + #:x index + #:width width + #:color (+ (* index 2) 1) + #:alpha 0.8 + #:line-color (* index 2) + )) + #:legend-anchor 'no-legend))) + +(define-runtime-path pr107-a "./test-data/pr107-a.dat") +(define-runtime-path pr107-b "./test-data/pr107-b.dat") +(define-runtime-path pr107-c "./test-data/pr107-c.dat") +(define-runtime-path pr107-d "./test-data/pr107-d.dat") +(define-runtime-path pr107-e "./test-data/pr107-e.dat") +(define-runtime-path pr107-f "./test-data/pr107-f.dat") + +(define pr107-test-suite + (test-suite + "box-and-whisker" + (test-case "PR#107: box-and-whisker case A" + (check-draw-steps (do-plot-box-and-whisker #f #t 7/8) pr107-a)) + (test-case "PR#107: box-and-whisker case B" + (check-draw-steps (do-plot-box-and-whisker #f #f 1.5) pr107-b)) + (test-case "PR#107: box-and-whisker case C" + (check-draw-steps (do-plot-box-and-whisker #t #t 1.5) pr107-c)) + (test-case "PR#107: violin case D" + (check-draw-steps (do-plot-violin #f #t 7/8) pr107-d)) + (test-case "PR#107: violin case E" + (check-draw-steps (do-plot-violin #f #f 1.5) pr107-e)) + (test-case "PR#107: violin case F" + (check-draw-steps (do-plot-violin #t #t 1.5) pr107-f)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr107-test-suite)) diff --git a/plot-test/plot/tests/PRs/108.rkt b/plot-test/plot/tests/PRs/108.rkt new file mode 100644 index 00000000..f6124378 --- /dev/null +++ b/plot-test/plot/tests/PRs/108.rkt @@ -0,0 +1,33 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; Tests for https://github.com/racket/plot/issues/108, error bars are not +;; culled out based on their center location, and partial error bars should be +;; visible when the plot area does not include the entire error bar + +(define-runtime-path pr108-data "./test-data/pr108.dat") + +;; This plot is set up to have the area such that the center and edges of +;; error bars are not in the plot, it should still draw a line from the +;; partial error bar at 4. +(define (do-plot-pr108 output-fn) + (output-fn + (list (function sqr 1 7) + (error-bars (list (vector 2 4 12) + (vector 4 16 20) + (vector 6 36 10)))) + #:x-min 3.5 #:x-max 4.5 + #:y-min 20 #:y-max 30)) + +(define pr108-test-suite + (test-suite + "PR#108: Zoom in for error-bars (plot package) not working properly." + (test-case "pr108" + (check-draw-steps do-plot-pr108 pr108-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr108-test-suite)) diff --git a/plot-test/plot/tests/PRs/111.rkt b/plot-test/plot/tests/PRs/111.rkt new file mode 100644 index 00000000..3893744f --- /dev/null +++ b/plot-test/plot/tests/PRs/111.rkt @@ -0,0 +1,37 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; Tests for https://github.com/racket/plot/pull/100, ignoring axis transforms +;; for lines renderer. + +(define (do-plot output-fn) + (define x (list 28 0.13 0.006765)) + (define y (list 1.27 0.63 0.325)) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform log-transform]) + (output-fn + (list + (tick-grid) + (lines (map vector x y) + #:label "with axis transforms" + #:color 1) + (lines (map vector x y) + #:ignore-axis-transforms? #t + #:label "no axis transforms" + #:color 2)) + #:title "Log-Log Plot"))) + +(define-runtime-path pr111-data "./test-data/pr111.dat") + +(define pr111-test-suite + (test-suite + "PR#111: add no-axis-transforms? to lines renderer" + (test-case "Log-Log Plot With no-axis-transforms?" + (check-draw-steps do-plot pr111-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr111-test-suite)) diff --git a/plot-test/plot/tests/PRs/117.rkt b/plot-test/plot/tests/PRs/117.rkt new file mode 100644 index 00000000..3cea6b21 --- /dev/null +++ b/plot-test/plot/tests/PRs/117.rkt @@ -0,0 +1,32 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; See https://github.com/racket/plot/issues/117 and associated discution. + +(define-runtime-path pr117-data "./test-data/pr117.dat") + +(define (do-plot-pr117 output-fn) + (parameterize ([plot-y-transform log-transform] + [plot-y-ticks (ticks-add + (log-ticks #:number 10) + (list 500 ; should be visible on the plot + (+ (expt 10 3) 500) ; should be visible on the plot + (+ (expt 10 4) 500) ; should be visible, next to the 10^4 label + (+ (expt 10 5) 500) ; should not be visible, too close to 10^5 + (+ (expt 10 6) 500) ; should not be visible, too colse to 10^6 + (+ (expt 10 7) 500) ; should not be visible, too close to 10^7 + ))]) + (output-fn (function exp) #:x-min 0. #:x-max 20))) + +(define pr117-test-suite + (test-suite + "PR#117: Tick labels at the wrong place on log plot" + (test-case "pr117" + (check-draw-steps do-plot-pr117 pr117-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr117-test-suite)) diff --git a/plot-test/plot/tests/PRs/118.rkt b/plot-test/plot/tests/PRs/118.rkt new file mode 100644 index 00000000..9d4539d8 --- /dev/null +++ b/plot-test/plot/tests/PRs/118.rkt @@ -0,0 +1,50 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; See https://github.com/racket/plot/issues/118 and associated discution. + +(define-runtime-path pr118-data "./test-data/pr118.dat") + +(define (do-plot-pr118 output-fn) + (define-values (xdata ydata) + (parameterize ([current-pseudo-random-generator (make-pseudo-random-generator)]) + (random-seed 42) ; ensure our test is deterministic + (define (randsin x)(+ (sin x) (/ ( - (random) 0.5) 5) ) ) + (define xdata (range 0 (* 2 pi) (/ pi 9 ) ) ) + (define ydata (map (lambda (x) (randsin x) ) xdata ) ) + (values xdata ydata))) + + (parameterize ([point-size 10] + [line-width 2] + [point-line-width 1.5] + [plot-pen-color-map 'set1] + [plot-x-label #f] + [plot-y-label #f]) + (output-fn (list + (function sin 0 (* 2 pi) + #:label "exact" + #:marker 'diamond + #:color 0 + #:marker-count 10) + (lines (map vector xdata ydata ) + #:label "discrete" + #:marker 'square + #:color 1 + #:marker-color "black") + (inverse sqr -2 2 #:color 3 + #:label "x = y²" + #:marker '5star)) + #:legend-anchor 'top-right))) + +(define pr118-test-suite + (test-suite + "PR#118: Add markers to lines and function renderers" + (test-case "pr118" + (check-draw-steps do-plot-pr118 pr118-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr118-test-suite)) diff --git a/plot-test/plot/tests/PRs/124.rkt b/plot-test/plot/tests/PRs/124.rkt new file mode 100644 index 00000000..7fc940e0 --- /dev/null +++ b/plot-test/plot/tests/PRs/124.rkt @@ -0,0 +1,33 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; see https://github.com/racket/plot/pull/124 + +(define-runtime-path pr124-data "./test-data/pr124.dat") + +(define (do-plot-pr124 output-fn) + (parameterize + ([plot-line-width 15] + [line-width 15] + [plot-inset '(0 10 10 0)] + [plot-pen-color-map 'set1] + [plot-legend-padding '(0 15 0 0)] + [plot-line-cap 'round] + [line-cap 'round]) + (output-fn + (list + (function sin -5 5 #:color 0 #:label "sin(x)") + (function cos -5 5 #:color 1 #:label "cos(x)"))))) + +(define pr124-test-suite + (test-suite + "PR#124: Add plot-inset and plot-legend-padding parameters" + (test-case "pr124" + (check-draw-steps do-plot-pr124 pr124-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr124-test-suite)) diff --git a/plot-test/plot/tests/PRs/13620.rkt b/plot-test/plot/tests/PRs/13620.rkt index 51c5ee4c..21dab240 100644 --- a/plot-test/plot/tests/PRs/13620.rkt +++ b/plot-test/plot/tests/PRs/13620.rkt @@ -1,18 +1,46 @@ #lang racket +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + "../helpers.rkt") -;; These tests pass when they terminate +;; https://github.com/racket/gnats-bugs/blob/7e4bb9a65cd4783bef9936b576c5e06a5da3fb01/all/13620 -(require plot) +(define (do-plot-contour-intervals output-fn) + (output-fn (contour-intervals * -1 1 -1 1 #:alphas '()))) -(printf "The following three plots should be blank:~n") -(plot (contour-intervals * -1 1 -1 1 #:alphas '())) -(plot3d (contour-intervals3d * -1 1 -1 1 #:alphas '())) -(plot3d (isosurfaces3d * -1 1 -1 1 -1 1 #:alphas '())) +(define (do-plot-contour-intervals3d output-fn) + (output-fn (contour-intervals3d * -1 1 -1 1 #:alphas '()))) -(with-handlers ([exn? (λ (_) (void))]) - (plot (stacked-histogram (list (vector 'a 1)) - #:alphas '()))) +(define (do-plot-isosurface3d output-fn) + (output-fn (isosurfaces3d * -1 1 -1 1 -1 1 #:alphas '()))) -(with-handlers ([exn? (λ (_) (void))]) - (plot3d (stacked-histogram3d (list (vector 'a 'a 1)) - #:alphas '()))) +(define-runtime-path gnats13620-ci-data "./test-data/gnats13620-ci.dat") +(define-runtime-path gnats13620-ci3d-data "./test-data/gnats13620-ci3d.dat") +(define-runtime-path gnats13620-is3d-data "./test-data/gnats13620-is3d.dat") + +(define gnats13620-test-suite + (test-suite + "GNATS#13620: stacked-histogram loops when given an empty list of labels" + (test-case "gnats13620-contour-intervals" + (check-draw-steps do-plot-contour-intervals gnats13620-ci-data)) + (test-case "gnats13620-contour-intervals3d" + (check-draw-steps-3d do-plot-contour-intervals3d gnats13620-ci3d-data)) + (test-case "gnats13620-isosurface3d" + (check-draw-steps-3d do-plot-isosurface3d gnats13620-is3d-data)) + (test-case "gnats13620-stacked-histogram" + ;; Should fail with a "could not determine sensible plot bounds" message + (check-exn + exn:fail? + (lambda () (plot (stacked-histogram (list (vector 'a 1)) #:alphas '()))))) + (test-case "gnats13620-histogram3d" + ;; Should fail with a "could not determine sensible plot bounds" message + (check-exn + exn:fail? + (lambda () (plot3d (stacked-histogram3d (list (vector 'a 'a 1)) #:alphas '()))))))) + +(module+ test + (require rackunit/text-ui) + (run-tests gnats13620-test-suite)) diff --git a/plot-test/plot/tests/PRs/24.rkt b/plot-test/plot/tests/PRs/24.rkt index 1aeda0d8..8b0e2155 100644 --- a/plot-test/plot/tests/PRs/24.rkt +++ b/plot-test/plot/tests/PRs/24.rkt @@ -1,24 +1,40 @@ -#lang racket/base -(require plot plot/utils) +#lang racket +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/24 ;; Plot all `known-point-symbols`. -;; This test succeeds when it terminates. +(define (do-plot output-fn) + (define NUM-ROWS 3) + (define YOFFSET 4) + (parameterize ([plot-x-axis? #f] + [plot-y-axis? #f] + [plot-x-far-axis? #f] + [plot-y-far-axis? #f] + [plot-decorations? #f]) + (output-fn + (for/list ([s (in-list known-point-symbols)] + [i (in-naturals)]) + (points (list (list (modulo i NUM-ROWS) (- (* YOFFSET (quotient i NUM-ROWS))))) + #:sym s + #:size 10)) + #:x-min -1 + #:x-max NUM-ROWS + #:y-min (- (* YOFFSET (add1 (quotient (length known-point-symbols) NUM-ROWS)))) + #:y-max 1))) + +(define-runtime-path pr24-data "./test-data/pr24.dat") -(define NUM-ROWS 3) -(define YOFFSET 4) +(define pr24-test-suite + (test-suite + "PR#24: Fix typo, 'cirlce2' => 'circle2'" + (test-case "pr24" (check-draw-steps do-plot pr24-data)))) -(parameterize ([plot-x-axis? #f] - [plot-y-axis? #f] - [plot-x-far-axis? #f] - [plot-y-far-axis? #f] - [plot-decorations? #f]) - (plot - (for/list ([s (in-list known-point-symbols)] - [i (in-naturals)]) - (points (list (list (modulo i NUM-ROWS) (- (* YOFFSET (quotient i NUM-ROWS))))) - #:sym s - #:size 10)) - #:x-min -1 - #:x-max NUM-ROWS - #:y-min (- (+ 1 (* YOFFSET (quotient (length known-point-symbols) NUM-ROWS)))) - #:y-max 1)) +(module+ test + (require rackunit/text-ui) + (run-tests pr24-test-suite)) diff --git a/plot-test/plot/tests/PRs/42.rkt b/plot-test/plot/tests/PRs/42.rkt new file mode 100644 index 00000000..d96b56b3 --- /dev/null +++ b/plot-test/plot/tests/PRs/42.rkt @@ -0,0 +1,110 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/42 - arrows and arrows3d + +;; test arrows - heads +(define (do-plot-arrows1 output-fn) + (output-fn + (list + (arrows + `((0 0) (2 1) (3 3) (0 0)) + #:arrow-head-size-or-scale '(= 50) + #:arrow-head-angle .2 + #:color 6 #:label "same size arrowheads") + (arrows + `(((2 0) (0 1)) + ((3 0) (-1 1))) + #:color 2 #:label "scaled arrowheads")))) + +;; test arrows going outside of the plot area +(define (do-plot-arrows2 output-fn) + (parameterize ([arrow-head-size-or-scale '(= 50)]) + (output-fn + (list + (arrows '((0 5) (3 5)) #:color 1 #:width 3 #:label "start OUT, end OUT") + (arrows '((0 4) (2 4)) #:color 2 #:width 3 #:label "start OUT, end IN") + (arrows '((1.5 3) (3 3)) #:color 3 #:width 3 #:label "start IN, end OUT") + (arrows '((1.5 2) (2.6 2)) #:color 4 #:width 3 #:label "start IN, end JUST OUT (ears not visible)") + (arrows '((0 1) (2.6 1)) #:color 5 #:width 3 #:label "start OUT, end JUST OUT (ears not visible)")) + #:x-min 1 #:x-max 2.5 + #:y-min 0 #:y-max 6 + #:legend-anchor 'bottom-left))) + +;; test arrows3d - heads +(define (do-plot-arrows3d1 output-fn) + (parameterize ([arrow-head-size-or-scale .5] + [arrow-head-angle .3] + [arrows-color 4]) + (output-fn + (list (arrows3d #((0 0 0) (1 1 1) (1 1 0) (1 2 2)) + #:alpha .5 #:label "scaled chained arrows") + (arrows3d #(#(#(1 2 3) #(-1/2 -1/2 -1/2)) + #(#(2 0 2) #(0 2 0))) + #:arrow-head-size-or-scale '(= 50) + #:arrow-head-angle .1 + #:color 'blue + #:label "same size arrowheads"))))) + +;; test arrows going outside of the plot area +(define (do-plot-arrows3d2 output-fn) + (parameterize ([arrow-head-size-or-scale '(= 50)]) + (output-fn + (list + (arrows3d '((0 5 0) (3 5 0)) #:color 1 #:width 3 #:label "start OUT, end OUT") + (arrows3d '((0 4 0) (2 4 0)) #:color 2 #:width 3 #:label "start OUT, end IN") + (arrows3d '((1.5 3 0) (3 3 0)) #:color 3 #:width 3 #:label "start IN, end OUT") + (arrows3d '((1.5 2 0) (2.6 2 0)) #:color 4 #:width 3 #:label "start IN, end JUST OUT (ears not visible)") + (arrows3d '((0 1 0) (2.6 1 0)) #:color 5 #:width 3 #:label "start OUT, end JUST OUT (ears not visible)") + ) + #:x-min 1 #:x-max 2.5 + #:y-min 0 #:y-max 6 + #:z-min -1 #:z-max 1 + #:legend-anchor 'bottom-left))) + +;; effect of parameters on vector fields +(define (do-plot-vectorfield output-fn) + (parameterize ([arrow-head-size-or-scale '(= 10)] + [arrow-head-angle .1]) + (output-fn + (vector-field (λ (x y) (vector (+ x y) (- x y))) + -2 2 -2 2)))) + +(define (do-plot-vectorfield3d output-fn) + (parameterize ([arrow-head-size-or-scale .3] + [arrow-head-angle 1.]) + (output-fn + (vector-field3d (λ (x y z) (vector x z y)) + -2 2 -2 2 -2 2)))) + +(define-runtime-path pr42-arrows1-data "./test-data/pr42-1-1.dat") +(define-runtime-path pr42-arrows2-data "./test-data/pr42-1-2.dat") +(define-runtime-path pr42-arrows3d1-data "./test-data/pr42-2-1.dat") +(define-runtime-path pr42-arrows3d2-data "./test-data/pr42-2-2.dat") +(define-runtime-path pr42-vectorfield-data "./test-data/pr42-3.dat") +(define-runtime-path pr42-vectorfield3d-data "./test-data/pr42-4.dat") + +(define pr42-test-suite + (test-suite + "PR#42: Arrows and arrows3d" + (test-case "pr42-arrows" + (check-draw-steps do-plot-arrows1 pr42-arrows1-data)) + (test-case "pr42-arrows" + (check-draw-steps do-plot-arrows2 pr42-arrows2-data)) + (test-case "pr42-arrows3d" + (check-draw-steps-3d do-plot-arrows3d1 pr42-arrows3d1-data)) + (test-case "pr42-arrows3d" + (check-draw-steps-3d do-plot-arrows3d2 pr42-arrows3d2-data)) + + (test-case "pr42-vectorfield" + (check-draw-steps do-plot-vectorfield pr42-vectorfield-data)) + (test-case "pr42-vectorfield3d" + (check-draw-steps-3d do-plot-vectorfield3d pr42-vectorfield3d-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr42-test-suite)) diff --git a/plot-test/plot/tests/PRs/45.rkt b/plot-test/plot/tests/PRs/45.rkt new file mode 100644 index 00000000..cbb4a127 --- /dev/null +++ b/plot-test/plot/tests/PRs/45.rkt @@ -0,0 +1,24 @@ +#lang racket/base +(require plot racket/class racket/gui/base) + +(define show-frame/subspace + (let ([other-eventspace (make-eventspace)]) + (lambda (make-frame [sleep-seconds 5]) + (define f + (parameterize ([current-eventspace other-eventspace]) + (make-frame))) + (send f show #t) + (sleep sleep-seconds) + (send f show #f)))) + +;; These plots should NOT have decorations. If they do, that means the parameter +;; is somehow ignored. +(show-frame/subspace + (lambda () + (parameterize ((plot-decorations? #f)) + (plot3d-frame (surface3d (λ (x y) (* (cos x) (sin y))) + -3.0 3.0 -3.0 3.0))))) +(show-frame/subspace + (lambda () + (parameterize ((plot-decorations? #f)) + (plot-frame (function sin) #:x-min -3 #:x-max 3)))) diff --git a/plot-test/plot/tests/PRs/46.rkt b/plot-test/plot/tests/PRs/46.rkt new file mode 100644 index 00000000..54a4a64f --- /dev/null +++ b/plot-test/plot/tests/PRs/46.rkt @@ -0,0 +1,240 @@ +#lang racket +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for https://github.com/racket/plot/issues/46 + +(define r3d (surface3d (lambda (x y) (- (sqr x) (sqr y))) -1 1 -1 1)) +(define r2d (function sin (- pi) pi)) + +;; Case 1: far ticks are the same as near ticks, labels are +;; drawn on the near axis only. +;; +;; plot-{x,y,z}-ticks - (linear-ticks) +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - NOT SET +;; plot-{x,y,z}-far-tick-labels? - NOT SET + +(define (do-plot-case1 output-fn) + (parameterize ([plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case1-3d output-fn) + (parameterize ([plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +;; Case 2: far ticks are the same as near ticks, but labels are +;; forced to be drawn on the far axis as well. +;; +;; plot-{x,y,z}-ticks - (linear-ticks) +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - NOT SET +;; plot-{x,y,z}-far-tick-labels? - #t + +(define (do-plot-case2 output-fn) + (parameterize ([plot-x-far-tick-labels? #t] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-far-tick-labels? #t] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-far-tick-labels? #t] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case2-3d output-fn) + (parameterize ([plot-x-far-tick-labels? #t] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-far-tick-labels? #t] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-far-tick-labels? #t] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +;; Case 3: far ticks are the same as near ticks, labels are +;; disabled on the near axis, but will not be drawn on the far axis. +;; +;; plot-{x,y,z}-ticks - (linear-ticks) +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - #f +;; plot-{x,y,z}-far-tick-labels? - NOT SET + +(define (do-plot-case3 output-fn) + (parameterize ([plot-x-tick-labels? #f] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-tick-labels? #f] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-tick-labels? #f] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case3-3d output-fn) + (parameterize ([plot-x-tick-labels? #f] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-tick-labels? #f] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-tick-labels? #f] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +;; Case 4: no near ticks, only far ticks. labels are drawn on the far ticks +;; +;; plot-{x,y,z}-ticks - no-ticks +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - NOT SET +;; plot-{x,y,z}-far-tick-labels? - NOT SET + +(define (do-plot-case4 output-fn) + (parameterize ([plot-x-ticks no-ticks] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks no-ticks] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks no-ticks] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case4-3d output-fn) + (parameterize ([plot-x-ticks no-ticks] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks no-ticks] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks no-ticks] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +;; Case 5: no near ticks, only far ticks, but disable drawing labels on the far ticks +;; +;; plot-{x,y,z}-ticks - no-ticks +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - NOT SET +;; plot-{x,y,z}-far-tick-labels? - #f + +(define (do-plot-case5 output-fn) + (parameterize ([plot-x-ticks no-ticks] + [plot-x-far-tick-labels? #f] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks no-ticks] + [plot-y-far-tick-labels? #f] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks no-ticks] + [plot-z-far-tick-labels? #f] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case5-3d output-fn) + (parameterize ([plot-x-ticks no-ticks] + [plot-x-far-tick-labels? #f] + [plot-x-far-ticks (linear-ticks)] + [plot-y-ticks no-ticks] + [plot-y-far-tick-labels? #f] + [plot-y-far-ticks (linear-ticks)] + [plot-z-ticks no-ticks] + [plot-z-far-tick-labels? #f] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +;; Case 6: far ticks are the same as near ticks, switch to drawing labels on the +;; far axis +;; +;; plot-{x,y,z}-ticks - (linear-ticks) +;; plot-{x,y,z}-far-ticks - (linear-ticks) +;; plot-{x,y,z}-tick-labels? - #f +;; plot-{x,y,z}-far-tick-labels? - #t +(define (do-plot-case6 output-fn) + (parameterize ([plot-x-tick-labels? #f] + [plot-x-far-tick-labels? #t] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-tick-labels? #f] + [plot-y-far-tick-labels? #t] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-tick-labels? #f] + [plot-z-far-tick-labels? #t] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r2d))) + +(define (do-plot-case6-3d output-fn) + (parameterize ([plot-x-tick-labels? #f] + [plot-x-far-tick-labels? #t] + [plot-x-ticks (linear-ticks)] + [plot-x-far-ticks (linear-ticks)] + [plot-y-tick-labels? #f] + [plot-y-far-tick-labels? #t] + [plot-y-ticks (linear-ticks)] + [plot-y-far-ticks (linear-ticks)] + [plot-z-tick-labels? #f] + [plot-z-far-tick-labels? #t] + [plot-z-ticks (linear-ticks)] + [plot-z-far-ticks (linear-ticks)]) + (output-fn r3d))) + +(define-runtime-path pr46-case1-data "./test-data/pr46-1.dat") +(define-runtime-path pr46-case1-3d-data "./test-data/pr46-1-3d.dat") +(define-runtime-path pr46-case2-data "./test-data/pr46-2.dat") +(define-runtime-path pr46-case2-3d-data "./test-data/pr46-2-3d.dat") +(define-runtime-path pr46-case3-data "./test-data/pr46-3.dat") +(define-runtime-path pr46-case3-3d-data "./test-data/pr46-3-3d.dat") +(define-runtime-path pr46-case4-data "./test-data/pr46-4.dat") +(define-runtime-path pr46-case4-3d-data "./test-data/pr46-4-3d.dat") +(define-runtime-path pr46-case5-data "./test-data/pr46-5.dat") +(define-runtime-path pr46-case5-3d-data "./test-data/pr46-5-3d.dat") +(define-runtime-path pr46-case6-data "./test-data/pr46-6.dat") +(define-runtime-path pr46-case6-3d-data "./test-data/pr46-6-3d.dat") + +(define pr46-test-suite + (test-suite + "PR#46: far tick labels drawn when parameter is #false" + (test-case "pr46 case1" + (check-draw-steps do-plot-case1 pr46-case1-data)) + (test-case "pr46 case1 3d" + (check-draw-steps-3d do-plot-case1-3d pr46-case1-3d-data)) + (test-case "pr46 case2" + (check-draw-steps do-plot-case2 pr46-case2-data)) + (test-case "pr46 case2 3d" + (check-draw-steps-3d do-plot-case2-3d pr46-case2-3d-data)) + (test-case "pr46 case3" + (check-draw-steps do-plot-case3 pr46-case3-data)) + (test-case "pr46 case3 3d" + (check-draw-steps-3d do-plot-case3-3d pr46-case3-3d-data)) + (test-case "pr46 case4" + (check-draw-steps do-plot-case4 pr46-case4-data)) + (test-case "pr46 case4 3d" + (check-draw-steps-3d do-plot-case4-3d pr46-case4-3d-data)) + (test-case "pr46 case5" + (check-draw-steps do-plot-case5 pr46-case5-data)) + (test-case "pr46 case5 3d" + (check-draw-steps-3d do-plot-case5-3d pr46-case5-3d-data)) + (test-case "pr46 case6" + (check-draw-steps do-plot-case6 pr46-case6-data)) + (test-case "pr46 case6 3d" + (check-draw-steps-3d do-plot-case6-3d pr46-case6-3d-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr46-test-suite)) diff --git a/plot-test/plot/tests/PRs/5.rkt b/plot-test/plot/tests/PRs/5.rkt new file mode 100644 index 00000000..e47409cb --- /dev/null +++ b/plot-test/plot/tests/PRs/5.rkt @@ -0,0 +1,26 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/5 + +(define (do-plot output-fn) + (parameterize ([plot-font-size 8] + [plot-font-family 'default] + [plot-legend-font-size 14] + [plot-legend-font-family 'modern]) + (output-fn (function sin -5 5 #:label "sin(x)")))) + +(define-runtime-path pr5-data "./test-data/pr5.dat") + +(define pr5-test-suite + (test-suite + "PR#5: Separate legend font from plot font for more control." + (test-case "pr5" (check-draw-steps do-plot pr5-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr5-test-suite)) diff --git a/plot-test/plot/tests/PRs/55.rkt b/plot-test/plot/tests/PRs/55.rkt new file mode 100644 index 00000000..c8e16db4 --- /dev/null +++ b/plot-test/plot/tests/PRs/55.rkt @@ -0,0 +1,44 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/55 + +(define (do-plot-polygons3d output-fn) + (output-fn + (polygons3d (list (list (list 1 0 0) (list 0 0 1) (list 0 1 0)) + (list (list 0 0 0) (list 0 0 1) (list 0 1 0)) + (list (list 1 0 0) (list 0 0 1) (list 0 0 0)))))) + +(define (do-plot-parametric-surface3d output-fn) + (output-fn + (parametric-surface3d (λ (ϕ φ) + (list (* (cos ϕ) (cos φ)) + (* (sin ϕ) (cos φ)) + (sin φ))) + 0 (* 2 (angle -1)) #:s-samples 80 + (- (/ (angle -1) 2)) (/ (angle -1) 2) #:t-samples 40))) + +(define (do-plot-polar3d output-fn) + (output-fn (polar3d (λ (ϕ φ) 1)))) + +(define-runtime-path pr55-polygons3d-data "./test-data/pr55-1.dat") +(define-runtime-path pr55-parametric-surface3d-data "./test-data/pr55-2.dat") +(define-runtime-path pr55-polar3d-data "./test-data/pr55-3.dat") + +(define pr55-test-suite + (test-suite + "PR#55: Parametric surface3d" + (test-case "pr55-polygons3d" + (check-draw-steps-3d do-plot-polygons3d pr55-polygons3d-data)) + (test-case "pr55-parametric-surface3d" + (check-draw-steps-3d do-plot-parametric-surface3d pr55-parametric-surface3d-data)) + (test-case "pr55-polar3d" + (check-draw-steps-3d do-plot-polar3d pr55-polar3d-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr55-test-suite)) diff --git a/plot-test/plot/tests/PRs/58.rkt b/plot-test/plot/tests/PRs/58.rkt new file mode 100644 index 00000000..0da06d0b --- /dev/null +++ b/plot-test/plot/tests/PRs/58.rkt @@ -0,0 +1,111 @@ +#lang racket +(require rackunit + plot + pict + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for https://github.com/racket/plot/issues/58 + +;; Setup a draw context used for font metrics by the picts used in these tests +;; -- this will ensure that tests produce identical data sets on all +;; platforms. Note that this line will make the pict look unaligned -- remove +;; this line to restore "normal" behavior. + +(dc-for-text-size (new mock-record-dc%)) + +(define (do-plot-2d output-fn) + (output-fn + (list + (lines '([10 1] [20 1.5] [30 1.7]) + #:color "DarkOrange" + #:width 3 + #:label (vc-append (standard-fish 35 25 #:color "DarkOrange") (text "One Fish"))) + (points '([10 1.2] [15 1.0] [20 0.9] [25 0.7] [30 0.4]) + #:color "forestgreen" + #:fill-color "medium forest green" + #:line-width 3 + #:sym 'fullcircle1 + #:size 20 + #:label (vc-append (hc-append + (standard-fish 25 15 #:color "forestgreen") + (standard-fish 25 15 #:color "medium forest green")) + (text "Two Fish"))) + (lines '([10 .5] [20 1.6] [30 1.0]) + #:color "firebrick" + #:width 3 + #:label (vc-append (standard-fish 50 30 #:color "firebrick") + (text "Red Fish"))) + (function sin 10 30 + #:color "steel blue" + #:width 3 + #:label (vc-append (standard-fish 30 50 #:color "steel blue") + (text "Blue Fish"))) + + ))) + +(define (do-plot-3d output-fn) + (output-fn + (surface3d (λ (x y) (+ (/ 1.0 x)) + (/ 1.0 y)) + -2 2 -2 2 + #:color '(255 128 128) + #:line-color '(255 128 128) + #:line-width 1.5 + #:label (standard-fish 50 30)))) + + +(define (do-plot-2d-title+axes output-fn) + (parameterize ((plot-title (hc-append 15 + (standard-fish 50 30 #:color "DarkGoldenRod") + (text "Fishy Plot" null 24) + (standard-fish 50 30 #:color "DarkGoldenRod"))) + (plot-x-label (standard-fish 75 30 #:color "RoyalBlue")) + (plot-x-far-label (standard-fish 75 30 #:color "Teal")) + (plot-y-label (standard-fish 75 30 #:color "Coral")) + (plot-y-far-label (standard-fish 75 30 #:color "DarkSalmon")) + (plot-z-label (standard-fish 75 30 #:color "DarkOrchid")) + (plot-z-far-label (standard-fish 75 30 #:color "Plum"))) + (output-fn (function sin -3 3)))) + +(define (do-plot-3d-title+axes output-fn) + (parameterize ((plot-title (hc-append 15 + (standard-fish 50 30 #:color "DarkGoldenRod") + (text "Fishy Plot" null 24) + (standard-fish 50 30 #:color "DarkGoldenRod"))) + (plot-x-label (standard-fish 75 30 #:color "RoyalBlue")) + (plot-x-far-label (standard-fish 75 30 #:color "Teal")) + (plot-y-label (standard-fish 75 30 #:color "Coral")) + (plot-y-far-label (standard-fish 75 30 #:color "DarkSalmon")) + (plot-z-label (standard-fish 75 30 #:color "DarkOrchid")) + (plot-z-far-label (standard-fish 75 30 #:color "Plum"))) + (output-fn (surface3d (λ (x y) (+ (/ 1.0 x)) + (/ 1.0 y)) + -2 2 -2 2 + #:color '(255 128 128) + #:line-color '(255 128 128) + #:line-width 1.5)))) + +(define-runtime-path pr58-2d "./test-data/pr58-2d.dat") +(define-runtime-path pr58-3d "./test-data/pr58-3d.dat") +(define-runtime-path pr58-2d-t "./test-data/pr58-2d-t.dat") +(define-runtime-path pr58-3d-t "./test-data/pr58-3d-t.dat") + +(define pr58-test-suite + (test-suite + "PR#58: add support for pict legend entries, title and axes" + (test-case "pr58 2d plots" + (check-draw-steps do-plot-2d pr58-2d)) + (test-case "pr58 3d plots" + (check-draw-steps-3d do-plot-3d pr58-3d)) + (test-case "pr58 2d plots title+axes" + (check-draw-steps do-plot-2d-title+axes pr58-2d-t)) + (test-case "pr58 3d plots title+axes" + (check-draw-steps-3d do-plot-3d-title+axes pr58-3d-t)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr58-test-suite)) + + diff --git a/plot-test/plot/tests/PRs/59.rkt b/plot-test/plot/tests/PRs/59.rkt new file mode 100644 index 00000000..64a44ea5 --- /dev/null +++ b/plot-test/plot/tests/PRs/59.rkt @@ -0,0 +1,40 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/59 + +(define (do-plot-not-inverted output-fn) + (output-fn (list (function sqr 1 7) + (error-bars (list (vector 2 4 12) + (vector 4 16 20) + (vector 6 36 10)) + #:invert? #f)) + #:title "Error Bars NOT Inverted")) + +;; NOTE: both the invert? parameter and the coordinates need to be inverted. +(define (do-plot-inverted output-fn) + (output-fn (list (function sqr 1 7) + (error-bars (list (vector 4 2 12) + (vector 16 4 20) + (vector 36 6 10)) + #:invert? #t)) + #:title "Error Bars Inverted")) + +(define-runtime-path pr59-not-inverted-data "./test-data/pr59-1.dat") +(define-runtime-path pr59-inverted-data "./test-data/pr59-2.dat") + +(define pr59-test-suite + (test-suite + "PR#59: Add #:invert? option to error-bars" + (test-case "pr59 not inverted" + (check-draw-steps do-plot-not-inverted pr59-not-inverted-data)) + (test-case "pr59 inverted" + (check-draw-steps do-plot-inverted pr59-inverted-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr59-test-suite)) diff --git a/plot-test/plot/tests/PRs/6.rkt b/plot-test/plot/tests/PRs/6.rkt new file mode 100644 index 00000000..5f57216f --- /dev/null +++ b/plot-test/plot/tests/PRs/6.rkt @@ -0,0 +1,41 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; See https://github.com/racket/plot/issues/6 and associated discution. + +(define-runtime-path pr6-data-round "./test-data/pr6-round.dat") +(define-runtime-path pr6-data-butt "./test-data/pr6-butt.dat") +(define-runtime-path pr6-data-projecting "./test-data/pr6-projecting.dat") + +(define (do-plot-pr6 output-fn) + (parameterize + ([plot-line-width 10] + [line-width 10] + [plot-pen-color-map 'set1]) + (output-fn + (list + (function sin -5 5 #:color 1 #:label "sin(x)") + (function cos -5 5 #:color 2 #:label "cos(x)"))))) + +(define pr6-test-suite + (test-suite + "PR#6: Add plot-line-cap and line-cap parameters" + (test-case "pr6-round" + (parameterize ([plot-line-cap 'round] + [line-cap 'round]) + (check-draw-steps do-plot-pr6 pr6-data-round))) + (test-case "pr6-butt" + (parameterize ([plot-line-cap 'butt] + [line-cap 'butt]) + (check-draw-steps do-plot-pr6 pr6-data-butt))) + (test-case "pr6-projecting" + (parameterize ([plot-line-cap 'projecting] + [line-cap 'projecting]) + (check-draw-steps do-plot-pr6 pr6-data-projecting))))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr6-test-suite)) diff --git a/plot-test/plot/tests/PRs/66.rkt b/plot-test/plot/tests/PRs/66.rkt new file mode 100644 index 00000000..bc2f1db3 --- /dev/null +++ b/plot-test/plot/tests/PRs/66.rkt @@ -0,0 +1,37 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/66 : color-field +(define (do-plot-color-field output-fn) + (output-fn + (color-field + (λ (x y) + (define z (make-rectangular x y)) + (if (< (magnitude z) 1) + (cond + [(< (magnitude z) 0.5) 'red] + [(< (angle z) 0) 'blue] + [else 'green]) + 'black)) + -2 2 -2 2))) + +(define-runtime-path pr66-color-field-data "./test-data/pr66-1.dat") + +(define pr66-test-suite + (test-suite + "PR#66: color-field" + (test-case "pr66-color-field" + (check-draw-steps do-plot-color-field pr66-color-field-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr66-test-suite)) + +;; + + + diff --git a/plot-test/plot/tests/PRs/68.rkt b/plot-test/plot/tests/PRs/68.rkt new file mode 100644 index 00000000..12b142ae --- /dev/null +++ b/plot-test/plot/tests/PRs/68.rkt @@ -0,0 +1,26 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/68 + +(define (do-plot-vector-field output-fn) + (output-fn + (vector-field (λ (x y) (list x 0)) + -10 10 -10 10 + #:scale 'auto))) + +(define-runtime-path pr68-vectorfield-data "./test-data/pr68.dat") + +(define pr68-test-suite + (test-suite + "PR#68: vector-field divide by zero error" + (test-case "pr68-vectorfield" + (check-draw-steps do-plot-vector-field pr68-vectorfield-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr68-test-suite)) diff --git a/plot-test/plot/tests/PRs/70-75.rkt b/plot-test/plot/tests/PRs/70-75.rkt new file mode 100644 index 00000000..017fde4a --- /dev/null +++ b/plot-test/plot/tests/PRs/70-75.rkt @@ -0,0 +1,246 @@ +#lang racket +(require rackunit + plot + racket/draw + racket/runtime-path + pict + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/70, 71, 72, 73, 74 + +(define rendertree2d (list (function values 0 1 #:label "fct" #:color 'blue) + (contour-intervals (λ (x y) (* x y)) 1 2 #:label "cti"))) + +(define rendertree3d (list (surface3d (λ (x y) 1) 0 1 0 1 #:label "srf") + (contour-intervals3d (λ (x y) (* x y)) 1 2 1 2 #:label "cti"))) + + +(define-runtime-path pr70/75-2d-nl "./test-data/pr70-2d-no-legend.dat") +(define (do-plot-2d-nl output-fn) + (output-fn rendertree2d + #:legend-anchor 'no-legend + #:title "no-legend")) + +(define-runtime-path pr70/75-2d-otl "./test-data/pr70-2d-outside-top-left.dat") +(define (do-plot-2d-otl output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-top-left + #:title "outside-top-left")) + +(define-runtime-path pr70/75-2d-ot "./test-data/pr70-2d-outside-top.dat") +(define (do-plot-2d-ot output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-top + #:title "outside-top")) + +(define-runtime-path pr70/75-2d-otr "./test-data/pr70-2d-outside-top-right.dat") +(define (do-plot-2d-otr output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-top-right + #:title "outside-top-right")) + +(define-runtime-path pr70/75-2d-olt "./test-data/pr70-2d-outside-left-top.dat") +(define (do-plot-2d-olt output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-left-top + #:title "outside-left-top")) + +(define-runtime-path pr70/75-2d-ol "./test-data/pr70-2d-outside-left.dat") +(define (do-plot-2d-ol output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-left + #:title "outside-left")) + +(define-runtime-path pr70/75-2d-olb "./test-data/pr70-2d-outside-left-bottom.dat") +(define (do-plot-2d-olb output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-left-bottom + #:title "outside-left-bottom")) + +(define-runtime-path pr70/75-2d-ort "./test-data/pr70-2d-outside-right-top.dat") +(define (do-plot-2d-ort output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-right-top + #:title "outside-right-top")) + +(define-runtime-path pr70/75-2d-or "./test-data/pr70-2d-outside-right.dat") +(define (do-plot-2d-or output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-right + #:title "outside-right")) + +(define-runtime-path pr70/75-2d-orb "./test-data/pr70-2d-outside-right-bottom.dat") +(define (do-plot-2d-orb output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-right-bottom + #:title "outside-right-bottom")) + +(define-runtime-path pr70/75-2d-obl "./test-data/pr70-2d-outside-bottom-left.dat") +(define (do-plot-2d-obl output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-bottom-left + #:title "outside-bottom-left")) + +(define-runtime-path pr70/75-2d-ob "./test-data/pr70-2d-outside-bottom.dat") +(define (do-plot-2d-ob output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-bottom + #:title "outside-bottom")) + +(define-runtime-path pr70/75-2d-obr "./test-data/pr70-2d-outside-bottom-right.dat") +(define (do-plot-2d-obr output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-bottom-right + #:title "outside-bottom-right")) + +(define-runtime-path pr70/75-2d-ogt "./test-data/pr70-2d-outside-global-top.dat") +(define (do-plot-2d-ogt output-fn) + (output-fn rendertree2d + #:legend-anchor 'outside-global-top + #:title "outside-global-top")) + +(define-runtime-path pr70/75-3d-nl "./test-data/pr70-3d-no-legend.dat") +(define (do-plot-3d-nl output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'no-legend + #:title "no-legend")) + +(define-runtime-path pr70/75-3d-otl "./test-data/pr70-3d-outside-top-left.dat") +(define (do-plot-3d-otl output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-top-left + #:title "outside-top-left")) + +(define-runtime-path pr70/75-3d-ot "./test-data/pr70-3d-outside-top.dat") +(define (do-plot-3d-ot output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-top + #:title "outside-top")) + +(define-runtime-path pr70/75-3d-otr "./test-data/pr70-3d-outside-top-right.dat") +(define (do-plot-3d-otr output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-top-right + #:title "outside-top-right")) + +(define-runtime-path pr70/75-3d-olt "./test-data/pr70-3d-outside-left-top.dat") +(define (do-plot-3d-olt output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-left-top + #:title "outside-left-top")) + +(define-runtime-path pr70/75-3d-ol "./test-data/pr70-3d-outside-left.dat") +(define (do-plot-3d-ol output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-left + #:title "outside-left")) + +(define-runtime-path pr70/75-3d-olb "./test-data/pr70-3d-outside-left-bottom.dat") +(define (do-plot-3d-olb output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-left-bottom + #:title "outside-left-bottom")) + +(define-runtime-path pr70/75-3d-ort "./test-data/pr70-3d-outside-right-top.dat") +(define (do-plot-3d-ort output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-right-top + #:title "outside-right-top")) + +(define-runtime-path pr70/75-3d-or "./test-data/pr70-3d-outside-right.dat") +(define (do-plot-3d-or output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-right + #:title "outside-right")) + +(define-runtime-path pr70/75-3d-orb "./test-data/pr70-3d-outside-right-bottom.dat") +(define (do-plot-3d-orb output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-right-bottom + #:title "outside-right-bottom")) + +(define-runtime-path pr70/75-3d-obl "./test-data/pr70-3d-outside-bottom-left.dat") +(define (do-plot-3d-obl output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-bottom-left + #:title "outside-bottom-left")) + +(define-runtime-path pr70/75-3d-ob "./test-data/pr70-3d-outside-bottom.dat") +(define (do-plot-3d-ob output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-bottom + #:title "outside-bottom")) + +(define-runtime-path pr70/75-3d-obr "./test-data/pr70-3d-outside-bottom-right.dat") +(define (do-plot-3d-obr output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-bottom-right + #:title "outside-bottom-right")) + +(define-runtime-path pr70/75-3d-ogt "./test-data/pr70-3d-outside-global-top.dat") +(define (do-plot-3d-ogt output-fn) + (output-fn (cons (points3d '((0 1 2)) #:label "an extra really really really long label") + rendertree3d) + #:legend-anchor 'outside-global-top + #:title "outside-global-top")) + +(define pr70-test-suite + (test-suite + "PR#70-75: outside legend placements" + (test-case "2d no-legend" (check-draw-steps do-plot-2d-nl pr70/75-2d-nl)) + + (test-case "2d outside-top-left" (check-draw-steps do-plot-2d-otl pr70/75-2d-otl)) + (test-case "2d outside-top" (check-draw-steps do-plot-2d-ot pr70/75-2d-ot)) + (test-case "2d outside-top-right" (check-draw-steps do-plot-2d-otr pr70/75-2d-otr)) + + (test-case "2d outside-left-top" (check-draw-steps do-plot-2d-olt pr70/75-2d-olt)) + (test-case "2d outside-left" (check-draw-steps do-plot-2d-ol pr70/75-2d-ol)) + (test-case "2d outside-left-bottom" (check-draw-steps do-plot-2d-olb pr70/75-2d-olb)) + + (test-case "2d outside-right-top" (check-draw-steps do-plot-2d-ort pr70/75-2d-ort)) + (test-case "2d outside-right" (check-draw-steps do-plot-2d-or pr70/75-2d-or)) + (test-case "2d outside-right-bottom" (check-draw-steps do-plot-2d-orb pr70/75-2d-orb)) + + (test-case "2d outside-bottom-left" (check-draw-steps do-plot-2d-obl pr70/75-2d-obl)) + (test-case "2d outside-bottom" (check-draw-steps do-plot-2d-ob pr70/75-2d-ob)) + (test-case "2d outside-bottom-right" (check-draw-steps do-plot-2d-obr pr70/75-2d-obr)) + + (test-case "2d outside-global-top" (check-draw-steps do-plot-2d-ogt pr70/75-2d-ogt)) + + (test-case "3d no-legend" (check-draw-steps-3d do-plot-3d-nl pr70/75-3d-nl)) + (test-case "3d outside-top-left" (check-draw-steps-3d do-plot-3d-otl pr70/75-3d-otl)) + (test-case "3d outside-top" (check-draw-steps-3d do-plot-3d-ot pr70/75-3d-ot)) + (test-case "3d outside-top-right" (check-draw-steps-3d do-plot-3d-otr pr70/75-3d-otr)) + + (test-case "3d outside-left-top" (check-draw-steps-3d do-plot-3d-olt pr70/75-3d-olt)) + (test-case "3d outside-left" (check-draw-steps-3d do-plot-3d-ol pr70/75-3d-ol)) + (test-case "3d outside-left-bottom" (check-draw-steps-3d do-plot-3d-olb pr70/75-3d-olb)) + + (test-case "3d outside-right-top" (check-draw-steps-3d do-plot-3d-ort pr70/75-3d-ort)) + (test-case "3d outside-right" (check-draw-steps-3d do-plot-3d-or pr70/75-3d-or)) + (test-case "3d outside-right-bottom" (check-draw-steps-3d do-plot-3d-orb pr70/75-3d-orb)) + + (test-case "3d outside-bottom-left" (check-draw-steps-3d do-plot-3d-obl pr70/75-3d-obl)) + (test-case "3d outside-bottom" (check-draw-steps-3d do-plot-3d-ob pr70/75-3d-ob)) + (test-case "3d outside-bottom-right" (check-draw-steps-3d do-plot-3d-obr pr70/75-3d-obr)) + + (test-case "3d outside-global-top" (check-draw-steps-3d do-plot-3d-ogt pr70/75-3d-ogt)) + + )) + +(module+ test + (require rackunit/text-ui) + (run-tests pr70-test-suite)) diff --git a/plot-test/plot/tests/PRs/75.rkt b/plot-test/plot/tests/PRs/75.rkt new file mode 100644 index 00000000..3b5f8033 --- /dev/null +++ b/plot-test/plot/tests/PRs/75.rkt @@ -0,0 +1,23 @@ +#lang racket +(require rackunit + plot pict + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/75 + +(define (do-plot-margin-calc output-fn) + (output-fn (function values 0 1) + #:title (standard-fish 700 350))) + +(define-runtime-path pr75-data "./test-data/pr75.dat") + +(define pr75-test-suite + (test-suite + "PR#75: margin error" + (test-case "pr75-margin" + (check-draw-steps do-plot-margin-calc pr75-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr75-test-suite)) diff --git a/plot-test/plot/tests/PRs/76.rkt b/plot-test/plot/tests/PRs/76.rkt new file mode 100644 index 00000000..9e947d81 --- /dev/null +++ b/plot-test/plot/tests/PRs/76.rkt @@ -0,0 +1,25 @@ +#lang racket +(require rackunit + plot pict + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/68 + +(define (do-plot-title output-fn) + (output-fn + (surface3d (λ (x y) 1) 0 1 0 1) + #:title (standard-fish 100 50))) + +(define-runtime-path pr76-data "./test-data/pr76.dat") + +(define pr76-test-suite + (test-suite + "PR#76: pict title for plot3d" + (test-case "pr76-plot3d-title" + (check-draw-steps-3d do-plot-title pr76-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr76-test-suite)) diff --git a/plot-test/plot/tests/PRs/81-legend-layout.rkt b/plot-test/plot/tests/PRs/81-legend-layout.rkt new file mode 100644 index 00000000..e8e4fde6 --- /dev/null +++ b/plot-test/plot/tests/PRs/81-legend-layout.rkt @@ -0,0 +1,51 @@ +#lang racket +(require rackunit + plot pict + racket/draw + racket/runtime-path + "../helpers.rkt") + +;; Tests for: https://github.com/racket/plot/pull/68 + +(define rendertree + (list (contour-intervals (λ (x y) (* x y)) 0 1 #:label "a") + (function values 0 1 #:label "b" #:color 1) + (function add1 0 1 #:label "a rather long one" #:color 2) + (function sub1 0 1 #:label (standard-fish 20 40) #:color 4))) + +(define (do-3row-equal output-fn) + (parameterize ([plot-legend-layout '(rows 3 equal-size)]) + (output-fn rendertree #:legend-anchor 'outside-top))) + +(define (do-3row-compact output-fn) + (parameterize ([plot-legend-layout '(rows 3 compact)]) + (output-fn rendertree #:legend-anchor 'outside-top))) + +(define (do-2col-equal output-fn) + (parameterize ([plot-legend-layout '(columns 2 equal-size)]) + (output-fn rendertree #:legend-anchor 'outside-left))) + +(define (do-2col-compact output-fn) + (parameterize ([plot-legend-layout '(columns 2 compact)]) + (output-fn rendertree #:legend-anchor 'outside-left))) + +(define-runtime-path pr81-data-1 "./test-data/pr81-1.dat") +(define-runtime-path pr81-data-2 "./test-data/pr81-2.dat") +(define-runtime-path pr81-data-3 "./test-data/pr81-3.dat") +(define-runtime-path pr81-data-4 "./test-data/pr81-4.dat") + +(define pr81-test-suite + (test-suite + "PR#81: horizontal layout for legend" + (test-case "pr81-3row-equal" + (check-draw-steps do-3row-equal pr81-data-1)) + (test-case "pr81-3row-compact" + (check-draw-steps do-3row-compact pr81-data-2)) + (test-case "pr81-2col-equal" + (check-draw-steps do-2col-equal pr81-data-3)) + (test-case "pr81-2col-compact" + (check-draw-steps do-2col-compact pr81-data-4)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr81-test-suite)) diff --git a/plot-test/plot/tests/PRs/86.rkt b/plot-test/plot/tests/PRs/86.rkt new file mode 100644 index 00000000..bc813606 --- /dev/null +++ b/plot-test/plot/tests/PRs/86.rkt @@ -0,0 +1,34 @@ +#lang racket +(require rackunit + plot pict racket/runtime-path + "../helpers.rkt") + +; tests for PR#86, https://github.com/racket/plot/pull/86 +; "add scientific? argument to log-ticks and log-ticks-format" + +(define ((do-plot scientific? [base 10]) output-fn) + (parameterize ([plot-x-ticks (log-ticks #:scientific? scientific? #:base base)] + [plot-x-transform log-transform]) + (output-fn + (function (λ (x) (log x base)) 1 1000)))) + +(define-runtime-path pr86-base10-sci-data "./test-data/pr86-1.dat") +(define-runtime-path pr86-base10-nosci-data "./test-data/pr86-2.dat") +(define-runtime-path pr86-base2-sci-data "./test-data/pr86-3.dat") +(define-runtime-path pr86-base2-nosci-data "./test-data/pr86-4.dat") + +(define pr86-test-suite + (test-suite + "PR#86: add scientific? to log-ticks" + (test-case "PR86: base 10, scientific? #t" + (check-draw-steps (do-plot #t 10) pr86-base10-sci-data)) + (test-case "PR86: base 10, scientific? #f" + (check-draw-steps (do-plot #f 10) pr86-base10-nosci-data)) + (test-case "PR86: base 2, scientific? #t" + (check-draw-steps (do-plot #t 2) pr86-base2-sci-data)) + (test-case "PR86: base 2, scientific? #f" + (check-draw-steps (do-plot #f 2) pr86-base2-nosci-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr86-test-suite)) diff --git a/plot-test/plot/tests/PRs/88.rkt b/plot-test/plot/tests/PRs/88.rkt new file mode 100644 index 00000000..dec93876 --- /dev/null +++ b/plot-test/plot/tests/PRs/88.rkt @@ -0,0 +1,99 @@ +#lang racket + +(require rackunit + plot racket/runtime-path + "../helpers.rkt") + +;; Tests for https://github.com/racket/plot/pull/88, aspect ratio function +;; testing. + +(plot-background "lightblue") +(plot-x-label #f) +(plot-y-label #f) +(plot-aspect-ratio #f) + +(define (do-plot-no-ar output-fn) + (output-fn (polar (lambda (t) 1)) + #:width 300 #:height 150 + #:title "No Aspect Ratio")) + +(define-runtime-path pr88-no-ar-data "./test-data/pr88-no-ar.dat") + +(define (do-plot-1610-ar output-fn) + (output-fn (polar (lambda (t) 1)) + #:aspect-ratio 16/10 + #:width 300 #:height 150 + #:title "16:10 Aspect Ratio")) + +(define-runtime-path pr88-1610-ar-data "./test-data/pr88-1610-ar.dat") + +(define (do-plot-11-ar output-fn) + (output-fn (polar (lambda (t) 1)) + #:aspect-ratio 1/1 + #:width 300 #:height 150 + #:title "1:1 Aspect Ratio")) + +(define-runtime-path pr88-11-ar-data "./test-data/pr88-11-ar.dat") + +(define (do-plot-11-ar-portrait output-fn) + (output-fn (polar (lambda (t) 1)) + #:aspect-ratio 1/1 + #:width 150 #:height 300 + #:title "1:1 Aspect Ratio")) + +(define-runtime-path pr88-11-ar-portrait-data "./test-data/pr88-11-ar-portrait.dat") + +(define (do-plot3d-no-ar output-fn) + (output-fn (polar3d (lambda (a b) 1)) + #:width 300 #:height 150 + #:title "No Aspect Ratio")) + +(define-runtime-path pr88-3d-no-ar-data "./test-data/pr88-3d-no-ar.dat") + +(define (do-plot3d-1610-ar output-fn) + (output-fn (polar3d (lambda (a b) 1)) + #:aspect-ratio 16/10 + #:width 300 #:height 150 + #:title "16:10 Aspect Ratio")) + +(define-runtime-path pr88-3d-1610-ar-data "./test-data/pr88-3d-1610-ar.dat") + +(define (do-plot3d-11-ar output-fn) + (output-fn (polar3d (lambda (a b) 1)) + #:aspect-ratio 1/1 + #:width 300 #:height 150 + #:title "1:1 Aspect Ratio")) + +(define-runtime-path pr88-3d-11-ar-data "./test-data/pr88-3d-11-ar.dat") + +(define (do-plot3d-11-ar-portrait output-fn) + (output-fn (polar3d (lambda (a b) 1)) + #:aspect-ratio 1/1 + #:width 150 #:height 300 + #:title "1:1 Aspect Ratio")) + +(define-runtime-path pr88-3d-11-ar-portrait-data "./test-data/pr88-3d-11-ar-portrait.dat") + +(define pr88-test-suite + (test-suite + "PR#88: add support for aspect-ratio" + (test-case "No Aspect Ratio" + (check-draw-steps do-plot-no-ar pr88-no-ar-data)) + (test-case "16:10 Aspect Ratio" + (check-draw-steps do-plot-1610-ar pr88-1610-ar-data)) + (test-case "1:1 Aspect Ratio" + (check-draw-steps do-plot-11-ar pr88-11-ar-data)) + (test-case "1:1 Aspect Ratio Portrait" + (check-draw-steps do-plot-11-ar-portrait pr88-11-ar-portrait-data)) + (test-case "No Aspect Ratio" + (check-draw-steps-3d do-plot3d-no-ar pr88-3d-no-ar-data)) + (test-case "16:10 Aspect Ratio" + (check-draw-steps-3d do-plot3d-1610-ar pr88-3d-1610-ar-data)) + (test-case "1:1 Aspect Ratio" + (check-draw-steps-3d do-plot3d-11-ar pr88-3d-11-ar-data)) + (test-case "1:1 Aspect Ratio Portrait" + (check-draw-steps-3d do-plot3d-11-ar-portrait pr88-3d-11-ar-portrait-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr88-test-suite)) diff --git a/plot-test/plot/tests/PRs/89.rkt b/plot-test/plot/tests/PRs/89.rkt new file mode 100644 index 00000000..1a889bec --- /dev/null +++ b/plot-test/plot/tests/PRs/89.rkt @@ -0,0 +1,29 @@ +#lang racket +(require rackunit + plot pict racket/runtime-path + "../helpers.rkt") + +; tests for PR#89, https://github.com/racket/plot/pull/89 +; "fix calculation of text-extends for anchor 'right center left" + +(define (do-plot output-fn) + (parameterize ([plot-x-label #f] + [plot-y-label #f]) + (output-fn + (polar (lambda (t) 1)) + #:x-min 4025584149602844706/10000000000000000000 + #:x-max 4025584149602844712/10000000000000000000 + #:y-min 6805367900508167/10000000000000000 + #:y-max 6805367900508171/10000000000000000))) + +(define-runtime-path pr89 "./test-data/pr89.dat") + +(define pr86-test-suite + (test-suite + "PR#89: text-extents" + (test-case "PR89: text-extents" + (check-draw-steps do-plot pr89)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pr86-test-suite)) diff --git a/plot-test/plot/tests/PRs/90.rkt b/plot-test/plot/tests/PRs/90.rkt new file mode 100644 index 00000000..587ecfbd --- /dev/null +++ b/plot-test/plot/tests/PRs/90.rkt @@ -0,0 +1,87 @@ +#lang racket +(require pict + plot + racket/draw + (only-in racket/gui/base + sleep/yield) + rackunit) + + +; tests for PR#90, https://github.com/racket/plot/pull/90 +; "Plotmetrics: access/calculate data about the plot area" + + +(define pr90-test-suite + (make-test-suite + "PR#90: plotmetrics" + (append + (let* ([bm (make-object bitmap% 400 400)] + [dc (make-object bitmap-dc% bm)] + [pm (plot/dc (polar (λ (x) x)) dc 0 0 400 400)]) + (list (test-suite "PR90: plot-metrics get-plot-bounds" + (check-within (send pm get-plot-bounds) + #(#(-3.2883704095701205 6.283185307179586) + #(-4.8144539337330965 1.81970262809755)) + 1e-15)) + (test-suite "PR90: plot-metrics plot->dc & dc->plot" + (check-within (send pm dc->plot (send pm plot->dc #(0 0))) + #(0 0) 1e-15)) + (test-suite "PR90: plot-metrics plane-vector" + (check-equal? (send pm plane-vector) + #(0 0 1))))) + + (let ([pmbm (plot3d-bitmap (polar3d (λ (ϕ θ) ϕ)))]) + (list (test-suite "PR90: bitmap" (check-true (is-a? pmbm bitmap%))) + (test-suite "PR90: 3d/bitmap get-plot-bounds" + (check-within (send pmbm get-plot-bounds) + #(#(-3.287703432872698 6.282003882664296) + #(-4.812750657123522 1.819088586099858) + #(-6.283185307179587 6.283185307179587)) + 1e-15)) + (test-suite "PR90: 3d/bitmap plot->dc & dc->plot" + (check-within (send pmbm plot->dc (send pmbm dc->plot #(200 200))) + #(200 200) 1e-15)) + (test-suite "PR90: 3d/bitmap plane-vector" + (check-equal? (send pmbm plot->dc (send pmbm plane-vector)) + (send pmbm plot->dc #(0 0 0)))))) + + (let ([pp (plot-pict (function (λ (x) x) 1 2))]) + (list (test-suite "PR90: plot-pict" (check-true (and (plot-pict? pp) (pict? pp)))) + (test-suite "PR90: plot-pict get-plot-bounds" + (check-equal? (plot-pict-bounds pp) + #(#(1 2) #(1 2)))) + (test-suite "PR90: plot-pict plot->dc & dc->plot" + (check-within ((plot-pict-dc->plot pp) ((plot-pict-plot->dc pp) #(0 0))) + #(0 0) 1e-15)) + (test-suite "PR90: plot-pict plane-vector" + (check-equal? (plot-pict-plane-vector pp) + #(0 0 1))))) + + (let* ([ps (plot3d-snip (surface3d (λ (x y) (+ x y)) 0 1 1 2))] + [plotcoords #(1 1 1)] + [coords (send ps plot->dc plotcoords)]) + (list (test-suite "PR90: 3d/snip" (check-true (is-a? ps plot-metrics<%>))) + (test-suite "PR90: 3d/snip get-plot-bounds" + (check-equal? (send ps get-plot-bounds) + #(#(0 1) #(1 2) #(1 3)))) + (test-suite "PR90: 3d/snip plot->dc & dc->plot" + (check-within (send ps plot->dc (send ps dc->plot #(200 200))) + #(200 200) 1e-13)) + (test-suite "PR90: 3d/snip plane-vector" + (check-equal? (send ps plot->dc (send ps plane-vector)) + (send ps plot->dc #(0 0 0)))) + (test-suite "PR90: 3d/snip before resize" + (check-equal? (send ps plot->dc plotcoords) coords)) + ;It's uncertain that the sleep/yield will be long enough for the async update to finish + ;for now this test is disabled. + #;(test-suite "PR90: 3d/snip after resize" + (send ps resize 800 800) + (sleep/yield .5) + (check-within (send ps plot->dc (send ps dc->plot #(200 200))) + #(200 200) 1e-13) + (check-not-equal? (send ps plot->dc plotcoords) coords))))) + )) + +(module+ test + (require rackunit/text-ui) + (run-tests pr90-test-suite)) diff --git a/plot-test/plot/tests/PRs/plot-unsafe-provide.rkt b/plot-test/plot/tests/PRs/plot-unsafe-provide.rkt new file mode 100644 index 00000000..57e01deb --- /dev/null +++ b/plot-test/plot/tests/PRs/plot-unsafe-provide.rkt @@ -0,0 +1,480 @@ +#lang racket/base + +;; Check that bad arguments to plot functions do not cause segfaults. +;; (since these functions are exported via `unsafe-provide`) +;; +;; To run these tests: +;; 1. `raco test ` +;; 2. uncomment the code at the bottom of this file, +;; run `racket ` +;; check that the tests output contract violations --- nothing worse +;; +;; It would be good to eliminate step 2, but rackunit and `with-handlers` don't +;; catch the exceptions. + +(require plot rackunit) + +(define BAD-ARG ;; none of the plot functions expect a box + (box #f)) + +(define example-renderer2 + (points (for/list ((i (in-range 0 4))) (list 0 i)) #:label "some points")) + +(define example-nonrenderer2 + (invisible-rect -5 5 -5 5)) + +(define example-renderer3 + (vector-field3d (λ (x y z) (vector x z y)) -2 2 -2 2 -2 2)) + +(define example-nonrenderer3 + (invisible-rect3d -5 5 -5 5 -5 5)) + +;; ----------------------------------------------------------------------------- +;; These tests should all pass + +(module+ test + (test-case "plot-snip" + (check-exn exn:fail:contract? + (lambda () + (plot-snip BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 BAD-ARG)))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:height BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:title BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:x-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:y-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-snip (list example-renderer2 example-nonrenderer2) + #:legend-anchor BAD-ARG)))) + + (test-case "plot-frame" + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:height BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot-frame (list example-renderer2 example-nonrenderer2) + #:legend-anchor BAD-ARG)))) + + (test-case "plot" + (check-exn exn:fail:contract? + (lambda () + (plot BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:height BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:title BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:x-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:y-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:legend-anchor BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:out-file BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:out-kind BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:fgcolor BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:bgcolor BAD-ARG))) + + (check-not-exn ;; unused argument + (lambda () + (plot (list example-renderer2 example-nonrenderer2) + #:lncolor BAD-ARG)))) + + (test-case "plot3d-snip" + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 BAD-ARG)))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:z-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:z-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:height BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:angle BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:altitude BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:title BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:x-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:y-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:z-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-snip (list example-renderer3 example-nonrenderer3) + #:legend-anchor BAD-ARG)))) + + (test-case "plot3d-frame" + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:z-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:z-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:height BAD-ARG)))) + + (test-case "plot3d" + (check-exn exn:fail:contract? + (lambda () + (plot3d BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:x-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:x-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:y-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:y-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:z-min BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:z-max BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:width BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:height BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:angle BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:altitude BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:az BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:alt BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:title BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:x-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:y-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:z-label BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:legend-anchor BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:out-file BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:out-kind BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:fgcolor BAD-ARG))) + + (check-exn exn:fail:contract? + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:bgcolor BAD-ARG))) + + (check-not-exn ;; unused argument + (lambda () + (plot3d (list example-renderer3 example-nonrenderer3) + #:lncolor BAD-ARG)))) + +) + +;; ----------------------------------------------------------------------------- +;; When uncommented, these expressions should raise contract error messages +;; that blame `BAD-ARG` (given: '#&#f) + +#;(let () + (plot-frame BAD-ARG) + (plot-frame (list example-renderer2 example-nonrenderer2) + #:title BAD-ARG) + (plot-frame (list example-renderer2 example-nonrenderer2) + #:x-label BAD-ARG) + (plot-frame (list example-renderer2 example-nonrenderer2) + #:y-label BAD-ARG) + (plot3d-frame BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:angle BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:altitude BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:title BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:x-label BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:y-label BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:z-label BAD-ARG) + (plot3d-frame (list example-renderer3 example-nonrenderer3) + #:legend-anchor BAD-ARG) + (void)) diff --git a/plot-test/plot/tests/PRs/snip-empty-selection.rkt b/plot-test/plot/tests/PRs/snip-empty-selection.rkt new file mode 100644 index 00000000..1a64eabe --- /dev/null +++ b/plot-test/plot/tests/PRs/snip-empty-selection.rkt @@ -0,0 +1,56 @@ +#lang racket +(require plot racket/gui/base racket/draw rackunit) + +;; 2D interactive plots would occasionally thrown an exception if the user +;; clicked on the plot. This was because the system would interpret it as a +;; drag-select operation which started and finished at the same place, +;; resulting in an empty selection -- empty selections are represented using +;; +nan.0, which cannot be converted to an exact number. +;; +;; In this test we simulate an empty selection using mouse events sent +;; directly to the snips `on-event` method. + +(define empty-selection-zoom + (test-suite + "empty-selection-zoom" + (test-case "empty-selection-zoom" + + ;; Scaffolding, construct a pasteboard to hold our plot snip + (define tl (new frame% [label "hello"] [width 800] [height 600])) + (define pb [new pasteboard%]) + (define editor (new editor-canvas% [parent tl] [editor pb])) + + ;; Construct the plot snip and add it to the pasteboard so it has an + ;; administrator. + (define snip (plot-snip (function sin -3 3))) + (send pb insert snip) + + ;; Show the frame -- this is not strictly needed, but will ensure that + ;; all widgets have their proper dimensions set and mouse events will be + ;; "interpreted" according to correct snip positions. + (send tl show #t) + + ;; Construct a dummy DC and the left-click, drag, left-release events + ;; which will simulate the drag-selection on the snip. Note that the + ;; start and end events have the same X, Y coordinates, which will result + ;; in an empty rectangle being selected. + (define dc (new record-dc% [width 800] [height 600])) + (define click (new mouse-event% [event-type 'left-down] [x 10] [y 10])) + (define drag (new mouse-event% [event-type 'motion] [left-down #t] [x 11] [y 11])) + (define unclick (new mouse-event% [event-type 'left-up] [x 10] [y 10])) + + ;; Send the snip the events -- the snip will think the user is selecting + ;; a region on the plot. + (send snip on-event dc 0 0 0 0 click) + (send snip on-event dc 0 0 0 0 drag) + (after + (check-not-exn + ;; zoom is triggered when the user releases the mouse event -- this + ;; used to throw an exception as it tried to operate on an empty + ;; rectangle, containing +nan.0 numbers. + (lambda () (send snip on-event dc 0 0 0 0 unclick))) + (send tl show #f))))) + +(module+ test + (require rackunit/text-ui) + (run-tests empty-selection-zoom)) diff --git a/plot-test/plot/tests/PRs/snip-overlay-renderers.rkt b/plot-test/plot/tests/PRs/snip-overlay-renderers.rkt new file mode 100644 index 00000000..5b3d97e4 --- /dev/null +++ b/plot-test/plot/tests/PRs/snip-overlay-renderers.rkt @@ -0,0 +1,57 @@ +#lang racket +(require plot racket/gui/base racket/draw rackunit) + +;; Refactoring done as part of #49 changed the number of init fields for the +;; 2d-plot-area%, but didn't update the overlay-renderer plot area. This unit +;; test exists to ensure that the overlay plot area is created at least once +;; during the testing process, and any initialization problems are caught +;; early. +;; +;; An additional bug was found where the `set-overlay-renderers` would only +;; accept a flat list of renderers instead of a renderer tree as advertised by +;; the method contract -- this unit tests also verifies that +;; `set-overlay-renderers` does in fact accept renderer trees. + +(define snip-overlay-renderers + (test-suite + "snip-overlay-renderers" + (test-case "snip-overlay-renderers" + + ;; Scaffolding, construct a pasteboard to hold our plot snip + (define tl (new frame% [label "hello"] [width 800] [height 600])) + (define pb [new pasteboard%]) + (define editor (new editor-canvas% [parent tl] [editor pb])) + + ;; Construct the plot snip and add it to the pasteboard so it has an + ;; administrator. + (define snip (plot-snip (function sin -3 3))) + (send pb insert snip) + + ;; Show the frame -- this is not strictly needed, but will ensure that + ;; all widgets have their proper dimensions set and mouse events will be + ;; "interpreted" according to correct snip positions. + (send tl show #t) + + ;; Construct a dummy DC on which to draw the snip + (define dc (new record-dc% [width 800] [height 600])) + + (after + (check-not-exn + (lambda () + ;; The 2d-plot-area% for the overlay area is created on-demand when + ;; overlay renderers are present. Also the overlay renderers are a + ;; renderer tree (nested lists) to ensure that these are accepted by + ;; the method. + (send snip set-overlay-renderers + (list (function cos -3 3) (list (vrule -1) (vrule 1)))) + (send snip draw dc 0 0 0 0 10 10 0 0 'no-caret) + + ;; Ensure that #f handled correctly, see + ;; https://github.com/racket/racket/issues/3753 + (send snip set-overlay-renderers #f) + (send snip draw dc 0 0 0 0 10 10 0 0 'no-caret))) + (send tl show #f))))) + +(module+ test + (require rackunit/text-ui) + (run-tests snip-overlay-renderers)) diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-ci.dat b/plot-test/plot/tests/PRs/test-data/gnats13620-ci.dat new file mode 100644 index 00000000..b79612c2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-ci.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-ci.png b/plot-test/plot/tests/PRs/test-data/gnats13620-ci.png new file mode 100644 index 00000000..b8f5b0e8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-ci.png differ diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.dat b/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.dat new file mode 100644 index 00000000..6675a504 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.png b/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.png new file mode 100644 index 00000000..2e8f1525 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-ci3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.dat b/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.dat new file mode 100644 index 00000000..6675a504 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.png b/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.png new file mode 100644 index 00000000..2e8f1525 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/gnats13620-is3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-a.dat b/plot-test/plot/tests/PRs/test-data/pr107-a.dat new file mode 100644 index 00000000..0f343952 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-a.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-a.png b/plot-test/plot/tests/PRs/test-data/pr107-a.png new file mode 100644 index 00000000..bff78214 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-a.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-b.dat b/plot-test/plot/tests/PRs/test-data/pr107-b.dat new file mode 100644 index 00000000..5e7c9a3a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-b.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-b.png b/plot-test/plot/tests/PRs/test-data/pr107-b.png new file mode 100644 index 00000000..8a79cf27 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-b.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-c.dat b/plot-test/plot/tests/PRs/test-data/pr107-c.dat new file mode 100644 index 00000000..1852bdf1 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-c.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-c.png b/plot-test/plot/tests/PRs/test-data/pr107-c.png new file mode 100644 index 00000000..a7d8bbec Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-c.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-d.dat b/plot-test/plot/tests/PRs/test-data/pr107-d.dat new file mode 100644 index 00000000..c81306e2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-d.png b/plot-test/plot/tests/PRs/test-data/pr107-d.png new file mode 100644 index 00000000..1140930c Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-e.dat b/plot-test/plot/tests/PRs/test-data/pr107-e.dat new file mode 100644 index 00000000..d43f459d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-e.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-e.png b/plot-test/plot/tests/PRs/test-data/pr107-e.png new file mode 100644 index 00000000..fcce9038 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-e.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-f.dat b/plot-test/plot/tests/PRs/test-data/pr107-f.dat new file mode 100644 index 00000000..c5d418d0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-f.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr107-f.png b/plot-test/plot/tests/PRs/test-data/pr107-f.png new file mode 100644 index 00000000..fcfa9ced Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr107-f.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr108.dat b/plot-test/plot/tests/PRs/test-data/pr108.dat new file mode 100644 index 00000000..58e344f4 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr108.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr108.png b/plot-test/plot/tests/PRs/test-data/pr108.png new file mode 100644 index 00000000..9f5884d0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr108.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr111.dat b/plot-test/plot/tests/PRs/test-data/pr111.dat new file mode 100644 index 00000000..67287265 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr111.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr111.png b/plot-test/plot/tests/PRs/test-data/pr111.png new file mode 100644 index 00000000..71baeb5d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr111.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr117.dat b/plot-test/plot/tests/PRs/test-data/pr117.dat new file mode 100644 index 00000000..541005a5 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr117.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr117.png b/plot-test/plot/tests/PRs/test-data/pr117.png new file mode 100644 index 00000000..b6ff1b4f Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr117.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr118.dat b/plot-test/plot/tests/PRs/test-data/pr118.dat new file mode 100644 index 00000000..dca632da Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr118.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr118.png b/plot-test/plot/tests/PRs/test-data/pr118.png new file mode 100644 index 00000000..96dec889 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr118.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr124.dat b/plot-test/plot/tests/PRs/test-data/pr124.dat new file mode 100644 index 00000000..491639af Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr124.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr124.png b/plot-test/plot/tests/PRs/test-data/pr124.png new file mode 100644 index 00000000..3bea4ccc Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr124.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr24.dat b/plot-test/plot/tests/PRs/test-data/pr24.dat new file mode 100644 index 00000000..6ec1be6e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr24.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr24.png b/plot-test/plot/tests/PRs/test-data/pr24.png new file mode 100644 index 00000000..68c42bf7 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr24.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-1-1.dat b/plot-test/plot/tests/PRs/test-data/pr42-1-1.dat new file mode 100644 index 00000000..6c2c2fb0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-1-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-1-1.png b/plot-test/plot/tests/PRs/test-data/pr42-1-1.png new file mode 100644 index 00000000..2b0e0631 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-1-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-1-2.dat b/plot-test/plot/tests/PRs/test-data/pr42-1-2.dat new file mode 100644 index 00000000..7a28807d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-1-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-1-2.png b/plot-test/plot/tests/PRs/test-data/pr42-1-2.png new file mode 100644 index 00000000..d968f9c3 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-1-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-2-1.dat b/plot-test/plot/tests/PRs/test-data/pr42-2-1.dat new file mode 100644 index 00000000..03c89593 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-2-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-2-1.png b/plot-test/plot/tests/PRs/test-data/pr42-2-1.png new file mode 100644 index 00000000..3a9d1591 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-2-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-2-2.dat b/plot-test/plot/tests/PRs/test-data/pr42-2-2.dat new file mode 100644 index 00000000..6b628ea0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-2-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-2-2.png b/plot-test/plot/tests/PRs/test-data/pr42-2-2.png new file mode 100644 index 00000000..656ea26b Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-2-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-3.dat b/plot-test/plot/tests/PRs/test-data/pr42-3.dat new file mode 100644 index 00000000..0d18bb2c Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-3.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-3.png b/plot-test/plot/tests/PRs/test-data/pr42-3.png new file mode 100644 index 00000000..02f46fc4 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-3.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-4.dat b/plot-test/plot/tests/PRs/test-data/pr42-4.dat new file mode 100644 index 00000000..f619d84d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-4.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr42-4.png b/plot-test/plot/tests/PRs/test-data/pr42-4.png new file mode 100644 index 00000000..aec87e73 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr42-4.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-1-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-1-3d.dat new file mode 100644 index 00000000..fd6a85eb Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-1-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-1-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-1-3d.png new file mode 100644 index 00000000..492df12a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-1-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-1.dat b/plot-test/plot/tests/PRs/test-data/pr46-1.dat new file mode 100644 index 00000000..402e053d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-1.png b/plot-test/plot/tests/PRs/test-data/pr46-1.png new file mode 100644 index 00000000..cd330e83 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-2-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-2-3d.dat new file mode 100644 index 00000000..a6dbc369 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-2-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-2-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-2-3d.png new file mode 100644 index 00000000..492df12a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-2-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-2.dat b/plot-test/plot/tests/PRs/test-data/pr46-2.dat new file mode 100644 index 00000000..617f02e6 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-2.png b/plot-test/plot/tests/PRs/test-data/pr46-2.png new file mode 100644 index 00000000..53f1303b Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-3-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-3-3d.dat new file mode 100644 index 00000000..ea8c43cf Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-3-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-3-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-3-3d.png new file mode 100644 index 00000000..24b784af Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-3-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-3.dat b/plot-test/plot/tests/PRs/test-data/pr46-3.dat new file mode 100644 index 00000000..47dbbe25 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-3.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-3.png b/plot-test/plot/tests/PRs/test-data/pr46-3.png new file mode 100644 index 00000000..9a48e94d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-3.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-4-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-4-3d.dat new file mode 100644 index 00000000..ba22af68 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-4-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-4-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-4-3d.png new file mode 100644 index 00000000..db7493cc Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-4-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-4.dat b/plot-test/plot/tests/PRs/test-data/pr46-4.dat new file mode 100644 index 00000000..f2c3cdb8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-4.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-4.png b/plot-test/plot/tests/PRs/test-data/pr46-4.png new file mode 100644 index 00000000..850376a1 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-4.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-5-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-5-3d.dat new file mode 100644 index 00000000..ba22af68 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-5-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-5-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-5-3d.png new file mode 100644 index 00000000..db7493cc Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-5-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-5.dat b/plot-test/plot/tests/PRs/test-data/pr46-5.dat new file mode 100644 index 00000000..2937135d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-5.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-5.png b/plot-test/plot/tests/PRs/test-data/pr46-5.png new file mode 100644 index 00000000..34897530 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-5.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-6-3d.dat b/plot-test/plot/tests/PRs/test-data/pr46-6-3d.dat new file mode 100644 index 00000000..d3d445ca Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-6-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-6-3d.png b/plot-test/plot/tests/PRs/test-data/pr46-6-3d.png new file mode 100644 index 00000000..24b784af Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-6-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-6.dat b/plot-test/plot/tests/PRs/test-data/pr46-6.dat new file mode 100644 index 00000000..06dbc484 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-6.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr46-6.png b/plot-test/plot/tests/PRs/test-data/pr46-6.png new file mode 100644 index 00000000..66687aa7 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr46-6.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr5.dat b/plot-test/plot/tests/PRs/test-data/pr5.dat new file mode 100644 index 00000000..8c21f31d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr5.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr5.png b/plot-test/plot/tests/PRs/test-data/pr5.png new file mode 100644 index 00000000..b9eab04e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr5.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-1.dat b/plot-test/plot/tests/PRs/test-data/pr55-1.dat new file mode 100644 index 00000000..e04d46b6 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-1.png b/plot-test/plot/tests/PRs/test-data/pr55-1.png new file mode 100644 index 00000000..d69a0702 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-2.dat b/plot-test/plot/tests/PRs/test-data/pr55-2.dat new file mode 100644 index 00000000..1a5af490 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-2.png b/plot-test/plot/tests/PRs/test-data/pr55-2.png new file mode 100644 index 00000000..5cb659ac Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-3.dat b/plot-test/plot/tests/PRs/test-data/pr55-3.dat new file mode 100644 index 00000000..29360e13 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-3.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr55-3.png b/plot-test/plot/tests/PRs/test-data/pr55-3.png new file mode 100644 index 00000000..01ad31c0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr55-3.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-2d-t.dat b/plot-test/plot/tests/PRs/test-data/pr58-2d-t.dat new file mode 100644 index 00000000..d85a76aa Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-2d-t.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-2d-t.png b/plot-test/plot/tests/PRs/test-data/pr58-2d-t.png new file mode 100644 index 00000000..843ab005 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-2d-t.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-2d.dat b/plot-test/plot/tests/PRs/test-data/pr58-2d.dat new file mode 100644 index 00000000..c20647de Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-2d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-2d.png b/plot-test/plot/tests/PRs/test-data/pr58-2d.png new file mode 100644 index 00000000..ed1ced0a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-2d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-3d-t.dat b/plot-test/plot/tests/PRs/test-data/pr58-3d-t.dat new file mode 100644 index 00000000..08d2484d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-3d-t.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-3d-t.png b/plot-test/plot/tests/PRs/test-data/pr58-3d-t.png new file mode 100644 index 00000000..5b12cd1a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-3d-t.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-3d.dat b/plot-test/plot/tests/PRs/test-data/pr58-3d.dat new file mode 100644 index 00000000..86a49cb8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-3d.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr58-3d.png b/plot-test/plot/tests/PRs/test-data/pr58-3d.png new file mode 100644 index 00000000..a3ff3716 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr58-3d.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr59-1.dat b/plot-test/plot/tests/PRs/test-data/pr59-1.dat new file mode 100644 index 00000000..90ab1dd3 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr59-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr59-1.png b/plot-test/plot/tests/PRs/test-data/pr59-1.png new file mode 100644 index 00000000..9af50df3 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr59-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr59-2.dat b/plot-test/plot/tests/PRs/test-data/pr59-2.dat new file mode 100644 index 00000000..812608d0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr59-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr59-2.png b/plot-test/plot/tests/PRs/test-data/pr59-2.png new file mode 100644 index 00000000..50b6fc8f Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr59-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-butt.dat b/plot-test/plot/tests/PRs/test-data/pr6-butt.dat new file mode 100644 index 00000000..b90f78f2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-butt.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-butt.png b/plot-test/plot/tests/PRs/test-data/pr6-butt.png new file mode 100644 index 00000000..4065e961 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-butt.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-projecting.dat b/plot-test/plot/tests/PRs/test-data/pr6-projecting.dat new file mode 100644 index 00000000..70d72d54 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-projecting.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-projecting.png b/plot-test/plot/tests/PRs/test-data/pr6-projecting.png new file mode 100644 index 00000000..0e740732 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-projecting.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-round.dat b/plot-test/plot/tests/PRs/test-data/pr6-round.dat new file mode 100644 index 00000000..bedb2c6a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-round.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr6-round.png b/plot-test/plot/tests/PRs/test-data/pr6-round.png new file mode 100644 index 00000000..f66b9841 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr6-round.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr66-1.dat b/plot-test/plot/tests/PRs/test-data/pr66-1.dat new file mode 100644 index 00000000..31de203c Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr66-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr66-1.png b/plot-test/plot/tests/PRs/test-data/pr66-1.png new file mode 100644 index 00000000..03334587 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr66-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr68.dat b/plot-test/plot/tests/PRs/test-data/pr68.dat new file mode 100644 index 00000000..f112274e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr68.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr68.png b/plot-test/plot/tests/PRs/test-data/pr68.png new file mode 100644 index 00000000..510622ed Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr68.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.dat new file mode 100644 index 00000000..afe814c6 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.png new file mode 100644 index 00000000..73a5f927 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-no-legend.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.dat new file mode 100644 index 00000000..3ad1dde2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.png new file mode 100644 index 00000000..19628911 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.dat new file mode 100644 index 00000000..9f749488 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.png new file mode 100644 index 00000000..49788c90 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.dat new file mode 100644 index 00000000..cc5145b5 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.png new file mode 100644 index 00000000..512949ec Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.dat new file mode 100644 index 00000000..fbc99998 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.png new file mode 100644 index 00000000..cf27d759 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-global-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.dat new file mode 100644 index 00000000..f7129921 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.png new file mode 100644 index 00000000..407f16b6 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.dat new file mode 100644 index 00000000..28aa0ffa Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.png new file mode 100644 index 00000000..6999d217 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.dat new file mode 100644 index 00000000..7a4bb736 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.png new file mode 100644 index 00000000..3c34696b Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.dat new file mode 100644 index 00000000..f2bae65d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.png new file mode 100644 index 00000000..6958b447 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.dat new file mode 100644 index 00000000..5bfd8547 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.png new file mode 100644 index 00000000..4e89a658 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.dat new file mode 100644 index 00000000..13eb777f Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.png new file mode 100644 index 00000000..e13e68a5 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.dat new file mode 100644 index 00000000..e4717295 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.png new file mode 100644 index 00000000..12305615 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.dat new file mode 100644 index 00000000..ac2fbc91 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.png new file mode 100644 index 00000000..5a95b25d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.dat new file mode 100644 index 00000000..667e55ab Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.png b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.png new file mode 100644 index 00000000..39b7fb5b Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-2d-outside-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.dat new file mode 100644 index 00000000..d4339a67 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.png new file mode 100644 index 00000000..e5699b77 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-no-legend.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.dat new file mode 100644 index 00000000..5d46f1fd Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.png new file mode 100644 index 00000000..07ed8e9e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.dat new file mode 100644 index 00000000..b0d93c96 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.png new file mode 100644 index 00000000..dbf2e1f1 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.dat new file mode 100644 index 00000000..e34dfa0a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.png new file mode 100644 index 00000000..e09672f5 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.dat new file mode 100644 index 00000000..b4cd4f75 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.png new file mode 100644 index 00000000..0e3bf8d0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-global-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.dat new file mode 100644 index 00000000..da6b40cf Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.png new file mode 100644 index 00000000..f8119255 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.dat new file mode 100644 index 00000000..04d1ff95 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.png new file mode 100644 index 00000000..5753067e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.dat new file mode 100644 index 00000000..b8c6e271 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.png new file mode 100644 index 00000000..e59aa564 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.dat new file mode 100644 index 00000000..b82cfea8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.png new file mode 100644 index 00000000..9f8284af Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-bottom.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.dat new file mode 100644 index 00000000..497bf762 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.png new file mode 100644 index 00000000..32b17a5e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.dat new file mode 100644 index 00000000..69335b12 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.png new file mode 100644 index 00000000..ba3900a8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.dat new file mode 100644 index 00000000..29da81bd Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.png new file mode 100644 index 00000000..26e58524 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-left.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.dat new file mode 100644 index 00000000..30d1e875 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.png new file mode 100644 index 00000000..998c66a9 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top-right.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.dat b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.dat new file mode 100644 index 00000000..8872db42 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.png b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.png new file mode 100644 index 00000000..8728f2c8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr70-3d-outside-top.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr75.dat b/plot-test/plot/tests/PRs/test-data/pr75.dat new file mode 100644 index 00000000..40440769 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr75.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr75.png b/plot-test/plot/tests/PRs/test-data/pr75.png new file mode 100644 index 00000000..52e4954a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr75.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr76.dat b/plot-test/plot/tests/PRs/test-data/pr76.dat new file mode 100644 index 00000000..986b4c2f Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr76.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr76.png b/plot-test/plot/tests/PRs/test-data/pr76.png new file mode 100644 index 00000000..73bfc1a2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr76.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-1.dat b/plot-test/plot/tests/PRs/test-data/pr81-1.dat new file mode 100644 index 00000000..de985bc8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-1.png b/plot-test/plot/tests/PRs/test-data/pr81-1.png new file mode 100644 index 00000000..99c28977 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-2.dat b/plot-test/plot/tests/PRs/test-data/pr81-2.dat new file mode 100644 index 00000000..d4fb9ef7 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-2.png b/plot-test/plot/tests/PRs/test-data/pr81-2.png new file mode 100644 index 00000000..d0869ca0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-3.dat b/plot-test/plot/tests/PRs/test-data/pr81-3.dat new file mode 100644 index 00000000..fd403dbf Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-3.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-3.png b/plot-test/plot/tests/PRs/test-data/pr81-3.png new file mode 100644 index 00000000..6b075add Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-3.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-4.dat b/plot-test/plot/tests/PRs/test-data/pr81-4.dat new file mode 100644 index 00000000..114a89f8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-4.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr81-4.png b/plot-test/plot/tests/PRs/test-data/pr81-4.png new file mode 100644 index 00000000..f42eaeb3 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr81-4.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-1.dat b/plot-test/plot/tests/PRs/test-data/pr86-1.dat new file mode 100644 index 00000000..f368696d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-1.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-1.png b/plot-test/plot/tests/PRs/test-data/pr86-1.png new file mode 100644 index 00000000..19060bd9 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-1.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-2.dat b/plot-test/plot/tests/PRs/test-data/pr86-2.dat new file mode 100644 index 00000000..80a80b98 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-2.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-2.png b/plot-test/plot/tests/PRs/test-data/pr86-2.png new file mode 100644 index 00000000..3eca9c88 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-2.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-3.dat b/plot-test/plot/tests/PRs/test-data/pr86-3.dat new file mode 100644 index 00000000..1ff28af1 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-3.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-3.png b/plot-test/plot/tests/PRs/test-data/pr86-3.png new file mode 100644 index 00000000..9bda2d0c Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-3.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-4.dat b/plot-test/plot/tests/PRs/test-data/pr86-4.dat new file mode 100644 index 00000000..90656057 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-4.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr86-4.png b/plot-test/plot/tests/PRs/test-data/pr86-4.png new file mode 100644 index 00000000..fbc32f8c Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr86-4.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.dat b/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.dat new file mode 100644 index 00000000..9ba07214 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.png b/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.png new file mode 100644 index 00000000..d41ba36e Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-11-ar-portrait.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-11-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-11-ar.dat new file mode 100644 index 00000000..28dc56cd Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-11-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-11-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-11-ar.png new file mode 100644 index 00000000..0be1824a Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-11-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.dat new file mode 100644 index 00000000..44c48039 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.png new file mode 100644 index 00000000..34151bb2 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-1610-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.dat b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.dat new file mode 100644 index 00000000..dfa094a0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.png b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.png new file mode 100644 index 00000000..74443932 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar-portrait.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.dat new file mode 100644 index 00000000..a3145606 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.png new file mode 100644 index 00000000..44defb90 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-11-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.dat new file mode 100644 index 00000000..3d287620 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.png new file mode 100644 index 00000000..d7c87a50 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-1610-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.dat new file mode 100644 index 00000000..060fecf0 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.png new file mode 100644 index 00000000..48607ba9 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-3d-no-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-no-ar.dat b/plot-test/plot/tests/PRs/test-data/pr88-no-ar.dat new file mode 100644 index 00000000..74285933 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-no-ar.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr88-no-ar.png b/plot-test/plot/tests/PRs/test-data/pr88-no-ar.png new file mode 100644 index 00000000..9fb5cfa7 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr88-no-ar.png differ diff --git a/plot-test/plot/tests/PRs/test-data/pr89.dat b/plot-test/plot/tests/PRs/test-data/pr89.dat new file mode 100644 index 00000000..ec3c82c8 Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr89.dat differ diff --git a/plot-test/plot/tests/PRs/test-data/pr89.png b/plot-test/plot/tests/PRs/test-data/pr89.png new file mode 100644 index 00000000..b54b033d Binary files /dev/null and b/plot-test/plot/tests/PRs/test-data/pr89.png differ diff --git a/plot-test/plot/tests/axis-transform-tests.rkt b/plot-test/plot/tests/axis-transform-tests.rkt index c5ee9a0e..5fbfe2b8 100644 --- a/plot-test/plot/tests/axis-transform-tests.rkt +++ b/plot-test/plot/tests/axis-transform-tests.rkt @@ -1,297 +1,473 @@ #lang racket -(require plot plot/utils) +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + "helpers.rkt") (x-axis-ticks? #f) (y-axis-ticks? #f) -(values +(define (do-plot1 output-fn) (parameterize ([plot-x-transform log-transform]) - (plot (list (function values 1 5) - (function cos 1 5 #:color 3)))) - (parameterize ([plot-x-transform cbrt-transform]) - (plot (list (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform log-transform] - [plot-y-transform cbrt-transform]) - (define xs (nonlinear-seq 1 5 20 log-transform)) - (define ys (nonlinear-seq -1 5 20 cbrt-transform)) - (plot (points (map vector xs ys))))) + (output-fn(list (function values 1 5) + (function cos 1 5 #:color 3))))) -(let () - (define trans1 (hand-drawn-transform 25)) - (define trans2 (hand-drawn-transform 100)) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -2 2 20 trans1)) - (define ys (nonlinear-seq -2 2 20 trans2)) - (plot (points (map vector xs ys)))))) +(define (do-plot2 output-fn) + (parameterize ([plot-x-transform cbrt-transform]) + (output-fn (list (function values -2 2) + (function cos -2 2 #:color 3))))) -(let () - (define trans1 (stretch-transform -1/2 1/2 4)) - (define trans2 (stretch-transform -1/2 1/2 1/4)) - (values - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (plot (list (y-axis -1/2) (y-axis 1/2) - (x-axis -1/2) (x-axis 1/2) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -2 2 20 trans1)) - (define ys (nonlinear-seq -2 2 20 trans2)) - (plot (points (map vector xs ys)))))) +(define (do-plot3 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform cbrt-transform]) + (define xs (nonlinear-seq 1 5 20 log-transform)) + (define ys (nonlinear-seq -1 5 20 cbrt-transform)) + (output-fn (points (map vector xs ys))))) -(let () - (define trans1 (axis-transform-compose id-transform (stretch-transform -1 1 1/4))) - (define trans2 (axis-transform-compose (stretch-transform -1 1 1/4) id-transform)) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis -1) (y-axis 1) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis -1) (y-axis 1) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -2 2 20 trans1)) - (define ys (nonlinear-seq -2 2 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot4 do-plot5 do-plot6) + (let ([trans1 (hand-drawn-transform 25)] + [trans2 (hand-drawn-transform 100)]) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (function values -2 2) + (function cos -2 2 #:color 3))))) -(let () - (define t1 (stretch-transform -2 -1 4)) - (define t2 (stretch-transform 1 2 4)) - (values - (parameterize ([plot-x-transform (axis-transform-compose t1 t2)] - [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))]) - (plot (list (y-axis -2) (y-axis -1) - (y-axis 1) (y-axis 2) - (function values -3 3) - (function cos -3 3 #:color 3)))) - (parameterize ([plot-x-transform (axis-transform-compose t2 t1)] - [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))]) - (plot (list (y-axis -2) (y-axis -1) - (y-axis 1) (y-axis 2) - (function values -3 3) - (function cos -3 3 #:color 3)))) - (parameterize ([plot-x-transform (axis-transform-compose t2 t1)] - [plot-y-transform (axis-transform-compose t1 t2)]) - (define xs (nonlinear-seq -3 3 20 (axis-transform-compose t2 t1))) - (define ys (nonlinear-seq -3 3 20 (axis-transform-compose t1 t2))) - (plot (points (map vector xs ys)))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (function values -2 2) + (function cos -2 2 #:color 3))))) -(let () - (define t1 (stretch-transform -2 0 4)) - (define t2 (stretch-transform -1 1 1/4)) - (define t3 (stretch-transform 2 3 4)) - (define trans1 (axis-transform-compose (axis-transform-compose t3 t2) t1)) - (define trans2 (axis-transform-compose (axis-transform-compose t2 t1) t3)) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis -2) (y-axis 0) - (y-axis -1) (y-axis 1) - (y-axis 2) (y-axis 3) - (function values -3 4) - (function cos -3 4 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis -2) (y-axis 0) - (y-axis -1) (y-axis 1) - (y-axis 2) (y-axis 3) - (function values -3 4) - (function cos -3 4 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -3 4 20 trans1)) - (define ys (nonlinear-seq -3 4 20 trans2)) - (plot (points (map vector xs ys)))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -2 2 20 trans1)) + (define ys (nonlinear-seq -2 2 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans1 (axis-transform-compose (stretch-transform 2 3 4) log-transform)) - (define trans2 (axis-transform-compose log-transform (stretch-transform 2 3 4))) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 2) (y-axis 3) - (function values 1 5) - (function cos 1 5 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 2) (y-axis 3) - (function values 1 5) - (function cos 1 5 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq 1 5 20 trans1)) - (define ys (nonlinear-seq 1 5 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot7 do-plot8) + (let ([trans1 (stretch-transform -1/2 1/2 4)] + [trans2 (stretch-transform -1/2 1/2 1/4)]) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (output-fn (list (y-axis -1/2) (y-axis 1/2) + (x-axis -1/2) (x-axis 1/2) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -2 2 20 trans1)) + (define ys (nonlinear-seq -2 2 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans (collapse-transform -1 1)) - (values - (parameterize ([plot-x-transform trans]) - (plot (list (y-axis 1) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans] - [plot-y-transform trans]) - (define xs (nonlinear-seq -2 2 20 trans)) - (plot (points (map vector xs xs)))))) +(define-values (do-plot9 do-plot10 do-plot11) + (let () + (define trans1 (axis-transform-compose id-transform (stretch-transform -1 1 1/4))) + (define trans2 (axis-transform-compose (stretch-transform -1 1 1/4) id-transform)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis -1) (y-axis 1) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis -1) (y-axis 1) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -2 2 20 trans1)) + (define ys (nonlinear-seq -2 2 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans1 (axis-transform-compose (collapse-transform 2 3) log-transform)) - (define trans2 (axis-transform-compose log-transform (collapse-transform 2 3))) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 3) - (function values 1 5) - (function cos 1 5 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 3) - (function values 1 5) - (function cos 1 5 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq 1 5 20 trans1)) - (define ys (nonlinear-seq 1 5 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot12 do-plot13 do-plot14) + (let () + (define t1 (stretch-transform -2 -1 4)) + (define t2 (stretch-transform 1 2 4)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform (axis-transform-compose t1 t2)] + [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))]) + (output-fn (list (y-axis -2) (y-axis -1) + (y-axis 1) (y-axis 2) + (function values -3 3) + (function cos -3 3 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform (axis-transform-compose t2 t1)] + [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))]) + (output-fn (list (y-axis -2) (y-axis -1) + (y-axis 1) (y-axis 2) + (function values -3 3) + (function cos -3 3 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform (axis-transform-compose t2 t1)] + [plot-y-transform (axis-transform-compose t1 t2)]) + (define xs (nonlinear-seq -3 3 20 (axis-transform-compose t2 t1))) + (define ys (nonlinear-seq -3 3 20 (axis-transform-compose t1 t2))) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans1 (axis-transform-compose (stretch-transform -1 1 4) - (collapse-transform -1/2 1/2))) - (define trans2 (axis-transform-compose (collapse-transform -1/2 1/2) - (stretch-transform -1 1 4))) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis -1) (y-axis 1) - (y-axis -1/2) (y-axis 1/2) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis -1) (y-axis 1) - (y-axis -1/2) (y-axis 1/2) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -2 2 20 trans1)) - (define ys (nonlinear-seq -2 2 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot15 do-plot16 do-plot17) + (let () + (define t1 (stretch-transform -2 0 4)) + (define t2 (stretch-transform -1 1 1/4)) + (define t3 (stretch-transform 2 3 4)) + (define trans1 (axis-transform-compose (axis-transform-compose t3 t2) t1)) + (define trans2 (axis-transform-compose (axis-transform-compose t2 t1) t3)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis -2) (y-axis 0) + (y-axis -1) (y-axis 1) + (y-axis 2) (y-axis 3) + (function values -3 4) + (function cos -3 4 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis -2) (y-axis 0) + (y-axis -1) (y-axis 1) + (y-axis 2) (y-axis 3) + (function values -3 4) + (function cos -3 4 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -3 4 20 trans1)) + (define ys (nonlinear-seq -3 4 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans1 (axis-transform-compose (collapse-transform -1 1) (collapse-transform -1/2 1/2))) - (define trans2 (axis-transform-compose (collapse-transform -1/2 1/2) (collapse-transform -1 1))) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 1) (y-axis 1/2) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 1) (y-axis 1/2) - (function values -2 2) - (function cos -2 2 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -2 2 20 trans1)) - (define ys (nonlinear-seq -2 2 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot18 do-plot19 do-plot20) + (let () + (define trans1 (axis-transform-compose (stretch-transform 2 3 4) log-transform)) + (define trans2 (axis-transform-compose log-transform (stretch-transform 2 3 4))) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 2) (y-axis 3) + (function values 1 5) + (function cos 1 5 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 2) (y-axis 3) + (function values 1 5) + (function cos 1 5 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq 1 5 20 trans1)) + (define ys (nonlinear-seq 1 5 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(parameterize ([plot-x-transform (collapse-transform -1 1)]) - (plot (function values 0 2))) +(define-values (do-plot21 do-plot22) + (let () + (define trans (collapse-transform -1 1)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans]) + (output-fn (list (y-axis 1) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans] + [plot-y-transform trans]) + (define xs (nonlinear-seq -2 2 20 trans)) + (output-fn (points (map vector xs xs)))))))) -(parameterize ([plot-x-transform (collapse-transform -1 1)]) - (plot (function values -2 0))) +(define-values (do-plot23 do-plot24 do-plot25) + (let () + (define trans1 (axis-transform-compose (collapse-transform 2 3) log-transform)) + (define trans2 (axis-transform-compose log-transform (collapse-transform 2 3))) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 3) + (function values 1 5) + (function cos 1 5 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 3) + (function values 1 5) + (function cos 1 5 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq 1 5 20 trans1)) + (define ys (nonlinear-seq 1 5 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(parameterize ([plot-x-transform (axis-transform-append id-transform log-transform 0.1)]) - (plot (function sin -4 4))) +(define-values (do-plot26 do-plot27 do-plot28) + (let () + (define trans1 (axis-transform-compose (stretch-transform -1 1 4) + (collapse-transform -1/2 1/2))) + (define trans2 (axis-transform-compose (collapse-transform -1/2 1/2) + (stretch-transform -1 1 4))) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis -1) (y-axis 1) + (y-axis -1/2) (y-axis 1/2) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis -1) (y-axis 1) + (y-axis -1/2) (y-axis 1/2) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -2 2 20 trans1)) + (define ys (nonlinear-seq -2 2 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define trans (axis-transform-append id-transform log-transform 2)) - (define ticks (log-ticks #:base 10)) - (values - (parameterize ([plot-x-transform trans] - [plot-x-ticks ticks]) - (plot (list (function values 1 15) - (function cos 1 15 #:color 3)))) - (parameterize ([plot-x-transform trans] - [plot-y-transform trans]) - (define xs (nonlinear-seq 1 15 20 trans)) - (plot (points (map vector xs xs)))))) +(define-values (do-plot29 do-plot30 do-plot31) + (let () + (define trans1 (axis-transform-compose (collapse-transform -1 1) (collapse-transform -1/2 1/2))) + (define trans2 (axis-transform-compose (collapse-transform -1/2 1/2) (collapse-transform -1 1))) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 1) (y-axis 1/2) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 1) (y-axis 1/2) + (function values -2 2) + (function cos -2 2 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -2 2 20 trans1)) + (define ys (nonlinear-seq -2 2 20 trans2)) + (output-fn (points (map vector xs ys)))))))) -(let () - (define t1 (stretch-transform 2 3 4)) - (define t2 (stretch-transform 7 8 4)) - (define trans1 (axis-transform-compose (axis-transform-append t1 t2 5) log-transform)) - (define trans2 (axis-transform-compose log-transform (axis-transform-append t1 t2 5))) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (for/list ([x (in-list '(2 3 7 8))]) (y-axis x)) - (function values 1 9)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (for/list ([x (in-list '(2 3 7 8))]) (y-axis x)) - (function values 1 9)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq 1 9 50 trans1)) - (define ys (nonlinear-seq 1 9 50 trans2)) - (plot (points (map vector xs ys)))))) +(define (do-plot32 output-fn) + (parameterize ([plot-x-transform (collapse-transform -1 1)]) + (output-fn (function values 0 2)))) -(let () - (define trans1 (axis-transform-append log-transform id-transform 5)) - (define trans2 (axis-transform-append id-transform log-transform 5)) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 5) - (function values 6 10) - (function cos 6 10 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 5) - (function values 6 10) - (function cos 6 10 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq 6 10 20 trans1)) - (define ys (nonlinear-seq 6 10 20 trans2)) - (plot (points (map vector xs ys)))) - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 5) - (function values 1 4) - (function cos 1 4 #:color 3)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 5) - (function values 1 4) - (function cos 1 4 #:color 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq 1 4 20 trans1)) - (define ys (nonlinear-seq 1 4 20 trans2)) - (plot (points (map vector xs ys)))))) +(define (do-plot33 output-fn) + (parameterize ([plot-x-transform (collapse-transform -1 1)]) + (output-fn (function values -2 0)))) -(parameterize ([plot-x-transform (axis-transform-compose (collapse-transform 2 6) - log-transform)] - [plot-x-ticks (ticks-add (log-ticks) '(2 6))]) - (plot (list (y-axis 2) (y-axis 6) - (function values 1 10)))) +(define (do-plot34 output-fn) + (parameterize ([plot-x-transform (axis-transform-append id-transform log-transform 0.1)]) + (output-fn (function sin -4 4)))) -(let () - (define trans1 (axis-transform-bound log-transform 0.1 5)) - (define trans2 (axis-transform-bound (stretch-transform 1 2 4) 1 2)) - (values - (parameterize ([plot-x-transform trans1]) - (plot (list (y-axis 0.1) (y-axis 5) - (function values -3 9)))) - (parameterize ([plot-x-transform trans2]) - (plot (list (y-axis 1) (y-axis 2) - (function values 0 3)))) - (parameterize ([plot-x-transform trans1] - [plot-y-transform trans2]) - (define xs (nonlinear-seq -3 9 20 trans1)) - (define ys (nonlinear-seq 0 3 20 trans2)) - (plot (points (map vector xs ys)))))) +(define-values (do-plot35 do-plot36) + (let () + (define trans (axis-transform-append id-transform log-transform 2)) + (define ticks (log-ticks #:base 10)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans] + [plot-x-ticks ticks]) + (output-fn (list (function values 1 15) + (function cos 1 15 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans] + [plot-y-transform trans]) + (define xs (nonlinear-seq 1 15 20 trans)) + (output-fn (points (map vector xs xs)))))))) + +(define-values (do-plot37 do-plot38 do-plot39) + (let () + (define t1 (stretch-transform 2 3 4)) + (define t2 (stretch-transform 7 8 4)) + (define trans1 (axis-transform-compose (axis-transform-append t1 t2 5) log-transform)) + (define trans2 (axis-transform-compose log-transform (axis-transform-append t1 t2 5))) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (for/list ([x (in-list '(2 3 7 8))]) (y-axis x)) + (function values 1 9))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (for/list ([x (in-list '(2 3 7 8))]) (y-axis x)) + (function values 1 9))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq 1 9 50 trans1)) + (define ys (nonlinear-seq 1 9 50 trans2)) + (output-fn (points (map vector xs ys)))))))) + +(define-values (do-plot40 do-plot41 do-plot42 do-plot43 do-plot44 do-plot45) + (let () + (define trans1 (axis-transform-append log-transform id-transform 5)) + (define trans2 (axis-transform-append id-transform log-transform 5)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 5) + (function values 6 10) + (function cos 6 10 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 5) + (function values 6 10) + (function cos 6 10 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq 6 10 20 trans1)) + (define ys (nonlinear-seq 6 10 20 trans2)) + (output-fn (points (map vector xs ys))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 5) + (function values 1 4) + (function cos 1 4 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 5) + (function values 1 4) + (function cos 1 4 #:color 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq 1 4 20 trans1)) + (define ys (nonlinear-seq 1 4 20 trans2)) + (output-fn (points (map vector xs ys)))))))) + +(define (do-plot46 output-fn) + (parameterize ([plot-x-transform (axis-transform-compose (collapse-transform 2 6) + log-transform)] + [plot-x-ticks (ticks-add (log-ticks) '(2 6))]) + (output-fn (list (y-axis 2) (y-axis 6) + (function values 1 10))))) + +(define-values (do-plot47 do-plot48 do-plot49) + (let () + (define trans1 (axis-transform-bound log-transform 0.1 5)) + (define trans2 (axis-transform-bound (stretch-transform 1 2 4) 1 2)) + (values + (lambda (output-fn) + (parameterize ([plot-x-transform trans1]) + (output-fn (list (y-axis 0.1) (y-axis 5) + (function values -3 9))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans2]) + (output-fn (list (y-axis 1) (y-axis 2) + (function values 0 3))))) + (lambda (output-fn) + (parameterize ([plot-x-transform trans1] + [plot-y-transform trans2]) + (define xs (nonlinear-seq -3 9 20 trans1)) + (define ys (nonlinear-seq 0 3 20 trans2)) + (output-fn (points (map vector xs ys)))))))) + +(define-runtime-path at1-data "./test-data/at1.dat") +(define-runtime-path at2-data "./test-data/at2.dat") +(define-runtime-path at3-data "./test-data/at3.dat") +(define-runtime-path at4-data "./test-data/at4.dat") +(define-runtime-path at5-data "./test-data/at5.dat") +(define-runtime-path at6-data "./test-data/at6.dat") +(define-runtime-path at7-data "./test-data/at7.dat") +(define-runtime-path at8-data "./test-data/at8.dat") +(define-runtime-path at9-data "./test-data/at9.dat") +(define-runtime-path at10-data "./test-data/at10.dat") +(define-runtime-path at11-data "./test-data/at11.dat") +(define-runtime-path at12-data "./test-data/at12.dat") +(define-runtime-path at13-data "./test-data/at13.dat") +(define-runtime-path at14-data "./test-data/at14.dat") +(define-runtime-path at15-data "./test-data/at15.dat") +(define-runtime-path at16-data "./test-data/at16.dat") +(define-runtime-path at17-data "./test-data/at17.dat") +(define-runtime-path at18-data "./test-data/at18.dat") +(define-runtime-path at19-data "./test-data/at19.dat") +(define-runtime-path at20-data "./test-data/at20.dat") +(define-runtime-path at21-data "./test-data/at21.dat") +(define-runtime-path at22-data "./test-data/at22.dat") +(define-runtime-path at23-data "./test-data/at23.dat") +(define-runtime-path at24-data "./test-data/at24.dat") +(define-runtime-path at25-data "./test-data/at25.dat") +(define-runtime-path at26-data "./test-data/at26.dat") +(define-runtime-path at27-data "./test-data/at27.dat") +(define-runtime-path at28-data "./test-data/at28.dat") +(define-runtime-path at29-data "./test-data/at29.dat") +(define-runtime-path at30-data "./test-data/at30.dat") +(define-runtime-path at31-data "./test-data/at31.dat") +(define-runtime-path at32-data "./test-data/at32.dat") +(define-runtime-path at33-data "./test-data/at33.dat") +(define-runtime-path at34-data "./test-data/at34.dat") +(define-runtime-path at35-data "./test-data/at35.dat") +(define-runtime-path at36-data "./test-data/at36.dat") +(define-runtime-path at37-data "./test-data/at37.dat") +(define-runtime-path at38-data "./test-data/at38.dat") +(define-runtime-path at39-data "./test-data/at39.dat") +(define-runtime-path at40-data "./test-data/at40.dat") +(define-runtime-path at41-data "./test-data/at41.dat") +(define-runtime-path at42-data "./test-data/at42.dat") +(define-runtime-path at43-data "./test-data/at43.dat") +(define-runtime-path at44-data "./test-data/at44.dat") +(define-runtime-path at45-data "./test-data/at45.dat") +(define-runtime-path at46-data "./test-data/at46.dat") +(define-runtime-path at47-data "./test-data/at47.dat") +(define-runtime-path at48-data "./test-data/at48.dat") +(define-runtime-path at49-data "./test-data/at49.dat") + +(define axis-transform-tests + (test-suite + "axis-transform-tests" + (test-case "test case 1" (check-draw-steps do-plot1 at1-data)) + (test-case "test case 2" (check-draw-steps do-plot2 at2-data)) + (test-case "test case 3" (check-draw-steps do-plot3 at3-data)) + (test-case "test case 4" (check-draw-steps do-plot4 at4-data)) + (test-case "test case 5" (check-draw-steps do-plot5 at5-data)) + (test-case "test case 6" (check-draw-steps do-plot6 at6-data)) + (test-case "test case 7" (check-draw-steps do-plot7 at7-data)) + (test-case "test case 8" (check-draw-steps do-plot8 at8-data)) + (test-case "test case 9" (check-draw-steps do-plot9 at9-data)) + (test-case "test case 10" (check-draw-steps do-plot10 at10-data)) + (test-case "test case 11" (check-draw-steps do-plot11 at11-data)) + (test-case "test case 12" (check-draw-steps do-plot12 at12-data)) + (test-case "test case 13" (check-draw-steps do-plot13 at13-data)) + (test-case "test case 14" (check-draw-steps do-plot14 at14-data)) + (test-case "test case 15" (check-draw-steps do-plot15 at15-data)) + (test-case "test case 16" (check-draw-steps do-plot16 at16-data)) + (test-case "test case 17" (check-draw-steps do-plot17 at17-data)) + (test-case "test case 18" (check-draw-steps do-plot18 at18-data)) + (test-case "test case 19" (check-draw-steps do-plot19 at19-data)) + (test-case "test case 20" (check-draw-steps do-plot20 at20-data)) + (test-case "test case 21" (check-draw-steps do-plot21 at21-data)) + (test-case "test case 22" (check-draw-steps do-plot22 at22-data)) + (test-case "test case 23" (check-draw-steps do-plot23 at23-data)) + (test-case "test case 24" (check-draw-steps do-plot24 at24-data)) + (test-case "test case 25" (check-draw-steps do-plot25 at25-data)) + (test-case "test case 26" (check-draw-steps do-plot26 at26-data)) + (test-case "test case 27" (check-draw-steps do-plot27 at27-data)) + (test-case "test case 28" (check-draw-steps do-plot28 at28-data)) + (test-case "test case 29" (check-draw-steps do-plot29 at29-data)) + (test-case "test case 30" (check-draw-steps do-plot30 at30-data)) + (test-case "test case 31" (check-draw-steps do-plot31 at31-data)) + (test-case "test case 32" (check-draw-steps do-plot32 at32-data)) + (test-case "test case 33" (check-draw-steps do-plot33 at33-data)) + (test-case "test case 34" (check-draw-steps do-plot34 at34-data)) + (test-case "test case 35" (check-draw-steps do-plot35 at35-data)) + (test-case "test case 36" (check-draw-steps do-plot36 at36-data)) + (test-case "test case 37" (check-draw-steps do-plot37 at37-data)) + (test-case "test case 38" (check-draw-steps do-plot38 at38-data)) + (test-case "test case 39" (check-draw-steps do-plot39 at39-data)) + (test-case "test case 40" (check-draw-steps do-plot40 at40-data)) + (test-case "test case 41" (check-draw-steps do-plot41 at41-data)) + (test-case "test case 42" (check-draw-steps do-plot42 at42-data)) + (test-case "test case 43" (check-draw-steps do-plot43 at43-data)) + (test-case "test case 44" (check-draw-steps do-plot44 at44-data)) + (test-case "test case 45" (check-draw-steps do-plot45 at45-data)) + (test-case "test case 46" (check-draw-steps do-plot46 at46-data)) + (test-case "test case 47" (check-draw-steps do-plot47 at47-data)) + (test-case "test case 48" (check-draw-steps do-plot48 at48-data)) + (test-case "test case 49" (check-draw-steps do-plot49 at49-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests axis-transform-tests)) diff --git a/plot-test/plot/tests/extreme-bounds-tests.rkt b/plot-test/plot/tests/extreme-bounds-tests.rkt index 5cddc990..eaeda721 100644 --- a/plot-test/plot/tests/extreme-bounds-tests.rkt +++ b/plot-test/plot/tests/extreme-bounds-tests.rkt @@ -1,28 +1,39 @@ #lang racket -(require plot plot/utils math/flonum) +(require plot plot/utils math/flonum + racket/runtime-path + rackunit + "helpers.rkt") (module+ test (module config info (define timeout 150))) -(printf "Point at 0,0:~n") -(plot (points '(#(0 0))) - #:x-min +min.0 #:x-max (flstep +min.0 1000) - #:y-min 0 #:y-max 1) +(define-runtime-path eb-1-data "./test-data/eb-1.rktd") +(define (do-plot-1 output-fn) + (output-fn (points '(#(0 0))) + #:x-min +min.0 #:x-max (flstep +min.0 1000) + #:y-min 0 #:y-max 1 + #:title "Point at 0,0")) -(printf "Point at 0,0,0:~n") -(plot3d (points3d '(#(0 0 0))) - #:x-min +min.0 #:x-max (flstep +min.0 1000) - #:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1) +(define-runtime-path eb-2-data "./test-data/eb-2.rktd") +(define (do-plot-2 output-fn) + (output-fn (points3d '(#(0 0 0))) + #:x-min +min.0 #:x-max (flstep +min.0 1000) + #:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1 + #:title "Point at 0,0,0")) -(printf "Steps should appear all the way from the bottom to the top:~n") -(plot (function fl (flstep 0.0 -1) (flstep 0.0 2))) +(define-runtime-path eb-3-data "./test-data/eb-3.rktd") +(define (do-plot-3 output-fn) + (output-fn (function fl (flstep 0.0 -1) (flstep 0.0 2)) + #:title "Steps should appear all the way from the bottom to the top")) -(printf "Steps should appear all the way from the bottom to the top:~n") -(plot3d (surface3d (λ (x y) (fl x)) - (flstep 0.0 -1) (flstep 0.0 2) - (flstep 0.0 -1) (flstep 0.0 2))) +(define-runtime-path eb-4-data "./test-data/eb-4.rktd") +(define (do-plot-4 output-fn) + (output-fn (surface3d (λ (x y) (fl x)) + (flstep 0.0 -1) (flstep 0.0 2) + (flstep 0.0 -1) (flstep 0.0 2)) + #:title "Steps should appear all the way from the bottom to the top")) (plot-x-label #f) (plot-y-label #f) @@ -34,43 +45,63 @@ (define (extreme-real->string x) (real->plot-label x (digits-for-range 0 (abs x)))) -(define num-2d 0) -(time - (for ([x-min (in-list stops)] - [x-max (in-list (rest stops))] - #:when #t - [y-min (in-list stops)] - [y-max (in-list (rest stops))]) - (displayln - (list (format "[~a,~a] × [~a,~a]" - (extreme-real->string x-min) (extreme-real->string x-max) - (extreme-real->string y-min) (extreme-real->string y-max)) - (time (plot (lines (list (vector x-min y-min) - (vector x-max y-max))))))) - (set! num-2d (+ 1 num-2d)))) +(define-runtime-path data-dir "./test-data") -(printf "Total 2D plots: ~a~n" num-2d) -(printf "-----------------------------------------~n") +(define 2d-test-case-counter 0) +(define 2d-test-cases + (test-suite + "2d-test-cases" + (for/list ([x-min (in-list stops)] + [x-max (in-list (rest stops))] + #:when #t + [y-min (in-list stops)] + [y-max (in-list (rest stops))]) + (set! 2d-test-case-counter (add1 2d-test-case-counter)) + (define name + (format "[~a,~a] × [~a,~a]" + (extreme-real->string x-min) (extreme-real->string x-max) + (extreme-real->string y-min) (extreme-real->string y-max))) + (define data-file (build-path data-dir (format "eb2d-~a.dat" 2d-test-case-counter))) + (define (do-plot output-fn) + (output-fn (lines (list (vector x-min y-min) (vector x-max y-max))) #:title name)) + (test-case name (check-draw-steps do-plot data-file))))) -(define num-3d 0) +(define 3d-test-case-counter 0) +(define 3d-test-cases + (test-suite + "3d-test-cases" + (for/list ([x-min (in-list stops)] + [x-max (in-list (rest stops))] + #:when #t + [y-min (in-list stops)] + [y-max (in-list (rest stops))] + #:when #t + [z-min (in-list stops)] + [z-max (in-list (rest stops))]) + (set! 3d-test-case-counter (add1 3d-test-case-counter)) + (define name + (format "[~a,~a] × [~a,~a] × [~a,~a]" + (extreme-real->string x-min) (extreme-real->string x-max) + (extreme-real->string y-min) (extreme-real->string y-max) + (extreme-real->string z-min) (extreme-real->string z-max))) + (define data-file (build-path data-dir (format "eb3d-~a.dat" 3d-test-case-counter))) + (define (do-plot output-fn) + (output-fn (lines3d (list (vector x-min y-min z-min) + (vector x-max y-max z-max))) + #:title name)) + (test-case name (check-draw-steps-3d do-plot data-file))))) -(time - (for ([x-min (in-list stops)] - [x-max (in-list (rest stops))] - #:when #t - [y-min (in-list stops)] - [y-max (in-list (rest stops))] - #:when #t - [z-min (in-list stops)] - [z-max (in-list (rest stops))]) - (displayln - (list (format "[~a,~a] × [~a,~a] × [~a,~a]" - (extreme-real->string x-min) (extreme-real->string x-max) - (extreme-real->string y-min) (extreme-real->string y-max) - (extreme-real->string z-min) (extreme-real->string z-max)) - (time (plot3d (lines3d (list (vector x-min y-min z-min) - (vector x-max y-max z-max))))))) - (set! num-3d (+ 1 num-3d)))) +(define extreme-bounds-tests + (test-suite + "extreme-bounds-tests" + (test-case "test case 1" (check-draw-steps do-plot-1 eb-1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot-2 eb-2-data)) + (test-case "test case 3" (check-draw-steps do-plot-3 eb-3-data)) + (test-case "test case 4" (check-draw-steps-3d do-plot-4 eb-4-data)) + 2d-test-cases + 3d-test-cases)) + +(module+ test + (require rackunit/text-ui) + (run-tests extreme-bounds-tests)) -(printf "Total plots: ~a~n" num-3d) -(printf "-----------------------------------------~n") diff --git a/plot-test/plot/tests/helpers.rkt b/plot-test/plot/tests/helpers.rkt new file mode 100644 index 00000000..ea0214f2 --- /dev/null +++ b/plot-test/plot/tests/helpers.rkt @@ -0,0 +1,254 @@ +#lang racket +(require plot racket/draw rackunit file/gzip file/gunzip) + +(provide check-draw-steps check-draw-steps-3d mock-record-dc%) + +;; Helper functions to write plot tests which verify that the renderers work +;; correctly. See `check-draw-steps` and `check-draw-steps-3d`. +;; +;; The overall testing strategy is that the user verifies a set of renderers +;; to work correctly, generates some draw steps and a sample image and uses +;; `check-draw-steps` (or `check-draw-steps-3d` for 3d plots) to verify that +;; the plot package continues to render the plots using the same draw commands +;; (therefore producing identical plots). +;; +;; If a test fails, the user has a sample image to compare what went wrong as +;; well as a new set of draw steps to compare against the saved one. + +;; Unless overridden, use these dimensions for the plots we generate for test +;; purposes. +(plot-width 1024) +(plot-height 768) + +;; A record-dc% to store the draw commands issued by plot or plot3d. We +;; override the font related functions to return constant and predictable +;; values -- this allows the tests to generate and verify the same draw +;; commands on different platforms where, due to different fonts installed, +;; the positions of various plot elements would be slightly different. +(define mock-record-dc% + (class record-dc% + (init) + (super-new) + (define/override (get-text-extent text (font #f) (combine? #f) (offset 0)) + (values (* 10 (string-length text)) 10 0 0)) + (define/override (get-char-width) 10) + (define/override (get-char-height) 10) + )) + +;; Generate the draw steps required to plot the RENDERER-TREE. This function +;; creates a `mock-record-dc%`, uses `plot/dc` to render to this DC and +;; retrieves the recorded steps from it. +(define (generate-draw-steps renderer-tree + #:x-min (x-min #f) + #:x-max (x-max #f) + #:y-min (y-min #f) + #:y-max (y-max #f) + #:width (width (plot-width)) + #:height (height (plot-height)) + #:title (title (plot-title)) + #:x-label (x-label (plot-x-label)) + #:y-label (y-label (plot-y-label)) + #:aspect-ratio (aspect-ratio (plot-aspect-ratio)) + #:legend-anchor (legend-anchor (plot-legend-anchor))) + (define dc (new mock-record-dc% [width width] [height height])) + (plot/dc renderer-tree dc 0 0 width height + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max + #:title title + #:x-label x-label #:y-label y-label + #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio) + (send dc get-recorded-datum)) + +;; Same as `generate-draw-steps` but uses `plot3d/dc` and should be used for +;; 3D plots. +(define (generate-draw-steps-3d renderer-tree + #:x-min (x-min #f) + #:x-max (x-max #f) + #:y-min (y-min #f) + #:y-max (y-max #f) + #:z-min (z-min #f) + #:z-max (z-max #f) + #:width (width (plot-width)) + #:height (height (plot-height)) + #:title (title #f) + #:x-label (x-label (plot-x-label)) + #:y-label (y-label (plot-y-label)) + #:z-label (z-label (plot-z-label)) + #:angle (angle (plot3d-angle)) + #:altitude (altitude (plot3d-altitude)) + #:aspect-ratio (aspect-ratio (plot-aspect-ratio)) + #:legend-anchor (legend-anchor (plot-legend-anchor))) + (define dc (new mock-record-dc% [width width] [height height])) + (plot3d/dc renderer-tree dc 0 0 width height + #:x-min x-min #:x-max x-max + #:y-min y-min #:y-max y-max + #:z-min z-min #:z-max z-max + #:title title + #:x-label x-label #:y-label y-label #:z-label z-label + #:angle angle + #:altitude altitude + #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio) + (send dc get-recorded-datum)) + +;; Return #t if two sets of draw steps, SET1 and SET2 are the same, false +;; otherwise. This function recursively traverses the cons tree of SET1 and +;; SET1 comparing elements using equal?, unless the elements are numbers in +;; which case it checks that the difference between them is small. +(define (same-draw-steps? set1 set2) + (cond ((and (pair? set1) (pair? set2)) + (and + (same-draw-steps? (car set1) (car set2)) + (same-draw-steps? (cdr set1) (cdr set2)))) + ((and (number? set1) (number? set2)) + (let ([difference (abs (- set1 set2))]) + (< difference 1e-4))) + (#t + (equal? set1 set2)))) + +;; Write a new set of draw steps to file. NEW-DRAW-STEPS are the new draw +;; steps, as produced by `generate-draw-steps` or `generate-draw-steps-3d` and +;; ORIGINAL-FILE is the original draw step file. The data is compressed and +;; saved in a file name prefixed with "new-". +(define (write-new-draw-steps new-draw-steps original-file) + (define-values (base name must-be-dir?) (split-path original-file)) + (make-directory* base) ; ensure the base path exists + (define data-file (build-path + base + (string-append "new-" (path->string name)))) + (define data (call-with-output-string (lambda (out) (write new-draw-steps out)))) + (call-with-input-string + data + (lambda (in) + (call-with-output-file + data-file + (lambda (out) + (gzip-through-ports in out #f (current-seconds))) + #:exists 'replace)))) + +;; Decompress and read draw steps from STEPS-FILE. If the file does not +;; exist, just return an empty list. +(define (read-draw-steps steps-file) + (if (file-exists? steps-file) + (let () + (define data + (call-with-output-string + (lambda (out) + (call-with-input-file + steps-file + (lambda (in) + (gunzip-through-ports in out)))))) + (call-with-input-string data read)) + null)) + +;; Verify that the draw steps produced by PLOT-FUNCTION match the ones in +;; SAVED-STEPS-FILE. If they do, this function returns VOID, otherwise it +;; fails using `fail`, so it is suitable for use in rackunit tests. +;; +;; When the function fails, the current set of draw steps as well as an image +;; of the current plot is saved in the same directory as SAVED-STEPS-FILE, +;; with the prefix "new-" they can be compared against the saved data to +;; determine what went wrong. +;; +;; The PLOT-FUNCTION is a function that must be supplied by the user to +;; generate the plot. Instead of calling `plot` directly, PLOT-FUNCTION will +;; take a function argument which will be used to pass the renderer tree to +;; (this allows calling plot inside a parameterize call). +;; +;; For example to test that the following plot works correctly: +;; +;; (parameterize ([plot-title "Hello"]) +;; (plot (function (lambda (x) x) -1 1))) +;; +;; You would need to write the following plot function: +;; +;; (define (plot-function output-fn) +;; (parameterize ([plot-title "Hello"]) +;; (output-fn (function (lambda (x) x) -1 1))) +;; +;; This way of writing the function allows testing it in different conditions. +;; For example, to generate an interactive plot in the DrRacket REPL you can +;; run: +;; +;; (plot-function plot) +;; +;; To write the plot to an image: +;; +;; (plot-function (lambda (rt) (plot-file rt "plot-image.png"))) +;; +(define (check-draw-steps plot-function saved-steps-file) + (define saved (read-draw-steps saved-steps-file)) + (define current (plot-function generate-draw-steps)) + (unless (same-draw-steps? saved current) + (write-new-draw-steps current saved-steps-file) + (define-values (base name must-be-dir?) (split-path saved-steps-file)) + (define data-file (build-path + base + (string-append "new-" (path->string name)))) + ;; Also generate an image of the current plot + (define image-file (path-replace-extension data-file ".png")) + (plot-function + (lambda (rt + #:x-min (x-min #f) + #:x-max (x-max #f) + #:y-min (y-min #f) + #:y-max (y-max #f) + #:width (width (plot-width)) + #:height (height (plot-height)) + #:title (title (plot-title)) + #:x-label (x-label (plot-x-label)) + #:y-label (y-label (plot-y-label)) + #:aspect-ratio (aspect-ratio (plot-aspect-ratio)) + #:legend-anchor (legend-anchor (plot-legend-anchor))) + (plot-file rt image-file + #:x-min x-min #:x-max x-max #:y-min y-min #:y-max y-max + #:width width #:height height + #:title title + #:x-label x-label #:y-label y-label + #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio))) + (fail (format "draw steps not the same, new set written to ~a" data-file)))) + +;; Same as `check-draw-steps` but for 3D plots. +(define (check-draw-steps-3d plot-function saved-steps-file) + (define saved (read-draw-steps saved-steps-file)) + (define current (plot-function generate-draw-steps-3d)) + (unless (same-draw-steps? saved current) + (write-new-draw-steps current saved-steps-file) + (define-values (base name must-be-dir?) (split-path saved-steps-file)) + (define data-file (build-path + base + (string-append "new-" (path->string name)))) + ;; Also generate an image of the current plot + (define image-file (path-replace-extension data-file ".png")) + (plot-function (lambda (rt + #:x-min (x-min #f) + #:x-max (x-max #f) + #:y-min (y-min #f) + #:y-max (y-max #f) + #:z-min (z-min #f) + #:z-max (z-max #f) + #:width (width (plot-width)) + #:height (height (plot-height)) + #:title (title #f) + #:x-label (x-label (plot-x-label)) + #:y-label (y-label (plot-y-label)) + #:z-label (z-label (plot-z-label)) + #:angle (angle (plot3d-angle)) + #:altitude (altitude (plot3d-altitude)) + #:aspect-ratio (aspect-ratio (plot-aspect-ratio)) + #:legend-anchor (legend-anchor (plot-legend-anchor))) + (plot3d-file rt image-file + #:x-min x-min #:x-max x-max + #:y-min y-min #:y-max y-max + #:z-min z-min #:z-max z-max + #:width width #:height height + #:title title + #:x-label x-label + #:y-label y-label + #:z-label z-label + #:angle angle + #:altitude altitude + #:legend-anchor legend-anchor + #:aspect-ratio aspect-ratio))) + (fail (format "draw steps not the same, new set written to ~a" data-file)))) diff --git a/plot-test/plot/tests/isosurface-tests.rkt b/plot-test/plot/tests/isosurface-tests.rkt index 3f393a31..be3aa098 100644 --- a/plot-test/plot/tests/isosurface-tests.rkt +++ b/plot-test/plot/tests/isosurface-tests.rkt @@ -1,63 +1,94 @@ #lang racket +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + math/flonum + "helpers.rkt") -(require plot plot/utils math/flonum) - -(time - (plot3d (isosurface3d (λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) 1 - #:color 2 #:line-style 'transparent - #:label "Sphere") - #:x-min -0.8 #:x-max 0.8 - #:y-min -0.8 #:y-max 0.8 - #:z-min -0.8 #:z-max 0.8 - #:altitude 30 - #:legend-anchor 'center)) - -(time - (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) - (plot3d (isosurfaces3d saddle #:d-min -1 #:d-max 1 #:label "d") - #:x-min -2 #:x-max 2 - #:y-min -2 #:y-max 2 - #:z-min -2 #:z-max 2 - #:legend-anchor 'top-left)) -(time - (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) - (plot3d (isosurfaces3d saddle #:d-min -1 #:d-max 1 - #:colors '(1 2 3) - #:line-colors '(1 2 3) - #:line-styles '(solid) - #:alphas '(3/4) - #:label "d") +(define (do-plot1 output-fn) + (output-fn (isosurface3d (λ (x y z) (sqrt (+ (sqr x) (sqr y) (sqr z)))) 1 + #:color 2 #:line-style 'transparent + #:label "Sphere") + #:x-min -0.8 #:x-max 0.8 + #:y-min -0.8 #:y-max 0.8 + #:z-min -0.8 #:z-max 0.8 + #:altitude 30 + #:legend-anchor 'center)) + + +(define (do-plot2 output-fn) + (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) + (output-fn (isosurfaces3d saddle #:d-min -1 #:d-max 1 #:label "d") + #:x-min -2 #:x-max 2 + #:y-min -2 #:y-max 2 + #:z-min -2 #:z-max 2 + #:legend-anchor 'top-left)) + +(define (do-plot3 output-fn) + (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) + (output-fn (isosurfaces3d saddle #:d-min -1 #:d-max 1 + #:colors '(1 2 3) + #:line-colors '(1 2 3) + #:line-styles '(solid) + #:alphas '(3/4) + #:label "d") #:x-min -2 #:x-max 2 #:y-min -2 #:y-max 2 #:z-min -2 #:z-max 2 #:legend-anchor 'top-left)) -(time - (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) - (plot3d (isosurface3d saddle -1/4 #:samples 21 - #:color "black" #:style 3 - #:alpha 1 - #:label "d = -1/4") - #:x-min -2 #:x-max 2 - #:y-min -2 #:y-max 2 - #:z-min -2 #:z-max 2)) +(define (do-plot4 output-fn) + (define saddle (λ (x y z) (- (sqr x) (* 1/2 (+ (sqr y) (sqr z)))))) + (output-fn (isosurface3d saddle -1/4 #:samples 21 + #:color "black" #:style 3 + #:alpha 1 + #:label "d = -1/4") + #:x-min -2 #:x-max 2 + #:y-min -2 #:y-max 2 + #:z-min -2 #:z-max 2)) (define 2pi (* 2 pi)) -(time - (define (f1 θ ρ) (+ 1 (/ θ 2pi) (* 1/8 (sin (* 8 ρ))))) - (define (f2 θ ρ) (+ (/ θ 2pi) (* 1/8 (sin (* 8 ρ))))) - (plot3d (list (polar3d f1 #:samples 41 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) - (polar3d f2 #:samples 41 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) - (parametric3d (λ (ρ) (3d-polar->3d-cartesian 0 ρ (f1 2pi ρ))) - (* -1/2 pi) (* 1/2 pi) - #:color "navajowhite" #:width 2) - (lines3d '(#(0 0 2) #(0 0 -2)) #:color "navajowhite" #:width 2)) - #:title "A Seashell" #:x-label #f #:y-label #f #:angle 210 #:altitude 30)) +(define (do-plot5 output-fn) + (define (f1 θ ρ) (+ 1 (/ θ 2pi) (* 1/8 (sin (* 8 ρ))))) + (define (f2 θ ρ) (+ (/ θ 2pi) (* 1/8 (sin (* 8 ρ))))) + (output-fn (list (polar3d f1 #:samples 41 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) + (polar3d f2 #:samples 41 #:color "navajowhite" #:line-style 'transparent #:alpha 2/3) + (parametric3d (λ (ρ) (3d-polar->3d-cartesian 0 ρ (f1 2pi ρ))) + (* -1/2 pi) (* 1/2 pi) + #:color "navajowhite" #:width 2) + (lines3d '(#(0 0 2) #(0 0 -2)) #:color "navajowhite" #:width 2)) + #:title "A Seashell" #:x-label #f #:y-label #f #:angle 210 #:altitude 30)) (define flepsilon (flnext 0.0)) -(time - (plot3d (isosurface3d (λ (x y z) (+ (sqr x) (sqr y) (sqr z))) (sqr (inexact->exact flepsilon)) - (- flepsilon) flepsilon (- flepsilon) flepsilon (- flepsilon) flepsilon))) +(define (do-plot6 output-fn) + (output-fn (isosurface3d (λ (x y z) (+ (sqr x) (sqr y) (sqr z))) (sqr (inexact->exact flepsilon)) + (- flepsilon) flepsilon (- flepsilon) flepsilon (- flepsilon) flepsilon))) + +(define-runtime-path isosurface-tests-1-data "./test-data/is-1.dat") +(define-runtime-path isosurface-tests-2-data "./test-data/is-2.dat") +(define-runtime-path isosurface-tests-3-data "./test-data/is-3.dat") +(define-runtime-path isosurface-tests-4-data "./test-data/is-4.dat") +(define-runtime-path isosurface-tests-5-data "./test-data/is-5.dat") +(define-runtime-path isosurface-tests-6-data "./test-data/is-6.dat") + + +(define isosurface-tests + (test-suite + "isosurface-tests" + (test-case "test case 1" (check-draw-steps-3d do-plot1 isosurface-tests-1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot2 isosurface-tests-2-data)) + (test-case "test case 3" (check-draw-steps-3d do-plot3 isosurface-tests-3-data)) + (test-case "test case 4" (check-draw-steps-3d do-plot4 isosurface-tests-4-data)) + (test-case "test case 5" (check-draw-steps-3d do-plot5 isosurface-tests-5-data)) + (test-case "test case 6" (check-draw-steps-3d do-plot6 isosurface-tests-6-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests isosurface-tests)) + + diff --git a/plot-test/plot/tests/pen-brush-hsv.rkt b/plot-test/plot/tests/pen-brush-hsv.rkt index f8150a64..ce1d16de 100644 --- a/plot-test/plot/tests/pen-brush-hsv.rkt +++ b/plot-test/plot/tests/pen-brush-hsv.rkt @@ -1,6 +1,9 @@ #lang racket -(require plot plot/utils) +(require plot plot/utils + racket/runtime-path + rackunit + "helpers.rkt") (define (rgb->hsv rgb) (match-define (list r g b) (map (λ (x) (/ x 255)) rgb)) @@ -50,23 +53,29 @@ (define x (/ h 60)) (+ 1/2 (* 1/6 (sin (* (/ x 6) (* 3 pi)))))) -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map first pen-colors) (list 360)))) - (function (λ (x) (* x 60))) - (function (λ (x) (pen-hue-transform (* x 60))) - #:color 3)) - #:title "Pen Hue") - -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map second pen-colors) - (list (second (first pen-colors)))))) - (function (λ (x) (pen-saturation-transform (* x 60))))) - #:y-min 0 #:y-max 1 - #:title "Pen Saturation") - -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map third pen-colors) - (list (third (first pen-colors)))))) - (function (λ (x) (pen-value-transform (* x 60))))) - #:y-min 0 #:y-max 1 - #:title "Pen Value") +(define-runtime-path pb-1-data "./test-data/pb-1.dat") +(define (do-plot-1 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map first pen-colors) (list 360)))) + (function (λ (x) (* x 60))) + (function (λ (x) (pen-hue-transform (* x 60))) + #:color 3)) + #:title "Pen Hue")) + +(define-runtime-path pb-2-data "./test-data/pb-2.dat") +(define (do-plot-2 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map second pen-colors) + (list (second (first pen-colors)))))) + (function (λ (x) (pen-saturation-transform (* x 60))))) + #:y-min 0 #:y-max 1 + #:title "Pen Saturation")) + +(define-runtime-path pb-3-data "./test-data/pb-3.dat") +(define (do-plot-3 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map third pen-colors) + (list (third (first pen-colors)))))) + (function (λ (x) (pen-value-transform (* x 60))))) + #:y-min 0 #:y-max 1 + #:title "Pen Value")) (define (integer->hue n) (let ([n (abs n)]) @@ -78,10 +87,12 @@ (define h (integer->hue n)) (hsv->rgb (list (pen-hue-transform h) (pen-saturation-transform h) (pen-value-transform h)))) -(plot (for/list ([n (in-range 60)]) - (lines (list (vector 0 n) (vector 1 n)) - #:color (pen-color n) - #:width 6))) +(define-runtime-path pb-4-data "./test-data/pb-4.dat") +(define (do-plot-4 output-fn) + (output-fn (for/list ([n (in-range 60)]) + (lines (list (vector 0 n) (vector 1 n)) + #:color (pen-color n) + #:width 6)))) (define (brush-hue-transform h) (define x (/ h 60)) @@ -96,23 +107,29 @@ (define (brush-value-transform h) 1) -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map first brush-colors) (list 360)))) - (function (λ (x) (* x 60))) - (function (λ (x) (brush-hue-transform (* x 60))) - #:color 3)) - #:title "Brush Hue") - -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map second brush-colors) - (list (second (first brush-colors)))))) - (function (λ (x) (brush-saturation-transform (* x 60))))) - #:y-min 0 #:y-max 1 - #:title "Brush Saturation") - -(plot (list (points (map vector '(0 1 2 3 4 5 6) (append (map third brush-colors) - (list (third (first brush-colors)))))) - (function (λ (x) (brush-value-transform (* x 60))))) - #:y-min 0 #:y-max 1 - #:title "Brush Value") +(define-runtime-path pb-5-data "./test-data/pb-5.dat") +(define (do-plot-5 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map first brush-colors) (list 360)))) + (function (λ (x) (* x 60))) + (function (λ (x) (brush-hue-transform (* x 60))) + #:color 3)) + #:title "Brush Hue")) + +(define-runtime-path pb-6-data "./test-data/pb-6.dat") +(define (do-plot-6 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map second brush-colors) + (list (second (first brush-colors)))))) + (function (λ (x) (brush-saturation-transform (* x 60))))) + #:y-min 0 #:y-max 1 + #:title "Brush Saturation")) + +(define-runtime-path pb-7-data "./test-data/pb-7.dat") +(define (do-plot-7 output-fn) + (output-fn (list (points (map vector '(0 1 2 3 4 5 6) (append (map third brush-colors) + (list (third (first brush-colors)))))) + (function (λ (x) (brush-value-transform (* x 60))))) + #:y-min 0 #:y-max 1 + #:title "Brush Value")) (define (brush-color n) (define h (integer->hue n)) @@ -133,12 +150,14 @@ (define (gray-brush-color i) (make-list 3 (brush-intensity-transform i))) -(plot (for/list ([n (in-range 8)]) - (function-interval sin (λ (x) (+ 1 (sin x))) n (+ 1 n) - #:color (gray-brush-color n) - #:line1-color (gray-pen-color n) - #:line2-color (gray-pen-color n) - #:line1-width 2 #:line2-width 2 #:alpha 1))) +(define-runtime-path pb-8-data "./test-data/pb-8.dat") +(define (do-plot-8 output-fn) + (output-fn (for/list ([n (in-range 8)]) + (function-interval sin (λ (x) (+ 1 (sin x))) n (+ 1 n) + #:color (gray-brush-color n) + #:line1-color (gray-pen-color n) + #:line2-color (gray-pen-color n) + #:line1-width 2 #:line2-width 2 #:alpha 1)))) (define new-brush-colors (append (list (gray-brush-color 0)) @@ -150,46 +169,77 @@ (build-list 120 brush-color) (build-list 7 (λ (n) (gray-brush-color (- 7 n)))))) -(plot (for/list ([n (in-range 60)]) - (lines (list (vector 0 n) (vector 1 n)) - #:color (brush-color n) - #:width 6))) - -(plot (for*/list ([i (in-range 6)] [j (in-range 20)]) - (define n (+ i (* j 6))) - (rectangles (list (vector (ivl (+ i 0.05) (+ i 0.95)) - (ivl (+ j 0.05) (+ j 0.95)))) - #:color (brush-color n) - #:line-color (pen-color n) - #:line-width 3)) - #:height 1200) - -(plot (list (for*/list ([n (in-range 8)]) - (rectangles (list (vector (ivl (+ n 0.05) (+ n 0.95)) - (ivl 0 1))) - #:color (->brush-color n) - #:line-color (->pen-color n) - #:line-width 3)) - (for*/list ([n (in-range 8)]) - (rectangles (list (vector (ivl (+ n 0.05) (+ n 0.95)) - (ivl 1.2 2.2))) - #:color (brush-color (- n 1)) - #:line-color (pen-color (- n 1)) - #:line-width 3))) - #:height 200) - -(plot (for/list ([n (in-range 12)]) - (function-interval (λ (x) (* 1/2 (sqr (+ x (* 2 n))))) - (λ (x) (+ 1/2 (sqr (+ x (* 2 n))))) - 0 12 #:color (brush-color n) - #:line1-color (pen-color n) - #:line2-color (pen-color n) - #:line1-width 2 #:line2-width 2))) - -(plot (for/list ([n (in-range 6)]) - (function-interval (λ (x) (* 1/2 (sin (+ x n)))) - (λ (x) (+ 1/2 (sin (+ x n)))) - -4 4 #:color (->brush-color (+ n 1)) - #:line1-color (->pen-color (+ n 1)) - #:line2-color (->pen-color (+ n 1)) - #:line1-width 2 #:line2-width 2))) +(define-runtime-path pb-9-data "./test-data/pb-9.dat") +(define (do-plot-9 output-fn) + (output-fn (for/list ([n (in-range 60)]) + (lines (list (vector 0 n) (vector 1 n)) + #:color (brush-color n) + #:width 6)))) + +(define-runtime-path pb-10-data "./test-data/pb-10.dat") +(define (do-plot-10 output-fn) + (output-fn (for*/list ([i (in-range 6)] [j (in-range 20)]) + (define n (+ i (* j 6))) + (rectangles (list (vector (ivl (+ i 0.05) (+ i 0.95)) + (ivl (+ j 0.05) (+ j 0.95)))) + #:color (brush-color n) + #:line-color (pen-color n) + #:line-width 3)) + #:height 1200)) + +(define-runtime-path pb-11-data "./test-data/pb-11.dat") +(define (do-plot-11 output-fn) + (output-fn (list (for*/list ([n (in-range 8)]) + (rectangles (list (vector (ivl (+ n 0.05) (+ n 0.95)) + (ivl 0 1))) + #:color (->brush-color n) + #:line-color (->pen-color n) + #:line-width 3)) + (for*/list ([n (in-range 8)]) + (rectangles (list (vector (ivl (+ n 0.05) (+ n 0.95)) + (ivl 1.2 2.2))) + #:color (brush-color (- n 1)) + #:line-color (pen-color (- n 1)) + #:line-width 3))) + #:height 200)) + +(define-runtime-path pb-12-data "./test-data/pb-12.dat") +(define (do-plot-12 output-fn) + (output-fn (for/list ([n (in-range 12)]) + (function-interval (λ (x) (* 1/2 (sqr (+ x (* 2 n))))) + (λ (x) (+ 1/2 (sqr (+ x (* 2 n))))) + 0 12 #:color (brush-color n) + #:line1-color (pen-color n) + #:line2-color (pen-color n) + #:line1-width 2 #:line2-width 2)))) + +(define-runtime-path pb-13-data "./test-data/pb-13.dat") +(define (do-plot-13 output-fn) + (output-fn (for/list ([n (in-range 6)]) + (function-interval (λ (x) (* 1/2 (sin (+ x n)))) + (λ (x) (+ 1/2 (sin (+ x n)))) + -4 4 #:color (->brush-color (+ n 1)) + #:line1-color (->pen-color (+ n 1)) + #:line2-color (->pen-color (+ n 1)) + #:line1-width 2 #:line2-width 2)))) + +(define pen-brush-hsv-tests + (test-suite + "pen-brush-hsv-tests" + (test-case "test case 1" (check-draw-steps do-plot-1 pb-1-data)) + (test-case "test case 2" (check-draw-steps do-plot-2 pb-2-data)) + (test-case "test case 3" (check-draw-steps do-plot-3 pb-3-data)) + (test-case "test case 4" (check-draw-steps do-plot-4 pb-4-data)) + (test-case "test case 5" (check-draw-steps do-plot-5 pb-5-data)) + (test-case "test case 6" (check-draw-steps do-plot-6 pb-6-data)) + (test-case "test case 7" (check-draw-steps do-plot-7 pb-7-data)) + (test-case "test case 8" (check-draw-steps do-plot-8 pb-8-data)) + (test-case "test case 9" (check-draw-steps do-plot-9 pb-9-data)) + (test-case "test case 10" (check-draw-steps do-plot-10 pb-10-data)) + (test-case "test case 11" (check-draw-steps do-plot-11 pb-11-data)) + (test-case "test case 12" (check-draw-steps do-plot-12 pb-12-data)) + (test-case "test case 13" (check-draw-steps do-plot-13 pb-13-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests pen-brush-hsv-tests)) diff --git a/plot-test/plot/tests/plot2d-tests.rkt b/plot-test/plot/tests/plot2d-tests.rkt index 808cc1ee..cf9483f3 100644 --- a/plot-test/plot/tests/plot2d-tests.rkt +++ b/plot-test/plot/tests/plot2d-tests.rkt @@ -1,102 +1,135 @@ #lang racket -(require rackunit plot plot/utils math/flonum) - -;(plot-new-window? #t) - -(plot (function / -249 250)) - -(time - (define xs (build-list 10000 (λ _ (random)))) - (plot (density xs 1/2))) - -(printf "Plot should be empty:~n") -(time - (plot empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1)) - -(printf "Plot should be empty:~n") -(time - (plot (points empty) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1)) - -(printf "Plot should be empty:~n") -(plot (rectangles (list (list (ivl 0 1) (ivl 0 1)))) - #:x-min 2 #:x-max 3) - -(plot (list (function values -4 4) (axes 1 2))) - -(time (plot (function values 0 1000))) - -(parameterize ([plot-x-transform log-transform] - [plot-x-ticks (log-ticks #:base 4)] - [plot-y-transform log-transform] - [plot-y-ticks (linear-ticks #:number 10)]) - (plot (function values 1 243))) - -(parameterize ([plot-background "black"] - [plot-foreground "white"] - [plot-background-alpha 1/2] - [plot-foreground-alpha 1/2]) - (plot (function sin -4 4 #:label "y = sin(x)"))) - -(parameterize ([plot-x-transform (hand-drawn-transform 200)] - [plot-y-transform (hand-drawn-transform 200)]) - (plot (function sqr -1 1))) - -(parameterize ([plot-x-transform log-transform] - #;[plot-y-transform log-transform]) - (time - (plot (list (function (λ (x) x) 0.1 10 #:samples 2 #:label "y = x") - (polar-axes)) - #:title "Nonlinear scaling" #:x-label "x axis" #:y-label "y-axis"))) +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + math/flonum + pict + "helpers.rkt") + +(define-runtime-path p2d-1-data "./test-data/p1d-1.dat") +(define (do-plot-1 output-fn) + (output-fn (function / -249 250))) + +(define-runtime-path p2d-2-data "./test-data/p2d-2.dat") +(define (do-plot-2 output-fn) + (random-seed 42) + (define xs (build-list 10000 (λ _ (random)))) + (output-fn (density xs 1/2))) + +(define-runtime-path p2d-3-data "./test-data/p2d-3.dat") +(define (do-plot-3 output-fn) + (output-fn empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 + #:title "plot should be empty")) + +(define-runtime-path p2d-4-data "./test-data/p2d-4.dat") +(define (do-plot-4 output-fn) + (output-fn (points empty) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 + #:title "plot should be empty")) + +(define-runtime-path p2d-5-data "./test-data/p2d-5.dat") +(define (do-plot-5 output-fn) + (output-fn (rectangles (list (list (ivl 0 1) (ivl 0 1)))) + #:x-min 2 #:x-max 3 + #:title "plot should be empty")) + +(define-runtime-path p2d-6-data "./test-data/p2d-6.dat") +(define (do-plot-6 output-fn) + (output-fn (list (function values -4 4) (axes 1 2)))) + +(define-runtime-path p2d-7-data "./test-data/p2d-7.dat") +(define (do-plot-7 output-fn) + (output-fn (function values 0 1000))) + +(define-runtime-path p2d-8-data "./test-data/p2d-8.dat") +(define (do-plot-8 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-x-ticks (log-ticks #:base 4)] + [plot-y-transform log-transform] + [plot-y-ticks (linear-ticks #:number 10)]) + (output-fn (function values 1 243)))) + +(define-runtime-path p2d-9-data "./test-data/p2d-9.dat") +(define (do-plot-9 output-fn) + (parameterize ([plot-background "black"] + [plot-foreground "white"] + [plot-background-alpha 1/2] + [plot-foreground-alpha 1/2]) + (output-fn (function sin -4 4 #:label "y = sin(x)")))) + +(define-runtime-path p2d-10-data "./test-data/p2d-10.dat") +(define (do-plot-10 output-fn) + (parameterize ([plot-x-transform (hand-drawn-transform 200)] + [plot-y-transform (hand-drawn-transform 200)]) + (output-fn (function sqr -1 1)))) + +(define-runtime-path p2d-11-data "./test-data/p2d-11.dat") +(define (do-plot-11 output-fn) + (parameterize ([plot-x-transform log-transform] + #;[plot-y-transform log-transform]) + (output-fn (list (function (λ (x) x) 0.1 10 #:samples 2 #:label "y = x") + (polar-axes)) + #:title "Nonlinear scaling" #:x-label "x axis" #:y-label "y-axis"))) (define (degrees->point θ [r 1]) (vector (* r (cos (degrees->radians θ))) (* r (sin (degrees->radians θ))))) -(plot (list (lines (list (degrees->point 0) - (degrees->point 120) - (degrees->point 180 0) - (degrees->point 240) - (degrees->point 0))) - (polar (λ (θ) 1) #:color 0))) +(define-runtime-path p2d-12-data "./test-data/p2d-12.dat") +(define (do-plot-12 output-fn) + (output-fn (list (lines (list (degrees->point 0) + (degrees->point 120) + (degrees->point 180 0) + (degrees->point 240) + (degrees->point 0))) + (polar (λ (θ) 1) #:color 0)))) ;(plot-x-transform cbrt-transform) ;(plot-y-transform cbrt-transform) ;(plot-x-transform (hand-drawn-transform 100)) ;(plot-y-transform (hand-drawn-transform 100)) -(time - (plot (vector-field (λ (x y) (vector x y)) - -5 5 -5 5 #:scale 'auto))) - -(time - (plot (vector-field (λ (x y) (vector (- y) x)) - -2 2 -1 4 #:scale 'normalized))) - -(time - (plot (list (lines (for/list ([i (in-range 6)]) - (degrees->point (* 2 72 i)))) - (list (polar (λ (θ) 1) #:color 0) - (polar (λ (θ) 0.38) #:color 0))))) - -(time - (plot (list (lines (for/list ([i (in-range 4)]) - (degrees->point (* 120 i)))) - (lines (for/list ([i (in-range 4)]) - (degrees->point (+ 60 (* 120 i))))) - (polar (λ (θ) 1) #:color 0) - (polar (λ (θ) 0.5) #:color 0)))) - -(time - (define xs (build-list 100 (λ _ (random)))) - (define ys (build-list 100 (λ _ (random)))) - (plot (list (points (map vector ys xs) #:sym 'full6star #:color 1) - (points (map vector xs ys) #:sym "B" #:color 3)))) - -(printf "This plot should be blank:~n") -(time - (plot (vector-field (λ (x y) (vector +nan.0 +nan.0))) - #:x-min -2 #:x-max 2 #:y-min -2 #:y-max 2)) +(define-runtime-path p2d-13-data "./test-data/p2d-13.dat") +(define (do-plot-13 output-fn) + (output-fn (vector-field (λ (x y) (vector x y)) + -5 5 -5 5 #:scale 'auto))) + +(define-runtime-path p2d-14-data "./test-data/p2d-14.dat") +(define (do-plot-14 output-fn) + (output-fn (vector-field (λ (x y) (vector (- y) x)) + -2 2 -1 4 #:scale 'normalized))) + +(define-runtime-path p2d-15-data "./test-data/p2d-15.dat") +(define (do-plot-15 output-fn) + (output-fn (list (lines (for/list ([i (in-range 6)]) + (degrees->point (* 2 72 i)))) + (list (polar (λ (θ) 1) #:color 0) + (polar (λ (θ) 0.38) #:color 0))))) + +(define-runtime-path p2d-16-data "./test-data/p2d-16.dat") +(define (do-plot-16 output-fn) + (output-fn (list (lines (for/list ([i (in-range 4)]) + (degrees->point (* 120 i)))) + (lines (for/list ([i (in-range 4)]) + (degrees->point (+ 60 (* 120 i))))) + (polar (λ (θ) 1) #:color 0) + (polar (λ (θ) 0.5) #:color 0)))) + +(define-runtime-path p2d-17-data "./test-data/p2d-17.dat") +(define (do-plot-17 output-fn) + (random-seed 42) + (define xs (build-list 100 (λ _ (random)))) + (define ys (build-list 100 (λ _ (random)))) + (output-fn (list (points (map vector ys xs) #:sym 'full6star #:color 1) + (points (map vector xs ys) #:sym "B" #:color 3)))) + +(define-runtime-path p2d-18-data "./test-data/p2d-18.dat") +(define (do-plot-18 output-fn) + (output-fn (vector-field (λ (x y) (vector +nan.0 +nan.0))) + #:x-min -2 #:x-max 2 #:y-min -2 #:y-max 2 + #:title "plot should be empty")) #;; high-contrast white-on-black: (begin @@ -109,200 +142,240 @@ ;; an exact rational function and a floating-point function ;; the plot of the exact rational function's graph should be smooth -(time - (parameterize ([plot-x-tick-label-angle 15]) - (plot (list (function (λ (x) x) #:label "Exact") - (function (λ (x) (fl x)) #:color 2 #:label "Inexact")) - #:x-min #e100000000000000.0 #:x-max #e100000000000000.1 - #:width 450))) - -(time - (plot (function cos 0 0.0000001) - #:width 500)) - -(time - (plot (list (function sin #:label "Sine" - #:color "Blue" #:style 'long-dash #:width 3) - (function sqr #:label "Square")) - #:x-min -3 #:x-max 3 - #:legend-anchor 'top-left)) - -(time - (plot (list (axes) - (function sqr -2.1 2.1 #:label "x^2") - (error-bars (map (λ (x) (vector x (sqr x) (/ 1/2 (+ (abs x) 1)))) - (sequence->list (in-range -2 2.1 1/8))) - #:x-min -1)))) - -(time - (plot (list (points '(#(1 1) #(2 2) #(3 3)) #:sym "bob" #:size 10 - #:x-min 2 #:x-max 3 #:y-min 1 #:y-max 3)) - #:x-min 0 #:x-max 4 #:y-min 0 #:y-max 4)) - -(time - (plot (list (x-axis 1) (y-axis 1) - (function sqr #f 2 #:color 1) - (inverse sqr #:color 2) - (function values #:color 0 #:style 1)) - #:x-min -2 #:y-min -1)) - -(time - (plot (list (polar-axes #:number 4) - (polar (λ (θ) (+ 0.5 (cos (* 1/2 θ)))) (* -2 pi) (* 2 pi))))) +(define-runtime-path p2d-19-data "./test-data/p2d-19.dat") +(define (do-plot-19 output-fn) + (parameterize ([plot-x-tick-label-angle 15]) + (output-fn (list (function (λ (x) x) #:label "Exact") + (function (λ (x) (fl x)) #:color 2 #:label "Inexact")) + #:x-min #e100000000000000.0 #:x-max #e100000000000000.1 + #:width 450))) + +(define-runtime-path p2d-20-data "./test-data/p2d-20.dat") +(define (do-plot-20 output-fn) + (output-fn (function cos 0 0.0000001) #:width 500)) + +(define-runtime-path p2d-21-data "./test-data/p2d-21.dat") +(define (do-plot-21 output-fn) + (output-fn (list (function sin #:label "Sine" + #:color "Blue" #:style 'long-dash #:width 3) + (function sqr #:label "Square")) + #:x-min -3 #:x-max 3 + #:legend-anchor 'top-left)) + +(define-runtime-path p2d-22-data "./test-data/p2d-22.dat") +(define (do-plot-22 output-fn) + (output-fn (list (axes) + (function sqr -2.1 2.1 #:label "x^2") + (error-bars (map (λ (x) (vector x (sqr x) (/ 1/2 (+ (abs x) 1)))) + (sequence->list (in-range -2 2.1 1/8))) + #:x-min -1)))) + +(define-runtime-path p2d-23-data "./test-data/p2d-23.dat") +(define (do-plot-23 output-fn) + (output-fn (list (points '(#(1 1) #(2 2) #(3 3)) #:sym "bob" #:size 10 + #:x-min 2 #:x-max 3 #:y-min 1 #:y-max 3)) + #:x-min 0 #:x-max 4 #:y-min 0 #:y-max 4)) + +(define-runtime-path p2d-24-data "./test-data/p2d-24.dat") +(define (do-plot-24 output-fn) + (output-fn (list (x-axis 1) (y-axis 1) + (function sqr #f 2 #:color 1) + (inverse sqr #:color 2) + (function values #:color 0 #:style 1)) + #:x-min -2 #:y-min -1)) + +(define-runtime-path p2d-25-data "./test-data/p2d-25.dat") +(define (do-plot-25 output-fn) + (output-fn (list (polar-axes #:number 4) + (polar (λ (θ) (+ 0.5 (cos (* 1/2 θ)))) (* -2 pi) (* 2 pi))))) ; draws both functions with x in [-1,1] -(plot (list (function sqr #f 1) - (function (λ (x) (* 2 (sqr x))) -1 #f - #:color "blue") - (axes 1 0 #:y-ticks? #f))) - -(printf "Plot should be empty:~n") -(plot (list (function sqr #f -1) - (function sqr 1 #f))) +(define-runtime-path p2d-26-data "./test-data/p2d-26.dat") +(define (do-plot-26 output-fn) + (output-fn (list (function sqr #f 1) + (function (λ (x) (* 2 (sqr x))) -1 #f + #:color "blue") + (axes 1 0 #:y-ticks? #f)))) + +(define-runtime-path p2d-27-data "./test-data/p2d-27.dat") +(define (do-plot-27 output-fn) + (output-fn (list (function sqr #f -1) + (function sqr 1 #f)) + #:title "plot should be empty")) ; draws both functions with x in [-1,2] (meaning nothing is drawn) -(printf "Plot should be empty:~n") -(plot (list (function sqr #f -1) - (function sqr 2 #f))) +(define-runtime-path p2d-28-data "./test-data/p2d-28.dat") +(define (do-plot-28 output-fn) + (output-fn (list (function sqr #f -1) + (function sqr 2 #f)) + #:title "plot should be empty")) ; draws first function with x in [-2,-1] -(plot (list (function sqr #f -1) - (function sqr 1 #f)) - #:x-min -2) +(define-runtime-path p2d-29-data "./test-data/p2d-29.dat") +(define (do-plot-29 output-fn) + (output-fn (list (function sqr #f -1) + (function sqr 1 #f)) + #:x-min -2)) ; draws second function with x in [1,2] -(plot (list (function sqr #f -1) - (function sqr 1 #f)) - #:x-max 2) +(define-runtime-path p2d-30-data "./test-data/p2d-30.dat") +(define (do-plot-30 output-fn) + (output-fn (list (function sqr #f -1) + (function sqr 1 #f)) + #:x-max 2)) ; draws both functions with x in [-2,2] -(plot (list (function sqr #f -1) - (function sqr 1 #f)) - #:x-min -2 #:x-max 2) +(define-runtime-path p2d-31-data "./test-data/p2d-31.dat") +(define (do-plot-31 output-fn) + (output-fn (list (function sqr #f -1) + (function sqr 1 #f)) + #:x-min -2 #:x-max 2)) ; draws both in full (particularly, without chopping off the top of the parabola), in [-2,2] -(plot (list (function sqr) - (function sin -2 2))) - -(time - (plot (list (discrete-histogram - (build-list 10 (λ (n) (vector (string-ref "abcdefghij" n) - (sqr n)))) - #:label "ord(x)^2") - (function truncate)))) - -(time - (plot (list (x-axis) - (discrete-histogram '((a -1) (b 2.6) (c 4) (d 3.1)) #:y-min #f - #:color 5 #:line-color 5 #:line-style 'long-dash - #:label "Corrupt") - (discrete-histogram '(#(a 1) #(b 2.6) #(c 4) #(d 3.1)) - #:x-min 5 - #:color 1 #:line-color 1 #:line-width 3 - #:label "Clean")) - #:title "Widgetyness of Widgets" - #:x-label "Widget" - #:y-label "Widgetyness" - #:legend-anchor 'bottom-right)) - -(time - (plot (stacked-histogram '(#(a (1 1 1)) #(b (1.5 3)) #(c ()) #(d (1/2))) - #:labels '("Red" #f "Blue")))) - -(time - (parameterize ([discrete-histogram-gap 0] - [discrete-histogram-skip 3] - [rectangle-line-width 2]) - (plot (list (discrete-histogram '(#(a 1) #(b 2.5) #(c 2)) #:label "Blue") - (discrete-histogram '(#(a 2) #(b 4) #(c 1)) #:x-min 2/3 #:color 1 #:line-color 1 - #:label "Red") - (discrete-histogram '(#(a 3) #(b 3) #(c 2.5)) #:x-min 4/3 #:color 2 #:line-color 2 - #:label "Green"))))) - -(time - (parameterize ([discrete-histogram-gap 0] - [discrete-histogram-skip 2] - [stacked-histogram-line-widths '(3)]) - (plot (list (stacked-histogram '(#(a (0.2 1)) #(b (2.5 1.2)) #(c (2 0)))) - (stacked-histogram '((a (2 1)) (b (1.1 0.9)) (c (1 1.1))) #:x-min 7/8 - #:colors '(3 4) - #:line-colors '(3 4)))))) - -(time - (parameterize ([plot-x-ticks (currency-ticks)]) - (plot (discrete-histogram (list (vector '(a . a) 1) (vector '(a . b) 2) - (vector '(b . b) 3) (vector '(b . a) 4)) - #:invert? #t #:add-ticks? #f)))) - -(time - (parameterize ([plot-x-ticks (currency-ticks)]) - (plot (stacked-histogram (list (vector '(a . a) '(1 2 1)) (vector '(a . b) '(2 1 3)) - (vector '(b . b) '()) (vector '(b . a) '(4 4 2))) - #:invert? #t #:add-ticks? #f)))) - -(time - (plot (rectangles - (map vector - (bounds->intervals (map log (linear-seq 10 20 10))) - (build-list 9 (λ (n) (ivl (sqr n) (- (sqr n))))))))) - -(time - (define (f x) (* (/ 1 (sqrt (* 2 pi))) - (exp (* -1/2 (sqr x))))) - (plot (list (area-histogram f (linear-seq -4 4 10)) - (function f -4 4)))) - -(time - ;; Intentionally using fewer samples than bins - (plot (list (area-histogram sqr (map (λ (x) (* (sqrt x) (sqrt 8))) (linear-seq 0 8 10)) #:samples 2) - (function sqr 0 8 #:samples 2)))) - -(time - (plot (list (area-histogram sqr (map (λ (x) (* (sqrt x) (sqrt 8))) (linear-seq 0 8 10))) - (function sqr 0 8)))) - -(time - (define xs (build-list 10000 (λ _ (random)))) - (define ys (build-list 10000 (λ _ (random)))) - (plot (list - (points (map vector xs ys) - #:x-min -1 #:x-max 1 #:y-min 0.5 #:y-max 1 - #:sym 'fullcircle #:size 6.5 #:alpha 1/8 - #:label "Dots")) - #:y-max 1.5)) - -(time - (plot (vector-field (λ (x y) (vector x y)) -0.5 1.85 -5 0.5 - #:color "blue" #:line-width 2/3 - #:scale 'auto #:label "(vector x y)") - #:x-min -1 #:x-max 5)) - -(time - (plot (list (function (λ (x) (* 220 (cos (* 4 x)))) -2 2) - (function (λ (x) (* 200 (sin (* 3 x)))) 0 #f - #:y-min -150 #:y-max 150 - #:color "blue")) - #:x-min -1/2 #:x-max 3)) - -(time - (plot (lines (reverse - (for/fold ([lst (list (vector 0 0))]) ([i (in-range 1 400)]) - (match-define (vector x y) (first lst)) - (cons (vector i (+ y (* 1/100 (- (random) 1/2)))) lst))) - #:alpha 0.5 #:label "Random walk"))) - -(time - (plot (function (λ (x) (/ 1.0 (fl x))) -2 2))) - -(time - (plot (parametric (λ (t) (vector (sin t) (cos t))) (- pi) pi - #:x-min -0.5 #:y-max 0.5) - #:x-min -1)) - -(time - (plot (list (function sin -1/2 1) - (parametric (λ (t) (vector (cos t) (sin t))) -2 1 - #:color "blue" #:style 'short-dash)))) +(define-runtime-path p2d-32-data "./test-data/p2d-32.dat") +(define (do-plot-32 output-fn) + (output-fn (list (function sqr) + (function sin -2 2)))) + +(define-runtime-path p2d-33-data "./test-data/p2d-33.dat") +(define (do-plot-33 output-fn) + (output-fn (list (discrete-histogram + (build-list 10 (λ (n) (vector (string-ref "abcdefghij" n) + (sqr n)))) + #:label "ord(x)^2") + (function truncate)))) + +(define-runtime-path p2d-34-data "./test-data/p2d-34.dat") +(define (do-plot-34 output-fn) + (output-fn (list (x-axis) + (discrete-histogram '((a -1) (b 2.6) (c 4) (d 3.1)) #:y-min #f + #:color 5 #:line-color 5 #:line-style 'long-dash + #:label "Corrupt") + (discrete-histogram '(#(a 1) #(b 2.6) #(c 4) #(d 3.1)) + #:x-min 5 + #:color 1 #:line-color 1 #:line-width 3 + #:label "Clean")) + #:title "Widgetyness of Widgets" + #:x-label "Widget" + #:y-label "Widgetyness" + #:legend-anchor 'bottom-right)) + +(define-runtime-path p2d-35-data "./test-data/p2d-35.dat") +(define (do-plot-35 output-fn) + (output-fn (stacked-histogram '(#(a (1 1 1)) #(b (1.5 3)) #(c ()) #(d (1/2))) + #:labels '("Red" #f "Blue")))) + +(define-runtime-path p2d-36-data "./test-data/p2d-36.dat") +(define (do-plot-36 output-fn) + (parameterize ([discrete-histogram-gap 0] + [discrete-histogram-skip 3] + [rectangle-line-width 2]) + (output-fn (list (discrete-histogram '(#(a 1) #(b 2.5) #(c 2)) #:label "Blue") + (discrete-histogram '(#(a 2) #(b 4) #(c 1)) #:x-min 2/3 #:color 1 #:line-color 1 + #:label "Red") + (discrete-histogram '(#(a 3) #(b 3) #(c 2.5)) #:x-min 4/3 #:color 2 #:line-color 2 + #:label "Green"))))) + +(define-runtime-path p2d-37-data "./test-data/p2d-37.dat") +(define (do-plot-37 output-fn) + (parameterize ([discrete-histogram-gap 0] + [discrete-histogram-skip 2] + [stacked-histogram-line-widths '(3)]) + (output-fn (list (stacked-histogram '(#(a (0.2 1)) #(b (2.5 1.2)) #(c (2 0)))) + (stacked-histogram '((a (2 1)) (b (1.1 0.9)) (c (1 1.1))) #:x-min 7/8 + #:colors '(3 4) + #:line-colors '(3 4)))))) + +(define-runtime-path p2d-38-data "./test-data/p2d-38.dat") +(define (do-plot-38 output-fn) + (parameterize ([plot-x-ticks (currency-ticks)]) + (output-fn (discrete-histogram (list (vector '(a . a) 1) (vector '(a . b) 2) + (vector '(b . b) 3) (vector '(b . a) 4)) + #:invert? #t #:add-ticks? #f)))) + +(define-runtime-path p2d-39-data "./test-data/p2d-39.dat") +(define (do-plot-39 output-fn) + (parameterize ([plot-x-ticks (currency-ticks)]) + (output-fn (stacked-histogram (list (vector '(a . a) '(1 2 1)) (vector '(a . b) '(2 1 3)) + (vector '(b . b) '()) (vector '(b . a) '(4 4 2))) + #:invert? #t #:add-ticks? #f)))) + +(define-runtime-path p2d-40-data "./test-data/p2d-40.dat") +(define (do-plot-40 output-fn) + (output-fn (rectangles + (map vector + (bounds->intervals (map log (linear-seq 10 20 10))) + (build-list 9 (λ (n) (ivl (sqr n) (- (sqr n))))))))) + +(define-runtime-path p2d-41-data "./test-data/p2d-41.dat") +(define (do-plot-41 output-fn) + (define (f x) (* (/ 1 (sqrt (* 2 pi))) + (exp (* -1/2 (sqr x))))) + (output-fn (list (area-histogram f (linear-seq -4 4 10)) + (function f -4 4)))) + +(define-runtime-path p2d-42-data "./test-data/p2d-42.dat") +(define (do-plot-42 output-fn) + ;; Intentionally using fewer samples than bins + (output-fn (list (area-histogram sqr (map (λ (x) (* (sqrt x) (sqrt 8))) (linear-seq 0 8 10)) #:samples 2) + (function sqr 0 8 #:samples 2)))) + +(define-runtime-path p2d-43-data "./test-data/p2d-43.dat") +(define (do-plot-43 output-fn) + (output-fn (list (area-histogram sqr (map (λ (x) (* (sqrt x) (sqrt 8))) (linear-seq 0 8 10))) + (function sqr 0 8)))) + +(define-runtime-path p2d-44-data "./test-data/p2d-44.dat") +(define (do-plot-44 output-fn) + (random-seed 42) + (define xs (build-list 10000 (λ _ (random)))) + (define ys (build-list 10000 (λ _ (random)))) + (output-fn (list + (points (map vector xs ys) + #:x-min -1 #:x-max 1 #:y-min 0.5 #:y-max 1 + #:sym 'fullcircle #:size 6.5 #:alpha 1/8 + #:label "Dots")) + #:y-max 1.5)) + +(define-runtime-path p2d-45-data "./test-data/p2d-45.dat") +(define (do-plot-45 output-fn) + (output-fn (vector-field (λ (x y) (vector x y)) -0.5 1.85 -5 0.5 + #:color "blue" #:line-width 2/3 + #:scale 'auto #:label "(vector x y)") + #:x-min -1 #:x-max 5)) + +(define-runtime-path p2d-46-data "./test-data/p2d-46.dat") +(define (do-plot-46 output-fn) + (output-fn (list (function (λ (x) (* 220 (cos (* 4 x)))) -2 2) + (function (λ (x) (* 200 (sin (* 3 x)))) 0 #f + #:y-min -150 #:y-max 150 + #:color "blue")) + #:x-min -1/2 #:x-max 3)) + +(define-runtime-path p2d-47-data "./test-data/p2d-47.dat") +(define (do-plot-47 output-fn) + (random-seed 42) + (output-fn (lines (reverse + (for/fold ([lst (list (vector 0 0))]) ([i (in-range 1 400)]) + (match-define (vector x y) (first lst)) + (cons (vector i (+ y (* 1/100 (- (random) 1/2)))) lst))) + #:alpha 0.5 #:label "Random walk"))) + +(define-runtime-path p2d-48-data "./test-data/p2d-48.dat") +(define (do-plot-48 output-fn) + (output-fn (function (λ (x) (/ 1.0 (fl x))) -2 2))) + +(define-runtime-path p2d-49-data "./test-data/p2d-49.dat") +(define (do-plot-49 output-fn) + (output-fn (parametric (λ (t) (vector (sin t) (cos t))) (- pi) pi + #:x-min -0.5 #:y-max 0.5) + #:x-min -1)) + +(define-runtime-path p2d-50-data "./test-data/p2d-50.dat") +(define (do-plot-50 output-fn) + (output-fn (list (function sin -1/2 1) + (parametric (λ (t) (vector (cos t) (sin t))) -2 1 + #:color "blue" #:style 'short-dash)))) (define (norm mx my x y) (exp (* -1/2 (+ (sqr (- x mx)) (sqr (- y my)))))) @@ -315,190 +388,338 @@ (define (f2 x y) (- (sqr x) (sqr y))) -(time (plot (list (contours f1 0 5 #:label "Cyan/Redness") - (contours f2 -5 0 #:colors '("blue") #:label "Blueness" - #:widths '(2) #:styles '(dot))) - #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5)) - -(printf "These two plots should be empty:~n") -(plot (contours f2 -5 0) #:x-min 1 #:x-max 3 #:y-min 1 #:y-max 3) -(plot (contour-intervals f2 -5 0) #:x-min 1 #:x-max 3 #:y-min 1 #:y-max 3) - -(time (plot (contour-intervals f1 -5 5 -5 5 #:label "z"))) - -(time (plot (contour-intervals - (λ (x y) - (define z (- x y)) - (cond [(< z -1) -1] - [(> z 1) 1] - [else z])) - -2 2 -2 2))) - -(time (plot (list (tick-grid) - (contour-intervals f1 -5 2 -5 2 - #:levels 5 - #:contour-styles '(transparent) - #:label "") - (contours f1 -2 5 -2 5 #:levels 5 #:label "")) - #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5 - #:legend-anchor 'center)) - -(time (plot (list (tick-grid) - (contour-intervals f1 -5 2 -5 2 - #:levels '(0.25 0.5 0.75 1.0 1.25 1.5 1.75) - #:colors (compose default-contour-colors (curry map ivl-center)) - #:styles '(0 1 2 3 4 5 6) - #:contour-styles '(transparent) - #:label "z") - (contours f1 -2 5 -2 5 #:levels '(0.25 0.5 0.75 1.0 1.25 1.5 1.75))) - #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5 - #:legend-anchor 'top-left)) +(define-runtime-path p2d-51-data "./test-data/p2d-51.dat") +(define (do-plot-51 output-fn) + (output-fn (list (contours f1 0 5 #:label "Cyan/Redness") + (contours f2 -5 0 #:colors '("blue") #:label "Blueness" + #:widths '(2) #:styles '(dot))) + #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5)) + +(define-runtime-path p2d-52-data "./test-data/p2d-52.dat") +(define (do-plot-52 output-fn) + (output-fn (contours f2 -5 0) #:x-min 1 #:x-max 3 #:y-min 1 #:y-max 3 + #:title "plot should be empty")) +(define-runtime-path p2d-53-data "./test-data/p2d-53.dat") +(define (do-plot-53 output-fn) + (output-fn (contour-intervals f2 -5 0) #:x-min 1 #:x-max 3 #:y-min 1 #:y-max 3 + #:title "plot should be empty")) + +(define-runtime-path p2d-54-data "./test-data/p2d-54.dat") +(define (do-plot-54 output-fn) + (output-fn (contour-intervals f1 -5 5 -5 5 #:label "z"))) + +(define-runtime-path p2d-55-data "./test-data/p2d-55.dat") +(define (do-plot-55 output-fn) + (output-fn (contour-intervals + (λ (x y) + (define z (- x y)) + (cond [(< z -1) -1] + [(> z 1) 1] + [else z])) + -2 2 -2 2))) + +(define-runtime-path p2d-56-data "./test-data/p2d-56.dat") +(define (do-plot-56 output-fn) + (output-fn (list (tick-grid) + (contour-intervals f1 -5 2 -5 2 + #:levels 5 + #:contour-styles '(transparent) + #:label "") + (contours f1 -2 5 -2 5 #:levels 5 #:label "")) + #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5 + #:legend-anchor 'center)) + +(define-runtime-path p2d-57-data "./test-data/p2d-57.dat") +(define (do-plot-57 output-fn) + (output-fn (list (tick-grid) + (contour-intervals f1 -5 2 -5 2 + #:levels '(0.25 0.5 0.75 1.0 1.25 1.5 1.75) + #:colors (compose default-contour-colors (curry map ivl-center)) + #:styles '(0 1 2 3 4 5 6) + #:contour-styles '(transparent) + #:label "z") + (contours f1 -2 5 -2 5 #:levels '(0.25 0.5 0.75 1.0 1.25 1.5 1.75))) + #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5 + #:legend-anchor 'top-left)) ; tests contour 7-sided and 8-sided saddle facets ; contour shading should line up with contour lines, no matter how weird -(parameterize ([contour-samples 10]) - (define (f x y) (sqr (sin (- x y)))) - (time (plot (contour-intervals f) - #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5))) - -(time - (define (f2 x) (sin (* x pi))) - (plot (list (x-tick-lines) - (function-interval atan (λ (x) (- (atan x))) - #:color 6 #:line1-color 6 #:line2-color 6) - (function-interval sqr f2 -1 1 #:alpha 0.5) - (function-label f2 -1/4 #:anchor 'top-left)))) - -(time - (define amps (linear-seq 1/4 1 8)) - (define colors (color-seq* '("darkred" "white" "darkblue") 7)) - (plot (flatten - (list - (x-tick-lines) - (for/list ([a1 (in-list amps)] - [a2 (in-list (rest amps))] - [color (in-list colors)]) - (inverse-interval (λ (y) (* a1 (sin y))) - (λ (y) (* a2 (sin y))) - (- pi) pi #:color color #:alpha 1 - #:label (format "f(~a,~a)" a1 a2))) - (y-tick-lines) - (inverse-label (λ (y) (* 1/4 (sin y))) (* -1/2 pi) - "x = 1/4 sin(y)"))) - #:legend-anchor 'top-left)) - -(time - (define a #(0 0)) - (define b #(1 1/2)) - (define c #(0 1)) - (define d #(1 3/2)) - (plot (list - (tick-grid) - (lines-interval (list a b) (list c d) - #:color 4 #:line1-color 4 #:line2-color 4 - #:label "Parallelogram") - (point-label #(1/2 5/4) #:anchor 'bottom-right #:alpha 0.5)) - #:legend-anchor 'bottom-left)) - -(time - (define (fa t) (vector (* 2 (cos (* 4/5 t))) (* 2 (sin (* 4/5 t))))) - (define (fb t) (vector (cos t) (sin t))) - (define (fc t) (vector (* 1/2 (cos (* 4/5 t))) (* 1/2 (sin (* 4/5 t))))) - (define t1 (- pi)) - (define t2 pi) - (plot (list - (x-tick-lines) - (lines (list (fa t1) (fb t1) (vector +nan.0 +nan.0) (fb t1) (fc t1)) - #:color "black" #:style 'dot) - (lines (list (fa t2) (fb t2) (vector +nan.0 +nan.0) (fb t2) (fc t2)) - #:color "black" #:style 'dot) - (parametric fa t1 t2 #:color 5 #:label "fa") - (parametric-interval fa fb t1 t2 #:color 5 #:label "(fa,fb)" - #:line1-style 'transparent - #:line2-style 'transparent) - (parametric fb t1 t2 #:color 1 #:label "fb") - (parametric-interval fb fc t1 t2 #:color 2 #:label "(fb,fc)" - #:line1-style 'transparent - #:line2-style 'transparent) - (parametric fc t1 t2 #:color 2 #:label "fc") - (x-axis #:ticks? #f) - (parametric-label fa t1 "fa(-π)" - #:size 14 #:anchor 'left #:point-size 5) - (parametric-label fa t2 "fa(π)" - #:size 14 #:anchor 'left #:point-size 5)) - #:legend-anchor 'top-right)) - -(time - (define (f1 θ) (+ 1/2 (* 1/6 (cos (* 5 θ))))) - (define (f2 θ) (+ 1 (* 1/4 (cos (* 10 θ))))) - (plot (list (polar-axes #:number 10) - (polar-interval f1 f2 - #:color 3 #:label "[f1,f2]" - #:line1-color 1 #:line1-width 2 #:line1-style 'dot - #:line2-color 2 #:line2-width 2) - (polar-label f1 0 #:anchor 'top-left) - (polar-label f2 (degrees->radians 36) #:anchor 'bottom-right) - (point-label #(1/2 1/2))))) - -(time - (define (f1 θ) (/ θ pi 2)) - (define (f2 θ) (+ (/ θ pi 2) 1)) - (plot (list (tick-grid) - (polar-interval f1 f2 0 (* 5 pi) - #:color 4 #:alpha 3/4 - #:line1-color 1 #:line2-color 1 - #:label "[f1,f2]")) - #:legend-anchor 'center)) - -(time - (define ((make-fun y) x) - (+ y (sqr x))) - - (values - (plot (build-list - 20 (λ (n) (function (make-fun n) #:color n #:style n #:width 2))) - #:x-min -2 #:x-max 2) - - (plot (list - (tick-grid) - (function-interval (λ (x) 0) (λ (x) 16) #:color "black" #:alpha 1/20) - (build-list - 12 (λ (n) (function-interval - (make-fun n) (make-fun (add1 n)) -2 0 - #:color (->pen-color n) #:style n #:alpha 1 - #:line1-style 'transparent #:line2-style 'transparent))) - (build-list - 12 (λ (n) (function-interval - (make-fun n) (make-fun (add1 n)) 0 2 - #:color n - #:line1-style 'transparent #:line2-style 'transparent))) - (build-list - 13 (λ (n) (function (make-fun n) -2 0 - #:color n #:width 2))) - (build-list - 13 (λ (n) (function (make-fun n) 0 2 - #:color n #:width 2 #:style n)))) - #:x-min -2 #:x-max 2))) - -(time - (define (f x) (/ (sin x) x)) - (parameterize ([plot-x-transform (stretch-transform -1 1 10)] - [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))] - [plot-y-ticks (fraction-ticks)]) - (plot (list (y-axis -1 #:ticks? #f) (y-axis 1 #:ticks? #f) - (function f -1 1 #:width 2 #:color 4) - (function f -14 -1 #:color 4 #:label "y = sin(x)/x") - (function f 1 14 #:color 4) - (point-label (vector 0 1) "y → 1 as x → 0" #:anchor 'bottom-right)) - #:y-max 1.2))) - -(time ;; check `hrule` and `vrule` arguments - (plot - (list (hrule -1) - (hrule 0 0) - (hrule 1 0 1 #:color 1 #:width 3 #:style 'long-dash #:alpha 0.6 #:label "H") - (vrule -1) - (vrule 0 0) - (vrule 1 0 1 #:color 2 #:width 3 #:style 'long-dash #:alpha 0.6 #:label "V")) - #:x-min -2 #:x-max 2 - #:y-min -2 #:y-max 2)) +(define-runtime-path p2d-58-data "./test-data/p2d-58.dat") +(define (do-plot-58 output-fn) + (parameterize ([contour-samples 10]) + (define (f x y) (sqr (sin (- x y)))) + (output-fn (contour-intervals f) + #:x-min -5 #:x-max 5 #:y-min -5 #:y-max 5))) + +(define-runtime-path p2d-59-data "./test-data/p2d-59.dat") +(define (do-plot-59 output-fn) + (define (f2 x) (sin (* x pi))) + (output-fn (list (x-tick-lines) + (function-interval atan (λ (x) (- (atan x))) + #:color 6 #:line1-color 6 #:line2-color 6) + (function-interval sqr f2 -1 1 #:alpha 0.5) + (function-label f2 -1/4 #:anchor 'top-left)))) + +(define-runtime-path p2d-60-data "./test-data/p2d-60.dat") +(define (do-plot-60 output-fn) + (define amps (linear-seq 1/4 1 8)) + (define colors (color-seq* '("darkred" "white" "darkblue") 7)) + (output-fn (flatten + (list + (x-tick-lines) + (for/list ([a1 (in-list amps)] + [a2 (in-list (rest amps))] + [color (in-list colors)]) + (inverse-interval (λ (y) (* a1 (sin y))) + (λ (y) (* a2 (sin y))) + (- pi) pi #:color color #:alpha 1 + #:label (format "f(~a,~a)" a1 a2))) + (y-tick-lines) + (inverse-label (λ (y) (* 1/4 (sin y))) (* -1/2 pi) + "x = 1/4 sin(y)"))) + #:legend-anchor 'top-left)) + +(define-runtime-path p2d-61-data "./test-data/p2d-61.dat") +(define (do-plot-61 output-fn) + (define a #(0 0)) + (define b #(1 1/2)) + (define c #(0 1)) + (define d #(1 3/2)) + (output-fn (list + (tick-grid) + (lines-interval (list a b) (list c d) + #:color 4 #:line1-color 4 #:line2-color 4 + #:label "Parallelogram") + (point-label #(1/2 5/4) #:anchor 'bottom-right #:alpha 0.5)) + #:legend-anchor 'bottom-left)) + +(define-runtime-path p2d-62-data "./test-data/p2d-62.dat") +(define (do-plot-62 output-fn) + (define (fa t) (vector (* 2 (cos (* 4/5 t))) (* 2 (sin (* 4/5 t))))) + (define (fb t) (vector (cos t) (sin t))) + (define (fc t) (vector (* 1/2 (cos (* 4/5 t))) (* 1/2 (sin (* 4/5 t))))) + (define t1 (- pi)) + (define t2 pi) + (output-fn (list + (x-tick-lines) + (lines (list (fa t1) (fb t1) (vector +nan.0 +nan.0) (fb t1) (fc t1)) + #:color "black" #:style 'dot) + (lines (list (fa t2) (fb t2) (vector +nan.0 +nan.0) (fb t2) (fc t2)) + #:color "black" #:style 'dot) + (parametric fa t1 t2 #:color 5 #:label "fa") + (parametric-interval fa fb t1 t2 #:color 5 #:label "(fa,fb)" + #:line1-style 'transparent + #:line2-style 'transparent) + (parametric fb t1 t2 #:color 1 #:label "fb") + (parametric-interval fb fc t1 t2 #:color 2 #:label "(fb,fc)" + #:line1-style 'transparent + #:line2-style 'transparent) + (parametric fc t1 t2 #:color 2 #:label "fc") + (x-axis #:ticks? #f) + (parametric-label fa t1 "fa(-π)" + #:size 14 #:anchor 'left #:point-size 5) + (parametric-label fa t2 "fa(π)" + #:size 14 #:anchor 'left #:point-size 5)) + #:legend-anchor 'top-right)) + +(define-runtime-path p2d-63-data "./test-data/p2d-63.dat") +(define (do-plot-63 output-fn) + (define (f1 θ) (+ 1/2 (* 1/6 (cos (* 5 θ))))) + (define (f2 θ) (+ 1 (* 1/4 (cos (* 10 θ))))) + (output-fn (list (polar-axes #:number 10) + (polar-interval f1 f2 + #:color 3 #:label "[f1,f2]" + #:line1-color 1 #:line1-width 2 #:line1-style 'dot + #:line2-color 2 #:line2-width 2) + (polar-label f1 0 #:anchor 'top-left) + (polar-label f2 (degrees->radians 36) #:anchor 'bottom-right) + (point-label #(1/2 1/2))))) + +(define-runtime-path p2d-64-data "./test-data/p2d-64.dat") +(define (do-plot-64 output-fn) + (define (f1 θ) (/ θ pi 2)) + (define (f2 θ) (+ (/ θ pi 2) 1)) + (output-fn (list (tick-grid) + (polar-interval f1 f2 0 (* 5 pi) + #:color 4 #:alpha 3/4 + #:line1-color 1 #:line2-color 1 + #:label "[f1,f2]")) + #:legend-anchor 'center)) + +(define ((make-fun y) x) + (+ y (sqr x))) + +(define-runtime-path p2d-65-data "./test-data/p2d-65.dat") +(define-runtime-path p2d-65a-data "./test-data/p2d-65a.dat") +(define (do-plot-65 output-fn) + (output-fn (build-list + 20 (λ (n) (function (make-fun n) #:color n #:style n #:width 2))) + #:x-min -2 #:x-max 2)) + +(define (do-plot-65a output-fn) + (output-fn (list + (tick-grid) + (function-interval (λ (x) 0) (λ (x) 16) #:color "black" #:alpha 1/20) + (build-list + 12 (λ (n) (function-interval + (make-fun n) (make-fun (add1 n)) -2 0 + #:color (->pen-color n) #:style n #:alpha 1 + #:line1-style 'transparent #:line2-style 'transparent))) + (build-list + 12 (λ (n) (function-interval + (make-fun n) (make-fun (add1 n)) 0 2 + #:color n + #:line1-style 'transparent #:line2-style 'transparent))) + (build-list + 13 (λ (n) (function (make-fun n) -2 0 + #:color n #:width 2))) + (build-list + 13 (λ (n) (function (make-fun n) 0 2 + #:color n #:width 2 #:style n)))) + #:x-min -2 #:x-max 2)) + +(define-runtime-path p2d-66-data "./test-data/p2d-66.dat") +(define (do-plot-66 output-fn) + (define (f x) (/ (sin x) x)) + (parameterize ([plot-x-transform (stretch-transform -1 1 10)] + [plot-x-ticks (ticks-add (plot-x-ticks) '(-1 1))] + [plot-y-ticks (fraction-ticks)]) + (output-fn (list (y-axis -1 #:ticks? #f) (y-axis 1 #:ticks? #f) + (function f -1 1 #:width 2 #:color 4) + (function f -14 -1 #:color 4 #:label "y = sin(x)/x") + (function f 1 14 #:color 4) + (point-label (vector 0 1) "y → 1 as x → 0" #:anchor 'bottom-right)) + #:y-max 1.2))) + +(define-runtime-path p2d-67-data "./test-data/p2d-67.dat") +(define (do-plot-67 output-fn) + (output-fn + (list (hrule -1) + (hrule 0 0) + (hrule 1 0 1 #:color 1 #:width 3 #:style 'long-dash #:alpha 0.6 #:label "H") + (vrule -1) + (vrule 0 0) + (vrule 1 0 1 #:color 2 #:width 3 #:style 'long-dash #:alpha 0.6 #:label "V")) + #:x-min -2 #:x-max 2 + #:y-min -2 #:y-max 2)) + +;; (printf "This plot should contain~n- 4 labels, all within the plot bounds~n- points near the top and bottom labels~n- no points near the left and right labels~n") +(define-runtime-path p2d-68-data "./test-data/p2d-68.dat") +(define (do-plot-68 output-fn) + (output-fn + ;; Add labels on the edges of the plot area. Each label will be positioned + ;; so it is inside the plot area + (list (point-label (vector 0 10) #:anchor 'auto) + (point-label (vector 0 -10) #:anchor 'auto) + ;; Side labels have no corresponding point + (point-label (vector 10 0) #:anchor 'auto #:point-sym 'none) + (point-label (vector -10 0) #:anchor 'auto #:point-sym 'none)) + #:x-min -10 #:x-max 10 + #:y-min -10 #:y-max 10)) + +;; (printf "This plot should contain points and functions labeled with standard fish~n") +(define-runtime-path p2d-69-data "./test-data/p2d-69.dat") +(define (do-plot-69 output-fn) + (define blue-fish (standard-fish 40 15 #:color "lightblue")) + (define red-fish (standard-fish 40 15 #:color "salmon")) + (define (f t) (vector (cos t) (sin t))) + (output-fn + (list (point-pict (vector 0 -10) blue-fish #:anchor 'auto #:point-size 15) + (parametric f 0 (* 2 pi)) + (parametric-pict f (/ pi 2) red-fish #:anchor 'bottom ) + (function sin) + (function-pict sin -5 red-fish #:anchor 'left) + (polar-pict (lambda (a) (* 8 (sin a))) (/ pi 4) red-fish) + (inverse-pict asin 1 red-fish)) + #:x-min -10 #:x-max 10 + #:y-min -10 #:y-max 10)) + +(define-runtime-path p2d-70-data "./test-data/p2d-70.dat") +(define (do-plot-70 output-fn) + (output-fn (rectangles (list (vector (ivl 2 3) (ivl -inf.0 +inf.0)) + (vector (ivl -inf.0 +inf.0) (ivl 2 3)) + (vector (ivl 5 6) (ivl 0 +inf.0))) + #:line-style 'transparent + #:alpha 0.5) + #:x-min -10 #:x-max 10 + #:y-min -10 #:y-max 10 + #:title "rectangles that extend to the edge of the plot")) + +(define plot2d-tests + (test-suite + "plot2d-tests" + (test-case "test case 1" (check-draw-steps do-plot-1 p2d-1-data)) + (test-case "test case 2" (check-draw-steps do-plot-2 p2d-2-data)) + (test-case "test case 3" (check-draw-steps do-plot-3 p2d-3-data)) + (test-case "test case 4" (check-draw-steps do-plot-4 p2d-4-data)) + (test-case "test case 5" (check-draw-steps do-plot-5 p2d-5-data)) + (test-case "test case 6" (check-draw-steps do-plot-6 p2d-6-data)) + (test-case "test case 7" (check-draw-steps do-plot-7 p2d-7-data)) + (test-case "test case 8" (check-draw-steps do-plot-8 p2d-8-data)) + (test-case "test case 9" (check-draw-steps do-plot-9 p2d-9-data)) + (test-case "test case 10" (check-draw-steps do-plot-10 p2d-10-data)) + (test-case "test case 11" (check-draw-steps do-plot-11 p2d-11-data)) + (test-case "test case 12" (check-draw-steps do-plot-12 p2d-12-data)) + (test-case "test case 13" (check-draw-steps do-plot-13 p2d-13-data)) + (test-case "test case 14" (check-draw-steps do-plot-14 p2d-14-data)) + (test-case "test case 15" (check-draw-steps do-plot-15 p2d-15-data)) + (test-case "test case 16" (check-draw-steps do-plot-16 p2d-16-data)) + (test-case "test case 17" (check-draw-steps do-plot-17 p2d-17-data)) + (test-case "test case 18" (check-draw-steps do-plot-18 p2d-18-data)) + (test-case "test case 19" (check-draw-steps do-plot-19 p2d-19-data)) + (test-case "test case 20" (check-draw-steps do-plot-20 p2d-20-data)) + (test-case "test case 21" (check-draw-steps do-plot-21 p2d-21-data)) + (test-case "test case 22" (check-draw-steps do-plot-22 p2d-22-data)) + (test-case "test case 23" (check-draw-steps do-plot-23 p2d-23-data)) + (test-case "test case 24" (check-draw-steps do-plot-24 p2d-24-data)) + (test-case "test case 25" (check-draw-steps do-plot-25 p2d-25-data)) + (test-case "test case 26" (check-draw-steps do-plot-26 p2d-26-data)) + (test-case "test case 27" (check-draw-steps do-plot-27 p2d-27-data)) + (test-case "test case 28" (check-draw-steps do-plot-28 p2d-28-data)) + (test-case "test case 29" (check-draw-steps do-plot-29 p2d-29-data)) + (test-case "test case 30" (check-draw-steps do-plot-30 p2d-30-data)) + (test-case "test case 31" (check-draw-steps do-plot-31 p2d-31-data)) + (test-case "test case 32" (check-draw-steps do-plot-32 p2d-32-data)) + (test-case "test case 33" (check-draw-steps do-plot-33 p2d-33-data)) + (test-case "test case 34" (check-draw-steps do-plot-34 p2d-34-data)) + (test-case "test case 35" (check-draw-steps do-plot-35 p2d-35-data)) + (test-case "test case 36" (check-draw-steps do-plot-36 p2d-36-data)) + (test-case "test case 37" (check-draw-steps do-plot-37 p2d-37-data)) + (test-case "test case 38" (check-draw-steps do-plot-38 p2d-38-data)) + (test-case "test case 39" (check-draw-steps do-plot-39 p2d-39-data)) + (test-case "test case 40" (check-draw-steps do-plot-40 p2d-40-data)) + (test-case "test case 41" (check-draw-steps do-plot-41 p2d-41-data)) + (test-case "test case 42" (check-draw-steps do-plot-42 p2d-42-data)) + (test-case "test case 43" (check-draw-steps do-plot-43 p2d-43-data)) + (test-case "test case 44" (check-draw-steps do-plot-44 p2d-44-data)) + (test-case "test case 45" (check-draw-steps do-plot-45 p2d-45-data)) + (test-case "test case 46" (check-draw-steps do-plot-46 p2d-46-data)) + (test-case "test case 47" (check-draw-steps do-plot-47 p2d-47-data)) + (test-case "test case 48" (check-draw-steps do-plot-48 p2d-48-data)) + (test-case "test case 49" (check-draw-steps do-plot-49 p2d-49-data)) + (test-case "test case 50" (check-draw-steps do-plot-50 p2d-50-data)) + (test-case "test case 51" (check-draw-steps do-plot-51 p2d-51-data)) + (test-case "test case 52" (check-draw-steps do-plot-52 p2d-52-data)) + (test-case "test case 53" (check-draw-steps do-plot-53 p2d-53-data)) + (test-case "test case 54" (check-draw-steps do-plot-54 p2d-54-data)) + (test-case "test case 55" (check-draw-steps do-plot-55 p2d-55-data)) + (test-case "test case 56" (check-draw-steps do-plot-56 p2d-56-data)) + (test-case "test case 57" (check-draw-steps do-plot-57 p2d-57-data)) + (test-case "test case 58" (check-draw-steps do-plot-58 p2d-58-data)) + (test-case "test case 59" (check-draw-steps do-plot-59 p2d-59-data)) + (test-case "test case 60" (check-draw-steps do-plot-60 p2d-60-data)) + (test-case "test case 61" (check-draw-steps do-plot-61 p2d-61-data)) + (test-case "test case 62" (check-draw-steps do-plot-62 p2d-62-data)) + (test-case "test case 63" (check-draw-steps do-plot-63 p2d-63-data)) + (test-case "test case 64" (check-draw-steps do-plot-64 p2d-64-data)) + (test-case "test case 65" (check-draw-steps do-plot-65 p2d-65-data)) + (test-case "test case 65a" (check-draw-steps do-plot-65a p2d-65a-data)) + (test-case "test case 66" (check-draw-steps do-plot-66 p2d-66-data)) + (test-case "test case 67" (check-draw-steps do-plot-67 p2d-67-data)) + (test-case "test case 68" (check-draw-steps do-plot-68 p2d-68-data)) + (test-case "test case 69" (check-draw-steps do-plot-69 p2d-69-data)) + (test-case "test case 70" (check-draw-steps do-plot-70 p2d-70-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests plot2d-tests)) diff --git a/plot-test/plot/tests/plot3d-bsp-tests.rkt b/plot-test/plot/tests/plot3d-bsp-tests.rkt index f5942fca..886481a8 100644 --- a/plot-test/plot/tests/plot3d-bsp-tests.rkt +++ b/plot-test/plot/tests/plot3d-bsp-tests.rkt @@ -1,151 +1,191 @@ #lang racket - (require plot (except-in plot/utils sample) math - profile - contract-profile) + rackunit + racket/runtime-path + "helpers.rkt") + +;; Test under crazy transformation, doing so will invalidate all test results, +;; but the plot output is nice. -#;; Test under crazy transformation -(begin +#;(begin (plot-x-transform cbrt-transform) (plot-y-transform cbrt-transform) (plot-z-transform cbrt-transform)) -(plot3d (list (contour-intervals3d * -1 1 -1 1 #:samples 2) - (isosurface3d (λ (x y z) z) - 0 -1 1 -1 1 -1 1 - #:samples 2 #:color 3))) - -(plot3d (list (parametric3d (λ (t) - (list (* 0.5 (cos (* 2 pi (- t)))) - (* 0.5 (sin (* 2 pi (- t)))) - t)) - -1 1 - #:samples 53 - #:color "green" - #:width 15 - #:alpha 0.6) - (parametric3d (λ (t) - (list (* 0.75 (cos (* 2 pi t))) - (* 0.75 (sin (* 2 pi t))) - t)) - -1 1 - #:samples 53 - #:color "red" - #:width 15 - #:alpha 0.6))) - -(plot3d (list (isosurface3d (λ (x y z) (+ x y z)) 0 -1 1 -1 1 -1 1 - #:samples 2 - #:line-width 2) - (isosurface3d (λ (x y z) x) 0 #:samples 2 - #:color "red" - #:line-width 2) - (isosurface3d (λ (x y z) (+ x (- y) z)) 0 - #:samples 2 - #:line-width 2) - (parametric3d (λ (t) - (list (* 0.75 (cos (* 5 pi t))) - (* 0.75 (sin (* 5 pi t))) - t)) - -1 1 #:width 2 #:color 2))) - -(let* ([xs (sample (uniform-dist -1 1) 10000)] - [ys (sample (uniform-dist -1 1) 10000)] - [zs (sample (uniform-dist -1 1) 10000)] - [xyzs (map list xs ys zs)]) - (time - (plot3d (list (isosurface3d (λ (x y z) (+ x y z)) 0 -1 1 -1 1 -1 1 - #:samples 2 - #:line-width 2) - (isosurface3d (λ (x y z) x) 0 #:samples 2 - #:color "red" - #:line-width 2) - (isosurface3d (λ (x y z) (+ x (- y) z)) 0 - #:samples 2 - #:line-width 2) - (points3d xyzs #:sym 'dot))))) - -(time - (for/last ([_ (in-range 1)]) - (plot3d - (list (contour-intervals3d - (λ (x y) - (* x (+ 0.1 y))) - -1 1 -1 1 - #:samples 41 - #:alphas '(0.85) - ;#:alpha 0.75 - ;#:line-width 2 - ;#:line-widths '(2) - ;#:line-styles '(transparent) - #:contour-widths '(2) - ;#:color 1 - ;#:label "" - ) - - (surface3d - (λ (x y) - (* (- (* (flnormal-pdf 0.0 0.2 (fl x) #f) - (flnormal-pdf 0.0 0.2 (fl y) #f)) - 0.7) - 0.4)) - -1 1 -1 1 - #:samples 40 - ;#:alphas '(0.75) - #:alpha 0.95 - #:color "plum" - #:line-color 6 - ;#:line-style 'transparent - ;#:line-width 2 - )) - #:x-min -1 #:x-max 1 - #:y-min -1 #:y-max 1 - ;#:out-file "test.pdf" - ))) +(define-runtime-path p3d-bsp-1-data "./test-data/p3d-bsp-1.dat") +(define (do-plot-1 output-fn) + (output-fn (list (contour-intervals3d * -1 1 -1 1 #:samples 2) + (isosurface3d (λ (x y z) z) + 0 -1 1 -1 1 -1 1 + #:samples 2 #:color 3)))) + +(define-runtime-path p3d-bsp-2-data "./test-data/p3d-bsp-2.dat") +(define (do-plot-2 output-fn) + (output-fn (list (parametric3d (λ (t) + (list (* 0.5 (cos (* 2 pi (- t)))) + (* 0.5 (sin (* 2 pi (- t)))) + t)) + -1 1 + #:samples 53 + #:color "green" + #:width 15 + #:alpha 0.6) + (parametric3d (λ (t) + (list (* 0.75 (cos (* 2 pi t))) + (* 0.75 (sin (* 2 pi t))) + t)) + -1 1 + #:samples 53 + #:color "red" + #:width 15 + #:alpha 0.6)))) + +(define-runtime-path p3d-bsp-3-data "./test-data/p3d-bsp-3.dat") +(define (do-plot-3 output-fn) + (output-fn (list (isosurface3d (λ (x y z) (+ x y z)) 0 -1 1 -1 1 -1 1 + #:samples 2 + #:line-width 2) + (isosurface3d (λ (x y z) x) 0 #:samples 2 + #:color "red" + #:line-width 2) + (isosurface3d (λ (x y z) (+ x (- y) z)) 0 + #:samples 2 + #:line-width 2) + (parametric3d (λ (t) + (list (* 0.75 (cos (* 5 pi t))) + (* 0.75 (sin (* 5 pi t))) + t)) + -1 1 #:width 2 #:color 2)))) + +(define-runtime-path p3d-bsp-4-data "./test-data/p3d-bsp-4.dat") +(define (do-plot-4 output-fn) + (random-seed 42) ; make `sample` and `uniform-dist` repeatable in tests + (let* ([xs (sample (uniform-dist -1 1) 10000)] + [ys (sample (uniform-dist -1 1) 10000)] + [zs (sample (uniform-dist -1 1) 10000)] + [xyzs (map list xs ys zs)]) + (output-fn (list (isosurface3d (λ (x y z) (+ x y z)) 0 -1 1 -1 1 -1 1 + #:samples 2 + #:line-width 2) + (isosurface3d (λ (x y z) x) 0 #:samples 2 + #:color "red" + #:line-width 2) + (isosurface3d (λ (x y z) (+ x (- y) z)) 0 + #:samples 2 + #:line-width 2) + (points3d xyzs #:sym 'dot))))) + +(define-runtime-path p3d-bsp-5-data "./test-data/p3d-bsp-5.dat") +(define (do-plot-5 output-fn) + (output-fn + (list (contour-intervals3d + (λ (x y) + (* x (+ 0.1 y))) + -1 1 -1 1 + #:samples 41 + #:alphas '(0.85) + ;#:alpha 0.75 + ;#:line-width 2 + ;#:line-widths '(2) + ;#:line-styles '(transparent) + #:contour-widths '(2) + ;#:color 1 + ;#:label "" + ) + + (surface3d + (λ (x y) + (* (- (* (flnormal-pdf 0.0 0.2 (fl x) #f) + (flnormal-pdf 0.0 0.2 (fl y) #f)) + 0.7) + 0.4)) + -1 1 -1 1 + #:samples 40 + ;#:alphas '(0.75) + #:alpha 0.95 + #:color "plum" + #:line-color 6 + ;#:line-style 'transparent + ;#:line-width 2 + )) + #:x-min -1 #:x-max 1 + #:y-min -1 #:y-max 1 + ;#:out-file "test.pdf" + )) (define (f2 x y) (let ([x (fl x)] [y (fl y)]) (- (sqrt (+ (abs y) (abs x)))))) -(plot3d (list (surface3d * -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 1) - (surface3d (λ (x y) (+ 0.1 (* x y))) -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 2) - (surface3d (λ (x y) (+ 0.2 (* x y))) -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 3 - #:line-width 2) - )) - -(plot3d (list - (isosurface3d (λ (x y z) (+ (- 1 x) (- 1 y) (- z 1.5))) 0 - #:alpha 0.85 #:color 2 #:line-color 2 - #:samples 4) - (discrete-histogram3d (list (vector 'a 'a 1) - (vector 'a 'b 2) - (vector 'b 'b 3)) - #:color 4 #:line-color 4 #:line-width 2 - #:alpha 0.65))) - -(plot3d (list - ;(isosurface3d (λ (x y z) (+ x y z)) 0 #:samples 2) - (surface3d * -1 1 -1 1) - (vector-field3d (λ (x y z) (vector x z y)) - #:line-width 2))) +(define-runtime-path p3d-bsp-6-data "./test-data/p3d-bsp-6.dat") +(define (do-plot-6 output-fn) + (output-fn (list (surface3d * -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 1) + (surface3d (λ (x y) (+ 0.1 (* x y))) -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 2) + (surface3d (λ (x y) (+ 0.2 (* x y))) -1 1 -1 1 #:samples 6 #:alpha 0.75 #:color 3 + #:line-width 2) + ))) + +(define-runtime-path p3d-bsp-7-data "./test-data/p3d-bsp-7.dat") +(define (do-plot-7 output-fn) + (output-fn (list + (isosurface3d (λ (x y z) (+ (- 1 x) (- 1 y) (- z 1.5))) 0 + #:alpha 0.85 #:color 2 #:line-color 2 + #:samples 4) + (discrete-histogram3d (list (vector 'a 'a 1) + (vector 'a 'b 2) + (vector 'b 'b 3)) + #:color 4 #:line-color 4 #:line-width 2 + #:alpha 0.65)))) + +(define-runtime-path p3d-bsp-8-data "./test-data/p3d-bsp-8.dat") +(define (do-plot-8 output-fn) + (output-fn (list + ;(isosurface3d (λ (x y z) (+ x y z)) 0 #:samples 2) + (surface3d * -1 1 -1 1) + (vector-field3d (λ (x y z) (vector x z y)) + #:line-width 2)))) (define (f x y) (* (sin x) (cos y))) -(time - (for/last ([_ (in-range 1)]) - (plot3d (list (contour-intervals3d f -3 3 -3 3) - (point-label3d (list -1 1 (f -1 1))))))) - -(parameterize ([plot-x-transform (hand-drawn-transform 50)] - [plot-y-transform (hand-drawn-transform 50)] - [plot-z-transform (hand-drawn-transform 50)] - ) - (plot3d (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) - -1 1 -1 1 #:samples 9 - #:contour-widths '(2) - #:line-widths '(2)))) +(define-runtime-path p3d-bsp-9-data "./test-data/p3d-bsp-9.dat") +(define (do-plot-9 output-fn) + (output-fn (list (contour-intervals3d f -3 3 -3 3) + (point-label3d (list -1 1 (f -1 1)))))) + +(define-runtime-path p3d-bsp-10-data "./test-data/p3d-bsp-10.dat") +(define (do-plot-10 output-fn) + (parameterize ([plot-x-transform (hand-drawn-transform 50)] + [plot-y-transform (hand-drawn-transform 50)] + [plot-z-transform (hand-drawn-transform 50)] + ) + (output-fn (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) + -1 1 -1 1 #:samples 9 + #:contour-widths '(2) + #:line-widths '(2))))) (define (saddle x y) (- (sqr x) (sqr y))) -(plot3d (list (surface3d saddle -1 1 -1 1) - (isoline3d saddle 1/4 #:width 2 #:style 'long-dash))) +(define-runtime-path p3d-bsp-11-data "./test-data/p3d-bsp-11.dat") +(define (do-plot-11 output-fn) + (output-fn (list (surface3d saddle -1 1 -1 1) + (isoline3d saddle 1/4 #:width 2 #:style 'long-dash)))) + + +(define plot3d-bsp-tests + (test-suite + "plot3d-bsp-tests" + (test-case "test case 1" (check-draw-steps-3d do-plot-1 p3d-bsp-1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot-2 p3d-bsp-2-data)) + (test-case "test case 3" (check-draw-steps-3d do-plot-3 p3d-bsp-3-data)) + (test-case "test case 4" (check-draw-steps-3d do-plot-4 p3d-bsp-4-data)) + (test-case "test case 5" (check-draw-steps-3d do-plot-5 p3d-bsp-5-data)) + (test-case "test case 6" (check-draw-steps-3d do-plot-6 p3d-bsp-6-data)) + (test-case "test case 7" (check-draw-steps-3d do-plot-7 p3d-bsp-7-data)) + (test-case "test case 8" (check-draw-steps-3d do-plot-8 p3d-bsp-8-data)) + (test-case "test case 9" (check-draw-steps-3d do-plot-9 p3d-bsp-9-data)) + (test-case "test case 10" (check-draw-steps-3d do-plot-10 p3d-bsp-10-data)) + (test-case "test case 11" (check-draw-steps-3d do-plot-11 p3d-bsp-11-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests plot3d-bsp-tests)) diff --git a/plot-test/plot/tests/plot3d-tests.rkt b/plot-test/plot/tests/plot3d-tests.rkt index 186290c0..4294337a 100644 --- a/plot-test/plot/tests/plot3d-tests.rkt +++ b/plot-test/plot/tests/plot3d-tests.rkt @@ -1,161 +1,189 @@ #lang racket -(require plot plot/utils math/flonum) +(require plot plot/utils math/flonum + racket/runtime-path + rackunit + "helpers.rkt") ;(plot-new-window? #t) -(printf "The following two plots should be empty:~n") -(time - (plot3d empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) - -(time - (plot3d (points3d empty) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) - -(printf "This plot should be empty:~n") -(plot3d (rectangles3d (list (list (ivl 0 1) (ivl 0 1) (ivl 0 1)))) - #:x-min 2 #:x-max 3) - -(parameterize ([plot-background "black"] - [plot-foreground "white"] - [plot-background-alpha 1/2] - [plot-foreground-alpha 1/2]) - (plot3d (surface3d (λ (x y) (* (sin x) (sin y))) -2 2 -2 2 #:label "z = trig(x,y)"))) - -(time - (plot3d (points3d '(#(0.1 0.6 0.3))) - #:x-min 0 #:x-max 1 #:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1)) - -(time - (plot3d (vector-field3d (λ (x y z) (vector x z y)) -2 2 -2 2 -2 2 - #:line-width 3))) - -(time - (define x-ivls (bounds->intervals (linear-seq 2 8 10))) - (define y-ivls (bounds->intervals (linear-seq -5 5 10))) - (define x-mids (linear-seq 2 8 9 #:start? #f #:end? #f)) - (define y-mids (linear-seq -5 5 9 #:start? #f #:end? #f)) - (plot3d (rectangles3d (append* - (for/list ([y-ivl (in-list y-ivls)] [y (in-list y-mids)]) - (for/list ([x-ivl (in-list x-ivls)] [x (in-list x-mids)]) - (vector x-ivl y-ivl (ivl 0 (exp (* -1/2 (+ (sqr (- x 5)) (sqr y))))))))) - #:alpha 3/4 - #:label "Approximate 2D Normal"))) - -(time - (plot3d (discrete-histogram3d (list (vector 'a 'a 1) - (vector 'a 'b 2) - (vector 'b 'b 3)) - #:label "Missing (b,a)" - #:color 4 #:line-color 4))) - -(time - (define c1s #(a b c d e)) - (define c2s #(1 2 3 4 5)) - (define cat-vals (build-list 15 (λ (n) (vector (vector-ref c1s (random 5)) - (vector-ref c2s (random 5)) - n)))) - (plot3d (discrete-histogram3d cat-vals))) - -(time - (plot3d (stacked-histogram3d '(#(a a (1 1 1)) #(a b (1.5 3)) #(b b ()) #(b a (1/2))) - #:labels '("Red" #f "Blue") #:alphas '(2/3)))) - -(time - (plot3d (stacked-histogram3d '(#(a a (1 1 1)) #(a b (1.5 3)) #(b b ()) #(b a (1/2))) - #:labels '("Red" #f "Blue") #:alphas '(2/3) - #:add-x-ticks? #f #:add-y-ticks? #f))) - -(time - (plot3d (surface3d + 0 10 0 1) - #:angle 10 #:z-label "z axis")) - -(parameterize ([plot-x-transform log-transform] - [plot-y-transform log-transform]) - (time (plot3d (surface3d + .01 3 .01 1)))) +(define-runtime-path p3d-1-data "./test-data/p3d-1.dat") +(define (do-plot-1 output-fn) + (output-fn empty #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1 + #:title "this plot should be empty")) + +(define-runtime-path p3d-2-data "./test-data/p3d-2.dat") +(define (do-plot-2 output-fn) + (output-fn (points3d empty) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1 + #:title "this plot should be empty")) + +(define-runtime-path p3d-3-data "./test-data/p3d-3.dat") +(define (do-plot-3 output-fn) + (output-fn (rectangles3d (list (list (ivl 0 1) (ivl 0 1) (ivl 0 1)))) + #:x-min 2 #:x-max 3 + #:title "this plot should be empty")) + +(define-runtime-path p3d-4-data "./test-data/p3d-4.dat") +(define (do-plot-4 output-fn) + (parameterize ([plot-background "black"] + [plot-foreground "white"] + [plot-background-alpha 1/2] + [plot-foreground-alpha 1/2]) + (output-fn (surface3d (λ (x y) (* (sin x) (sin y))) -2 2 -2 2 #:label "z = trig(x,y)")))) + +(define-runtime-path p3d-5-data "./test-data/p3d-5.dat") +(define (do-plot-5 output-fn) + (output-fn (points3d '(#(0.1 0.6 0.3))) + #:x-min 0 #:x-max 1 #:y-min 0 #:y-max 1 #:z-min 0 #:z-max 1)) + +(define-runtime-path p3d-6-data "./test-data/p3d-6.dat") +(define (do-plot-6 output-fn) + (output-fn (vector-field3d (λ (x y z) (vector x z y)) -2 2 -2 2 -2 2 + #:line-width 3))) + +(define-runtime-path p3d-7-data "./test-data/p3d-7.dat") +(define (do-plot-7 output-fn) + (define x-ivls (bounds->intervals (linear-seq 2 8 10))) + (define y-ivls (bounds->intervals (linear-seq -5 5 10))) + (define x-mids (linear-seq 2 8 9 #:start? #f #:end? #f)) + (define y-mids (linear-seq -5 5 9 #:start? #f #:end? #f)) + (output-fn (rectangles3d (append* + (for/list ([y-ivl (in-list y-ivls)] [y (in-list y-mids)]) + (for/list ([x-ivl (in-list x-ivls)] [x (in-list x-mids)]) + (vector x-ivl y-ivl (ivl 0 (exp (* -1/2 (+ (sqr (- x 5)) (sqr y))))))))) + #:alpha 3/4 + #:label "Approximate 2D Normal"))) + +(define-runtime-path p3d-8-data "./test-data/p3d-8.dat") +(define (do-plot-8 output-fn) + (output-fn (discrete-histogram3d (list (vector 'a 'a 1) + (vector 'a 'b 2) + (vector 'b 'b 3)) + #:label "Missing (b,a)" + #:color 4 #:line-color 4))) + +(define-runtime-path p3d-9-data "./test-data/p3d-9.dat") +(define (do-plot-9 output-fn) + (random-seed 42) ; make test reproducible + (define c1s #(a b c d e)) + (define c2s #(1 2 3 4 5)) + (define cat-vals (build-list 15 (λ (n) (vector (vector-ref c1s (random 5)) + (vector-ref c2s (random 5)) + n)))) + (output-fn (discrete-histogram3d cat-vals))) + +(define-runtime-path p3d-10-data "./test-data/p3d-10.dat") +(define (do-plot-10 output-fn) + (output-fn (stacked-histogram3d '(#(a a (1 1 1)) #(a b (1.5 3)) #(b b ()) #(b a (1/2))) + #:labels '("Red" #f "Blue") #:alphas '(2/3)))) + +(define-runtime-path p3d-11-data "./test-data/p3d-11.dat") +(define (do-plot-11 output-fn) + (output-fn (stacked-histogram3d '(#(a a (1 1 1)) #(a b (1.5 3)) #(b b ()) #(b a (1/2))) + #:labels '("Red" #f "Blue") #:alphas '(2/3) + #:add-x-ticks? #f #:add-y-ticks? #f))) + +(define-runtime-path p3d-12-data "./test-data/p3d-12.dat") +(define (do-plot-12 output-fn) + (output-fn (surface3d + 0 10 0 1) #:angle 10 #:z-label "z axis")) + +(define-runtime-path p3d-13-data "./test-data/p3d-13.dat") +(define (do-plot-13 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform log-transform]) + (output-fn (surface3d + .01 3 .01 1)))) ;(plot-x-transform cbrt-transform) ;(plot-y-transform cbrt-transform) ;(plot-z-transform cbrt-transform) -(time - (plot3d (surface3d (λ (x y) (+ (/ 1.0 (fl x)) - (/ 1.0 (fl y)))) - -2 2 -2 2 - #:color '(255 128 128) - #:line-color '(255 128 128) - #:line-width 1.5 - #:label "Inverse") - #:title "Here it is!" - #:x-label "WannaHockaLoogi" - #:y-label "An Impossibly Long Y Axis Label" - #:angle 330 #:altitude 0)) - -(time - (plot3d (surface3d (λ (x y) - (+ (/ (+ (abs x) 0.01)) - (/ (+ (abs y) 0.01)))) - -4 4 -4 4 #:color '(128 128 255) - #:label "Z sort test polygons") - #:angle 330 #:altitude 41 - #:z-label #f #:y-label #f #:x-label #f)) - -(let () +(define-runtime-path p3d-14-data "./test-data/p3d-14.dat") +(define (do-plot-14 output-fn) + (output-fn (surface3d (λ (x y) (+ (/ 1.0 (fl x)) + (/ 1.0 (fl y)))) + -2 2 -2 2 + #:color '(255 128 128) + #:line-color '(255 128 128) + #:line-width 1.5 + #:label "Inverse") + #:title "Here it is!" + #:x-label "WannaHockaLoogi" + #:y-label "An Impossibly Long Y Axis Label" + #:angle 330 #:altitude 0)) + +(define-runtime-path p3d-15-data "./test-data/p3d-15.dat") +(define (do-plot-15 output-fn) + (output-fn (surface3d (λ (x y) + (+ (/ (+ (abs x) 0.01)) + (/ (+ (abs y) 0.01)))) + -4 4 -4 4 #:color '(128 128 255) + #:label "Z sort test polygons") + #:angle 330 #:altitude 41 + #:z-label #f #:y-label #f #:x-label #f)) + +(define-runtime-path p3d-16-data "./test-data/p3d-16.dat") +(define (do-plot-16 output-fn) + (random-seed 42) ; make test reproducible (define xs (build-list 200 (λ (n) (/ 1 (- (random) 0.5))))) (define ys (build-list 200 (λ (n) (/ 1 (- (random) 0.5))))) (define zs (build-list 200 (λ (n) (/ 1 (- (random) 0.5))))) - (time - (plot3d (points3d (map vector xs ys zs) - #:x-min -20 #:x-max 20 - #:y-min -20 #:y-max 20 - #:z-min -20 #:z-max 20 - #:label "Widget Locations") - #:angle 15 #:title "Random Points"))) - -(let () + (output-fn (points3d (map vector xs ys zs) + #:x-min -20 #:x-max 20 + #:y-min -20 #:y-max 20 + #:z-min -20 #:z-max 20 + #:label "Widget Locations") + #:angle 15 #:title "Random Points")) + +(define-runtime-path p3d-17-data "./test-data/p3d-17.dat") +(define (do-plot-17 output-fn) + (random-seed 42) ; make test reproducible (define xs (build-list 10000 (λ (n) (/ 1 (- (random) 0.5))))) (define ys (build-list 10000 (λ (n) (/ 1 (- (random) 0.5))))) (define zs (build-list 10000 (λ (n) (/ 1 (- (random) 0.5))))) - (time - (plot3d (points3d (map vector xs ys zs) - #:x-min -20 #:x-max 20 - #:y-min -20 #:y-max 20 - #:z-min -20 #:z-max 20 - #:color "blue" #:sym 'dot ;#:size 10 - #:alpha 0.5) - #:angle 30 #:altitude 30 - #:title "A Bunch of Random Points Concentrated at the Origin" - #:x-label "x" #:y-label "y" #:z-label "z"))) + (output-fn (points3d (map vector xs ys zs) + #:x-min -20 #:x-max 20 + #:y-min -20 #:y-max 20 + #:z-min -20 #:z-max 20 + #:color "blue" #:sym 'dot ;#:size 10 + #:alpha 0.5) + #:angle 30 #:altitude 30 + #:title "A Bunch of Random Points Concentrated at the Origin" + #:x-label "x" #:y-label "y" #:z-label "z")) ;; tests line clipping: should look like a sphere with six poles chopped off -(time - (plot3d (parametric3d (λ (t) - (vector (* (cos (* 80 t)) (cos t)) - (* (sin (* 80 t)) (cos t)) - (sin t))) - (- pi) pi - #:x-min -0.8 #:x-max 0.8 - #:y-min -0.8 #:y-max 0.8 - #:z-min -0.8 #:z-max 0.8 - #:color "blue" #:width 1/2 #:style 'long-dash - #:samples 3000 #:alpha 0.5 - #:label "Sphere") - #:altitude 22 - #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) - -(time - (plot3d (surface3d (λ (x y) (+ x y)) -0.81 0.81 -0.81 0.81 - #:line-color '(0 0 255) #:line-width 1 #:line-style 'dot) - #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) - -(time +(define-runtime-path p3d-18-data "./test-data/p3d-18.dat") +(define (do-plot-18 output-fn) + (output-fn (parametric3d (λ (t) + (vector (* (cos (* 80 t)) (cos t)) + (* (sin (* 80 t)) (cos t)) + (sin t))) + (- pi) pi + #:x-min -0.8 #:x-max 0.8 + #:y-min -0.8 #:y-max 0.8 + #:z-min -0.8 #:z-max 0.8 + #:color "blue" #:width 1/2 #:style 'long-dash + #:samples 3000 #:alpha 0.5 + #:label "Sphere") + #:altitude 22 + #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) + +(define-runtime-path p3d-19-data "./test-data/p3d-19.dat") +(define (do-plot-19 output-fn) + (output-fn (surface3d (λ (x y) (+ x y)) -0.81 0.81 -0.81 0.81 + #:line-color '(0 0 255) #:line-width 1 #:line-style 'dot) + #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) + +(define-runtime-path p3d-20-data "./test-data/p3d-20.dat") +(define (do-plot-20 output-fn) + (random-seed 42) ; make test reproducible (define xs (build-list 200 (λ (n) (* 2 (- (random) 0.5))))) (define ys (build-list 200 (λ (n) (* 2 (- (random) 0.5))))) (define zs (build-list 200 (λ (n) (* 2 (- (random) 0.5))))) - (plot3d (list (surface3d (λ (x y) (+ x y)) -0.81 0.81 -0.81 0.81 - #:line-color '(0 0 255) #:line-width 1 - #:line-style 'dot) - (points3d (map vector xs ys zs))) - #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) + (output-fn (list (surface3d (λ (x y) (+ x y)) -0.81 0.81 -0.81 0.81 + #:line-color '(0 0 255) #:line-width 1 + #:line-style 'dot) + (points3d (map vector xs ys zs))) + #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1 #:z-min -1 #:z-max 1)) (define (norm mx my x y) (exp (* -1/2 (+ (sqr (- x mx)) (sqr (- y my)))))) @@ -184,80 +212,143 @@ (sqrt (- 1 (sqr d))) 0)) -(parameterize ([plot3d-diffuse-light? #f] - [plot3d-specular-light? #f]) - (time (plot3d (surface3d f5 -5 5 -5 5 #:style 'transparent)))) - -(time (plot3d (contours3d f5 -4 4 -4 4 #:colors '(0) - #:label "z"))) - -(time (plot3d (contour-intervals3d f5 -4 4 -4 4 #:label "z"))) - -(time (plot3d (contour-intervals3d - (λ (x y) - (define z (- x y)) - (cond [(< z -1) -1] - [(> z 1) 1] - [else z])) - -2 2 -2 2))) - -(time - (plot3d (contour-intervals3d (λ (x y) (+ x y))) - #:x-min #e100000000000000.0 #:x-max #e100000000000000.1 - #:y-min #e100000000000000.0 #:y-max #e100000000000000.1 - #:width 500)) - -(time - (plot3d (list (surface3d f5 0 4 -4 4 #:color '(128 255 160) #:alpha 0.5 - #:label "x pos.") - (contour-intervals3d f5 -4 0 -4 4 - #:colors '(0 1 5) - #:line-colors '(0 4 2) - #:line-widths '(1.5) #:line-styles '(dot) - #:contour-colors '(0) - #:contour-widths '(0) - #:contour-styles '(transparent) - #:alphas '(0.75) - #:label "x neg.")) - #:z-min 0.25 #:z-max 1.1 - #:legend-anchor 'top)) - -(time - (parameterize ([plot3d-samples 81]) - (plot3d (contour-intervals3d - f5 -4 4 -4 4 #:label "z" - #:line-styles '(transparent))))) - -(time - (plot3d (list (contours3d f5 -4 4 -4 4) - (contour-intervals3d f5 -2.5 2.5 -2.5 2.5 - #:z-min 0.25 #:z-max 1.5 #:label "z")))) - -(time - (plot3d (contour-intervals3d f5 -3 3 -3 3 - #:colors '((255 128 128) (128 128 255))))) - -(time - (plot3d (list (surface3d f4 -4 4 -4 4 #:color '(255 224 0)) - (contours3d f4 -4 4 -4 4)) - #:angle -30)) - -(time (plot3d (contour-intervals3d f1 -4 4 -4 4))) - -(time (parameterize ([plot3d-samples 101]) - (plot3d (contour-intervals3d f2 -2 2 -2 2 #:levels 10 - #:line-styles '(transparent) - #:contour-styles '(long-dash) - #:alphas '(1 2/3)) - #:altitude 20))) - -(time - (plot3d (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -min.0 +min.0 -min.0 +min.0))) - -(time - (define (f x y) (* (sin x) (cos y))) - (plot3d (list (contour-intervals3d f -3 3 -3 3) - (point-label3d (list -1 1 (f -1 1)))))) - -(time - (plot3d (vector-field3d (lambda (x y z) (list 1 1 0)) 0 10 0 10 0 10))) +(define-runtime-path p3d-21-data "./test-data/p3d-21.dat") +(define (do-plot-21 output-fn) + (parameterize ([plot3d-diffuse-light? #f] + [plot3d-specular-light? #f]) + (output-fn (surface3d f5 -5 5 -5 5 #:style 'transparent)))) + +(define-runtime-path p3d-22-data "./test-data/p3d-22.dat") +(define (do-plot-22 output-fn) + (output-fn (contours3d f5 -4 4 -4 4 #:colors '(0) #:label "z"))) + +(define-runtime-path p3d-23-data "./test-data/p3d-23.dat") +(define (do-plot-23 output-fn) + (output-fn (contour-intervals3d f5 -4 4 -4 4 #:label "z"))) + +(define-runtime-path p3d-24-data "./test-data/p3d-24.dat") +(define (do-plot-24 output-fn) + (output-fn (contour-intervals3d + (λ (x y) + (define z (- x y)) + (cond [(< z -1) -1] + [(> z 1) 1] + [else z])) + -2 2 -2 2))) + +(define-runtime-path p3d-25-data "./test-data/p3d-25.dat") +(define (do-plot-25 output-fn) + (output-fn (contour-intervals3d (λ (x y) (+ x y))) + #:x-min #e100000000000000.0 #:x-max #e100000000000000.1 + #:y-min #e100000000000000.0 #:y-max #e100000000000000.1 + #:width 500)) + +(define-runtime-path p3d-26-data "./test-data/p3d-26.dat") +(define (do-plot-26 output-fn) + (output-fn (list (surface3d f5 0 4 -4 4 #:color '(128 255 160) #:alpha 0.5 + #:label "x pos.") + (contour-intervals3d f5 -4 0 -4 4 + #:colors '(0 1 5) + #:line-colors '(0 4 2) + #:line-widths '(1.5) #:line-styles '(dot) + #:contour-colors '(0) + #:contour-widths '(0) + #:contour-styles '(transparent) + #:alphas '(0.75) + #:label "x neg.")) + #:z-min 0.25 #:z-max 1.1 + #:legend-anchor 'top)) + +(define-runtime-path p3d-27-data "./test-data/p3d-27.dat") +(define (do-plot-27 output-fn) + (parameterize ([plot3d-samples 81]) + (output-fn (contour-intervals3d + f5 -4 4 -4 4 #:label "z" + #:line-styles '(transparent))))) + +(define-runtime-path p3d-28-data "./test-data/p3d-28.dat") +(define (do-plot-28 output-fn) + (output-fn (list (contours3d f5 -4 4 -4 4) + (contour-intervals3d f5 -2.5 2.5 -2.5 2.5 + #:z-min 0.25 #:z-max 1.5 #:label "z")))) + +(define-runtime-path p3d-29-data "./test-data/p3d-29.dat") +(define (do-plot-29 output-fn) + (output-fn (contour-intervals3d f5 -3 3 -3 3 + #:colors '((255 128 128) (128 128 255))))) + +(define-runtime-path p3d-30-data "./test-data/p3d-30.dat") +(define (do-plot-30 output-fn) + (output-fn (list (surface3d f4 -4 4 -4 4 #:color '(255 224 0)) + (contours3d f4 -4 4 -4 4)) + #:angle -30)) + +(define-runtime-path p3d-31-data "./test-data/p3d-31.dat") +(define (do-plot-31 output-fn) + (output-fn (contour-intervals3d f1 -4 4 -4 4))) + +(define-runtime-path p3d-32-data "./test-data/p3d-32.dat") +(define (do-plot-32 output-fn) + (parameterize ([plot3d-samples 101]) + (output-fn (contour-intervals3d f2 -2 2 -2 2 #:levels 10 + #:line-styles '(transparent) + #:contour-styles '(long-dash) + #:alphas '(1 2/3)) + #:altitude 20))) + +(define-runtime-path p3d-33-data "./test-data/p3d-33.dat") +(define (do-plot-33 output-fn) + (output-fn (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -min.0 +min.0 -min.0 +min.0))) + +(define-runtime-path p3d-34-data "./test-data/p3d-34.dat") +(define (do-plot-34 output-fn) + (define (f x y) (* (sin x) (cos y))) + (output-fn (list (contour-intervals3d f -3 3 -3 3) + (point-label3d (list -1 1 (f -1 1)))))) + +(define-runtime-path p3d-35-data "./test-data/p3d-35.dat") +(define (do-plot-35 output-fn) + (output-fn (vector-field3d (lambda (x y z) (list 1 1 0)) 0 10 0 10 0 10))) + +(define plot3d-tests + (test-suite + "plot3d-tests" + (test-case "test case 1" (check-draw-steps-3d do-plot-1 p3d-1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot-2 p3d-2-data)) + (test-case "test case 3" (check-draw-steps-3d do-plot-3 p3d-3-data)) + (test-case "test case 4" (check-draw-steps-3d do-plot-4 p3d-4-data)) + (test-case "test case 5" (check-draw-steps-3d do-plot-5 p3d-5-data)) + (test-case "test case 6" (check-draw-steps-3d do-plot-6 p3d-6-data)) + (test-case "test case 7" (check-draw-steps-3d do-plot-7 p3d-7-data)) + (test-case "test case 8" (check-draw-steps-3d do-plot-8 p3d-8-data)) + (test-case "test case 9" (check-draw-steps-3d do-plot-9 p3d-9-data)) + (test-case "test case 10" (check-draw-steps-3d do-plot-10 p3d-10-data)) + (test-case "test case 11" (check-draw-steps-3d do-plot-11 p3d-11-data)) + (test-case "test case 12" (check-draw-steps-3d do-plot-12 p3d-12-data)) + (test-case "test case 13" (check-draw-steps-3d do-plot-13 p3d-13-data)) + (test-case "test case 14" (check-draw-steps-3d do-plot-14 p3d-14-data)) + (test-case "test case 15" (check-draw-steps-3d do-plot-15 p3d-15-data)) + (test-case "test case 16" (check-draw-steps-3d do-plot-16 p3d-16-data)) + (test-case "test case 17" (check-draw-steps-3d do-plot-17 p3d-17-data)) + (test-case "test case 18" (check-draw-steps-3d do-plot-18 p3d-18-data)) + (test-case "test case 19" (check-draw-steps-3d do-plot-19 p3d-19-data)) + (test-case "test case 20" (check-draw-steps-3d do-plot-20 p3d-20-data)) + (test-case "test case 21" (check-draw-steps-3d do-plot-21 p3d-21-data)) + (test-case "test case 22" (check-draw-steps-3d do-plot-22 p3d-22-data)) + (test-case "test case 23" (check-draw-steps-3d do-plot-23 p3d-23-data)) + (test-case "test case 24" (check-draw-steps-3d do-plot-24 p3d-24-data)) + (test-case "test case 25" (check-draw-steps-3d do-plot-25 p3d-25-data)) + (test-case "test case 26" (check-draw-steps-3d do-plot-26 p3d-26-data)) + (test-case "test case 27" (check-draw-steps-3d do-plot-27 p3d-27-data)) + (test-case "test case 28" (check-draw-steps-3d do-plot-28 p3d-28-data)) + (test-case "test case 29" (check-draw-steps-3d do-plot-29 p3d-29-data)) + (test-case "test case 30" (check-draw-steps-3d do-plot-30 p3d-30-data)) + (test-case "test case 31" (check-draw-steps-3d do-plot-31 p3d-31-data)) + (test-case "test case 32" (check-draw-steps-3d do-plot-32 p3d-32-data)) + (test-case "test case 33" (check-draw-steps-3d do-plot-33 p3d-33-data)) + (test-case "test case 34" (check-draw-steps-3d do-plot-34 p3d-34-data)) + (test-case "test case 35" (check-draw-steps-3d do-plot-35 p3d-35-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests plot3d-tests)) diff --git a/plot-test/plot/tests/subdivision-tests.rkt b/plot-test/plot/tests/subdivision-tests.rkt index 5bf63e2c..0c26ee68 100644 --- a/plot-test/plot/tests/subdivision-tests.rkt +++ b/plot-test/plot/tests/subdivision-tests.rkt @@ -1,36 +1,72 @@ #lang racket +(require rackunit + plot + plot/utils + racket/draw + racket/runtime-path + "helpers.rkt") -(require plot - plot/private/plot2d/plot-area - plot/private/plot3d/plot-area) - -(parameterize ([plot-x-transform log-transform] - [plot-x-ticks (log-ticks)]) - (values - (plot (lines '(#(1 1) #(200 200)))) - (plot3d (lines3d '(#(1 1 1) #(200 200 200)))))) - -(plot2d-subdivisions) -(plot3d-subdivisions) - -(time - (parameterize ([plot3d-samples 4] - [plot-x-transform log-transform] - [plot-x-ticks (log-ticks)] - [plot-y-transform log-transform] - [plot-y-ticks (log-ticks)]) - (values - (plot (lines '(#(1 1) #(200 200)))) - (plot3d (surface3d + 1 200 1 200))))) - -(plot2d-subdivisions) -(plot3d-subdivisions) - -(time - (parameterize ([plot-x-transform (collapse-transform -1 1)]) - (values - (plot (lines '(#(-2 -2) #(2 2)))) - (plot3d (surface3d + -2 2 -2 2))))) - -(plot2d-subdivisions) -(plot3d-subdivisions) +;; NOTE: these plots used to test some `plot2d-subdivisions` and +;; `plot3d-subdivisions` parameters, but, while these parameters are defined, +;; but are not used by the plot package -- their usage was commented out and +;; disappeared over time. I suspect they were used during debugging to +;; determine how many subdivisions are done for the plot, as there is still +;; one commented out place where the plot3d-subdivisions is incremented (an +;; equivalent commented out increment also existed for `plot2d-subdivisions` +;; +;; Now, these plots just exercise the plot library in interesting ways. + +(define (do-plot1 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-x-ticks (log-ticks)]) + (output-fn (lines '(#(1 1) #(200 200)))))) + +(define (do-plot2 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-x-ticks (log-ticks)]) + (output-fn (lines3d '(#(1 1 1) #(200 200 200)))))) + +(define (do-plot3 output-fn) + (parameterize ([plot3d-samples 4] + [plot-x-transform log-transform] + [plot-x-ticks (log-ticks)] + [plot-y-transform log-transform] + [plot-y-ticks (log-ticks)]) + (output-fn (lines '(#(1 1) #(200 200)))))) + +(define (do-plot4 output-fn) + (parameterize ([plot3d-samples 4] + [plot-x-transform log-transform] + [plot-x-ticks (log-ticks)] + [plot-y-transform log-transform] + [plot-y-ticks (log-ticks)]) + (output-fn (surface3d + 1 200 1 200)))) + +(define (do-plot5 output-fn) + (parameterize ([plot-x-transform (collapse-transform -1 1)]) + (output-fn (lines '(#(-2 -2) #(2 2)))))) + +(define (do-plot6 output-fn) + (parameterize ([plot-x-transform (collapse-transform -1 1)]) + (output-fn (surface3d + -2 2 -2 2)))) + +(define-runtime-path subdivision1-data "./test-data/sd-1.dat") +(define-runtime-path subdivision2-data "./test-data/sd-2.dat") +(define-runtime-path subdivision3-data "./test-data/sd-3.dat") +(define-runtime-path subdivision4-data "./test-data/sd-4.dat") +(define-runtime-path subdivision5-data "./test-data/sd-5.dat") +(define-runtime-path subdivision6-data "./test-data/sd-6.dat") + +(define subdivision-tests + (test-suite + "subdivision-tests" + (test-case "test case 1" (check-draw-steps do-plot1 subdivision1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot2 subdivision2-data)) + (test-case "test case 3" (check-draw-steps do-plot3 subdivision3-data)) + (test-case "test case 4" (check-draw-steps-3d do-plot4 subdivision4-data)) + (test-case "test case 5" (check-draw-steps do-plot5 subdivision5-data)) + (test-case "test case 6" (check-draw-steps-3d do-plot6 subdivision6-data)))) + +(module+ test + (require rackunit/text-ui) + (run-tests subdivision-tests)) diff --git a/plot-test/plot/tests/test-data/at1.dat b/plot-test/plot/tests/test-data/at1.dat new file mode 100644 index 00000000..0afd561c Binary files /dev/null and b/plot-test/plot/tests/test-data/at1.dat differ diff --git a/plot-test/plot/tests/test-data/at1.png b/plot-test/plot/tests/test-data/at1.png new file mode 100644 index 00000000..50de7029 Binary files /dev/null and b/plot-test/plot/tests/test-data/at1.png differ diff --git a/plot-test/plot/tests/test-data/at10.dat b/plot-test/plot/tests/test-data/at10.dat new file mode 100644 index 00000000..d47ead80 Binary files /dev/null and b/plot-test/plot/tests/test-data/at10.dat differ diff --git a/plot-test/plot/tests/test-data/at10.png b/plot-test/plot/tests/test-data/at10.png new file mode 100644 index 00000000..73924f36 Binary files /dev/null and b/plot-test/plot/tests/test-data/at10.png differ diff --git a/plot-test/plot/tests/test-data/at11.dat b/plot-test/plot/tests/test-data/at11.dat new file mode 100644 index 00000000..2824037d Binary files /dev/null and b/plot-test/plot/tests/test-data/at11.dat differ diff --git a/plot-test/plot/tests/test-data/at11.png b/plot-test/plot/tests/test-data/at11.png new file mode 100644 index 00000000..6f4e2a75 Binary files /dev/null and b/plot-test/plot/tests/test-data/at11.png differ diff --git a/plot-test/plot/tests/test-data/at12.dat b/plot-test/plot/tests/test-data/at12.dat new file mode 100644 index 00000000..1c1f2ee9 Binary files /dev/null and b/plot-test/plot/tests/test-data/at12.dat differ diff --git a/plot-test/plot/tests/test-data/at12.png b/plot-test/plot/tests/test-data/at12.png new file mode 100644 index 00000000..f3c0eacc Binary files /dev/null and b/plot-test/plot/tests/test-data/at12.png differ diff --git a/plot-test/plot/tests/test-data/at13.dat b/plot-test/plot/tests/test-data/at13.dat new file mode 100644 index 00000000..40689ff3 Binary files /dev/null and b/plot-test/plot/tests/test-data/at13.dat differ diff --git a/plot-test/plot/tests/test-data/at13.png b/plot-test/plot/tests/test-data/at13.png new file mode 100644 index 00000000..f3c0eacc Binary files /dev/null and b/plot-test/plot/tests/test-data/at13.png differ diff --git a/plot-test/plot/tests/test-data/at14.dat b/plot-test/plot/tests/test-data/at14.dat new file mode 100644 index 00000000..f24666bb Binary files /dev/null and b/plot-test/plot/tests/test-data/at14.dat differ diff --git a/plot-test/plot/tests/test-data/at14.png b/plot-test/plot/tests/test-data/at14.png new file mode 100644 index 00000000..bf0a136f Binary files /dev/null and b/plot-test/plot/tests/test-data/at14.png differ diff --git a/plot-test/plot/tests/test-data/at15.dat b/plot-test/plot/tests/test-data/at15.dat new file mode 100644 index 00000000..3c089d52 Binary files /dev/null and b/plot-test/plot/tests/test-data/at15.dat differ diff --git a/plot-test/plot/tests/test-data/at15.png b/plot-test/plot/tests/test-data/at15.png new file mode 100644 index 00000000..d33c1d24 Binary files /dev/null and b/plot-test/plot/tests/test-data/at15.png differ diff --git a/plot-test/plot/tests/test-data/at16.dat b/plot-test/plot/tests/test-data/at16.dat new file mode 100644 index 00000000..3c089d52 Binary files /dev/null and b/plot-test/plot/tests/test-data/at16.dat differ diff --git a/plot-test/plot/tests/test-data/at16.png b/plot-test/plot/tests/test-data/at16.png new file mode 100644 index 00000000..d33c1d24 Binary files /dev/null and b/plot-test/plot/tests/test-data/at16.png differ diff --git a/plot-test/plot/tests/test-data/at17.dat b/plot-test/plot/tests/test-data/at17.dat new file mode 100644 index 00000000..c6e46708 Binary files /dev/null and b/plot-test/plot/tests/test-data/at17.dat differ diff --git a/plot-test/plot/tests/test-data/at17.png b/plot-test/plot/tests/test-data/at17.png new file mode 100644 index 00000000..f1535e5d Binary files /dev/null and b/plot-test/plot/tests/test-data/at17.png differ diff --git a/plot-test/plot/tests/test-data/at18.dat b/plot-test/plot/tests/test-data/at18.dat new file mode 100644 index 00000000..98819674 Binary files /dev/null and b/plot-test/plot/tests/test-data/at18.dat differ diff --git a/plot-test/plot/tests/test-data/at18.png b/plot-test/plot/tests/test-data/at18.png new file mode 100644 index 00000000..8af7c4be Binary files /dev/null and b/plot-test/plot/tests/test-data/at18.png differ diff --git a/plot-test/plot/tests/test-data/at19.dat b/plot-test/plot/tests/test-data/at19.dat new file mode 100644 index 00000000..14b890fd Binary files /dev/null and b/plot-test/plot/tests/test-data/at19.dat differ diff --git a/plot-test/plot/tests/test-data/at19.png b/plot-test/plot/tests/test-data/at19.png new file mode 100644 index 00000000..dd76c663 Binary files /dev/null and b/plot-test/plot/tests/test-data/at19.png differ diff --git a/plot-test/plot/tests/test-data/at2.dat b/plot-test/plot/tests/test-data/at2.dat new file mode 100644 index 00000000..07a0a760 Binary files /dev/null and b/plot-test/plot/tests/test-data/at2.dat differ diff --git a/plot-test/plot/tests/test-data/at2.png b/plot-test/plot/tests/test-data/at2.png new file mode 100644 index 00000000..4458e3d0 Binary files /dev/null and b/plot-test/plot/tests/test-data/at2.png differ diff --git a/plot-test/plot/tests/test-data/at20.dat b/plot-test/plot/tests/test-data/at20.dat new file mode 100644 index 00000000..4aa8ffa3 Binary files /dev/null and b/plot-test/plot/tests/test-data/at20.dat differ diff --git a/plot-test/plot/tests/test-data/at20.png b/plot-test/plot/tests/test-data/at20.png new file mode 100644 index 00000000..4ef08790 Binary files /dev/null and b/plot-test/plot/tests/test-data/at20.png differ diff --git a/plot-test/plot/tests/test-data/at21.dat b/plot-test/plot/tests/test-data/at21.dat new file mode 100644 index 00000000..5cdd4b7e Binary files /dev/null and b/plot-test/plot/tests/test-data/at21.dat differ diff --git a/plot-test/plot/tests/test-data/at21.png b/plot-test/plot/tests/test-data/at21.png new file mode 100644 index 00000000..c52a1417 Binary files /dev/null and b/plot-test/plot/tests/test-data/at21.png differ diff --git a/plot-test/plot/tests/test-data/at22.dat b/plot-test/plot/tests/test-data/at22.dat new file mode 100644 index 00000000..baa3cb5a Binary files /dev/null and b/plot-test/plot/tests/test-data/at22.dat differ diff --git a/plot-test/plot/tests/test-data/at22.png b/plot-test/plot/tests/test-data/at22.png new file mode 100644 index 00000000..bd3b68f0 Binary files /dev/null and b/plot-test/plot/tests/test-data/at22.png differ diff --git a/plot-test/plot/tests/test-data/at23.dat b/plot-test/plot/tests/test-data/at23.dat new file mode 100644 index 00000000..1c186df0 Binary files /dev/null and b/plot-test/plot/tests/test-data/at23.dat differ diff --git a/plot-test/plot/tests/test-data/at23.png b/plot-test/plot/tests/test-data/at23.png new file mode 100644 index 00000000..2432a2b1 Binary files /dev/null and b/plot-test/plot/tests/test-data/at23.png differ diff --git a/plot-test/plot/tests/test-data/at24.dat b/plot-test/plot/tests/test-data/at24.dat new file mode 100644 index 00000000..7672abec Binary files /dev/null and b/plot-test/plot/tests/test-data/at24.dat differ diff --git a/plot-test/plot/tests/test-data/at24.png b/plot-test/plot/tests/test-data/at24.png new file mode 100644 index 00000000..a83375e2 Binary files /dev/null and b/plot-test/plot/tests/test-data/at24.png differ diff --git a/plot-test/plot/tests/test-data/at25.dat b/plot-test/plot/tests/test-data/at25.dat new file mode 100644 index 00000000..d9f8b0bd Binary files /dev/null and b/plot-test/plot/tests/test-data/at25.dat differ diff --git a/plot-test/plot/tests/test-data/at25.png b/plot-test/plot/tests/test-data/at25.png new file mode 100644 index 00000000..0422d892 Binary files /dev/null and b/plot-test/plot/tests/test-data/at25.png differ diff --git a/plot-test/plot/tests/test-data/at26.dat b/plot-test/plot/tests/test-data/at26.dat new file mode 100644 index 00000000..028cf3eb Binary files /dev/null and b/plot-test/plot/tests/test-data/at26.dat differ diff --git a/plot-test/plot/tests/test-data/at26.png b/plot-test/plot/tests/test-data/at26.png new file mode 100644 index 00000000..a424b46b Binary files /dev/null and b/plot-test/plot/tests/test-data/at26.png differ diff --git a/plot-test/plot/tests/test-data/at27.dat b/plot-test/plot/tests/test-data/at27.dat new file mode 100644 index 00000000..028cf3eb Binary files /dev/null and b/plot-test/plot/tests/test-data/at27.dat differ diff --git a/plot-test/plot/tests/test-data/at27.png b/plot-test/plot/tests/test-data/at27.png new file mode 100644 index 00000000..a424b46b Binary files /dev/null and b/plot-test/plot/tests/test-data/at27.png differ diff --git a/plot-test/plot/tests/test-data/at28.dat b/plot-test/plot/tests/test-data/at28.dat new file mode 100644 index 00000000..64e29de5 Binary files /dev/null and b/plot-test/plot/tests/test-data/at28.dat differ diff --git a/plot-test/plot/tests/test-data/at28.png b/plot-test/plot/tests/test-data/at28.png new file mode 100644 index 00000000..a508f553 Binary files /dev/null and b/plot-test/plot/tests/test-data/at28.png differ diff --git a/plot-test/plot/tests/test-data/at29.dat b/plot-test/plot/tests/test-data/at29.dat new file mode 100644 index 00000000..0daab4d9 Binary files /dev/null and b/plot-test/plot/tests/test-data/at29.dat differ diff --git a/plot-test/plot/tests/test-data/at29.png b/plot-test/plot/tests/test-data/at29.png new file mode 100644 index 00000000..2b4a93ac Binary files /dev/null and b/plot-test/plot/tests/test-data/at29.png differ diff --git a/plot-test/plot/tests/test-data/at3.dat b/plot-test/plot/tests/test-data/at3.dat new file mode 100644 index 00000000..88239b72 Binary files /dev/null and b/plot-test/plot/tests/test-data/at3.dat differ diff --git a/plot-test/plot/tests/test-data/at3.png b/plot-test/plot/tests/test-data/at3.png new file mode 100644 index 00000000..e1c86360 Binary files /dev/null and b/plot-test/plot/tests/test-data/at3.png differ diff --git a/plot-test/plot/tests/test-data/at30.dat b/plot-test/plot/tests/test-data/at30.dat new file mode 100644 index 00000000..0daab4d9 Binary files /dev/null and b/plot-test/plot/tests/test-data/at30.dat differ diff --git a/plot-test/plot/tests/test-data/at30.png b/plot-test/plot/tests/test-data/at30.png new file mode 100644 index 00000000..2b4a93ac Binary files /dev/null and b/plot-test/plot/tests/test-data/at30.png differ diff --git a/plot-test/plot/tests/test-data/at31.dat b/plot-test/plot/tests/test-data/at31.dat new file mode 100644 index 00000000..d61d6aea Binary files /dev/null and b/plot-test/plot/tests/test-data/at31.dat differ diff --git a/plot-test/plot/tests/test-data/at31.png b/plot-test/plot/tests/test-data/at31.png new file mode 100644 index 00000000..bd3b68f0 Binary files /dev/null and b/plot-test/plot/tests/test-data/at31.png differ diff --git a/plot-test/plot/tests/test-data/at32.dat b/plot-test/plot/tests/test-data/at32.dat new file mode 100644 index 00000000..e3d186fb Binary files /dev/null and b/plot-test/plot/tests/test-data/at32.dat differ diff --git a/plot-test/plot/tests/test-data/at32.png b/plot-test/plot/tests/test-data/at32.png new file mode 100644 index 00000000..13aae28e Binary files /dev/null and b/plot-test/plot/tests/test-data/at32.png differ diff --git a/plot-test/plot/tests/test-data/at33.dat b/plot-test/plot/tests/test-data/at33.dat new file mode 100644 index 00000000..92114a62 Binary files /dev/null and b/plot-test/plot/tests/test-data/at33.dat differ diff --git a/plot-test/plot/tests/test-data/at33.png b/plot-test/plot/tests/test-data/at33.png new file mode 100644 index 00000000..4005b295 Binary files /dev/null and b/plot-test/plot/tests/test-data/at33.png differ diff --git a/plot-test/plot/tests/test-data/at34.dat b/plot-test/plot/tests/test-data/at34.dat new file mode 100644 index 00000000..dcca2f40 Binary files /dev/null and b/plot-test/plot/tests/test-data/at34.dat differ diff --git a/plot-test/plot/tests/test-data/at34.png b/plot-test/plot/tests/test-data/at34.png new file mode 100644 index 00000000..f63e0c2f Binary files /dev/null and b/plot-test/plot/tests/test-data/at34.png differ diff --git a/plot-test/plot/tests/test-data/at35.dat b/plot-test/plot/tests/test-data/at35.dat new file mode 100644 index 00000000..91cf37c6 Binary files /dev/null and b/plot-test/plot/tests/test-data/at35.dat differ diff --git a/plot-test/plot/tests/test-data/at35.png b/plot-test/plot/tests/test-data/at35.png new file mode 100644 index 00000000..9f6b961d Binary files /dev/null and b/plot-test/plot/tests/test-data/at35.png differ diff --git a/plot-test/plot/tests/test-data/at36.dat b/plot-test/plot/tests/test-data/at36.dat new file mode 100644 index 00000000..2d402632 Binary files /dev/null and b/plot-test/plot/tests/test-data/at36.dat differ diff --git a/plot-test/plot/tests/test-data/at36.png b/plot-test/plot/tests/test-data/at36.png new file mode 100644 index 00000000..30e61488 Binary files /dev/null and b/plot-test/plot/tests/test-data/at36.png differ diff --git a/plot-test/plot/tests/test-data/at37.dat b/plot-test/plot/tests/test-data/at37.dat new file mode 100644 index 00000000..9738ee40 Binary files /dev/null and b/plot-test/plot/tests/test-data/at37.dat differ diff --git a/plot-test/plot/tests/test-data/at37.png b/plot-test/plot/tests/test-data/at37.png new file mode 100644 index 00000000..df8d8eca Binary files /dev/null and b/plot-test/plot/tests/test-data/at37.png differ diff --git a/plot-test/plot/tests/test-data/at38.dat b/plot-test/plot/tests/test-data/at38.dat new file mode 100644 index 00000000..9c2369f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/at38.dat differ diff --git a/plot-test/plot/tests/test-data/at38.png b/plot-test/plot/tests/test-data/at38.png new file mode 100644 index 00000000..45eb5a66 Binary files /dev/null and b/plot-test/plot/tests/test-data/at38.png differ diff --git a/plot-test/plot/tests/test-data/at39.dat b/plot-test/plot/tests/test-data/at39.dat new file mode 100644 index 00000000..d56e4064 Binary files /dev/null and b/plot-test/plot/tests/test-data/at39.dat differ diff --git a/plot-test/plot/tests/test-data/at39.png b/plot-test/plot/tests/test-data/at39.png new file mode 100644 index 00000000..53c12ed2 Binary files /dev/null and b/plot-test/plot/tests/test-data/at39.png differ diff --git a/plot-test/plot/tests/test-data/at4.dat b/plot-test/plot/tests/test-data/at4.dat new file mode 100644 index 00000000..67ae9b81 Binary files /dev/null and b/plot-test/plot/tests/test-data/at4.dat differ diff --git a/plot-test/plot/tests/test-data/at4.png b/plot-test/plot/tests/test-data/at4.png new file mode 100644 index 00000000..ec0fc275 Binary files /dev/null and b/plot-test/plot/tests/test-data/at4.png differ diff --git a/plot-test/plot/tests/test-data/at40.dat b/plot-test/plot/tests/test-data/at40.dat new file mode 100644 index 00000000..82a7abb7 Binary files /dev/null and b/plot-test/plot/tests/test-data/at40.dat differ diff --git a/plot-test/plot/tests/test-data/at40.png b/plot-test/plot/tests/test-data/at40.png new file mode 100644 index 00000000..c8fcfd8e Binary files /dev/null and b/plot-test/plot/tests/test-data/at40.png differ diff --git a/plot-test/plot/tests/test-data/at41.dat b/plot-test/plot/tests/test-data/at41.dat new file mode 100644 index 00000000..3774db6d Binary files /dev/null and b/plot-test/plot/tests/test-data/at41.dat differ diff --git a/plot-test/plot/tests/test-data/at41.png b/plot-test/plot/tests/test-data/at41.png new file mode 100644 index 00000000..82f29885 Binary files /dev/null and b/plot-test/plot/tests/test-data/at41.png differ diff --git a/plot-test/plot/tests/test-data/at42.dat b/plot-test/plot/tests/test-data/at42.dat new file mode 100644 index 00000000..e57bba26 Binary files /dev/null and b/plot-test/plot/tests/test-data/at42.dat differ diff --git a/plot-test/plot/tests/test-data/at42.png b/plot-test/plot/tests/test-data/at42.png new file mode 100644 index 00000000..6f0ebbb1 Binary files /dev/null and b/plot-test/plot/tests/test-data/at42.png differ diff --git a/plot-test/plot/tests/test-data/at43.dat b/plot-test/plot/tests/test-data/at43.dat new file mode 100644 index 00000000..8f886c23 Binary files /dev/null and b/plot-test/plot/tests/test-data/at43.dat differ diff --git a/plot-test/plot/tests/test-data/at43.png b/plot-test/plot/tests/test-data/at43.png new file mode 100644 index 00000000..53d43b4a Binary files /dev/null and b/plot-test/plot/tests/test-data/at43.png differ diff --git a/plot-test/plot/tests/test-data/at44.dat b/plot-test/plot/tests/test-data/at44.dat new file mode 100644 index 00000000..68c40177 Binary files /dev/null and b/plot-test/plot/tests/test-data/at44.dat differ diff --git a/plot-test/plot/tests/test-data/at44.png b/plot-test/plot/tests/test-data/at44.png new file mode 100644 index 00000000..654f1ad9 Binary files /dev/null and b/plot-test/plot/tests/test-data/at44.png differ diff --git a/plot-test/plot/tests/test-data/at45.dat b/plot-test/plot/tests/test-data/at45.dat new file mode 100644 index 00000000..d535ec4e Binary files /dev/null and b/plot-test/plot/tests/test-data/at45.dat differ diff --git a/plot-test/plot/tests/test-data/at45.png b/plot-test/plot/tests/test-data/at45.png new file mode 100644 index 00000000..592f7363 Binary files /dev/null and b/plot-test/plot/tests/test-data/at45.png differ diff --git a/plot-test/plot/tests/test-data/at46.dat b/plot-test/plot/tests/test-data/at46.dat new file mode 100644 index 00000000..f69ebd98 Binary files /dev/null and b/plot-test/plot/tests/test-data/at46.dat differ diff --git a/plot-test/plot/tests/test-data/at46.png b/plot-test/plot/tests/test-data/at46.png new file mode 100644 index 00000000..056022f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/at46.png differ diff --git a/plot-test/plot/tests/test-data/at47.dat b/plot-test/plot/tests/test-data/at47.dat new file mode 100644 index 00000000..95de3e12 Binary files /dev/null and b/plot-test/plot/tests/test-data/at47.dat differ diff --git a/plot-test/plot/tests/test-data/at47.png b/plot-test/plot/tests/test-data/at47.png new file mode 100644 index 00000000..cc1a9c86 Binary files /dev/null and b/plot-test/plot/tests/test-data/at47.png differ diff --git a/plot-test/plot/tests/test-data/at48.dat b/plot-test/plot/tests/test-data/at48.dat new file mode 100644 index 00000000..437a6c86 Binary files /dev/null and b/plot-test/plot/tests/test-data/at48.dat differ diff --git a/plot-test/plot/tests/test-data/at48.png b/plot-test/plot/tests/test-data/at48.png new file mode 100644 index 00000000..0ac33781 Binary files /dev/null and b/plot-test/plot/tests/test-data/at48.png differ diff --git a/plot-test/plot/tests/test-data/at49.dat b/plot-test/plot/tests/test-data/at49.dat new file mode 100644 index 00000000..40c6997d Binary files /dev/null and b/plot-test/plot/tests/test-data/at49.dat differ diff --git a/plot-test/plot/tests/test-data/at49.png b/plot-test/plot/tests/test-data/at49.png new file mode 100644 index 00000000..86db8540 Binary files /dev/null and b/plot-test/plot/tests/test-data/at49.png differ diff --git a/plot-test/plot/tests/test-data/at5.dat b/plot-test/plot/tests/test-data/at5.dat new file mode 100644 index 00000000..b1a8b825 Binary files /dev/null and b/plot-test/plot/tests/test-data/at5.dat differ diff --git a/plot-test/plot/tests/test-data/at5.png b/plot-test/plot/tests/test-data/at5.png new file mode 100644 index 00000000..3600ca5d Binary files /dev/null and b/plot-test/plot/tests/test-data/at5.png differ diff --git a/plot-test/plot/tests/test-data/at6.dat b/plot-test/plot/tests/test-data/at6.dat new file mode 100644 index 00000000..098118b7 Binary files /dev/null and b/plot-test/plot/tests/test-data/at6.dat differ diff --git a/plot-test/plot/tests/test-data/at6.png b/plot-test/plot/tests/test-data/at6.png new file mode 100644 index 00000000..911ae36c Binary files /dev/null and b/plot-test/plot/tests/test-data/at6.png differ diff --git a/plot-test/plot/tests/test-data/at7.dat b/plot-test/plot/tests/test-data/at7.dat new file mode 100644 index 00000000..83de2837 Binary files /dev/null and b/plot-test/plot/tests/test-data/at7.dat differ diff --git a/plot-test/plot/tests/test-data/at7.png b/plot-test/plot/tests/test-data/at7.png new file mode 100644 index 00000000..30b860fb Binary files /dev/null and b/plot-test/plot/tests/test-data/at7.png differ diff --git a/plot-test/plot/tests/test-data/at8.dat b/plot-test/plot/tests/test-data/at8.dat new file mode 100644 index 00000000..4fa0ef91 Binary files /dev/null and b/plot-test/plot/tests/test-data/at8.dat differ diff --git a/plot-test/plot/tests/test-data/at8.png b/plot-test/plot/tests/test-data/at8.png new file mode 100644 index 00000000..435509bc Binary files /dev/null and b/plot-test/plot/tests/test-data/at8.png differ diff --git a/plot-test/plot/tests/test-data/at9.dat b/plot-test/plot/tests/test-data/at9.dat new file mode 100644 index 00000000..97397835 Binary files /dev/null and b/plot-test/plot/tests/test-data/at9.dat differ diff --git a/plot-test/plot/tests/test-data/at9.png b/plot-test/plot/tests/test-data/at9.png new file mode 100644 index 00000000..73924f36 Binary files /dev/null and b/plot-test/plot/tests/test-data/at9.png differ diff --git a/plot-test/plot/tests/test-data/eb-1.png b/plot-test/plot/tests/test-data/eb-1.png new file mode 100644 index 00000000..6fa0e01f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-1.png differ diff --git a/plot-test/plot/tests/test-data/eb-1.rktd b/plot-test/plot/tests/test-data/eb-1.rktd new file mode 100644 index 00000000..30381a14 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-1.rktd differ diff --git a/plot-test/plot/tests/test-data/eb-2.png b/plot-test/plot/tests/test-data/eb-2.png new file mode 100644 index 00000000..d3bead54 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-2.png differ diff --git a/plot-test/plot/tests/test-data/eb-2.rktd b/plot-test/plot/tests/test-data/eb-2.rktd new file mode 100644 index 00000000..fb73c85d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-2.rktd differ diff --git a/plot-test/plot/tests/test-data/eb-3.png b/plot-test/plot/tests/test-data/eb-3.png new file mode 100644 index 00000000..31b4e41a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-3.png differ diff --git a/plot-test/plot/tests/test-data/eb-3.rktd b/plot-test/plot/tests/test-data/eb-3.rktd new file mode 100644 index 00000000..db33c452 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-3.rktd differ diff --git a/plot-test/plot/tests/test-data/eb-4.png b/plot-test/plot/tests/test-data/eb-4.png new file mode 100644 index 00000000..41456946 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-4.png differ diff --git a/plot-test/plot/tests/test-data/eb-4.rktd b/plot-test/plot/tests/test-data/eb-4.rktd new file mode 100644 index 00000000..cb8856d9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb-4.rktd differ diff --git a/plot-test/plot/tests/test-data/eb2d-1.dat b/plot-test/plot/tests/test-data/eb2d-1.dat new file mode 100644 index 00000000..ae28c5ec Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-1.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-1.png b/plot-test/plot/tests/test-data/eb2d-1.png new file mode 100644 index 00000000..7ed9ec8e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-1.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-10.dat b/plot-test/plot/tests/test-data/eb2d-10.dat new file mode 100644 index 00000000..c23f1d3a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-10.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-10.png b/plot-test/plot/tests/test-data/eb2d-10.png new file mode 100644 index 00000000..9cee9d2e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-10.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-11.dat b/plot-test/plot/tests/test-data/eb2d-11.dat new file mode 100644 index 00000000..1d69f4d7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-11.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-11.png b/plot-test/plot/tests/test-data/eb2d-11.png new file mode 100644 index 00000000..7a04f374 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-11.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-12.dat b/plot-test/plot/tests/test-data/eb2d-12.dat new file mode 100644 index 00000000..66427237 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-12.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-12.png b/plot-test/plot/tests/test-data/eb2d-12.png new file mode 100644 index 00000000..b361328f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-12.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-13.dat b/plot-test/plot/tests/test-data/eb2d-13.dat new file mode 100644 index 00000000..7d378e55 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-13.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-13.png b/plot-test/plot/tests/test-data/eb2d-13.png new file mode 100644 index 00000000..3fa4facf Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-13.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-14.dat b/plot-test/plot/tests/test-data/eb2d-14.dat new file mode 100644 index 00000000..e39dd62c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-14.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-14.png b/plot-test/plot/tests/test-data/eb2d-14.png new file mode 100644 index 00000000..24cef3af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-14.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-15.dat b/plot-test/plot/tests/test-data/eb2d-15.dat new file mode 100644 index 00000000..e07ff0c7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-15.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-15.png b/plot-test/plot/tests/test-data/eb2d-15.png new file mode 100644 index 00000000..77474a61 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-15.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-16.dat b/plot-test/plot/tests/test-data/eb2d-16.dat new file mode 100644 index 00000000..195a59d4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-16.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-16.png b/plot-test/plot/tests/test-data/eb2d-16.png new file mode 100644 index 00000000..6dced957 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-16.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-17.dat b/plot-test/plot/tests/test-data/eb2d-17.dat new file mode 100644 index 00000000..b5b588d3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-17.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-17.png b/plot-test/plot/tests/test-data/eb2d-17.png new file mode 100644 index 00000000..3d2812d7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-17.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-18.dat b/plot-test/plot/tests/test-data/eb2d-18.dat new file mode 100644 index 00000000..2300e5b3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-18.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-18.png b/plot-test/plot/tests/test-data/eb2d-18.png new file mode 100644 index 00000000..ae46e682 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-18.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-19.dat b/plot-test/plot/tests/test-data/eb2d-19.dat new file mode 100644 index 00000000..132e3967 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-19.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-19.png b/plot-test/plot/tests/test-data/eb2d-19.png new file mode 100644 index 00000000..07338b82 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-19.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-2.dat b/plot-test/plot/tests/test-data/eb2d-2.dat new file mode 100644 index 00000000..874b5452 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-2.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-2.png b/plot-test/plot/tests/test-data/eb2d-2.png new file mode 100644 index 00000000..4f31c77a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-2.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-20.dat b/plot-test/plot/tests/test-data/eb2d-20.dat new file mode 100644 index 00000000..4b6353b4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-20.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-20.png b/plot-test/plot/tests/test-data/eb2d-20.png new file mode 100644 index 00000000..7b5b15ac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-20.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-21.dat b/plot-test/plot/tests/test-data/eb2d-21.dat new file mode 100644 index 00000000..595a3a97 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-21.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-21.png b/plot-test/plot/tests/test-data/eb2d-21.png new file mode 100644 index 00000000..fb9c5531 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-21.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-22.dat b/plot-test/plot/tests/test-data/eb2d-22.dat new file mode 100644 index 00000000..c2542176 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-22.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-22.png b/plot-test/plot/tests/test-data/eb2d-22.png new file mode 100644 index 00000000..a95c88fe Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-22.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-23.dat b/plot-test/plot/tests/test-data/eb2d-23.dat new file mode 100644 index 00000000..9a3ddac1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-23.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-23.png b/plot-test/plot/tests/test-data/eb2d-23.png new file mode 100644 index 00000000..fcc00bca Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-23.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-24.dat b/plot-test/plot/tests/test-data/eb2d-24.dat new file mode 100644 index 00000000..6cbf737b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-24.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-24.png b/plot-test/plot/tests/test-data/eb2d-24.png new file mode 100644 index 00000000..3ac1da0c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-24.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-25.dat b/plot-test/plot/tests/test-data/eb2d-25.dat new file mode 100644 index 00000000..66b323e2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-25.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-25.png b/plot-test/plot/tests/test-data/eb2d-25.png new file mode 100644 index 00000000..ac322369 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-25.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-26.dat b/plot-test/plot/tests/test-data/eb2d-26.dat new file mode 100644 index 00000000..ca697ad4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-26.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-26.png b/plot-test/plot/tests/test-data/eb2d-26.png new file mode 100644 index 00000000..7c67f439 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-26.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-27.dat b/plot-test/plot/tests/test-data/eb2d-27.dat new file mode 100644 index 00000000..77b76080 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-27.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-27.png b/plot-test/plot/tests/test-data/eb2d-27.png new file mode 100644 index 00000000..3ad1763e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-27.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-28.dat b/plot-test/plot/tests/test-data/eb2d-28.dat new file mode 100644 index 00000000..7543b13b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-28.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-28.png b/plot-test/plot/tests/test-data/eb2d-28.png new file mode 100644 index 00000000..a61b0d3f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-28.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-29.dat b/plot-test/plot/tests/test-data/eb2d-29.dat new file mode 100644 index 00000000..ebae2528 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-29.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-29.png b/plot-test/plot/tests/test-data/eb2d-29.png new file mode 100644 index 00000000..3c54d25a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-29.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-3.dat b/plot-test/plot/tests/test-data/eb2d-3.dat new file mode 100644 index 00000000..eae61e40 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-3.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-3.png b/plot-test/plot/tests/test-data/eb2d-3.png new file mode 100644 index 00000000..c8e5ac2f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-3.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-30.dat b/plot-test/plot/tests/test-data/eb2d-30.dat new file mode 100644 index 00000000..dceb3a58 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-30.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-30.png b/plot-test/plot/tests/test-data/eb2d-30.png new file mode 100644 index 00000000..9538ead0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-30.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-31.dat b/plot-test/plot/tests/test-data/eb2d-31.dat new file mode 100644 index 00000000..fa3196d0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-31.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-31.png b/plot-test/plot/tests/test-data/eb2d-31.png new file mode 100644 index 00000000..f625d83b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-31.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-32.dat b/plot-test/plot/tests/test-data/eb2d-32.dat new file mode 100644 index 00000000..5363e44c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-32.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-32.png b/plot-test/plot/tests/test-data/eb2d-32.png new file mode 100644 index 00000000..36f3571e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-32.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-33.dat b/plot-test/plot/tests/test-data/eb2d-33.dat new file mode 100644 index 00000000..a9f022b8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-33.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-33.png b/plot-test/plot/tests/test-data/eb2d-33.png new file mode 100644 index 00000000..328a2a28 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-33.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-34.dat b/plot-test/plot/tests/test-data/eb2d-34.dat new file mode 100644 index 00000000..a8a12b1f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-34.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-34.png b/plot-test/plot/tests/test-data/eb2d-34.png new file mode 100644 index 00000000..e0f5516a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-34.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-35.dat b/plot-test/plot/tests/test-data/eb2d-35.dat new file mode 100644 index 00000000..5e8aab35 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-35.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-35.png b/plot-test/plot/tests/test-data/eb2d-35.png new file mode 100644 index 00000000..9e28dee9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-35.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-36.dat b/plot-test/plot/tests/test-data/eb2d-36.dat new file mode 100644 index 00000000..c620a400 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-36.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-36.png b/plot-test/plot/tests/test-data/eb2d-36.png new file mode 100644 index 00000000..15aa933e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-36.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-4.dat b/plot-test/plot/tests/test-data/eb2d-4.dat new file mode 100644 index 00000000..5fc32e76 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-4.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-4.png b/plot-test/plot/tests/test-data/eb2d-4.png new file mode 100644 index 00000000..7c5503d3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-4.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-5.dat b/plot-test/plot/tests/test-data/eb2d-5.dat new file mode 100644 index 00000000..2a56abc5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-5.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-5.png b/plot-test/plot/tests/test-data/eb2d-5.png new file mode 100644 index 00000000..6606f974 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-5.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-6.dat b/plot-test/plot/tests/test-data/eb2d-6.dat new file mode 100644 index 00000000..fb9ca82f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-6.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-6.png b/plot-test/plot/tests/test-data/eb2d-6.png new file mode 100644 index 00000000..1b1e217b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-6.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-7.dat b/plot-test/plot/tests/test-data/eb2d-7.dat new file mode 100644 index 00000000..8affb80a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-7.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-7.png b/plot-test/plot/tests/test-data/eb2d-7.png new file mode 100644 index 00000000..2965bea2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-7.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-8.dat b/plot-test/plot/tests/test-data/eb2d-8.dat new file mode 100644 index 00000000..d85368ee Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-8.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-8.png b/plot-test/plot/tests/test-data/eb2d-8.png new file mode 100644 index 00000000..b2257dc5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-8.png differ diff --git a/plot-test/plot/tests/test-data/eb2d-9.dat b/plot-test/plot/tests/test-data/eb2d-9.dat new file mode 100644 index 00000000..7eb444fb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-9.dat differ diff --git a/plot-test/plot/tests/test-data/eb2d-9.png b/plot-test/plot/tests/test-data/eb2d-9.png new file mode 100644 index 00000000..43e90045 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb2d-9.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-1.dat b/plot-test/plot/tests/test-data/eb3d-1.dat new file mode 100644 index 00000000..38e411b3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-1.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-1.png b/plot-test/plot/tests/test-data/eb3d-1.png new file mode 100644 index 00000000..0f9d6d5b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-1.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-10.dat b/plot-test/plot/tests/test-data/eb3d-10.dat new file mode 100644 index 00000000..a9f82f3e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-10.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-10.png b/plot-test/plot/tests/test-data/eb3d-10.png new file mode 100644 index 00000000..378e400c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-10.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-100.dat b/plot-test/plot/tests/test-data/eb3d-100.dat new file mode 100644 index 00000000..aacb4f54 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-100.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-100.png b/plot-test/plot/tests/test-data/eb3d-100.png new file mode 100644 index 00000000..dba30b52 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-100.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-101.dat b/plot-test/plot/tests/test-data/eb3d-101.dat new file mode 100644 index 00000000..2dbd76af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-101.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-101.png b/plot-test/plot/tests/test-data/eb3d-101.png new file mode 100644 index 00000000..68b98ae8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-101.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-102.dat b/plot-test/plot/tests/test-data/eb3d-102.dat new file mode 100644 index 00000000..cfc7ad10 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-102.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-102.png b/plot-test/plot/tests/test-data/eb3d-102.png new file mode 100644 index 00000000..daab2901 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-102.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-103.dat b/plot-test/plot/tests/test-data/eb3d-103.dat new file mode 100644 index 00000000..d613857e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-103.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-103.png b/plot-test/plot/tests/test-data/eb3d-103.png new file mode 100644 index 00000000..8b572e00 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-103.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-104.dat b/plot-test/plot/tests/test-data/eb3d-104.dat new file mode 100644 index 00000000..6b25c658 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-104.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-104.png b/plot-test/plot/tests/test-data/eb3d-104.png new file mode 100644 index 00000000..131ee3e3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-104.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-105.dat b/plot-test/plot/tests/test-data/eb3d-105.dat new file mode 100644 index 00000000..ad406fa1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-105.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-105.png b/plot-test/plot/tests/test-data/eb3d-105.png new file mode 100644 index 00000000..b5eccdd1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-105.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-106.dat b/plot-test/plot/tests/test-data/eb3d-106.dat new file mode 100644 index 00000000..3077b22b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-106.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-106.png b/plot-test/plot/tests/test-data/eb3d-106.png new file mode 100644 index 00000000..8db4249d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-106.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-107.dat b/plot-test/plot/tests/test-data/eb3d-107.dat new file mode 100644 index 00000000..4f3b1205 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-107.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-107.png b/plot-test/plot/tests/test-data/eb3d-107.png new file mode 100644 index 00000000..b64229b2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-107.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-108.dat b/plot-test/plot/tests/test-data/eb3d-108.dat new file mode 100644 index 00000000..b1231f8d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-108.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-108.png b/plot-test/plot/tests/test-data/eb3d-108.png new file mode 100644 index 00000000..549801ee Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-108.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-109.dat b/plot-test/plot/tests/test-data/eb3d-109.dat new file mode 100644 index 00000000..c0a5330b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-109.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-109.png b/plot-test/plot/tests/test-data/eb3d-109.png new file mode 100644 index 00000000..89437dfa Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-109.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-11.dat b/plot-test/plot/tests/test-data/eb3d-11.dat new file mode 100644 index 00000000..743910c7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-11.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-11.png b/plot-test/plot/tests/test-data/eb3d-11.png new file mode 100644 index 00000000..6980189a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-11.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-110.dat b/plot-test/plot/tests/test-data/eb3d-110.dat new file mode 100644 index 00000000..25384727 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-110.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-110.png b/plot-test/plot/tests/test-data/eb3d-110.png new file mode 100644 index 00000000..594bc50b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-110.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-111.dat b/plot-test/plot/tests/test-data/eb3d-111.dat new file mode 100644 index 00000000..9f88c6b8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-111.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-111.png b/plot-test/plot/tests/test-data/eb3d-111.png new file mode 100644 index 00000000..51569adb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-111.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-112.dat b/plot-test/plot/tests/test-data/eb3d-112.dat new file mode 100644 index 00000000..5b4bea31 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-112.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-112.png b/plot-test/plot/tests/test-data/eb3d-112.png new file mode 100644 index 00000000..d690a24f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-112.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-113.dat b/plot-test/plot/tests/test-data/eb3d-113.dat new file mode 100644 index 00000000..4105a38d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-113.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-113.png b/plot-test/plot/tests/test-data/eb3d-113.png new file mode 100644 index 00000000..7afcf1d5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-113.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-114.dat b/plot-test/plot/tests/test-data/eb3d-114.dat new file mode 100644 index 00000000..41a8c3af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-114.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-114.png b/plot-test/plot/tests/test-data/eb3d-114.png new file mode 100644 index 00000000..10649252 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-114.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-115.dat b/plot-test/plot/tests/test-data/eb3d-115.dat new file mode 100644 index 00000000..6f462552 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-115.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-115.png b/plot-test/plot/tests/test-data/eb3d-115.png new file mode 100644 index 00000000..20e16d80 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-115.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-116.dat b/plot-test/plot/tests/test-data/eb3d-116.dat new file mode 100644 index 00000000..344b411b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-116.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-116.png b/plot-test/plot/tests/test-data/eb3d-116.png new file mode 100644 index 00000000..0b6e1e8d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-116.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-117.dat b/plot-test/plot/tests/test-data/eb3d-117.dat new file mode 100644 index 00000000..28abc912 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-117.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-117.png b/plot-test/plot/tests/test-data/eb3d-117.png new file mode 100644 index 00000000..380d9841 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-117.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-118.dat b/plot-test/plot/tests/test-data/eb3d-118.dat new file mode 100644 index 00000000..40709816 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-118.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-118.png b/plot-test/plot/tests/test-data/eb3d-118.png new file mode 100644 index 00000000..d6a1b0c2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-118.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-119.dat b/plot-test/plot/tests/test-data/eb3d-119.dat new file mode 100644 index 00000000..036f5743 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-119.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-119.png b/plot-test/plot/tests/test-data/eb3d-119.png new file mode 100644 index 00000000..f701229d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-119.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-12.dat b/plot-test/plot/tests/test-data/eb3d-12.dat new file mode 100644 index 00000000..5de60800 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-12.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-12.png b/plot-test/plot/tests/test-data/eb3d-12.png new file mode 100644 index 00000000..5b728756 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-12.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-120.dat b/plot-test/plot/tests/test-data/eb3d-120.dat new file mode 100644 index 00000000..0be57282 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-120.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-120.png b/plot-test/plot/tests/test-data/eb3d-120.png new file mode 100644 index 00000000..de116b8f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-120.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-121.dat b/plot-test/plot/tests/test-data/eb3d-121.dat new file mode 100644 index 00000000..6bf488b0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-121.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-121.png b/plot-test/plot/tests/test-data/eb3d-121.png new file mode 100644 index 00000000..fd419627 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-121.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-122.dat b/plot-test/plot/tests/test-data/eb3d-122.dat new file mode 100644 index 00000000..6bfaa512 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-122.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-122.png b/plot-test/plot/tests/test-data/eb3d-122.png new file mode 100644 index 00000000..375ad574 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-122.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-123.dat b/plot-test/plot/tests/test-data/eb3d-123.dat new file mode 100644 index 00000000..c5a72f7d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-123.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-123.png b/plot-test/plot/tests/test-data/eb3d-123.png new file mode 100644 index 00000000..4eb725bf Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-123.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-124.dat b/plot-test/plot/tests/test-data/eb3d-124.dat new file mode 100644 index 00000000..99051d1a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-124.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-124.png b/plot-test/plot/tests/test-data/eb3d-124.png new file mode 100644 index 00000000..a75b7886 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-124.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-125.dat b/plot-test/plot/tests/test-data/eb3d-125.dat new file mode 100644 index 00000000..c5bb6d34 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-125.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-125.png b/plot-test/plot/tests/test-data/eb3d-125.png new file mode 100644 index 00000000..861e996f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-125.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-126.dat b/plot-test/plot/tests/test-data/eb3d-126.dat new file mode 100644 index 00000000..3aceb3ef Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-126.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-126.png b/plot-test/plot/tests/test-data/eb3d-126.png new file mode 100644 index 00000000..360393ce Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-126.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-127.dat b/plot-test/plot/tests/test-data/eb3d-127.dat new file mode 100644 index 00000000..460f7681 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-127.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-127.png b/plot-test/plot/tests/test-data/eb3d-127.png new file mode 100644 index 00000000..045516e5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-127.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-128.dat b/plot-test/plot/tests/test-data/eb3d-128.dat new file mode 100644 index 00000000..4d7045ef Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-128.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-128.png b/plot-test/plot/tests/test-data/eb3d-128.png new file mode 100644 index 00000000..5d7348af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-128.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-129.dat b/plot-test/plot/tests/test-data/eb3d-129.dat new file mode 100644 index 00000000..f159e60d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-129.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-129.png b/plot-test/plot/tests/test-data/eb3d-129.png new file mode 100644 index 00000000..cad2c492 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-129.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-13.dat b/plot-test/plot/tests/test-data/eb3d-13.dat new file mode 100644 index 00000000..8271a503 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-13.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-13.png b/plot-test/plot/tests/test-data/eb3d-13.png new file mode 100644 index 00000000..dfbb2cd6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-13.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-130.dat b/plot-test/plot/tests/test-data/eb3d-130.dat new file mode 100644 index 00000000..cd71c57c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-130.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-130.png b/plot-test/plot/tests/test-data/eb3d-130.png new file mode 100644 index 00000000..1df55f36 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-130.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-131.dat b/plot-test/plot/tests/test-data/eb3d-131.dat new file mode 100644 index 00000000..9ad64b2b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-131.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-131.png b/plot-test/plot/tests/test-data/eb3d-131.png new file mode 100644 index 00000000..af43f5af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-131.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-132.dat b/plot-test/plot/tests/test-data/eb3d-132.dat new file mode 100644 index 00000000..d2c0c718 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-132.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-132.png b/plot-test/plot/tests/test-data/eb3d-132.png new file mode 100644 index 00000000..8757db4f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-132.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-133.dat b/plot-test/plot/tests/test-data/eb3d-133.dat new file mode 100644 index 00000000..94d4419e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-133.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-133.png b/plot-test/plot/tests/test-data/eb3d-133.png new file mode 100644 index 00000000..42a00a8f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-133.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-134.dat b/plot-test/plot/tests/test-data/eb3d-134.dat new file mode 100644 index 00000000..1329fa0b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-134.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-134.png b/plot-test/plot/tests/test-data/eb3d-134.png new file mode 100644 index 00000000..5f3db45b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-134.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-135.dat b/plot-test/plot/tests/test-data/eb3d-135.dat new file mode 100644 index 00000000..0ad05542 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-135.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-135.png b/plot-test/plot/tests/test-data/eb3d-135.png new file mode 100644 index 00000000..25a9eee8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-135.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-136.dat b/plot-test/plot/tests/test-data/eb3d-136.dat new file mode 100644 index 00000000..773f0458 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-136.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-136.png b/plot-test/plot/tests/test-data/eb3d-136.png new file mode 100644 index 00000000..b418f290 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-136.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-137.dat b/plot-test/plot/tests/test-data/eb3d-137.dat new file mode 100644 index 00000000..629539dc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-137.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-137.png b/plot-test/plot/tests/test-data/eb3d-137.png new file mode 100644 index 00000000..63ee1fb5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-137.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-138.dat b/plot-test/plot/tests/test-data/eb3d-138.dat new file mode 100644 index 00000000..6748af3f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-138.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-138.png b/plot-test/plot/tests/test-data/eb3d-138.png new file mode 100644 index 00000000..5284b663 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-138.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-139.dat b/plot-test/plot/tests/test-data/eb3d-139.dat new file mode 100644 index 00000000..c4c62a1e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-139.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-139.png b/plot-test/plot/tests/test-data/eb3d-139.png new file mode 100644 index 00000000..b22d1034 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-139.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-14.dat b/plot-test/plot/tests/test-data/eb3d-14.dat new file mode 100644 index 00000000..d8741a3e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-14.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-14.png b/plot-test/plot/tests/test-data/eb3d-14.png new file mode 100644 index 00000000..a684e01c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-14.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-140.dat b/plot-test/plot/tests/test-data/eb3d-140.dat new file mode 100644 index 00000000..00112f0e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-140.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-140.png b/plot-test/plot/tests/test-data/eb3d-140.png new file mode 100644 index 00000000..d5486da9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-140.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-141.dat b/plot-test/plot/tests/test-data/eb3d-141.dat new file mode 100644 index 00000000..54f1b0dc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-141.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-141.png b/plot-test/plot/tests/test-data/eb3d-141.png new file mode 100644 index 00000000..07e6305f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-141.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-142.dat b/plot-test/plot/tests/test-data/eb3d-142.dat new file mode 100644 index 00000000..299cf688 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-142.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-142.png b/plot-test/plot/tests/test-data/eb3d-142.png new file mode 100644 index 00000000..a8c519bd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-142.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-143.dat b/plot-test/plot/tests/test-data/eb3d-143.dat new file mode 100644 index 00000000..f1030027 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-143.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-143.png b/plot-test/plot/tests/test-data/eb3d-143.png new file mode 100644 index 00000000..aa3e1df2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-143.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-144.dat b/plot-test/plot/tests/test-data/eb3d-144.dat new file mode 100644 index 00000000..1d6d740c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-144.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-144.png b/plot-test/plot/tests/test-data/eb3d-144.png new file mode 100644 index 00000000..ddc22216 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-144.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-145.dat b/plot-test/plot/tests/test-data/eb3d-145.dat new file mode 100644 index 00000000..5a6cd8fb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-145.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-145.png b/plot-test/plot/tests/test-data/eb3d-145.png new file mode 100644 index 00000000..22ea54dc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-145.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-146.dat b/plot-test/plot/tests/test-data/eb3d-146.dat new file mode 100644 index 00000000..d98036db Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-146.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-146.png b/plot-test/plot/tests/test-data/eb3d-146.png new file mode 100644 index 00000000..d922daac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-146.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-147.dat b/plot-test/plot/tests/test-data/eb3d-147.dat new file mode 100644 index 00000000..d9520d34 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-147.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-147.png b/plot-test/plot/tests/test-data/eb3d-147.png new file mode 100644 index 00000000..ae4ebaee Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-147.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-148.dat b/plot-test/plot/tests/test-data/eb3d-148.dat new file mode 100644 index 00000000..cf665b20 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-148.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-148.png b/plot-test/plot/tests/test-data/eb3d-148.png new file mode 100644 index 00000000..fb53046e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-148.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-149.dat b/plot-test/plot/tests/test-data/eb3d-149.dat new file mode 100644 index 00000000..012be603 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-149.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-149.png b/plot-test/plot/tests/test-data/eb3d-149.png new file mode 100644 index 00000000..b9ac3873 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-149.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-15.dat b/plot-test/plot/tests/test-data/eb3d-15.dat new file mode 100644 index 00000000..52f87e1f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-15.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-15.png b/plot-test/plot/tests/test-data/eb3d-15.png new file mode 100644 index 00000000..e7612ec0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-15.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-150.dat b/plot-test/plot/tests/test-data/eb3d-150.dat new file mode 100644 index 00000000..ff5d0861 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-150.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-150.png b/plot-test/plot/tests/test-data/eb3d-150.png new file mode 100644 index 00000000..6a484f62 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-150.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-151.dat b/plot-test/plot/tests/test-data/eb3d-151.dat new file mode 100644 index 00000000..cf4f550c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-151.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-151.png b/plot-test/plot/tests/test-data/eb3d-151.png new file mode 100644 index 00000000..ff703f07 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-151.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-152.dat b/plot-test/plot/tests/test-data/eb3d-152.dat new file mode 100644 index 00000000..8ec9128a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-152.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-152.png b/plot-test/plot/tests/test-data/eb3d-152.png new file mode 100644 index 00000000..7000322f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-152.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-153.dat b/plot-test/plot/tests/test-data/eb3d-153.dat new file mode 100644 index 00000000..e2c18342 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-153.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-153.png b/plot-test/plot/tests/test-data/eb3d-153.png new file mode 100644 index 00000000..1b2408f7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-153.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-154.dat b/plot-test/plot/tests/test-data/eb3d-154.dat new file mode 100644 index 00000000..318240ed Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-154.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-154.png b/plot-test/plot/tests/test-data/eb3d-154.png new file mode 100644 index 00000000..b92ff529 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-154.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-155.dat b/plot-test/plot/tests/test-data/eb3d-155.dat new file mode 100644 index 00000000..812acb29 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-155.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-155.png b/plot-test/plot/tests/test-data/eb3d-155.png new file mode 100644 index 00000000..d612243a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-155.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-156.dat b/plot-test/plot/tests/test-data/eb3d-156.dat new file mode 100644 index 00000000..ec62f28a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-156.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-156.png b/plot-test/plot/tests/test-data/eb3d-156.png new file mode 100644 index 00000000..da6c3544 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-156.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-157.dat b/plot-test/plot/tests/test-data/eb3d-157.dat new file mode 100644 index 00000000..f79713f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-157.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-157.png b/plot-test/plot/tests/test-data/eb3d-157.png new file mode 100644 index 00000000..55b104e4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-157.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-158.dat b/plot-test/plot/tests/test-data/eb3d-158.dat new file mode 100644 index 00000000..23030caa Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-158.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-158.png b/plot-test/plot/tests/test-data/eb3d-158.png new file mode 100644 index 00000000..45180942 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-158.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-159.dat b/plot-test/plot/tests/test-data/eb3d-159.dat new file mode 100644 index 00000000..20e650a6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-159.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-159.png b/plot-test/plot/tests/test-data/eb3d-159.png new file mode 100644 index 00000000..7ba57f24 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-159.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-16.dat b/plot-test/plot/tests/test-data/eb3d-16.dat new file mode 100644 index 00000000..3b4a8617 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-16.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-16.png b/plot-test/plot/tests/test-data/eb3d-16.png new file mode 100644 index 00000000..fc3771bc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-16.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-160.dat b/plot-test/plot/tests/test-data/eb3d-160.dat new file mode 100644 index 00000000..4250b02e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-160.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-160.png b/plot-test/plot/tests/test-data/eb3d-160.png new file mode 100644 index 00000000..e20cce4d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-160.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-161.dat b/plot-test/plot/tests/test-data/eb3d-161.dat new file mode 100644 index 00000000..ac8eacb2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-161.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-161.png b/plot-test/plot/tests/test-data/eb3d-161.png new file mode 100644 index 00000000..f8dd3293 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-161.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-162.dat b/plot-test/plot/tests/test-data/eb3d-162.dat new file mode 100644 index 00000000..3ffa1f7e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-162.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-162.png b/plot-test/plot/tests/test-data/eb3d-162.png new file mode 100644 index 00000000..481c72ac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-162.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-163.dat b/plot-test/plot/tests/test-data/eb3d-163.dat new file mode 100644 index 00000000..252f602a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-163.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-163.png b/plot-test/plot/tests/test-data/eb3d-163.png new file mode 100644 index 00000000..6bd60620 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-163.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-164.dat b/plot-test/plot/tests/test-data/eb3d-164.dat new file mode 100644 index 00000000..b4689012 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-164.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-164.png b/plot-test/plot/tests/test-data/eb3d-164.png new file mode 100644 index 00000000..15ffda29 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-164.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-165.dat b/plot-test/plot/tests/test-data/eb3d-165.dat new file mode 100644 index 00000000..5e5bc040 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-165.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-165.png b/plot-test/plot/tests/test-data/eb3d-165.png new file mode 100644 index 00000000..2720bf2a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-165.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-166.dat b/plot-test/plot/tests/test-data/eb3d-166.dat new file mode 100644 index 00000000..822be1d2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-166.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-166.png b/plot-test/plot/tests/test-data/eb3d-166.png new file mode 100644 index 00000000..ae332997 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-166.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-167.dat b/plot-test/plot/tests/test-data/eb3d-167.dat new file mode 100644 index 00000000..23e0238f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-167.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-167.png b/plot-test/plot/tests/test-data/eb3d-167.png new file mode 100644 index 00000000..dd2fc7dd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-167.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-168.dat b/plot-test/plot/tests/test-data/eb3d-168.dat new file mode 100644 index 00000000..d599e4f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-168.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-168.png b/plot-test/plot/tests/test-data/eb3d-168.png new file mode 100644 index 00000000..5487c5c8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-168.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-169.dat b/plot-test/plot/tests/test-data/eb3d-169.dat new file mode 100644 index 00000000..cf52b6b0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-169.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-169.png b/plot-test/plot/tests/test-data/eb3d-169.png new file mode 100644 index 00000000..5d76e064 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-169.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-17.dat b/plot-test/plot/tests/test-data/eb3d-17.dat new file mode 100644 index 00000000..c9b0b7b4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-17.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-17.png b/plot-test/plot/tests/test-data/eb3d-17.png new file mode 100644 index 00000000..3acfda38 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-17.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-170.dat b/plot-test/plot/tests/test-data/eb3d-170.dat new file mode 100644 index 00000000..bbcc13f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-170.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-170.png b/plot-test/plot/tests/test-data/eb3d-170.png new file mode 100644 index 00000000..fd27eaec Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-170.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-171.dat b/plot-test/plot/tests/test-data/eb3d-171.dat new file mode 100644 index 00000000..3488b390 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-171.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-171.png b/plot-test/plot/tests/test-data/eb3d-171.png new file mode 100644 index 00000000..63e1c972 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-171.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-172.dat b/plot-test/plot/tests/test-data/eb3d-172.dat new file mode 100644 index 00000000..c3d93b01 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-172.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-172.png b/plot-test/plot/tests/test-data/eb3d-172.png new file mode 100644 index 00000000..a355e7af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-172.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-173.dat b/plot-test/plot/tests/test-data/eb3d-173.dat new file mode 100644 index 00000000..fe200fe1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-173.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-173.png b/plot-test/plot/tests/test-data/eb3d-173.png new file mode 100644 index 00000000..c57a6721 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-173.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-174.dat b/plot-test/plot/tests/test-data/eb3d-174.dat new file mode 100644 index 00000000..448f45e2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-174.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-174.png b/plot-test/plot/tests/test-data/eb3d-174.png new file mode 100644 index 00000000..00d82251 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-174.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-175.dat b/plot-test/plot/tests/test-data/eb3d-175.dat new file mode 100644 index 00000000..075cb480 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-175.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-175.png b/plot-test/plot/tests/test-data/eb3d-175.png new file mode 100644 index 00000000..7726ecb7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-175.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-176.dat b/plot-test/plot/tests/test-data/eb3d-176.dat new file mode 100644 index 00000000..12be748e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-176.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-176.png b/plot-test/plot/tests/test-data/eb3d-176.png new file mode 100644 index 00000000..01e718b9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-176.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-177.dat b/plot-test/plot/tests/test-data/eb3d-177.dat new file mode 100644 index 00000000..bd5a9255 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-177.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-177.png b/plot-test/plot/tests/test-data/eb3d-177.png new file mode 100644 index 00000000..4b9a75ab Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-177.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-178.dat b/plot-test/plot/tests/test-data/eb3d-178.dat new file mode 100644 index 00000000..932aff5a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-178.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-178.png b/plot-test/plot/tests/test-data/eb3d-178.png new file mode 100644 index 00000000..e3d052e4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-178.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-179.dat b/plot-test/plot/tests/test-data/eb3d-179.dat new file mode 100644 index 00000000..32418b98 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-179.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-179.png b/plot-test/plot/tests/test-data/eb3d-179.png new file mode 100644 index 00000000..65895355 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-179.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-18.dat b/plot-test/plot/tests/test-data/eb3d-18.dat new file mode 100644 index 00000000..82239f4a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-18.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-18.png b/plot-test/plot/tests/test-data/eb3d-18.png new file mode 100644 index 00000000..fa272f64 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-18.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-180.dat b/plot-test/plot/tests/test-data/eb3d-180.dat new file mode 100644 index 00000000..0fcc457f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-180.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-180.png b/plot-test/plot/tests/test-data/eb3d-180.png new file mode 100644 index 00000000..6eb3dc5a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-180.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-181.dat b/plot-test/plot/tests/test-data/eb3d-181.dat new file mode 100644 index 00000000..cacdb5be Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-181.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-181.png b/plot-test/plot/tests/test-data/eb3d-181.png new file mode 100644 index 00000000..be9b0fac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-181.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-182.dat b/plot-test/plot/tests/test-data/eb3d-182.dat new file mode 100644 index 00000000..2cc34ee4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-182.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-182.png b/plot-test/plot/tests/test-data/eb3d-182.png new file mode 100644 index 00000000..03c20698 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-182.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-183.dat b/plot-test/plot/tests/test-data/eb3d-183.dat new file mode 100644 index 00000000..9033e137 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-183.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-183.png b/plot-test/plot/tests/test-data/eb3d-183.png new file mode 100644 index 00000000..105426bd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-183.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-184.dat b/plot-test/plot/tests/test-data/eb3d-184.dat new file mode 100644 index 00000000..df7361a9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-184.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-184.png b/plot-test/plot/tests/test-data/eb3d-184.png new file mode 100644 index 00000000..086d3f24 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-184.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-185.dat b/plot-test/plot/tests/test-data/eb3d-185.dat new file mode 100644 index 00000000..8a795364 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-185.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-185.png b/plot-test/plot/tests/test-data/eb3d-185.png new file mode 100644 index 00000000..d225b9e6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-185.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-186.dat b/plot-test/plot/tests/test-data/eb3d-186.dat new file mode 100644 index 00000000..58236e69 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-186.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-186.png b/plot-test/plot/tests/test-data/eb3d-186.png new file mode 100644 index 00000000..a30a28fb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-186.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-187.dat b/plot-test/plot/tests/test-data/eb3d-187.dat new file mode 100644 index 00000000..0ef76b34 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-187.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-187.png b/plot-test/plot/tests/test-data/eb3d-187.png new file mode 100644 index 00000000..d14f04f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-187.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-188.dat b/plot-test/plot/tests/test-data/eb3d-188.dat new file mode 100644 index 00000000..a61f4f44 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-188.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-188.png b/plot-test/plot/tests/test-data/eb3d-188.png new file mode 100644 index 00000000..d58b25bd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-188.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-189.dat b/plot-test/plot/tests/test-data/eb3d-189.dat new file mode 100644 index 00000000..1f310a13 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-189.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-189.png b/plot-test/plot/tests/test-data/eb3d-189.png new file mode 100644 index 00000000..27a89475 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-189.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-19.dat b/plot-test/plot/tests/test-data/eb3d-19.dat new file mode 100644 index 00000000..35998c97 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-19.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-19.png b/plot-test/plot/tests/test-data/eb3d-19.png new file mode 100644 index 00000000..02fe65ac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-19.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-190.dat b/plot-test/plot/tests/test-data/eb3d-190.dat new file mode 100644 index 00000000..b6766aef Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-190.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-190.png b/plot-test/plot/tests/test-data/eb3d-190.png new file mode 100644 index 00000000..0714816b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-190.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-191.dat b/plot-test/plot/tests/test-data/eb3d-191.dat new file mode 100644 index 00000000..9b15081a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-191.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-191.png b/plot-test/plot/tests/test-data/eb3d-191.png new file mode 100644 index 00000000..9f59d5d4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-191.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-192.dat b/plot-test/plot/tests/test-data/eb3d-192.dat new file mode 100644 index 00000000..8882489f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-192.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-192.png b/plot-test/plot/tests/test-data/eb3d-192.png new file mode 100644 index 00000000..1f9b1de6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-192.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-193.dat b/plot-test/plot/tests/test-data/eb3d-193.dat new file mode 100644 index 00000000..59b22d51 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-193.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-193.png b/plot-test/plot/tests/test-data/eb3d-193.png new file mode 100644 index 00000000..5656089d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-193.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-194.dat b/plot-test/plot/tests/test-data/eb3d-194.dat new file mode 100644 index 00000000..49e65775 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-194.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-194.png b/plot-test/plot/tests/test-data/eb3d-194.png new file mode 100644 index 00000000..a807a414 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-194.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-195.dat b/plot-test/plot/tests/test-data/eb3d-195.dat new file mode 100644 index 00000000..4329bc37 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-195.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-195.png b/plot-test/plot/tests/test-data/eb3d-195.png new file mode 100644 index 00000000..04ed2bdf Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-195.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-196.dat b/plot-test/plot/tests/test-data/eb3d-196.dat new file mode 100644 index 00000000..f3269bb1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-196.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-196.png b/plot-test/plot/tests/test-data/eb3d-196.png new file mode 100644 index 00000000..267d9d70 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-196.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-197.dat b/plot-test/plot/tests/test-data/eb3d-197.dat new file mode 100644 index 00000000..c703c608 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-197.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-197.png b/plot-test/plot/tests/test-data/eb3d-197.png new file mode 100644 index 00000000..6eb8c098 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-197.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-198.dat b/plot-test/plot/tests/test-data/eb3d-198.dat new file mode 100644 index 00000000..d62f76d3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-198.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-198.png b/plot-test/plot/tests/test-data/eb3d-198.png new file mode 100644 index 00000000..2f95f006 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-198.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-199.dat b/plot-test/plot/tests/test-data/eb3d-199.dat new file mode 100644 index 00000000..9e72da0c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-199.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-199.png b/plot-test/plot/tests/test-data/eb3d-199.png new file mode 100644 index 00000000..8ad94ae1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-199.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-2.dat b/plot-test/plot/tests/test-data/eb3d-2.dat new file mode 100644 index 00000000..eb95f2c1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-2.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-2.png b/plot-test/plot/tests/test-data/eb3d-2.png new file mode 100644 index 00000000..91b61dd3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-2.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-20.dat b/plot-test/plot/tests/test-data/eb3d-20.dat new file mode 100644 index 00000000..1318fcc8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-20.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-20.png b/plot-test/plot/tests/test-data/eb3d-20.png new file mode 100644 index 00000000..018e137d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-20.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-200.dat b/plot-test/plot/tests/test-data/eb3d-200.dat new file mode 100644 index 00000000..c816c1f6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-200.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-200.png b/plot-test/plot/tests/test-data/eb3d-200.png new file mode 100644 index 00000000..2099bf08 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-200.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-201.dat b/plot-test/plot/tests/test-data/eb3d-201.dat new file mode 100644 index 00000000..cbad26c7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-201.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-201.png b/plot-test/plot/tests/test-data/eb3d-201.png new file mode 100644 index 00000000..a0e385f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-201.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-202.dat b/plot-test/plot/tests/test-data/eb3d-202.dat new file mode 100644 index 00000000..e5e13468 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-202.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-202.png b/plot-test/plot/tests/test-data/eb3d-202.png new file mode 100644 index 00000000..765cbcfe Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-202.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-203.dat b/plot-test/plot/tests/test-data/eb3d-203.dat new file mode 100644 index 00000000..3d5daafa Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-203.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-203.png b/plot-test/plot/tests/test-data/eb3d-203.png new file mode 100644 index 00000000..c8a16a35 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-203.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-204.dat b/plot-test/plot/tests/test-data/eb3d-204.dat new file mode 100644 index 00000000..32ae3c6f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-204.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-204.png b/plot-test/plot/tests/test-data/eb3d-204.png new file mode 100644 index 00000000..cef51e85 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-204.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-205.dat b/plot-test/plot/tests/test-data/eb3d-205.dat new file mode 100644 index 00000000..d0641680 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-205.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-205.png b/plot-test/plot/tests/test-data/eb3d-205.png new file mode 100644 index 00000000..a00dcd3f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-205.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-206.dat b/plot-test/plot/tests/test-data/eb3d-206.dat new file mode 100644 index 00000000..9a26ae0c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-206.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-206.png b/plot-test/plot/tests/test-data/eb3d-206.png new file mode 100644 index 00000000..a2d8c909 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-206.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-207.dat b/plot-test/plot/tests/test-data/eb3d-207.dat new file mode 100644 index 00000000..79af7ce3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-207.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-207.png b/plot-test/plot/tests/test-data/eb3d-207.png new file mode 100644 index 00000000..f874f335 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-207.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-208.dat b/plot-test/plot/tests/test-data/eb3d-208.dat new file mode 100644 index 00000000..05055883 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-208.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-208.png b/plot-test/plot/tests/test-data/eb3d-208.png new file mode 100644 index 00000000..972d8f2e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-208.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-209.dat b/plot-test/plot/tests/test-data/eb3d-209.dat new file mode 100644 index 00000000..c40abf3a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-209.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-209.png b/plot-test/plot/tests/test-data/eb3d-209.png new file mode 100644 index 00000000..5afabf57 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-209.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-21.dat b/plot-test/plot/tests/test-data/eb3d-21.dat new file mode 100644 index 00000000..ce8295fb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-21.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-21.png b/plot-test/plot/tests/test-data/eb3d-21.png new file mode 100644 index 00000000..f1f6295a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-21.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-210.dat b/plot-test/plot/tests/test-data/eb3d-210.dat new file mode 100644 index 00000000..02717b04 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-210.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-210.png b/plot-test/plot/tests/test-data/eb3d-210.png new file mode 100644 index 00000000..d9ec9a8c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-210.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-211.dat b/plot-test/plot/tests/test-data/eb3d-211.dat new file mode 100644 index 00000000..dfc39310 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-211.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-211.png b/plot-test/plot/tests/test-data/eb3d-211.png new file mode 100644 index 00000000..1b1f64bb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-211.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-212.dat b/plot-test/plot/tests/test-data/eb3d-212.dat new file mode 100644 index 00000000..5cde15b5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-212.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-212.png b/plot-test/plot/tests/test-data/eb3d-212.png new file mode 100644 index 00000000..8ea0e374 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-212.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-213.dat b/plot-test/plot/tests/test-data/eb3d-213.dat new file mode 100644 index 00000000..d35944cc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-213.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-213.png b/plot-test/plot/tests/test-data/eb3d-213.png new file mode 100644 index 00000000..ec5839da Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-213.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-214.dat b/plot-test/plot/tests/test-data/eb3d-214.dat new file mode 100644 index 00000000..c6a1cd38 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-214.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-214.png b/plot-test/plot/tests/test-data/eb3d-214.png new file mode 100644 index 00000000..9c145059 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-214.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-215.dat b/plot-test/plot/tests/test-data/eb3d-215.dat new file mode 100644 index 00000000..e47f0f1d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-215.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-215.png b/plot-test/plot/tests/test-data/eb3d-215.png new file mode 100644 index 00000000..72aaa20b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-215.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-216.dat b/plot-test/plot/tests/test-data/eb3d-216.dat new file mode 100644 index 00000000..c5fe4261 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-216.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-216.png b/plot-test/plot/tests/test-data/eb3d-216.png new file mode 100644 index 00000000..ce0f5be4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-216.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-22.dat b/plot-test/plot/tests/test-data/eb3d-22.dat new file mode 100644 index 00000000..b7692699 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-22.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-22.png b/plot-test/plot/tests/test-data/eb3d-22.png new file mode 100644 index 00000000..705f1262 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-22.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-23.dat b/plot-test/plot/tests/test-data/eb3d-23.dat new file mode 100644 index 00000000..fbeaac73 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-23.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-23.png b/plot-test/plot/tests/test-data/eb3d-23.png new file mode 100644 index 00000000..966f70a8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-23.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-24.dat b/plot-test/plot/tests/test-data/eb3d-24.dat new file mode 100644 index 00000000..f18a676a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-24.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-24.png b/plot-test/plot/tests/test-data/eb3d-24.png new file mode 100644 index 00000000..00682e06 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-24.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-25.dat b/plot-test/plot/tests/test-data/eb3d-25.dat new file mode 100644 index 00000000..b996b7d8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-25.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-25.png b/plot-test/plot/tests/test-data/eb3d-25.png new file mode 100644 index 00000000..cbe78d9a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-25.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-26.dat b/plot-test/plot/tests/test-data/eb3d-26.dat new file mode 100644 index 00000000..b6e4a46b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-26.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-26.png b/plot-test/plot/tests/test-data/eb3d-26.png new file mode 100644 index 00000000..63c665c2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-26.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-27.dat b/plot-test/plot/tests/test-data/eb3d-27.dat new file mode 100644 index 00000000..dc83d874 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-27.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-27.png b/plot-test/plot/tests/test-data/eb3d-27.png new file mode 100644 index 00000000..fed69170 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-27.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-28.dat b/plot-test/plot/tests/test-data/eb3d-28.dat new file mode 100644 index 00000000..2e504fae Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-28.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-28.png b/plot-test/plot/tests/test-data/eb3d-28.png new file mode 100644 index 00000000..94de850a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-28.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-29.dat b/plot-test/plot/tests/test-data/eb3d-29.dat new file mode 100644 index 00000000..2f8c1f26 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-29.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-29.png b/plot-test/plot/tests/test-data/eb3d-29.png new file mode 100644 index 00000000..39e8c9e2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-29.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-3.dat b/plot-test/plot/tests/test-data/eb3d-3.dat new file mode 100644 index 00000000..b41afe14 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-3.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-3.png b/plot-test/plot/tests/test-data/eb3d-3.png new file mode 100644 index 00000000..ac383b10 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-3.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-30.dat b/plot-test/plot/tests/test-data/eb3d-30.dat new file mode 100644 index 00000000..70e1b401 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-30.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-30.png b/plot-test/plot/tests/test-data/eb3d-30.png new file mode 100644 index 00000000..09382b93 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-30.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-31.dat b/plot-test/plot/tests/test-data/eb3d-31.dat new file mode 100644 index 00000000..f4504b24 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-31.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-31.png b/plot-test/plot/tests/test-data/eb3d-31.png new file mode 100644 index 00000000..446eee1a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-31.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-32.dat b/plot-test/plot/tests/test-data/eb3d-32.dat new file mode 100644 index 00000000..0b607a69 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-32.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-32.png b/plot-test/plot/tests/test-data/eb3d-32.png new file mode 100644 index 00000000..2d3ab897 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-32.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-33.dat b/plot-test/plot/tests/test-data/eb3d-33.dat new file mode 100644 index 00000000..bbd890bb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-33.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-33.png b/plot-test/plot/tests/test-data/eb3d-33.png new file mode 100644 index 00000000..b403c80d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-33.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-34.dat b/plot-test/plot/tests/test-data/eb3d-34.dat new file mode 100644 index 00000000..e3a0fef9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-34.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-34.png b/plot-test/plot/tests/test-data/eb3d-34.png new file mode 100644 index 00000000..e2549121 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-34.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-35.dat b/plot-test/plot/tests/test-data/eb3d-35.dat new file mode 100644 index 00000000..727b5e7b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-35.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-35.png b/plot-test/plot/tests/test-data/eb3d-35.png new file mode 100644 index 00000000..cbf18eac Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-35.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-36.dat b/plot-test/plot/tests/test-data/eb3d-36.dat new file mode 100644 index 00000000..95b323fc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-36.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-36.png b/plot-test/plot/tests/test-data/eb3d-36.png new file mode 100644 index 00000000..b4c12368 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-36.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-37.dat b/plot-test/plot/tests/test-data/eb3d-37.dat new file mode 100644 index 00000000..46f9e71c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-37.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-37.png b/plot-test/plot/tests/test-data/eb3d-37.png new file mode 100644 index 00000000..40ccf7b2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-37.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-38.dat b/plot-test/plot/tests/test-data/eb3d-38.dat new file mode 100644 index 00000000..e80c3490 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-38.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-38.png b/plot-test/plot/tests/test-data/eb3d-38.png new file mode 100644 index 00000000..3fbd78e9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-38.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-39.dat b/plot-test/plot/tests/test-data/eb3d-39.dat new file mode 100644 index 00000000..b1a3a5fd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-39.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-39.png b/plot-test/plot/tests/test-data/eb3d-39.png new file mode 100644 index 00000000..15889757 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-39.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-4.dat b/plot-test/plot/tests/test-data/eb3d-4.dat new file mode 100644 index 00000000..3d1a3544 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-4.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-4.png b/plot-test/plot/tests/test-data/eb3d-4.png new file mode 100644 index 00000000..ffdb391f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-4.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-40.dat b/plot-test/plot/tests/test-data/eb3d-40.dat new file mode 100644 index 00000000..77e49fce Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-40.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-40.png b/plot-test/plot/tests/test-data/eb3d-40.png new file mode 100644 index 00000000..72aec827 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-40.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-41.dat b/plot-test/plot/tests/test-data/eb3d-41.dat new file mode 100644 index 00000000..ddd616a6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-41.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-41.png b/plot-test/plot/tests/test-data/eb3d-41.png new file mode 100644 index 00000000..4f1062d9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-41.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-42.dat b/plot-test/plot/tests/test-data/eb3d-42.dat new file mode 100644 index 00000000..2e24fe1d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-42.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-42.png b/plot-test/plot/tests/test-data/eb3d-42.png new file mode 100644 index 00000000..7dcf474d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-42.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-43.dat b/plot-test/plot/tests/test-data/eb3d-43.dat new file mode 100644 index 00000000..efd431f9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-43.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-43.png b/plot-test/plot/tests/test-data/eb3d-43.png new file mode 100644 index 00000000..bb1ecfea Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-43.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-44.dat b/plot-test/plot/tests/test-data/eb3d-44.dat new file mode 100644 index 00000000..379f0431 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-44.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-44.png b/plot-test/plot/tests/test-data/eb3d-44.png new file mode 100644 index 00000000..86d52dd7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-44.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-45.dat b/plot-test/plot/tests/test-data/eb3d-45.dat new file mode 100644 index 00000000..be59b7a0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-45.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-45.png b/plot-test/plot/tests/test-data/eb3d-45.png new file mode 100644 index 00000000..0ea6e301 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-45.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-46.dat b/plot-test/plot/tests/test-data/eb3d-46.dat new file mode 100644 index 00000000..217ab7b4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-46.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-46.png b/plot-test/plot/tests/test-data/eb3d-46.png new file mode 100644 index 00000000..609871f0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-46.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-47.dat b/plot-test/plot/tests/test-data/eb3d-47.dat new file mode 100644 index 00000000..c3184082 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-47.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-47.png b/plot-test/plot/tests/test-data/eb3d-47.png new file mode 100644 index 00000000..79cc7f93 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-47.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-48.dat b/plot-test/plot/tests/test-data/eb3d-48.dat new file mode 100644 index 00000000..1c18d7cd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-48.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-48.png b/plot-test/plot/tests/test-data/eb3d-48.png new file mode 100644 index 00000000..ee70d597 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-48.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-49.dat b/plot-test/plot/tests/test-data/eb3d-49.dat new file mode 100644 index 00000000..0c34da92 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-49.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-49.png b/plot-test/plot/tests/test-data/eb3d-49.png new file mode 100644 index 00000000..ee04c2e3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-49.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-5.dat b/plot-test/plot/tests/test-data/eb3d-5.dat new file mode 100644 index 00000000..ab6a90ab Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-5.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-5.png b/plot-test/plot/tests/test-data/eb3d-5.png new file mode 100644 index 00000000..8e308e65 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-5.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-50.dat b/plot-test/plot/tests/test-data/eb3d-50.dat new file mode 100644 index 00000000..80ddd6c3 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-50.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-50.png b/plot-test/plot/tests/test-data/eb3d-50.png new file mode 100644 index 00000000..52d4912f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-50.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-51.dat b/plot-test/plot/tests/test-data/eb3d-51.dat new file mode 100644 index 00000000..de9e7370 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-51.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-51.png b/plot-test/plot/tests/test-data/eb3d-51.png new file mode 100644 index 00000000..96562635 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-51.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-52.dat b/plot-test/plot/tests/test-data/eb3d-52.dat new file mode 100644 index 00000000..405a515f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-52.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-52.png b/plot-test/plot/tests/test-data/eb3d-52.png new file mode 100644 index 00000000..efa1e74b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-52.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-53.dat b/plot-test/plot/tests/test-data/eb3d-53.dat new file mode 100644 index 00000000..0d810b71 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-53.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-53.png b/plot-test/plot/tests/test-data/eb3d-53.png new file mode 100644 index 00000000..d5ee6bb2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-53.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-54.dat b/plot-test/plot/tests/test-data/eb3d-54.dat new file mode 100644 index 00000000..e0dfb55c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-54.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-54.png b/plot-test/plot/tests/test-data/eb3d-54.png new file mode 100644 index 00000000..7001c9e6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-54.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-55.dat b/plot-test/plot/tests/test-data/eb3d-55.dat new file mode 100644 index 00000000..e948b617 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-55.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-55.png b/plot-test/plot/tests/test-data/eb3d-55.png new file mode 100644 index 00000000..3cf4afbd Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-55.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-56.dat b/plot-test/plot/tests/test-data/eb3d-56.dat new file mode 100644 index 00000000..f98bb981 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-56.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-56.png b/plot-test/plot/tests/test-data/eb3d-56.png new file mode 100644 index 00000000..b852e96d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-56.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-57.dat b/plot-test/plot/tests/test-data/eb3d-57.dat new file mode 100644 index 00000000..2545e1af Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-57.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-57.png b/plot-test/plot/tests/test-data/eb3d-57.png new file mode 100644 index 00000000..3866c178 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-57.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-58.dat b/plot-test/plot/tests/test-data/eb3d-58.dat new file mode 100644 index 00000000..8677a243 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-58.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-58.png b/plot-test/plot/tests/test-data/eb3d-58.png new file mode 100644 index 00000000..c5580c3f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-58.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-59.dat b/plot-test/plot/tests/test-data/eb3d-59.dat new file mode 100644 index 00000000..0ba9801c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-59.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-59.png b/plot-test/plot/tests/test-data/eb3d-59.png new file mode 100644 index 00000000..1389538e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-59.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-6.dat b/plot-test/plot/tests/test-data/eb3d-6.dat new file mode 100644 index 00000000..e43acaf8 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-6.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-6.png b/plot-test/plot/tests/test-data/eb3d-6.png new file mode 100644 index 00000000..96f18a95 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-6.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-60.dat b/plot-test/plot/tests/test-data/eb3d-60.dat new file mode 100644 index 00000000..5850db27 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-60.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-60.png b/plot-test/plot/tests/test-data/eb3d-60.png new file mode 100644 index 00000000..9bb98fb5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-60.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-61.dat b/plot-test/plot/tests/test-data/eb3d-61.dat new file mode 100644 index 00000000..805b637f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-61.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-61.png b/plot-test/plot/tests/test-data/eb3d-61.png new file mode 100644 index 00000000..8737f9d7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-61.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-62.dat b/plot-test/plot/tests/test-data/eb3d-62.dat new file mode 100644 index 00000000..9ed66d72 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-62.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-62.png b/plot-test/plot/tests/test-data/eb3d-62.png new file mode 100644 index 00000000..e33060de Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-62.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-63.dat b/plot-test/plot/tests/test-data/eb3d-63.dat new file mode 100644 index 00000000..b2d16fa6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-63.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-63.png b/plot-test/plot/tests/test-data/eb3d-63.png new file mode 100644 index 00000000..c613dfd7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-63.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-64.dat b/plot-test/plot/tests/test-data/eb3d-64.dat new file mode 100644 index 00000000..017281b4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-64.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-64.png b/plot-test/plot/tests/test-data/eb3d-64.png new file mode 100644 index 00000000..ea9f18a5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-64.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-65.dat b/plot-test/plot/tests/test-data/eb3d-65.dat new file mode 100644 index 00000000..0ae1645e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-65.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-65.png b/plot-test/plot/tests/test-data/eb3d-65.png new file mode 100644 index 00000000..254fd904 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-65.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-66.dat b/plot-test/plot/tests/test-data/eb3d-66.dat new file mode 100644 index 00000000..991be8c4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-66.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-66.png b/plot-test/plot/tests/test-data/eb3d-66.png new file mode 100644 index 00000000..c1494f5f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-66.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-67.dat b/plot-test/plot/tests/test-data/eb3d-67.dat new file mode 100644 index 00000000..5d2bf16c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-67.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-67.png b/plot-test/plot/tests/test-data/eb3d-67.png new file mode 100644 index 00000000..ac6608a4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-67.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-68.dat b/plot-test/plot/tests/test-data/eb3d-68.dat new file mode 100644 index 00000000..704c242a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-68.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-68.png b/plot-test/plot/tests/test-data/eb3d-68.png new file mode 100644 index 00000000..e8615dbe Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-68.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-69.dat b/plot-test/plot/tests/test-data/eb3d-69.dat new file mode 100644 index 00000000..35aebaf2 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-69.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-69.png b/plot-test/plot/tests/test-data/eb3d-69.png new file mode 100644 index 00000000..42b4ded0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-69.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-7.dat b/plot-test/plot/tests/test-data/eb3d-7.dat new file mode 100644 index 00000000..686dc582 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-7.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-7.png b/plot-test/plot/tests/test-data/eb3d-7.png new file mode 100644 index 00000000..e72f57b1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-7.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-70.dat b/plot-test/plot/tests/test-data/eb3d-70.dat new file mode 100644 index 00000000..3f2ff9f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-70.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-70.png b/plot-test/plot/tests/test-data/eb3d-70.png new file mode 100644 index 00000000..6a9859a9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-70.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-71.dat b/plot-test/plot/tests/test-data/eb3d-71.dat new file mode 100644 index 00000000..9d4ff637 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-71.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-71.png b/plot-test/plot/tests/test-data/eb3d-71.png new file mode 100644 index 00000000..1347bcc9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-71.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-72.dat b/plot-test/plot/tests/test-data/eb3d-72.dat new file mode 100644 index 00000000..e0dc2978 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-72.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-72.png b/plot-test/plot/tests/test-data/eb3d-72.png new file mode 100644 index 00000000..6ebfea76 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-72.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-73.dat b/plot-test/plot/tests/test-data/eb3d-73.dat new file mode 100644 index 00000000..5c6c69a9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-73.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-73.png b/plot-test/plot/tests/test-data/eb3d-73.png new file mode 100644 index 00000000..ef13d5e7 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-73.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-74.dat b/plot-test/plot/tests/test-data/eb3d-74.dat new file mode 100644 index 00000000..fbd9ecbe Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-74.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-74.png b/plot-test/plot/tests/test-data/eb3d-74.png new file mode 100644 index 00000000..1faeebd0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-74.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-75.dat b/plot-test/plot/tests/test-data/eb3d-75.dat new file mode 100644 index 00000000..465b0208 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-75.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-75.png b/plot-test/plot/tests/test-data/eb3d-75.png new file mode 100644 index 00000000..595406bb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-75.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-76.dat b/plot-test/plot/tests/test-data/eb3d-76.dat new file mode 100644 index 00000000..7f1e30eb Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-76.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-76.png b/plot-test/plot/tests/test-data/eb3d-76.png new file mode 100644 index 00000000..7b2e9733 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-76.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-77.dat b/plot-test/plot/tests/test-data/eb3d-77.dat new file mode 100644 index 00000000..7d3f877e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-77.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-77.png b/plot-test/plot/tests/test-data/eb3d-77.png new file mode 100644 index 00000000..10ccbc60 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-77.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-78.dat b/plot-test/plot/tests/test-data/eb3d-78.dat new file mode 100644 index 00000000..ede684ea Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-78.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-78.png b/plot-test/plot/tests/test-data/eb3d-78.png new file mode 100644 index 00000000..805cf1e4 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-78.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-79.dat b/plot-test/plot/tests/test-data/eb3d-79.dat new file mode 100644 index 00000000..20bc16ed Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-79.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-79.png b/plot-test/plot/tests/test-data/eb3d-79.png new file mode 100644 index 00000000..e1a5ca75 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-79.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-8.dat b/plot-test/plot/tests/test-data/eb3d-8.dat new file mode 100644 index 00000000..529307e1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-8.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-8.png b/plot-test/plot/tests/test-data/eb3d-8.png new file mode 100644 index 00000000..0f7287ef Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-8.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-80.dat b/plot-test/plot/tests/test-data/eb3d-80.dat new file mode 100644 index 00000000..4b8f2150 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-80.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-80.png b/plot-test/plot/tests/test-data/eb3d-80.png new file mode 100644 index 00000000..30c7ac66 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-80.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-81.dat b/plot-test/plot/tests/test-data/eb3d-81.dat new file mode 100644 index 00000000..be3e419f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-81.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-81.png b/plot-test/plot/tests/test-data/eb3d-81.png new file mode 100644 index 00000000..115ef6a1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-81.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-82.dat b/plot-test/plot/tests/test-data/eb3d-82.dat new file mode 100644 index 00000000..46f42bc6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-82.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-82.png b/plot-test/plot/tests/test-data/eb3d-82.png new file mode 100644 index 00000000..4392265c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-82.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-83.dat b/plot-test/plot/tests/test-data/eb3d-83.dat new file mode 100644 index 00000000..da8ab2ea Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-83.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-83.png b/plot-test/plot/tests/test-data/eb3d-83.png new file mode 100644 index 00000000..401fdc1e Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-83.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-84.dat b/plot-test/plot/tests/test-data/eb3d-84.dat new file mode 100644 index 00000000..d09227da Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-84.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-84.png b/plot-test/plot/tests/test-data/eb3d-84.png new file mode 100644 index 00000000..a1f4f4db Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-84.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-85.dat b/plot-test/plot/tests/test-data/eb3d-85.dat new file mode 100644 index 00000000..47290ae9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-85.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-85.png b/plot-test/plot/tests/test-data/eb3d-85.png new file mode 100644 index 00000000..091983e6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-85.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-86.dat b/plot-test/plot/tests/test-data/eb3d-86.dat new file mode 100644 index 00000000..c6bd0ad9 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-86.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-86.png b/plot-test/plot/tests/test-data/eb3d-86.png new file mode 100644 index 00000000..2f735184 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-86.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-87.dat b/plot-test/plot/tests/test-data/eb3d-87.dat new file mode 100644 index 00000000..d1e9ca7d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-87.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-87.png b/plot-test/plot/tests/test-data/eb3d-87.png new file mode 100644 index 00000000..bc96c21b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-87.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-88.dat b/plot-test/plot/tests/test-data/eb3d-88.dat new file mode 100644 index 00000000..ec76b503 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-88.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-88.png b/plot-test/plot/tests/test-data/eb3d-88.png new file mode 100644 index 00000000..2e538ebe Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-88.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-89.dat b/plot-test/plot/tests/test-data/eb3d-89.dat new file mode 100644 index 00000000..d5490043 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-89.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-89.png b/plot-test/plot/tests/test-data/eb3d-89.png new file mode 100644 index 00000000..5f677058 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-89.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-9.dat b/plot-test/plot/tests/test-data/eb3d-9.dat new file mode 100644 index 00000000..6c6a7dbf Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-9.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-9.png b/plot-test/plot/tests/test-data/eb3d-9.png new file mode 100644 index 00000000..58942ef0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-9.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-90.dat b/plot-test/plot/tests/test-data/eb3d-90.dat new file mode 100644 index 00000000..624b1420 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-90.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-90.png b/plot-test/plot/tests/test-data/eb3d-90.png new file mode 100644 index 00000000..260af692 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-90.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-91.dat b/plot-test/plot/tests/test-data/eb3d-91.dat new file mode 100644 index 00000000..e01b59ef Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-91.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-91.png b/plot-test/plot/tests/test-data/eb3d-91.png new file mode 100644 index 00000000..e818db93 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-91.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-92.dat b/plot-test/plot/tests/test-data/eb3d-92.dat new file mode 100644 index 00000000..c84509e6 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-92.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-92.png b/plot-test/plot/tests/test-data/eb3d-92.png new file mode 100644 index 00000000..eeaa388d Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-92.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-93.dat b/plot-test/plot/tests/test-data/eb3d-93.dat new file mode 100644 index 00000000..a85bffe0 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-93.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-93.png b/plot-test/plot/tests/test-data/eb3d-93.png new file mode 100644 index 00000000..c795d948 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-93.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-94.dat b/plot-test/plot/tests/test-data/eb3d-94.dat new file mode 100644 index 00000000..27c42fa1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-94.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-94.png b/plot-test/plot/tests/test-data/eb3d-94.png new file mode 100644 index 00000000..86de9b4c Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-94.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-95.dat b/plot-test/plot/tests/test-data/eb3d-95.dat new file mode 100644 index 00000000..2bdd1331 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-95.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-95.png b/plot-test/plot/tests/test-data/eb3d-95.png new file mode 100644 index 00000000..75b014cc Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-95.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-96.dat b/plot-test/plot/tests/test-data/eb3d-96.dat new file mode 100644 index 00000000..89e7d1f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-96.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-96.png b/plot-test/plot/tests/test-data/eb3d-96.png new file mode 100644 index 00000000..a03de2cf Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-96.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-97.dat b/plot-test/plot/tests/test-data/eb3d-97.dat new file mode 100644 index 00000000..dbc2679f Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-97.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-97.png b/plot-test/plot/tests/test-data/eb3d-97.png new file mode 100644 index 00000000..db19493a Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-97.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-98.dat b/plot-test/plot/tests/test-data/eb3d-98.dat new file mode 100644 index 00000000..26e86a0b Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-98.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-98.png b/plot-test/plot/tests/test-data/eb3d-98.png new file mode 100644 index 00000000..ef42fca5 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-98.png differ diff --git a/plot-test/plot/tests/test-data/eb3d-99.dat b/plot-test/plot/tests/test-data/eb3d-99.dat new file mode 100644 index 00000000..5212aa08 Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-99.dat differ diff --git a/plot-test/plot/tests/test-data/eb3d-99.png b/plot-test/plot/tests/test-data/eb3d-99.png new file mode 100644 index 00000000..c85ebcad Binary files /dev/null and b/plot-test/plot/tests/test-data/eb3d-99.png differ diff --git a/plot-test/plot/tests/test-data/is-1.dat b/plot-test/plot/tests/test-data/is-1.dat new file mode 100644 index 00000000..e2565359 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-1.dat differ diff --git a/plot-test/plot/tests/test-data/is-1.png b/plot-test/plot/tests/test-data/is-1.png new file mode 100644 index 00000000..51b05a20 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-1.png differ diff --git a/plot-test/plot/tests/test-data/is-2.dat b/plot-test/plot/tests/test-data/is-2.dat new file mode 100644 index 00000000..0f851cb2 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-2.dat differ diff --git a/plot-test/plot/tests/test-data/is-2.png b/plot-test/plot/tests/test-data/is-2.png new file mode 100644 index 00000000..d0d4a366 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-2.png differ diff --git a/plot-test/plot/tests/test-data/is-3.dat b/plot-test/plot/tests/test-data/is-3.dat new file mode 100644 index 00000000..71949e5e Binary files /dev/null and b/plot-test/plot/tests/test-data/is-3.dat differ diff --git a/plot-test/plot/tests/test-data/is-3.png b/plot-test/plot/tests/test-data/is-3.png new file mode 100644 index 00000000..5c5a4bd3 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-3.png differ diff --git a/plot-test/plot/tests/test-data/is-4.dat b/plot-test/plot/tests/test-data/is-4.dat new file mode 100644 index 00000000..ca61c576 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-4.dat differ diff --git a/plot-test/plot/tests/test-data/is-4.png b/plot-test/plot/tests/test-data/is-4.png new file mode 100644 index 00000000..35b15212 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-4.png differ diff --git a/plot-test/plot/tests/test-data/is-5.dat b/plot-test/plot/tests/test-data/is-5.dat new file mode 100644 index 00000000..971f7c68 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-5.dat differ diff --git a/plot-test/plot/tests/test-data/is-5.png b/plot-test/plot/tests/test-data/is-5.png new file mode 100644 index 00000000..ebec06c3 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-5.png differ diff --git a/plot-test/plot/tests/test-data/is-6.dat b/plot-test/plot/tests/test-data/is-6.dat new file mode 100644 index 00000000..6ed10930 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-6.dat differ diff --git a/plot-test/plot/tests/test-data/is-6.png b/plot-test/plot/tests/test-data/is-6.png new file mode 100644 index 00000000..76084bb5 Binary files /dev/null and b/plot-test/plot/tests/test-data/is-6.png differ diff --git a/plot-test/plot/tests/test-data/p1d-1.dat b/plot-test/plot/tests/test-data/p1d-1.dat new file mode 100644 index 00000000..8cec797f Binary files /dev/null and b/plot-test/plot/tests/test-data/p1d-1.dat differ diff --git a/plot-test/plot/tests/test-data/p1d-1.png b/plot-test/plot/tests/test-data/p1d-1.png new file mode 100644 index 00000000..84380f1c Binary files /dev/null and b/plot-test/plot/tests/test-data/p1d-1.png differ diff --git a/plot-test/plot/tests/test-data/p2d-10.dat b/plot-test/plot/tests/test-data/p2d-10.dat new file mode 100644 index 00000000..50c7036f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-10.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-10.png b/plot-test/plot/tests/test-data/p2d-10.png new file mode 100644 index 00000000..69bd5cf7 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-10.png differ diff --git a/plot-test/plot/tests/test-data/p2d-11.dat b/plot-test/plot/tests/test-data/p2d-11.dat new file mode 100644 index 00000000..ccafc2db Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-11.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-11.png b/plot-test/plot/tests/test-data/p2d-11.png new file mode 100644 index 00000000..f22a329c Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-11.png differ diff --git a/plot-test/plot/tests/test-data/p2d-12.dat b/plot-test/plot/tests/test-data/p2d-12.dat new file mode 100644 index 00000000..ad80e594 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-12.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-12.png b/plot-test/plot/tests/test-data/p2d-12.png new file mode 100644 index 00000000..71688be5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-12.png differ diff --git a/plot-test/plot/tests/test-data/p2d-13.dat b/plot-test/plot/tests/test-data/p2d-13.dat new file mode 100644 index 00000000..b42fdb35 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-13.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-13.png b/plot-test/plot/tests/test-data/p2d-13.png new file mode 100644 index 00000000..a556fd4a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-13.png differ diff --git a/plot-test/plot/tests/test-data/p2d-14.dat b/plot-test/plot/tests/test-data/p2d-14.dat new file mode 100644 index 00000000..0d660c1f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-14.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-14.png b/plot-test/plot/tests/test-data/p2d-14.png new file mode 100644 index 00000000..fd2781a0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-14.png differ diff --git a/plot-test/plot/tests/test-data/p2d-15.dat b/plot-test/plot/tests/test-data/p2d-15.dat new file mode 100644 index 00000000..05b62915 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-15.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-15.png b/plot-test/plot/tests/test-data/p2d-15.png new file mode 100644 index 00000000..d6973eab Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-15.png differ diff --git a/plot-test/plot/tests/test-data/p2d-16.dat b/plot-test/plot/tests/test-data/p2d-16.dat new file mode 100644 index 00000000..73981f2f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-16.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-16.png b/plot-test/plot/tests/test-data/p2d-16.png new file mode 100644 index 00000000..21e9eaae Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-16.png differ diff --git a/plot-test/plot/tests/test-data/p2d-17.dat b/plot-test/plot/tests/test-data/p2d-17.dat new file mode 100644 index 00000000..a19e1369 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-17.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-17.png b/plot-test/plot/tests/test-data/p2d-17.png new file mode 100644 index 00000000..86f31e96 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-17.png differ diff --git a/plot-test/plot/tests/test-data/p2d-18.dat b/plot-test/plot/tests/test-data/p2d-18.dat new file mode 100644 index 00000000..29c026d1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-18.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-18.png b/plot-test/plot/tests/test-data/p2d-18.png new file mode 100644 index 00000000..cf439ea5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-18.png differ diff --git a/plot-test/plot/tests/test-data/p2d-19.dat b/plot-test/plot/tests/test-data/p2d-19.dat new file mode 100644 index 00000000..0daab726 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-19.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-19.png b/plot-test/plot/tests/test-data/p2d-19.png new file mode 100644 index 00000000..5f253f53 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-19.png differ diff --git a/plot-test/plot/tests/test-data/p2d-2.dat b/plot-test/plot/tests/test-data/p2d-2.dat new file mode 100644 index 00000000..1fe50ed0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-2.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-2.png b/plot-test/plot/tests/test-data/p2d-2.png new file mode 100644 index 00000000..b0f06dff Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-2.png differ diff --git a/plot-test/plot/tests/test-data/p2d-20.dat b/plot-test/plot/tests/test-data/p2d-20.dat new file mode 100644 index 00000000..d1ad0ae1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-20.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-20.png b/plot-test/plot/tests/test-data/p2d-20.png new file mode 100644 index 00000000..c74efc97 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-20.png differ diff --git a/plot-test/plot/tests/test-data/p2d-21.dat b/plot-test/plot/tests/test-data/p2d-21.dat new file mode 100644 index 00000000..6e50afe3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-21.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-21.png b/plot-test/plot/tests/test-data/p2d-21.png new file mode 100644 index 00000000..3ed74503 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-21.png differ diff --git a/plot-test/plot/tests/test-data/p2d-22.dat b/plot-test/plot/tests/test-data/p2d-22.dat new file mode 100644 index 00000000..a86f99dc Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-22.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-22.png b/plot-test/plot/tests/test-data/p2d-22.png new file mode 100644 index 00000000..dc66aae9 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-22.png differ diff --git a/plot-test/plot/tests/test-data/p2d-23.dat b/plot-test/plot/tests/test-data/p2d-23.dat new file mode 100644 index 00000000..a0d242f8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-23.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-23.png b/plot-test/plot/tests/test-data/p2d-23.png new file mode 100644 index 00000000..a90ba3a1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-23.png differ diff --git a/plot-test/plot/tests/test-data/p2d-24.dat b/plot-test/plot/tests/test-data/p2d-24.dat new file mode 100644 index 00000000..9740f661 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-24.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-24.png b/plot-test/plot/tests/test-data/p2d-24.png new file mode 100644 index 00000000..a265b3f3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-24.png differ diff --git a/plot-test/plot/tests/test-data/p2d-25.dat b/plot-test/plot/tests/test-data/p2d-25.dat new file mode 100644 index 00000000..208334e4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-25.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-25.png b/plot-test/plot/tests/test-data/p2d-25.png new file mode 100644 index 00000000..23286ad4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-25.png differ diff --git a/plot-test/plot/tests/test-data/p2d-26.dat b/plot-test/plot/tests/test-data/p2d-26.dat new file mode 100644 index 00000000..6335a476 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-26.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-26.png b/plot-test/plot/tests/test-data/p2d-26.png new file mode 100644 index 00000000..aeafff8d Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-26.png differ diff --git a/plot-test/plot/tests/test-data/p2d-27.dat b/plot-test/plot/tests/test-data/p2d-27.dat new file mode 100644 index 00000000..19be6e1a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-27.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-27.png b/plot-test/plot/tests/test-data/p2d-27.png new file mode 100644 index 00000000..bfef08b8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-27.png differ diff --git a/plot-test/plot/tests/test-data/p2d-28.dat b/plot-test/plot/tests/test-data/p2d-28.dat new file mode 100644 index 00000000..ae5bca0d Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-28.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-28.png b/plot-test/plot/tests/test-data/p2d-28.png new file mode 100644 index 00000000..73684286 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-28.png differ diff --git a/plot-test/plot/tests/test-data/p2d-29.dat b/plot-test/plot/tests/test-data/p2d-29.dat new file mode 100644 index 00000000..39431e36 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-29.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-29.png b/plot-test/plot/tests/test-data/p2d-29.png new file mode 100644 index 00000000..bcba9340 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-29.png differ diff --git a/plot-test/plot/tests/test-data/p2d-3.dat b/plot-test/plot/tests/test-data/p2d-3.dat new file mode 100644 index 00000000..2ecb318a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-3.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-3.png b/plot-test/plot/tests/test-data/p2d-3.png new file mode 100644 index 00000000..be960f67 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-3.png differ diff --git a/plot-test/plot/tests/test-data/p2d-30.dat b/plot-test/plot/tests/test-data/p2d-30.dat new file mode 100644 index 00000000..463f4c24 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-30.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-30.png b/plot-test/plot/tests/test-data/p2d-30.png new file mode 100644 index 00000000..0f1745ab Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-30.png differ diff --git a/plot-test/plot/tests/test-data/p2d-31.dat b/plot-test/plot/tests/test-data/p2d-31.dat new file mode 100644 index 00000000..ce4cadc9 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-31.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-31.png b/plot-test/plot/tests/test-data/p2d-31.png new file mode 100644 index 00000000..5208f723 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-31.png differ diff --git a/plot-test/plot/tests/test-data/p2d-32.dat b/plot-test/plot/tests/test-data/p2d-32.dat new file mode 100644 index 00000000..39e839f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-32.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-32.png b/plot-test/plot/tests/test-data/p2d-32.png new file mode 100644 index 00000000..26e03722 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-32.png differ diff --git a/plot-test/plot/tests/test-data/p2d-33.dat b/plot-test/plot/tests/test-data/p2d-33.dat new file mode 100644 index 00000000..a54936af Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-33.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-33.png b/plot-test/plot/tests/test-data/p2d-33.png new file mode 100644 index 00000000..30895f14 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-33.png differ diff --git a/plot-test/plot/tests/test-data/p2d-34.dat b/plot-test/plot/tests/test-data/p2d-34.dat new file mode 100644 index 00000000..6dacd1de Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-34.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-34.png b/plot-test/plot/tests/test-data/p2d-34.png new file mode 100644 index 00000000..888e0fd1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-34.png differ diff --git a/plot-test/plot/tests/test-data/p2d-35.dat b/plot-test/plot/tests/test-data/p2d-35.dat new file mode 100644 index 00000000..10f9c3d0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-35.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-35.png b/plot-test/plot/tests/test-data/p2d-35.png new file mode 100644 index 00000000..4cabd1a7 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-35.png differ diff --git a/plot-test/plot/tests/test-data/p2d-36.dat b/plot-test/plot/tests/test-data/p2d-36.dat new file mode 100644 index 00000000..4e581b71 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-36.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-36.png b/plot-test/plot/tests/test-data/p2d-36.png new file mode 100644 index 00000000..89e7732f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-36.png differ diff --git a/plot-test/plot/tests/test-data/p2d-37.dat b/plot-test/plot/tests/test-data/p2d-37.dat new file mode 100644 index 00000000..4367fa73 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-37.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-37.png b/plot-test/plot/tests/test-data/p2d-37.png new file mode 100644 index 00000000..548cb786 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-37.png differ diff --git a/plot-test/plot/tests/test-data/p2d-38.dat b/plot-test/plot/tests/test-data/p2d-38.dat new file mode 100644 index 00000000..1f9fa42d Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-38.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-38.png b/plot-test/plot/tests/test-data/p2d-38.png new file mode 100644 index 00000000..b4b1f14b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-38.png differ diff --git a/plot-test/plot/tests/test-data/p2d-39.dat b/plot-test/plot/tests/test-data/p2d-39.dat new file mode 100644 index 00000000..eb2b36ea Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-39.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-39.png b/plot-test/plot/tests/test-data/p2d-39.png new file mode 100644 index 00000000..b9e43410 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-39.png differ diff --git a/plot-test/plot/tests/test-data/p2d-4.dat b/plot-test/plot/tests/test-data/p2d-4.dat new file mode 100644 index 00000000..2ecb318a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-4.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-4.png b/plot-test/plot/tests/test-data/p2d-4.png new file mode 100644 index 00000000..7fefec7f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-4.png differ diff --git a/plot-test/plot/tests/test-data/p2d-40.dat b/plot-test/plot/tests/test-data/p2d-40.dat new file mode 100644 index 00000000..041b7f25 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-40.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-40.png b/plot-test/plot/tests/test-data/p2d-40.png new file mode 100644 index 00000000..d03c074b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-40.png differ diff --git a/plot-test/plot/tests/test-data/p2d-41.dat b/plot-test/plot/tests/test-data/p2d-41.dat new file mode 100644 index 00000000..97446cd1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-41.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-41.png b/plot-test/plot/tests/test-data/p2d-41.png new file mode 100644 index 00000000..c0a30561 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-41.png differ diff --git a/plot-test/plot/tests/test-data/p2d-42.dat b/plot-test/plot/tests/test-data/p2d-42.dat new file mode 100644 index 00000000..60dd7ad2 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-42.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-42.png b/plot-test/plot/tests/test-data/p2d-42.png new file mode 100644 index 00000000..364adc8a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-42.png differ diff --git a/plot-test/plot/tests/test-data/p2d-43.dat b/plot-test/plot/tests/test-data/p2d-43.dat new file mode 100644 index 00000000..9b27a3a4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-43.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-43.png b/plot-test/plot/tests/test-data/p2d-43.png new file mode 100644 index 00000000..b99ed452 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-43.png differ diff --git a/plot-test/plot/tests/test-data/p2d-44.dat b/plot-test/plot/tests/test-data/p2d-44.dat new file mode 100644 index 00000000..08ea99cd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-44.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-44.png b/plot-test/plot/tests/test-data/p2d-44.png new file mode 100644 index 00000000..26974f20 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-44.png differ diff --git a/plot-test/plot/tests/test-data/p2d-45.dat b/plot-test/plot/tests/test-data/p2d-45.dat new file mode 100644 index 00000000..309953cf Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-45.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-45.png b/plot-test/plot/tests/test-data/p2d-45.png new file mode 100644 index 00000000..2a846efe Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-45.png differ diff --git a/plot-test/plot/tests/test-data/p2d-46.dat b/plot-test/plot/tests/test-data/p2d-46.dat new file mode 100644 index 00000000..4d98aee2 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-46.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-46.png b/plot-test/plot/tests/test-data/p2d-46.png new file mode 100644 index 00000000..642da8ba Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-46.png differ diff --git a/plot-test/plot/tests/test-data/p2d-47.dat b/plot-test/plot/tests/test-data/p2d-47.dat new file mode 100644 index 00000000..8715c577 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-47.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-47.png b/plot-test/plot/tests/test-data/p2d-47.png new file mode 100644 index 00000000..e4727cc4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-47.png differ diff --git a/plot-test/plot/tests/test-data/p2d-48.dat b/plot-test/plot/tests/test-data/p2d-48.dat new file mode 100644 index 00000000..994f68dd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-48.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-48.png b/plot-test/plot/tests/test-data/p2d-48.png new file mode 100644 index 00000000..5562f3e4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-48.png differ diff --git a/plot-test/plot/tests/test-data/p2d-49.dat b/plot-test/plot/tests/test-data/p2d-49.dat new file mode 100644 index 00000000..470e6718 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-49.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-49.png b/plot-test/plot/tests/test-data/p2d-49.png new file mode 100644 index 00000000..95a4c654 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-49.png differ diff --git a/plot-test/plot/tests/test-data/p2d-5.dat b/plot-test/plot/tests/test-data/p2d-5.dat new file mode 100644 index 00000000..919fd71b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-5.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-5.png b/plot-test/plot/tests/test-data/p2d-5.png new file mode 100644 index 00000000..1c6c86b0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-5.png differ diff --git a/plot-test/plot/tests/test-data/p2d-50.dat b/plot-test/plot/tests/test-data/p2d-50.dat new file mode 100644 index 00000000..6f170012 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-50.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-50.png b/plot-test/plot/tests/test-data/p2d-50.png new file mode 100644 index 00000000..aa52333a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-50.png differ diff --git a/plot-test/plot/tests/test-data/p2d-51.dat b/plot-test/plot/tests/test-data/p2d-51.dat new file mode 100644 index 00000000..4b22a264 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-51.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-51.png b/plot-test/plot/tests/test-data/p2d-51.png new file mode 100644 index 00000000..5a9944d0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-51.png differ diff --git a/plot-test/plot/tests/test-data/p2d-52.dat b/plot-test/plot/tests/test-data/p2d-52.dat new file mode 100644 index 00000000..18d9ef95 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-52.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-52.png b/plot-test/plot/tests/test-data/p2d-52.png new file mode 100644 index 00000000..9c8e155a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-52.png differ diff --git a/plot-test/plot/tests/test-data/p2d-53.dat b/plot-test/plot/tests/test-data/p2d-53.dat new file mode 100644 index 00000000..18d9ef95 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-53.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-53.png b/plot-test/plot/tests/test-data/p2d-53.png new file mode 100644 index 00000000..9c8e155a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-53.png differ diff --git a/plot-test/plot/tests/test-data/p2d-54.dat b/plot-test/plot/tests/test-data/p2d-54.dat new file mode 100644 index 00000000..d6d438b4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-54.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-54.png b/plot-test/plot/tests/test-data/p2d-54.png new file mode 100644 index 00000000..f6d6ef69 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-54.png differ diff --git a/plot-test/plot/tests/test-data/p2d-55.dat b/plot-test/plot/tests/test-data/p2d-55.dat new file mode 100644 index 00000000..7f2a23cf Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-55.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-55.png b/plot-test/plot/tests/test-data/p2d-55.png new file mode 100644 index 00000000..42c923d4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-55.png differ diff --git a/plot-test/plot/tests/test-data/p2d-56.dat b/plot-test/plot/tests/test-data/p2d-56.dat new file mode 100644 index 00000000..0924f0c4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-56.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-56.png b/plot-test/plot/tests/test-data/p2d-56.png new file mode 100644 index 00000000..5b9cc17c Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-56.png differ diff --git a/plot-test/plot/tests/test-data/p2d-57.dat b/plot-test/plot/tests/test-data/p2d-57.dat new file mode 100644 index 00000000..26d01b2a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-57.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-57.png b/plot-test/plot/tests/test-data/p2d-57.png new file mode 100644 index 00000000..d328f2f1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-57.png differ diff --git a/plot-test/plot/tests/test-data/p2d-58.dat b/plot-test/plot/tests/test-data/p2d-58.dat new file mode 100644 index 00000000..5ec8be14 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-58.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-58.png b/plot-test/plot/tests/test-data/p2d-58.png new file mode 100644 index 00000000..44ad37ec Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-58.png differ diff --git a/plot-test/plot/tests/test-data/p2d-59.dat b/plot-test/plot/tests/test-data/p2d-59.dat new file mode 100644 index 00000000..7d66bfb8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-59.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-59.png b/plot-test/plot/tests/test-data/p2d-59.png new file mode 100644 index 00000000..60fe4639 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-59.png differ diff --git a/plot-test/plot/tests/test-data/p2d-6.dat b/plot-test/plot/tests/test-data/p2d-6.dat new file mode 100644 index 00000000..c237bb65 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-6.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-6.png b/plot-test/plot/tests/test-data/p2d-6.png new file mode 100644 index 00000000..4aef2b36 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-6.png differ diff --git a/plot-test/plot/tests/test-data/p2d-60.dat b/plot-test/plot/tests/test-data/p2d-60.dat new file mode 100644 index 00000000..6d3ad65b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-60.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-60.png b/plot-test/plot/tests/test-data/p2d-60.png new file mode 100644 index 00000000..b62ddefd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-60.png differ diff --git a/plot-test/plot/tests/test-data/p2d-61.dat b/plot-test/plot/tests/test-data/p2d-61.dat new file mode 100644 index 00000000..6492b8dc Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-61.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-61.png b/plot-test/plot/tests/test-data/p2d-61.png new file mode 100644 index 00000000..e425dde0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-61.png differ diff --git a/plot-test/plot/tests/test-data/p2d-62.dat b/plot-test/plot/tests/test-data/p2d-62.dat new file mode 100644 index 00000000..c44dc55e Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-62.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-62.png b/plot-test/plot/tests/test-data/p2d-62.png new file mode 100644 index 00000000..85d68529 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-62.png differ diff --git a/plot-test/plot/tests/test-data/p2d-63.dat b/plot-test/plot/tests/test-data/p2d-63.dat new file mode 100644 index 00000000..ad073be1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-63.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-63.png b/plot-test/plot/tests/test-data/p2d-63.png new file mode 100644 index 00000000..0869f0e5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-63.png differ diff --git a/plot-test/plot/tests/test-data/p2d-64.dat b/plot-test/plot/tests/test-data/p2d-64.dat new file mode 100644 index 00000000..be5b1616 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-64.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-64.png b/plot-test/plot/tests/test-data/p2d-64.png new file mode 100644 index 00000000..8e17dfdd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-64.png differ diff --git a/plot-test/plot/tests/test-data/p2d-65.dat b/plot-test/plot/tests/test-data/p2d-65.dat new file mode 100644 index 00000000..38d7b038 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-65.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-65.png b/plot-test/plot/tests/test-data/p2d-65.png new file mode 100644 index 00000000..3e987b2e Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-65.png differ diff --git a/plot-test/plot/tests/test-data/p2d-65a.dat b/plot-test/plot/tests/test-data/p2d-65a.dat new file mode 100644 index 00000000..a76c62e0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-65a.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-65a.png b/plot-test/plot/tests/test-data/p2d-65a.png new file mode 100644 index 00000000..e334498a Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-65a.png differ diff --git a/plot-test/plot/tests/test-data/p2d-66.dat b/plot-test/plot/tests/test-data/p2d-66.dat new file mode 100644 index 00000000..51935654 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-66.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-66.png b/plot-test/plot/tests/test-data/p2d-66.png new file mode 100644 index 00000000..72d46fcd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-66.png differ diff --git a/plot-test/plot/tests/test-data/p2d-67.dat b/plot-test/plot/tests/test-data/p2d-67.dat new file mode 100644 index 00000000..c046140f Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-67.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-67.png b/plot-test/plot/tests/test-data/p2d-67.png new file mode 100644 index 00000000..9f1eb7d7 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-67.png differ diff --git a/plot-test/plot/tests/test-data/p2d-68.dat b/plot-test/plot/tests/test-data/p2d-68.dat new file mode 100644 index 00000000..34e33c99 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-68.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-68.png b/plot-test/plot/tests/test-data/p2d-68.png new file mode 100644 index 00000000..2e99563d Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-68.png differ diff --git a/plot-test/plot/tests/test-data/p2d-69.dat b/plot-test/plot/tests/test-data/p2d-69.dat new file mode 100644 index 00000000..208607ea Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-69.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-69.png b/plot-test/plot/tests/test-data/p2d-69.png new file mode 100644 index 00000000..a1bc3d52 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-69.png differ diff --git a/plot-test/plot/tests/test-data/p2d-7.dat b/plot-test/plot/tests/test-data/p2d-7.dat new file mode 100644 index 00000000..e19eecca Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-7.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-7.png b/plot-test/plot/tests/test-data/p2d-7.png new file mode 100644 index 00000000..60980566 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-7.png differ diff --git a/plot-test/plot/tests/test-data/p2d-70.dat b/plot-test/plot/tests/test-data/p2d-70.dat new file mode 100644 index 00000000..ab59618b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-70.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-70.png b/plot-test/plot/tests/test-data/p2d-70.png new file mode 100644 index 00000000..040d87a8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-70.png differ diff --git a/plot-test/plot/tests/test-data/p2d-8.dat b/plot-test/plot/tests/test-data/p2d-8.dat new file mode 100644 index 00000000..636ce78b Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-8.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-8.png b/plot-test/plot/tests/test-data/p2d-8.png new file mode 100644 index 00000000..86e003cd Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-8.png differ diff --git a/plot-test/plot/tests/test-data/p2d-9.dat b/plot-test/plot/tests/test-data/p2d-9.dat new file mode 100644 index 00000000..58721c5e Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-9.dat differ diff --git a/plot-test/plot/tests/test-data/p2d-9.png b/plot-test/plot/tests/test-data/p2d-9.png new file mode 100644 index 00000000..e79420e0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p2d-9.png differ diff --git a/plot-test/plot/tests/test-data/p3d-1.dat b/plot-test/plot/tests/test-data/p3d-1.dat new file mode 100644 index 00000000..a7348555 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-1.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-1.png b/plot-test/plot/tests/test-data/p3d-1.png new file mode 100644 index 00000000..4bbec61e Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-1.png differ diff --git a/plot-test/plot/tests/test-data/p3d-10.dat b/plot-test/plot/tests/test-data/p3d-10.dat new file mode 100644 index 00000000..b0f5e21d Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-10.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-10.png b/plot-test/plot/tests/test-data/p3d-10.png new file mode 100644 index 00000000..34a689cf Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-10.png differ diff --git a/plot-test/plot/tests/test-data/p3d-11.dat b/plot-test/plot/tests/test-data/p3d-11.dat new file mode 100644 index 00000000..b7f40a9b Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-11.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-11.png b/plot-test/plot/tests/test-data/p3d-11.png new file mode 100644 index 00000000..ac49b3f3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-11.png differ diff --git a/plot-test/plot/tests/test-data/p3d-12.dat b/plot-test/plot/tests/test-data/p3d-12.dat new file mode 100644 index 00000000..4bf69fad Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-12.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-12.png b/plot-test/plot/tests/test-data/p3d-12.png new file mode 100644 index 00000000..ba4dcec8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-12.png differ diff --git a/plot-test/plot/tests/test-data/p3d-13.dat b/plot-test/plot/tests/test-data/p3d-13.dat new file mode 100644 index 00000000..2e451f42 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-13.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-13.png b/plot-test/plot/tests/test-data/p3d-13.png new file mode 100644 index 00000000..6e859535 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-13.png differ diff --git a/plot-test/plot/tests/test-data/p3d-14.dat b/plot-test/plot/tests/test-data/p3d-14.dat new file mode 100644 index 00000000..cf792891 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-14.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-14.png b/plot-test/plot/tests/test-data/p3d-14.png new file mode 100644 index 00000000..d2bef3bc Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-14.png differ diff --git a/plot-test/plot/tests/test-data/p3d-15.dat b/plot-test/plot/tests/test-data/p3d-15.dat new file mode 100644 index 00000000..10979121 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-15.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-15.png b/plot-test/plot/tests/test-data/p3d-15.png new file mode 100644 index 00000000..2fa37e58 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-15.png differ diff --git a/plot-test/plot/tests/test-data/p3d-16.dat b/plot-test/plot/tests/test-data/p3d-16.dat new file mode 100644 index 00000000..229f1862 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-16.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-16.png b/plot-test/plot/tests/test-data/p3d-16.png new file mode 100644 index 00000000..cd8282d5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-16.png differ diff --git a/plot-test/plot/tests/test-data/p3d-17.dat b/plot-test/plot/tests/test-data/p3d-17.dat new file mode 100644 index 00000000..7a38b6ee Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-17.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-17.png b/plot-test/plot/tests/test-data/p3d-17.png new file mode 100644 index 00000000..865ffd6a Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-17.png differ diff --git a/plot-test/plot/tests/test-data/p3d-18.dat b/plot-test/plot/tests/test-data/p3d-18.dat new file mode 100644 index 00000000..1974892f Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-18.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-18.png b/plot-test/plot/tests/test-data/p3d-18.png new file mode 100644 index 00000000..79bfbe20 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-18.png differ diff --git a/plot-test/plot/tests/test-data/p3d-19.dat b/plot-test/plot/tests/test-data/p3d-19.dat new file mode 100644 index 00000000..0d891a2a Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-19.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-19.png b/plot-test/plot/tests/test-data/p3d-19.png new file mode 100644 index 00000000..25c20aa8 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-19.png differ diff --git a/plot-test/plot/tests/test-data/p3d-2.dat b/plot-test/plot/tests/test-data/p3d-2.dat new file mode 100644 index 00000000..69a30cf0 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-2.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-2.png b/plot-test/plot/tests/test-data/p3d-2.png new file mode 100644 index 00000000..4bbec61e Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-2.png differ diff --git a/plot-test/plot/tests/test-data/p3d-20.dat b/plot-test/plot/tests/test-data/p3d-20.dat new file mode 100644 index 00000000..516c0b47 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-20.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-20.png b/plot-test/plot/tests/test-data/p3d-20.png new file mode 100644 index 00000000..4ccf9324 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-20.png differ diff --git a/plot-test/plot/tests/test-data/p3d-21.dat b/plot-test/plot/tests/test-data/p3d-21.dat new file mode 100644 index 00000000..c56a3ef4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-21.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-21.png b/plot-test/plot/tests/test-data/p3d-21.png new file mode 100644 index 00000000..450c4ecb Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-21.png differ diff --git a/plot-test/plot/tests/test-data/p3d-22.dat b/plot-test/plot/tests/test-data/p3d-22.dat new file mode 100644 index 00000000..e742ba7c Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-22.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-22.png b/plot-test/plot/tests/test-data/p3d-22.png new file mode 100644 index 00000000..28245cb4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-22.png differ diff --git a/plot-test/plot/tests/test-data/p3d-23.dat b/plot-test/plot/tests/test-data/p3d-23.dat new file mode 100644 index 00000000..f902d990 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-23.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-23.png b/plot-test/plot/tests/test-data/p3d-23.png new file mode 100644 index 00000000..40181d44 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-23.png differ diff --git a/plot-test/plot/tests/test-data/p3d-24.dat b/plot-test/plot/tests/test-data/p3d-24.dat new file mode 100644 index 00000000..c9e91198 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-24.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-24.png b/plot-test/plot/tests/test-data/p3d-24.png new file mode 100644 index 00000000..1f40eb83 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-24.png differ diff --git a/plot-test/plot/tests/test-data/p3d-25.dat b/plot-test/plot/tests/test-data/p3d-25.dat new file mode 100644 index 00000000..8163cd8c Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-25.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-25.png b/plot-test/plot/tests/test-data/p3d-25.png new file mode 100644 index 00000000..fa038947 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-25.png differ diff --git a/plot-test/plot/tests/test-data/p3d-26.dat b/plot-test/plot/tests/test-data/p3d-26.dat new file mode 100644 index 00000000..646301ad Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-26.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-26.png b/plot-test/plot/tests/test-data/p3d-26.png new file mode 100644 index 00000000..48d8df69 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-26.png differ diff --git a/plot-test/plot/tests/test-data/p3d-27.dat b/plot-test/plot/tests/test-data/p3d-27.dat new file mode 100644 index 00000000..65ea20ac Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-27.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-27.png b/plot-test/plot/tests/test-data/p3d-27.png new file mode 100644 index 00000000..c2513410 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-27.png differ diff --git a/plot-test/plot/tests/test-data/p3d-28.dat b/plot-test/plot/tests/test-data/p3d-28.dat new file mode 100644 index 00000000..f886ae84 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-28.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-28.png b/plot-test/plot/tests/test-data/p3d-28.png new file mode 100644 index 00000000..588a4449 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-28.png differ diff --git a/plot-test/plot/tests/test-data/p3d-29.dat b/plot-test/plot/tests/test-data/p3d-29.dat new file mode 100644 index 00000000..d3cfc3cf Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-29.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-29.png b/plot-test/plot/tests/test-data/p3d-29.png new file mode 100644 index 00000000..f77684e3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-29.png differ diff --git a/plot-test/plot/tests/test-data/p3d-3.dat b/plot-test/plot/tests/test-data/p3d-3.dat new file mode 100644 index 00000000..453ca47f Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-3.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-3.png b/plot-test/plot/tests/test-data/p3d-3.png new file mode 100644 index 00000000..36c01d12 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-3.png differ diff --git a/plot-test/plot/tests/test-data/p3d-30.dat b/plot-test/plot/tests/test-data/p3d-30.dat new file mode 100644 index 00000000..20214c2a Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-30.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-30.png b/plot-test/plot/tests/test-data/p3d-30.png new file mode 100644 index 00000000..39fb205e Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-30.png differ diff --git a/plot-test/plot/tests/test-data/p3d-31.dat b/plot-test/plot/tests/test-data/p3d-31.dat new file mode 100644 index 00000000..f0840b60 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-31.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-31.png b/plot-test/plot/tests/test-data/p3d-31.png new file mode 100644 index 00000000..64e1c1af Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-31.png differ diff --git a/plot-test/plot/tests/test-data/p3d-32.dat b/plot-test/plot/tests/test-data/p3d-32.dat new file mode 100644 index 00000000..0c711805 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-32.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-32.png b/plot-test/plot/tests/test-data/p3d-32.png new file mode 100644 index 00000000..565d3ad5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-32.png differ diff --git a/plot-test/plot/tests/test-data/p3d-33.dat b/plot-test/plot/tests/test-data/p3d-33.dat new file mode 100644 index 00000000..63d04336 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-33.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-33.png b/plot-test/plot/tests/test-data/p3d-33.png new file mode 100644 index 00000000..b59c809f Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-33.png differ diff --git a/plot-test/plot/tests/test-data/p3d-34.dat b/plot-test/plot/tests/test-data/p3d-34.dat new file mode 100644 index 00000000..a032f846 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-34.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-34.png b/plot-test/plot/tests/test-data/p3d-34.png new file mode 100644 index 00000000..1354d16c Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-34.png differ diff --git a/plot-test/plot/tests/test-data/p3d-35.dat b/plot-test/plot/tests/test-data/p3d-35.dat new file mode 100644 index 00000000..dffd593a Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-35.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-35.png b/plot-test/plot/tests/test-data/p3d-35.png new file mode 100644 index 00000000..98d10609 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-35.png differ diff --git a/plot-test/plot/tests/test-data/p3d-4.dat b/plot-test/plot/tests/test-data/p3d-4.dat new file mode 100644 index 00000000..baaaf80c Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-4.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-4.png b/plot-test/plot/tests/test-data/p3d-4.png new file mode 100644 index 00000000..da65e636 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-4.png differ diff --git a/plot-test/plot/tests/test-data/p3d-5.dat b/plot-test/plot/tests/test-data/p3d-5.dat new file mode 100644 index 00000000..4f79e568 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-5.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-5.png b/plot-test/plot/tests/test-data/p3d-5.png new file mode 100644 index 00000000..b233b44b Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-5.png differ diff --git a/plot-test/plot/tests/test-data/p3d-6.dat b/plot-test/plot/tests/test-data/p3d-6.dat new file mode 100644 index 00000000..53af1fa3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-6.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-6.png b/plot-test/plot/tests/test-data/p3d-6.png new file mode 100644 index 00000000..c6f23862 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-6.png differ diff --git a/plot-test/plot/tests/test-data/p3d-7.dat b/plot-test/plot/tests/test-data/p3d-7.dat new file mode 100644 index 00000000..ecaf67f4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-7.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-7.png b/plot-test/plot/tests/test-data/p3d-7.png new file mode 100644 index 00000000..5e7b5949 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-7.png differ diff --git a/plot-test/plot/tests/test-data/p3d-8.dat b/plot-test/plot/tests/test-data/p3d-8.dat new file mode 100644 index 00000000..c48f606e Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-8.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-8.png b/plot-test/plot/tests/test-data/p3d-8.png new file mode 100644 index 00000000..8ed796f4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-8.png differ diff --git a/plot-test/plot/tests/test-data/p3d-9.dat b/plot-test/plot/tests/test-data/p3d-9.dat new file mode 100644 index 00000000..89e8ab24 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-9.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-9.png b/plot-test/plot/tests/test-data/p3d-9.png new file mode 100644 index 00000000..8e63955e Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-9.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-1.dat b/plot-test/plot/tests/test-data/p3d-bsp-1.dat new file mode 100644 index 00000000..959b551d Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-1.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-1.png b/plot-test/plot/tests/test-data/p3d-bsp-1.png new file mode 100644 index 00000000..cf943f94 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-1.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-10.dat b/plot-test/plot/tests/test-data/p3d-bsp-10.dat new file mode 100644 index 00000000..732272ff Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-10.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-10.png b/plot-test/plot/tests/test-data/p3d-bsp-10.png new file mode 100644 index 00000000..745e33a4 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-10.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-11.dat b/plot-test/plot/tests/test-data/p3d-bsp-11.dat new file mode 100644 index 00000000..8d11b1cf Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-11.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-11.png b/plot-test/plot/tests/test-data/p3d-bsp-11.png new file mode 100644 index 00000000..c3f20fc5 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-11.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-2.dat b/plot-test/plot/tests/test-data/p3d-bsp-2.dat new file mode 100644 index 00000000..3b7f9a01 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-2.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-2.png b/plot-test/plot/tests/test-data/p3d-bsp-2.png new file mode 100644 index 00000000..e9df0230 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-2.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-3.dat b/plot-test/plot/tests/test-data/p3d-bsp-3.dat new file mode 100644 index 00000000..b347c6b6 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-3.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-3.png b/plot-test/plot/tests/test-data/p3d-bsp-3.png new file mode 100644 index 00000000..e0033926 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-3.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-4.dat b/plot-test/plot/tests/test-data/p3d-bsp-4.dat new file mode 100644 index 00000000..30c73009 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-4.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-4.png b/plot-test/plot/tests/test-data/p3d-bsp-4.png new file mode 100644 index 00000000..3ef971e2 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-4.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-5.dat b/plot-test/plot/tests/test-data/p3d-bsp-5.dat new file mode 100644 index 00000000..b73b32c2 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-5.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-5.png b/plot-test/plot/tests/test-data/p3d-bsp-5.png new file mode 100644 index 00000000..9d33d340 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-5.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-6.dat b/plot-test/plot/tests/test-data/p3d-bsp-6.dat new file mode 100644 index 00000000..d96c8881 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-6.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-6.png b/plot-test/plot/tests/test-data/p3d-bsp-6.png new file mode 100644 index 00000000..7eaf17c3 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-6.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-7.dat b/plot-test/plot/tests/test-data/p3d-bsp-7.dat new file mode 100644 index 00000000..0b39e192 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-7.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-7.png b/plot-test/plot/tests/test-data/p3d-bsp-7.png new file mode 100644 index 00000000..68c67de6 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-7.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-8.dat b/plot-test/plot/tests/test-data/p3d-bsp-8.dat new file mode 100644 index 00000000..7f714c25 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-8.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-8.png b/plot-test/plot/tests/test-data/p3d-bsp-8.png new file mode 100644 index 00000000..1cb35e2b Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-8.png differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-9.dat b/plot-test/plot/tests/test-data/p3d-bsp-9.dat new file mode 100644 index 00000000..71c738b1 Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-9.dat differ diff --git a/plot-test/plot/tests/test-data/p3d-bsp-9.png b/plot-test/plot/tests/test-data/p3d-bsp-9.png new file mode 100644 index 00000000..1354d16c Binary files /dev/null and b/plot-test/plot/tests/test-data/p3d-bsp-9.png differ diff --git a/plot-test/plot/tests/test-data/pb-1.dat b/plot-test/plot/tests/test-data/pb-1.dat new file mode 100644 index 00000000..34d7a5b0 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-1.dat differ diff --git a/plot-test/plot/tests/test-data/pb-1.png b/plot-test/plot/tests/test-data/pb-1.png new file mode 100644 index 00000000..9b020aa5 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-1.png differ diff --git a/plot-test/plot/tests/test-data/pb-10.dat b/plot-test/plot/tests/test-data/pb-10.dat new file mode 100644 index 00000000..e354ae59 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-10.dat differ diff --git a/plot-test/plot/tests/test-data/pb-10.png b/plot-test/plot/tests/test-data/pb-10.png new file mode 100644 index 00000000..b103f65d Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-10.png differ diff --git a/plot-test/plot/tests/test-data/pb-11.dat b/plot-test/plot/tests/test-data/pb-11.dat new file mode 100644 index 00000000..5658d4b6 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-11.dat differ diff --git a/plot-test/plot/tests/test-data/pb-11.png b/plot-test/plot/tests/test-data/pb-11.png new file mode 100644 index 00000000..b73a9f3d Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-11.png differ diff --git a/plot-test/plot/tests/test-data/pb-12.dat b/plot-test/plot/tests/test-data/pb-12.dat new file mode 100644 index 00000000..566f75ab Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-12.dat differ diff --git a/plot-test/plot/tests/test-data/pb-12.png b/plot-test/plot/tests/test-data/pb-12.png new file mode 100644 index 00000000..618c5ef0 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-12.png differ diff --git a/plot-test/plot/tests/test-data/pb-13.dat b/plot-test/plot/tests/test-data/pb-13.dat new file mode 100644 index 00000000..360d1d68 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-13.dat differ diff --git a/plot-test/plot/tests/test-data/pb-13.png b/plot-test/plot/tests/test-data/pb-13.png new file mode 100644 index 00000000..f63261e6 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-13.png differ diff --git a/plot-test/plot/tests/test-data/pb-2.dat b/plot-test/plot/tests/test-data/pb-2.dat new file mode 100644 index 00000000..71c53220 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-2.dat differ diff --git a/plot-test/plot/tests/test-data/pb-2.png b/plot-test/plot/tests/test-data/pb-2.png new file mode 100644 index 00000000..0146bb95 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-2.png differ diff --git a/plot-test/plot/tests/test-data/pb-3.dat b/plot-test/plot/tests/test-data/pb-3.dat new file mode 100644 index 00000000..c983d21c Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-3.dat differ diff --git a/plot-test/plot/tests/test-data/pb-3.png b/plot-test/plot/tests/test-data/pb-3.png new file mode 100644 index 00000000..876e8c48 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-3.png differ diff --git a/plot-test/plot/tests/test-data/pb-4.dat b/plot-test/plot/tests/test-data/pb-4.dat new file mode 100644 index 00000000..691b12f6 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-4.dat differ diff --git a/plot-test/plot/tests/test-data/pb-4.png b/plot-test/plot/tests/test-data/pb-4.png new file mode 100644 index 00000000..7d87528e Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-4.png differ diff --git a/plot-test/plot/tests/test-data/pb-5.dat b/plot-test/plot/tests/test-data/pb-5.dat new file mode 100644 index 00000000..52d2b358 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-5.dat differ diff --git a/plot-test/plot/tests/test-data/pb-5.png b/plot-test/plot/tests/test-data/pb-5.png new file mode 100644 index 00000000..5f6ed1b9 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-5.png differ diff --git a/plot-test/plot/tests/test-data/pb-6.dat b/plot-test/plot/tests/test-data/pb-6.dat new file mode 100644 index 00000000..84e14c7b Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-6.dat differ diff --git a/plot-test/plot/tests/test-data/pb-6.png b/plot-test/plot/tests/test-data/pb-6.png new file mode 100644 index 00000000..057596ac Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-6.png differ diff --git a/plot-test/plot/tests/test-data/pb-7.dat b/plot-test/plot/tests/test-data/pb-7.dat new file mode 100644 index 00000000..b53f9b7a Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-7.dat differ diff --git a/plot-test/plot/tests/test-data/pb-7.png b/plot-test/plot/tests/test-data/pb-7.png new file mode 100644 index 00000000..044e8469 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-7.png differ diff --git a/plot-test/plot/tests/test-data/pb-8.dat b/plot-test/plot/tests/test-data/pb-8.dat new file mode 100644 index 00000000..b191aaf4 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-8.dat differ diff --git a/plot-test/plot/tests/test-data/pb-8.png b/plot-test/plot/tests/test-data/pb-8.png new file mode 100644 index 00000000..559a1baa Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-8.png differ diff --git a/plot-test/plot/tests/test-data/pb-9.dat b/plot-test/plot/tests/test-data/pb-9.dat new file mode 100644 index 00000000..293dffa5 Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-9.dat differ diff --git a/plot-test/plot/tests/test-data/pb-9.png b/plot-test/plot/tests/test-data/pb-9.png new file mode 100644 index 00000000..00dfd0bc Binary files /dev/null and b/plot-test/plot/tests/test-data/pb-9.png differ diff --git a/plot-test/plot/tests/test-data/sd-1.dat b/plot-test/plot/tests/test-data/sd-1.dat new file mode 100644 index 00000000..c6c2fd74 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-1.dat differ diff --git a/plot-test/plot/tests/test-data/sd-1.png b/plot-test/plot/tests/test-data/sd-1.png new file mode 100644 index 00000000..6b7d860f Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-1.png differ diff --git a/plot-test/plot/tests/test-data/sd-2.dat b/plot-test/plot/tests/test-data/sd-2.dat new file mode 100644 index 00000000..73ff3597 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-2.dat differ diff --git a/plot-test/plot/tests/test-data/sd-2.png b/plot-test/plot/tests/test-data/sd-2.png new file mode 100644 index 00000000..b1069d81 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-2.png differ diff --git a/plot-test/plot/tests/test-data/sd-3.dat b/plot-test/plot/tests/test-data/sd-3.dat new file mode 100644 index 00000000..70e0d672 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-3.dat differ diff --git a/plot-test/plot/tests/test-data/sd-3.png b/plot-test/plot/tests/test-data/sd-3.png new file mode 100644 index 00000000..6b58a62e Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-3.png differ diff --git a/plot-test/plot/tests/test-data/sd-4.dat b/plot-test/plot/tests/test-data/sd-4.dat new file mode 100644 index 00000000..a2a08298 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-4.dat differ diff --git a/plot-test/plot/tests/test-data/sd-4.png b/plot-test/plot/tests/test-data/sd-4.png new file mode 100644 index 00000000..f66d7a45 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-4.png differ diff --git a/plot-test/plot/tests/test-data/sd-5.dat b/plot-test/plot/tests/test-data/sd-5.dat new file mode 100644 index 00000000..f47826fc Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-5.dat differ diff --git a/plot-test/plot/tests/test-data/sd-5.png b/plot-test/plot/tests/test-data/sd-5.png new file mode 100644 index 00000000..599a296e Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-5.png differ diff --git a/plot-test/plot/tests/test-data/sd-6.dat b/plot-test/plot/tests/test-data/sd-6.dat new file mode 100644 index 00000000..54a19c8d Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-6.dat differ diff --git a/plot-test/plot/tests/test-data/sd-6.png b/plot-test/plot/tests/test-data/sd-6.png new file mode 100644 index 00000000..74cc4aa8 Binary files /dev/null and b/plot-test/plot/tests/test-data/sd-6.png differ diff --git a/plot-test/plot/tests/test-data/tt-1.dat b/plot-test/plot/tests/test-data/tt-1.dat new file mode 100644 index 00000000..d94746aa Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-1.dat differ diff --git a/plot-test/plot/tests/test-data/tt-1.png b/plot-test/plot/tests/test-data/tt-1.png new file mode 100644 index 00000000..cf4a9b2f Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-1.png differ diff --git a/plot-test/plot/tests/test-data/tt-10.dat b/plot-test/plot/tests/test-data/tt-10.dat new file mode 100644 index 00000000..a6e2a969 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-10.dat differ diff --git a/plot-test/plot/tests/test-data/tt-10.png b/plot-test/plot/tests/test-data/tt-10.png new file mode 100644 index 00000000..eaf43935 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-10.png differ diff --git a/plot-test/plot/tests/test-data/tt-11.dat b/plot-test/plot/tests/test-data/tt-11.dat new file mode 100644 index 00000000..9dff5f85 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-11.dat differ diff --git a/plot-test/plot/tests/test-data/tt-11.png b/plot-test/plot/tests/test-data/tt-11.png new file mode 100644 index 00000000..a3cf28e8 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-11.png differ diff --git a/plot-test/plot/tests/test-data/tt-12.dat b/plot-test/plot/tests/test-data/tt-12.dat new file mode 100644 index 00000000..c8fafee7 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-12.dat differ diff --git a/plot-test/plot/tests/test-data/tt-12.png b/plot-test/plot/tests/test-data/tt-12.png new file mode 100644 index 00000000..79fcf6f5 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-12.png differ diff --git a/plot-test/plot/tests/test-data/tt-13.dat b/plot-test/plot/tests/test-data/tt-13.dat new file mode 100644 index 00000000..0348eb8e Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-13.dat differ diff --git a/plot-test/plot/tests/test-data/tt-13.png b/plot-test/plot/tests/test-data/tt-13.png new file mode 100644 index 00000000..d33fdb5e Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-13.png differ diff --git a/plot-test/plot/tests/test-data/tt-14.dat b/plot-test/plot/tests/test-data/tt-14.dat new file mode 100644 index 00000000..33b30978 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-14.dat differ diff --git a/plot-test/plot/tests/test-data/tt-14.png b/plot-test/plot/tests/test-data/tt-14.png new file mode 100644 index 00000000..4b8c36d1 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-14.png differ diff --git a/plot-test/plot/tests/test-data/tt-15.dat b/plot-test/plot/tests/test-data/tt-15.dat new file mode 100644 index 00000000..e86b634c Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-15.dat differ diff --git a/plot-test/plot/tests/test-data/tt-15.png b/plot-test/plot/tests/test-data/tt-15.png new file mode 100644 index 00000000..75dd9cf9 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-15.png differ diff --git a/plot-test/plot/tests/test-data/tt-16.dat b/plot-test/plot/tests/test-data/tt-16.dat new file mode 100644 index 00000000..0dd3eaa2 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-16.dat differ diff --git a/plot-test/plot/tests/test-data/tt-16.png b/plot-test/plot/tests/test-data/tt-16.png new file mode 100644 index 00000000..ba954ba5 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-16.png differ diff --git a/plot-test/plot/tests/test-data/tt-17.dat b/plot-test/plot/tests/test-data/tt-17.dat new file mode 100644 index 00000000..a2921479 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-17.dat differ diff --git a/plot-test/plot/tests/test-data/tt-17.png b/plot-test/plot/tests/test-data/tt-17.png new file mode 100644 index 00000000..ca4dd05e Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-17.png differ diff --git a/plot-test/plot/tests/test-data/tt-18.dat b/plot-test/plot/tests/test-data/tt-18.dat new file mode 100644 index 00000000..4b543864 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-18.dat differ diff --git a/plot-test/plot/tests/test-data/tt-18.png b/plot-test/plot/tests/test-data/tt-18.png new file mode 100644 index 00000000..b60eadec Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-18.png differ diff --git a/plot-test/plot/tests/test-data/tt-19.dat b/plot-test/plot/tests/test-data/tt-19.dat new file mode 100644 index 00000000..af767686 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-19.dat differ diff --git a/plot-test/plot/tests/test-data/tt-19.png b/plot-test/plot/tests/test-data/tt-19.png new file mode 100644 index 00000000..a2dba6a7 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-19.png differ diff --git a/plot-test/plot/tests/test-data/tt-2.dat b/plot-test/plot/tests/test-data/tt-2.dat new file mode 100644 index 00000000..794eb7e7 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-2.dat differ diff --git a/plot-test/plot/tests/test-data/tt-2.png b/plot-test/plot/tests/test-data/tt-2.png new file mode 100644 index 00000000..5d532403 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-2.png differ diff --git a/plot-test/plot/tests/test-data/tt-20.dat b/plot-test/plot/tests/test-data/tt-20.dat new file mode 100644 index 00000000..b2e2f428 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-20.dat differ diff --git a/plot-test/plot/tests/test-data/tt-20.png b/plot-test/plot/tests/test-data/tt-20.png new file mode 100644 index 00000000..e9ef3aca Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-20.png differ diff --git a/plot-test/plot/tests/test-data/tt-21.dat b/plot-test/plot/tests/test-data/tt-21.dat new file mode 100644 index 00000000..ad4a2431 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-21.dat differ diff --git a/plot-test/plot/tests/test-data/tt-21.png b/plot-test/plot/tests/test-data/tt-21.png new file mode 100644 index 00000000..fdb92cd3 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-21.png differ diff --git a/plot-test/plot/tests/test-data/tt-22.dat b/plot-test/plot/tests/test-data/tt-22.dat new file mode 100644 index 00000000..5685dbee Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-22.dat differ diff --git a/plot-test/plot/tests/test-data/tt-22.png b/plot-test/plot/tests/test-data/tt-22.png new file mode 100644 index 00000000..bb22490f Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-22.png differ diff --git a/plot-test/plot/tests/test-data/tt-23.dat b/plot-test/plot/tests/test-data/tt-23.dat new file mode 100644 index 00000000..ab3ded46 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-23.dat differ diff --git a/plot-test/plot/tests/test-data/tt-23.png b/plot-test/plot/tests/test-data/tt-23.png new file mode 100644 index 00000000..7d6bebb3 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-23.png differ diff --git a/plot-test/plot/tests/test-data/tt-24.dat b/plot-test/plot/tests/test-data/tt-24.dat new file mode 100644 index 00000000..423d0d9d Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-24.dat differ diff --git a/plot-test/plot/tests/test-data/tt-24.png b/plot-test/plot/tests/test-data/tt-24.png new file mode 100644 index 00000000..6a646d11 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-24.png differ diff --git a/plot-test/plot/tests/test-data/tt-25.dat b/plot-test/plot/tests/test-data/tt-25.dat new file mode 100644 index 00000000..d827d98a Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-25.dat differ diff --git a/plot-test/plot/tests/test-data/tt-25.png b/plot-test/plot/tests/test-data/tt-25.png new file mode 100644 index 00000000..cd729892 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-25.png differ diff --git a/plot-test/plot/tests/test-data/tt-26.dat b/plot-test/plot/tests/test-data/tt-26.dat new file mode 100644 index 00000000..19c5ff65 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-26.dat differ diff --git a/plot-test/plot/tests/test-data/tt-26.png b/plot-test/plot/tests/test-data/tt-26.png new file mode 100644 index 00000000..3728e6a4 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-26.png differ diff --git a/plot-test/plot/tests/test-data/tt-27.dat b/plot-test/plot/tests/test-data/tt-27.dat new file mode 100644 index 00000000..01511d00 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-27.dat differ diff --git a/plot-test/plot/tests/test-data/tt-27.png b/plot-test/plot/tests/test-data/tt-27.png new file mode 100644 index 00000000..132e7856 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-27.png differ diff --git a/plot-test/plot/tests/test-data/tt-28.dat b/plot-test/plot/tests/test-data/tt-28.dat new file mode 100644 index 00000000..a94f848e Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-28.dat differ diff --git a/plot-test/plot/tests/test-data/tt-28.png b/plot-test/plot/tests/test-data/tt-28.png new file mode 100644 index 00000000..d18a50a3 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-28.png differ diff --git a/plot-test/plot/tests/test-data/tt-29.dat b/plot-test/plot/tests/test-data/tt-29.dat new file mode 100644 index 00000000..1d681680 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-29.dat differ diff --git a/plot-test/plot/tests/test-data/tt-29.png b/plot-test/plot/tests/test-data/tt-29.png new file mode 100644 index 00000000..c7077f79 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-29.png differ diff --git a/plot-test/plot/tests/test-data/tt-3.dat b/plot-test/plot/tests/test-data/tt-3.dat new file mode 100644 index 00000000..4fd366c4 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-3.dat differ diff --git a/plot-test/plot/tests/test-data/tt-3.png b/plot-test/plot/tests/test-data/tt-3.png new file mode 100644 index 00000000..964822b8 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-3.png differ diff --git a/plot-test/plot/tests/test-data/tt-30.dat b/plot-test/plot/tests/test-data/tt-30.dat new file mode 100644 index 00000000..f46db6da Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-30.dat differ diff --git a/plot-test/plot/tests/test-data/tt-30.png b/plot-test/plot/tests/test-data/tt-30.png new file mode 100644 index 00000000..9d22be38 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-30.png differ diff --git a/plot-test/plot/tests/test-data/tt-31.dat b/plot-test/plot/tests/test-data/tt-31.dat new file mode 100644 index 00000000..87926d76 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-31.dat differ diff --git a/plot-test/plot/tests/test-data/tt-31.png b/plot-test/plot/tests/test-data/tt-31.png new file mode 100644 index 00000000..c067b171 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-31.png differ diff --git a/plot-test/plot/tests/test-data/tt-32.dat b/plot-test/plot/tests/test-data/tt-32.dat new file mode 100644 index 00000000..7f72f402 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-32.dat differ diff --git a/plot-test/plot/tests/test-data/tt-32.png b/plot-test/plot/tests/test-data/tt-32.png new file mode 100644 index 00000000..afa8903b Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-32.png differ diff --git a/plot-test/plot/tests/test-data/tt-33.dat b/plot-test/plot/tests/test-data/tt-33.dat new file mode 100644 index 00000000..81c14bac Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-33.dat differ diff --git a/plot-test/plot/tests/test-data/tt-33.png b/plot-test/plot/tests/test-data/tt-33.png new file mode 100644 index 00000000..78d39cef Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-33.png differ diff --git a/plot-test/plot/tests/test-data/tt-34.dat b/plot-test/plot/tests/test-data/tt-34.dat new file mode 100644 index 00000000..26367826 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-34.dat differ diff --git a/plot-test/plot/tests/test-data/tt-34.png b/plot-test/plot/tests/test-data/tt-34.png new file mode 100644 index 00000000..0ff5b2d2 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-34.png differ diff --git a/plot-test/plot/tests/test-data/tt-35.dat b/plot-test/plot/tests/test-data/tt-35.dat new file mode 100644 index 00000000..98f1a9b6 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-35.dat differ diff --git a/plot-test/plot/tests/test-data/tt-35.png b/plot-test/plot/tests/test-data/tt-35.png new file mode 100644 index 00000000..cf775aff Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-35.png differ diff --git a/plot-test/plot/tests/test-data/tt-36.dat b/plot-test/plot/tests/test-data/tt-36.dat new file mode 100644 index 00000000..457d074a Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-36.dat differ diff --git a/plot-test/plot/tests/test-data/tt-36.png b/plot-test/plot/tests/test-data/tt-36.png new file mode 100644 index 00000000..6360ca14 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-36.png differ diff --git a/plot-test/plot/tests/test-data/tt-37.dat b/plot-test/plot/tests/test-data/tt-37.dat new file mode 100644 index 00000000..45a2d0da Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-37.dat differ diff --git a/plot-test/plot/tests/test-data/tt-37.png b/plot-test/plot/tests/test-data/tt-37.png new file mode 100644 index 00000000..62610573 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-37.png differ diff --git a/plot-test/plot/tests/test-data/tt-38.dat b/plot-test/plot/tests/test-data/tt-38.dat new file mode 100644 index 00000000..e62ea6cc Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-38.dat differ diff --git a/plot-test/plot/tests/test-data/tt-38.png b/plot-test/plot/tests/test-data/tt-38.png new file mode 100644 index 00000000..139bb2ef Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-38.png differ diff --git a/plot-test/plot/tests/test-data/tt-39.dat b/plot-test/plot/tests/test-data/tt-39.dat new file mode 100644 index 00000000..ba20bf2b Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-39.dat differ diff --git a/plot-test/plot/tests/test-data/tt-39.png b/plot-test/plot/tests/test-data/tt-39.png new file mode 100644 index 00000000..08df73a5 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-39.png differ diff --git a/plot-test/plot/tests/test-data/tt-4.dat b/plot-test/plot/tests/test-data/tt-4.dat new file mode 100644 index 00000000..67c589b8 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-4.dat differ diff --git a/plot-test/plot/tests/test-data/tt-4.png b/plot-test/plot/tests/test-data/tt-4.png new file mode 100644 index 00000000..b4de8909 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-4.png differ diff --git a/plot-test/plot/tests/test-data/tt-5.dat b/plot-test/plot/tests/test-data/tt-5.dat new file mode 100644 index 00000000..43b6fbbd Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-5.dat differ diff --git a/plot-test/plot/tests/test-data/tt-5.png b/plot-test/plot/tests/test-data/tt-5.png new file mode 100644 index 00000000..545d1db1 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-5.png differ diff --git a/plot-test/plot/tests/test-data/tt-6.dat b/plot-test/plot/tests/test-data/tt-6.dat new file mode 100644 index 00000000..d4b6e1b2 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-6.dat differ diff --git a/plot-test/plot/tests/test-data/tt-6.png b/plot-test/plot/tests/test-data/tt-6.png new file mode 100644 index 00000000..9cd7bfdb Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-6.png differ diff --git a/plot-test/plot/tests/test-data/tt-7.dat b/plot-test/plot/tests/test-data/tt-7.dat new file mode 100644 index 00000000..6786d112 Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-7.dat differ diff --git a/plot-test/plot/tests/test-data/tt-7.png b/plot-test/plot/tests/test-data/tt-7.png new file mode 100644 index 00000000..fe80c6ab Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-7.png differ diff --git a/plot-test/plot/tests/test-data/tt-8.dat b/plot-test/plot/tests/test-data/tt-8.dat new file mode 100644 index 00000000..fe28482a Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-8.dat differ diff --git a/plot-test/plot/tests/test-data/tt-8.png b/plot-test/plot/tests/test-data/tt-8.png new file mode 100644 index 00000000..3f54bf5b Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-8.png differ diff --git a/plot-test/plot/tests/test-data/tt-9.dat b/plot-test/plot/tests/test-data/tt-9.dat new file mode 100644 index 00000000..0a7b281e Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-9.dat differ diff --git a/plot-test/plot/tests/test-data/tt-9.png b/plot-test/plot/tests/test-data/tt-9.png new file mode 100644 index 00000000..1def4e0b Binary files /dev/null and b/plot-test/plot/tests/test-data/tt-9.png differ diff --git a/plot-test/plot/tests/tick-tests.rkt b/plot-test/plot/tests/tick-tests.rkt index 7e1c5dc4..7aa2048f 100644 --- a/plot-test/plot/tests/tick-tests.rkt +++ b/plot-test/plot/tests/tick-tests.rkt @@ -1,6 +1,9 @@ #lang racket -(require plot plot/utils) +(require plot plot/utils + racket/runtime-path + rackunit + "helpers.rkt") (plot-font-family 'swiss) @@ -12,235 +15,361 @@ (contour-ticks (plot-d-ticks) z-min z-max 'auto #f)))])) ;; try to verify that we always get 3-5 isosurfaces from the isosurfaces3d renderer -(time - (plot (function (λ (x) - (let ([ts (get-isosurface-ticks 1/10 (+ 1/10 x))]) - (if (empty? ts) +nan.0 (length ts)))) - #:samples 10000) - #:x-min 0 #:x-max 10 - #:x-label "bounds size (min = 1/10)" - #:y-label "number of ticks")) +(define-runtime-path tt-1-data "./test-data/tt-1.dat") +(define (do-plot-1 output-fn) + (output-fn (function (λ (x) + (let ([ts (get-isosurface-ticks 1/10 (+ 1/10 x))]) + (if (empty? ts) +nan.0 (length ts)))) + #:samples 10000) + #:x-min 0 #:x-max 10 + #:x-label "bounds size (min = 1/10)" + #:y-label "number of ticks")) ;; try to verify that we always get 3-5 isosurfaces from the isosurfaces3d renderer -(time - (plot3d (contour-intervals3d (λ (x y) - (let ([ts (get-isosurface-ticks x (+ x y))]) - (if (empty? ts) +nan.0 (length ts)))) - #:samples 101 #:line-styles '(transparent)) - #:x-min 0 #:x-max 10 #:y-min 0 #:y-max 10 - #:x-label "bounds min" #:y-label "bounds size" - #:z-label "number of ticks")) - -(time - (plot (contour-intervals (λ (x y) - (let ([ts (get-isosurface-ticks x (+ x y))]) - (if (empty? ts) +nan.0 (length ts)))) - #:samples 101) - #:x-min 0 #:x-max 10 #:y-min 0 #:y-max 10 - #:x-label "bounds min" #:y-label "bounds size")) - -(plot (function (λ (x) (count pre-tick-major? (ticks-generate (linear-ticks) 0 x))) - #e0.1 10)) -(plot (function (λ (x) (count pre-tick-major? (ticks-generate (linear-ticks #:number 40) 0 x))) - 1 100)) - -(parameterize ([plot-x-ticks (linear-ticks #:base 2 #:divisors '(1 2))] - #;[plot-y-ticks (linear-ticks #:base (* 1 2 3 4 5) #:divisors '(1 2 3 4 5))]) - (plot (function cos 0.013 2.1176))) - -(parameterize ([plot-x-transform log-transform] - [plot-x-ticks (ticks (log-ticks-layout) - (fraction-ticks-format))] - [plot-y-ticks (fraction-ticks)]) - (plot (function (λ (x) (+ 1 (cos x))) 0.0001 12))) - -(parameterize ([plot-x-ticks (date-ticks #:number 3)] - [plot-y-ticks (currency-ticks)]) - (plot (function values -1 1))) - -(parameterize* ([currency-ticks-formats uk-currency-formats] - [currency-ticks-scales uk-currency-scales] - [plot-x-ticks (date-ticks)] - [plot-y-ticks (currency-ticks #:kind 'GBP)]) - (plot (function values 101232512 2321236192))) - -(parameterize ([plot-x-ticks (currency-ticks #:kind 'EUR - #:scales eu-currency-scales - #:formats eu-currency-formats)] - [plot-y-ticks (currency-ticks)]) - (plot (function (λ (x) (* x 1.377)) 8000000 10000000) - #:title "EUR-USD Conversion, 2011-10-13" - #:x-label "Euros" - #:y-label "Dollars")) - -(parameterize ([plot-x-ticks no-ticks]) - (plot (function sin -1 4))) - -(parameterize ([plot-x-transform log-transform] - [plot-y-transform log-transform] - [plot-x-ticks (log-ticks #:base 10)] - [plot-y-ticks (log-ticks #:base 2)]) - (plot (function values 0.1 10))) - -(parameterize ([plot-x-transform log-transform] - [plot-y-transform (stretch-transform -1 1 4)] - [plot-x-ticks (ticks (linear-ticks-layout) - (log-ticks-format #:base 10))] - [plot-y-ticks (ticks (linear-ticks-layout) - (currency-ticks-format #:kind 'USD))]) - (plot (function log 0.1 10))) - -(parameterize ([plot-x-transform log-transform] - [plot-x-ticks (log-ticks #:base 10)]) - (plot (function values 10000000000000 1000000000000000))) - -(plot (polar-axes) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1) - -(plot (polar-axes) #:x-min 0 #:x-max 3 #:y-min 0 #:y-max 3) - -(plot (polar-axes) #:x-min 1 #:x-max 4 #:y-min 1 #:y-max 4) - -(plot (polar-axes #:number 12) #:x-min 10 #:x-max 12 #:y-min 10 #:y-max 12) - -(parameterize ([plot-z-transform log-transform] - [plot-z-ticks (log-ticks)] - [contour-samples (plot3d-samples)]) - (values - (plot (contours (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z")) - (plot (contour-intervals (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z")) - (plot3d (contours3d (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z")) - (plot3d (contour-intervals3d (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z")))) - -(plot (contours (λ (x y) (* 1/2 (+ (sqr x) (sqr y)))) -1 1 -1 1 #:label "z")) -(plot3d (contours3d (λ (x y) (* 1/2 (+ (sqr x) (sqr y)))) -1 1 -1 1 #:label "z")) - -(parameterize ([plot-y-ticks (ticks-scale (plot-y-ticks) (linear-scale 2 1))]) - (plot (list (function sqr -2 2) - (function sin -4 4)))) +(define-runtime-path tt-2-data "./test-data/tt-2.dat") +(define (do-plot-2 output-fn) + (output-fn (contour-intervals3d (λ (x y) + (let ([ts (get-isosurface-ticks x (+ x y))]) + (if (empty? ts) +nan.0 (length ts)))) + #:samples 101 #:line-styles '(transparent)) + #:x-min 0 #:x-max 10 #:y-min 0 #:y-max 10 + #:x-label "bounds min" #:y-label "bounds size" + #:z-label "number of ticks")) + +(define-runtime-path tt-3-data "./test-data/tt-3.dat") +(define (do-plot-3 output-fn) + (output-fn (contour-intervals (λ (x y) + (let ([ts (get-isosurface-ticks x (+ x y))]) + (if (empty? ts) +nan.0 (length ts)))) + #:samples 101) + #:x-min 0 #:x-max 10 #:y-min 0 #:y-max 10 + #:x-label "bounds min" #:y-label "bounds size")) + +(define-runtime-path tt-4-data "./test-data/tt-4.dat") +(define (do-plot-4 output-fn) + (output-fn (function (λ (x) (count pre-tick-major? (ticks-generate (linear-ticks) 0 x))) + #e0.1 10))) +(define-runtime-path tt-5-data "./test-data/tt-5.dat") +(define (do-plot-5 output-fn) + (output-fn (function (λ (x) (count pre-tick-major? (ticks-generate (linear-ticks #:number 40) 0 x))) + 1 100))) + +(define-runtime-path tt-6-data "./test-data/tt-6.dat") +(define (do-plot-6 output-fn) + (parameterize ([plot-x-ticks (linear-ticks #:base 2 #:divisors '(1 2))] + #;[plot-y-ticks (linear-ticks #:base (* 1 2 3 4 5) #:divisors '(1 2 3 4 5))]) + (output-fn (function cos 0.013 2.1176)))) + +(define-runtime-path tt-7-data "./test-data/tt-7.dat") +(define (do-plot-7 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-x-ticks (ticks (log-ticks-layout) + (fraction-ticks-format))] + [plot-y-ticks (fraction-ticks)]) + (output-fn (function (λ (x) (+ 1 (cos x))) 0.0001 12)))) + +(define-runtime-path tt-8-data "./test-data/tt-8.dat") +(define (do-plot-8 output-fn) + (parameterize ([plot-x-ticks (date-ticks #:number 3)] + [plot-y-ticks (currency-ticks)]) + (output-fn (function values -1 1)))) + +(define-runtime-path tt-9-data "./test-data/tt-9.dat") +(define (do-plot-9 output-fn) + (parameterize* ([currency-ticks-formats uk-currency-formats] + [currency-ticks-scales uk-currency-scales] + [plot-x-ticks (date-ticks)] + [plot-y-ticks (currency-ticks #:kind 'GBP)]) + (output-fn (function values 101232512 2321236192)))) + +(define-runtime-path tt-10-data "./test-data/tt-10.dat") +(define (do-plot-10 output-fn) + (parameterize ([plot-x-ticks (currency-ticks #:kind 'EUR + #:scales eu-currency-scales + #:formats eu-currency-formats)] + [plot-y-ticks (currency-ticks)]) + (output-fn (function (λ (x) (* x 1.377)) 8000000 10000000) + #:title "EUR-USD Conversion, 2011-10-13" + #:x-label "Euros" + #:y-label "Dollars"))) + +(define-runtime-path tt-11-data "./test-data/tt-11.dat") +(define (do-plot-11 output-fn) + (parameterize ([plot-x-ticks no-ticks]) + (output-fn (function sin -1 4)))) + +(define-runtime-path tt-12-data "./test-data/tt-12.dat") +(define (do-plot-12 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform log-transform] + [plot-x-ticks (log-ticks #:base 10)] + [plot-y-ticks (log-ticks #:base 2)]) + (output-fn (function values 0.1 10)))) + +(define-runtime-path tt-13-data "./test-data/tt-13.dat") +(define (do-plot-13 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-y-transform (stretch-transform -1 1 4)] + [plot-x-ticks (ticks (linear-ticks-layout) + (log-ticks-format #:base 10))] + [plot-y-ticks (ticks (linear-ticks-layout) + (currency-ticks-format #:kind 'USD))]) + (output-fn (function log 0.1 10)))) + +(define-runtime-path tt-14-data "./test-data/tt-14.dat") +(define (do-plot-14 output-fn) + (parameterize ([plot-x-transform log-transform] + [plot-x-ticks (log-ticks #:base 10)]) + (output-fn (function values 10000000000000 1000000000000000)))) + +(define-runtime-path tt-15-data "./test-data/tt-15.dat") +(define (do-plot-15 output-fn) + (output-fn (polar-axes) #:x-min -1 #:x-max 1 #:y-min -1 #:y-max 1)) + +(define-runtime-path tt-16-data "./test-data/tt-16.dat") +(define (do-plot-16 output-fn) + (output-fn (polar-axes) #:x-min 0 #:x-max 3 #:y-min 0 #:y-max 3)) + +(define-runtime-path tt-17-data "./test-data/tt-17.dat") +(define (do-plot-17 output-fn) + (output-fn (polar-axes) #:x-min 1 #:x-max 4 #:y-min 1 #:y-max 4)) + +(define-runtime-path tt-18-data "./test-data/tt-18.dat") +(define (do-plot-18 output-fn) + (output-fn (polar-axes #:number 12) #:x-min 10 #:x-max 12 #:y-min 10 #:y-max 12)) + +(define-runtime-path tt-31-data "./test-data/tt-31.dat") +(define-runtime-path tt-32-data "./test-data/tt-32.dat") +(define-runtime-path tt-33-data "./test-data/tt-33.dat") +(define-runtime-path tt-34-data "./test-data/tt-34.dat") + +(define-values (do-plot-31 do-plot-32 do-plot-33 do-plot-34) + (parameterize ([plot-z-transform log-transform] + [plot-z-ticks (log-ticks)] + [contour-samples (plot3d-samples)]) + (values + (lambda (output-fn) + (output-fn (contours (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z"))) + (lambda (output-fn) + (output-fn (contour-intervals (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z"))) + (lambda (output-fn) + (output-fn (contours3d (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z"))) + (lambda (output-fn) + (output-fn (contour-intervals3d (λ (x y) (exp (- (+ (sqr x) (sqr y))))) -2 2 -2 2 #:label "z")))))) + + +(define-runtime-path tt-19-data "./test-data/tt-19.dat") +(define (do-plot-19 output-fn) + (output-fn (contours (λ (x y) (* 1/2 (+ (sqr x) (sqr y)))) -1 1 -1 1 #:label "z"))) +(define-runtime-path tt-20-data "./test-data/tt-20.dat") +(define (do-plot-20 output-fn) + (output-fn (contours3d (λ (x y) (* 1/2 (+ (sqr x) (sqr y)))) -1 1 -1 1 #:label "z"))) + +(define-runtime-path tt-21-data "./test-data/tt-21.dat") +(define (do-plot-21 output-fn) + (parameterize ([plot-y-ticks (ticks-scale (plot-y-ticks) (linear-scale 2 1))]) + (output-fn (list (function sqr -2 2) + (function sin -4 4))))) (define exp-scale (invertible-function exp log)) -(parameterize ([plot-y-ticks (ticks-scale (log-ticks) exp-scale)]) - (plot (function values -10 10))) - -(parameterize ([plot-y-ticks (ticks-add (ticks no-ticks-layout (linear-ticks-format)) - '(1/3 2/3))]) - (plot (function sin -4 4))) - -(plot (list (function sin -4 4) - (points '(#(-3.75 -1/4)) #:size 10) - (x-ticks (list (tick 1.5 #t "3/2") (tick 3 #t "Three"))) - (y-ticks (list (tick 1/4 #t "1/4") (tick -1/4 #f ""))))) - -(parameterize ([plot-z-ticks (linear-ticks #:number 5)]) - (plot3d (list (surface3d (λ (x y) (* 2 (+ (sin x) (cos y)))) -4 4 -4 4 #:alpha 1/2) - (x-ticks (list (tick 1.5 #t "3/2") (tick 3 #t "Three"))) - (y-ticks (list (tick 1/3 #t "1/3") (tick -1/3 #f "1/3"))) - (z-ticks (list (tick pi #f "π") (tick (- pi) #t "-π")))))) - -(parameterize ([plot-title "Money for time in a sine wave"] - [plot-x-far-ticks (time-ticks)] - [plot-y-ticks (currency-ticks #:kind 'USD)] - [plot-y-far-ticks (ticks-scale (currency-ticks #:kind 'EUR) (linear-scale 1.47))] - [plot-x-label #f] - [plot-y-label #f]) - (values - (parameterize ([plot-x-axis? #f] - [plot-x-far-axis? #f]) - (plot (list (function sin -4 4) - (x-axis -0.25 #:ticks? #f #:labels? #t) - (x-axis 0.25 #:ticks? #t #:labels? #t #:far? #t)))) - - (parameterize ([plot-y-axis? #f] - [plot-y-far-axis? #f]) - (plot (list (function sin -4 4) - (y-axis -1 #:ticks? #f #:labels? #t) - (y-axis 1 #:ticks? #t #:labels? #t #:far? #t)))))) - -(parameterize ([plot-y-ticks (fraction-ticks)]) - (plot (function sin (- pi) pi))) - -(parameterize ([plot-x-far-label "x far axis"] - [plot-x-ticks (linear-ticks #:number 10)] - [plot-y-far-label "y far axis"] - [plot-y-far-ticks (date-ticks)] - [plot-z-label "z axis"] - [plot-z-far-label "z far axis"] - [plot-z-far-ticks (currency-ticks #:number 5)]) - (plot3d (surface3d (λ (x y) (+ (sin x) (cos y))) -2 2 -2 2 #:alpha 1/2) - #:angle 60 #:altitude 35)) - -(parameterize ([plot-title "Saddle"] - [plot-x-axis? #f] - [plot-y-axis? #f] - [plot-z-axis? #f] - [plot-x-far-axis? #f] - [plot-y-far-axis? #f] - [plot-z-far-axis? #f] - [plot-x-label #f] - [plot-y-label #f] - [plot-z-label #f] - [plot-x-far-label #f] - [plot-y-far-label #f] - [plot-z-far-label #f]) - (plot3d (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -2 2 -2 2 - #:label "z"))) - -(parameterize ([plot-decorations? #f]) - (values - (plot (function sin -4 4) - #:title "Hello") - (plot3d (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -2 2 -2 2)))) - -(time - (define ((degrees-ticks-format suffix) x-min x-max ts) - (map (λ (label) (format "~a\ub0~a" label suffix)) - ((linear-ticks-format) x-min x-max ts))) - - (define C-ticks (ticks (linear-ticks-layout) (degrees-ticks-format 'C))) - - (define F/C-ticks (ticks-scale - (ticks (linear-ticks-layout) (degrees-ticks-format 'F)) - (linear-scale 9/5 32))) - - (define data (list #(0 0) #(15 0.6) #(30 9.5) #(45 10.0) #(60 16.6) - #(75 41.6) #(90 42.7) #(105 65.5) #(120 78.9) - #(135 78.9) #(150 131.1) #(165 151.1) #(180 176.2))) - - (define (temp/time-trend x) (/ (sqr x) 180)) - - (define above-data (filter (λ (v) (match-let ([(vector x y) v]) - (y . > . (temp/time-trend x)))) - data)) - - (parameterize ([plot-x-ticks (time-ticks)] - [plot-y-ticks C-ticks] - [plot-y-far-ticks F/C-ticks]) - (plot (list (function temp/time-trend 0 180 #:style 'long-dash #:color 3 - #:label "Trend") - (lines data #:color 2 #:width 2) - (points data #:color 2 #:line-width 2 #:fill-color 0 #:sym 'fullcircle - #:label "Measurement") - (map (λ (d) (point-label d #:anchor 'bottom #:point-color 2 #:point-size 7)) - above-data)) - #:y-min -25 #:x-label "Time" #:y-label "Temp." - #:title "Temp./Time With Applied Heat (Measurement and Trend)"))) - -(parameterize ([plot-x-ticks (fraction-ticks)] - [plot-y-ticks (currency-ticks)]) - (plot (list (function sin -4 4) - (function-label sin 1/3)))) - -(parameterize ((plot-x-tick-label-angle 45) - (plot-x-tick-label-anchor 'top-right) - (plot-y-tick-label-angle 45) - (plot-y-tick-label-anchor 'bottom-right) - (plot-x-far-tick-label-angle 45) - (plot-x-far-tick-label-anchor 'bottom-left) - (plot-y-far-tick-label-angle 45) - (plot-y-far-tick-label-anchor 'top-left) - (plot-x-far-label "x far axis") - (plot-y-far-label "y far axis")) - (plot (list (discrete-histogram '(#(asdglkj 5399) #(liegjd 5390) #(pqlcxkgfj 3534))) - (x-ticks (list (tick 1 #t "asdgwieasdgwefj")) #:far? #t) - (y-ticks (list (tick 2500 #t "asdgwegawegfgwiej")) #:far? #t)))) +(define-runtime-path tt-22-data "./test-data/tt-22.dat") +(define (do-plot-22 output-fn) + (parameterize ([plot-y-ticks (ticks-scale (log-ticks) exp-scale)]) + (output-fn (function values -10 10)))) + +(define-runtime-path tt-23-data "./test-data/tt-23.dat") +(define (do-plot-23 output-fn) + (parameterize ([plot-y-ticks (ticks-add (ticks no-ticks-layout (linear-ticks-format)) + '(1/3 2/3))]) + (output-fn (function sin -4 4)))) + +(define-runtime-path tt-24-data "./test-data/tt-24.dat") +(define (do-plot-24 output-fn) + (output-fn (list (function sin -4 4) + (points '(#(-3.75 -1/4)) #:size 10) + (x-ticks (list (tick 1.5 #t "3/2") (tick 3 #t "Three"))) + (y-ticks (list (tick 1/4 #t "1/4") (tick -1/4 #f "")))))) + +(define-runtime-path tt-25-data "./test-data/tt-25.dat") +(define (do-plot-25 output-fn) + (parameterize ([plot-z-ticks (linear-ticks #:number 5)]) + (output-fn (list (surface3d (λ (x y) (* 2 (+ (sin x) (cos y)))) -4 4 -4 4 #:alpha 1/2) + (x-ticks (list (tick 1.5 #t "3/2") (tick 3 #t "Three"))) + (y-ticks (list (tick 1/3 #t "1/3") (tick -1/3 #f "1/3"))) + (z-ticks (list (tick pi #f "π") (tick (- pi) #t "-π"))))))) + +(define-runtime-path tt-35-data "./test-data/tt-35.dat") +(define-runtime-path tt-36-data "./test-data/tt-36.dat") +(define-values (do-plot-35 do-plot-36) + (parameterize ([plot-title "Money for time in a sine wave"] + [plot-x-far-ticks (time-ticks)] + [plot-y-ticks (currency-ticks #:kind 'USD)] + [plot-y-far-ticks (ticks-scale (currency-ticks #:kind 'EUR) (linear-scale 1.47))] + [plot-x-label #f] + [plot-y-label #f]) + (values + (lambda (output-fn) + (parameterize ([plot-x-axis? #f] + [plot-x-far-axis? #f]) + (output-fn (list (function sin -4 4) + (x-axis -0.25 #:ticks? #f #:labels? #t) + (x-axis 0.25 #:ticks? #t #:labels? #t #:far? #t))))) + + (lambda (output-fn) + (parameterize ([plot-y-axis? #f] + [plot-y-far-axis? #f]) + (output-fn (list (function sin -4 4) + (y-axis -1 #:ticks? #f #:labels? #t) + (y-axis 1 #:ticks? #t #:labels? #t #:far? #t)))))))) + +(define-runtime-path tt-26-data "./test-data/tt-26.dat") +(define (do-plot-26 output-fn) + (parameterize ([plot-y-ticks (fraction-ticks)]) + (output-fn (function sin (- pi) pi)))) + +(define-runtime-path tt-37-data "./test-data/tt-37.dat") +(define (do-plot-37 output-fn) + (parameterize ([plot-x-far-label "x far axis"] + [plot-x-ticks (linear-ticks #:number 10)] + [plot-y-far-label "y far axis"] + [plot-y-far-ticks (date-ticks)] + [plot-z-label "z axis"] + [plot-z-far-label "z far axis"] + [plot-z-far-ticks (currency-ticks #:number 5)]) + (output-fn (surface3d (λ (x y) (+ (sin x) (cos y))) -2 2 -2 2 #:alpha 1/2) + #:angle 60 #:altitude 35))) + +(define-runtime-path tt-27-data "./test-data/tt-27.dat") +(define (do-plot-27 output-fn) + (parameterize ([plot-title "Saddle"] + [plot-x-axis? #f] + [plot-y-axis? #f] + [plot-z-axis? #f] + [plot-x-far-axis? #f] + [plot-y-far-axis? #f] + [plot-z-far-axis? #f] + [plot-x-label #f] + [plot-y-label #f] + [plot-z-label #f] + [plot-x-far-label #f] + [plot-y-far-label #f] + [plot-z-far-label #f]) + (output-fn (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -2 2 -2 2 + #:label "z")))) + +(define-runtime-path tt-38-data "./test-data/tt-38.dat") +(define-runtime-path tt-39-data "./test-data/tt-39.dat") +(define-values (do-plot-38 do-plot-39) + (parameterize ([plot-decorations? #f]) + (values + (lambda (output-fn) + (output-fn (function sin -4 4) #:title "Hello")) + (lambda (output-fn) + (output-fn (contour-intervals3d (λ (x y) (- (sqr x) (sqr y))) -2 2 -2 2)))))) + +(define-runtime-path tt-28-data "./test-data/tt-28.dat") +(define (do-plot-28 output-fn) + (define ((degrees-ticks-format suffix) x-min x-max ts) + (map (λ (label) (format "~a\ub0~a" label suffix)) + ((linear-ticks-format) x-min x-max ts))) + + (define C-ticks (ticks (linear-ticks-layout) (degrees-ticks-format 'C))) + + (define F/C-ticks (ticks-scale + (ticks (linear-ticks-layout) (degrees-ticks-format 'F)) + (linear-scale 9/5 32))) + + (define data (list #(0 0) #(15 0.6) #(30 9.5) #(45 10.0) #(60 16.6) + #(75 41.6) #(90 42.7) #(105 65.5) #(120 78.9) + #(135 78.9) #(150 131.1) #(165 151.1) #(180 176.2))) + + (define (temp/time-trend x) (/ (sqr x) 180)) + + (define above-data (filter (λ (v) (match-let ([(vector x y) v]) + (y . > . (temp/time-trend x)))) + data)) + + (parameterize ([plot-x-ticks (time-ticks)] + [plot-y-ticks C-ticks] + [plot-y-far-ticks F/C-ticks]) + (output-fn (list (function temp/time-trend 0 180 #:style 'long-dash #:color 3 + #:label "Trend") + (lines data #:color 2 #:width 2) + (points data #:color 2 #:line-width 2 #:fill-color 0 #:sym 'fullcircle + #:label "Measurement") + (map (λ (d) (point-label d #:anchor 'bottom #:point-color 2 #:point-size 7)) + above-data)) + #:y-min -25 #:x-label "Time" #:y-label "Temp." + #:title "Temp./Time With Applied Heat (Measurement and Trend)"))) + +(define-runtime-path tt-29-data "./test-data/tt-29.dat") +(define (do-plot-29 output-fn) + (parameterize ([plot-x-ticks (fraction-ticks)] + [plot-y-ticks (currency-ticks)]) + (output-fn (list (function sin -4 4) + (function-label sin 1/3))))) + +(define-runtime-path tt-30-data "./test-data/tt-30.dat") +(define (do-plot-30 output-fn) + (parameterize ((plot-x-tick-label-angle 45) + (plot-x-tick-label-anchor 'top-right) + (plot-y-tick-label-angle 45) + (plot-y-tick-label-anchor 'bottom-right) + (plot-x-far-tick-label-angle 45) + (plot-x-far-tick-label-anchor 'bottom-left) + (plot-y-far-tick-label-angle 45) + (plot-y-far-tick-label-anchor 'top-left) + (plot-x-far-label "x far axis") + (plot-y-far-label "y far axis")) + (output-fn (list (discrete-histogram '(#(asdglkj 5399) #(liegjd 5390) #(pqlcxkgfj 3534))) + (x-ticks (list (tick 1 #t "asdgwieasdgwefj")) #:far? #t) + (y-ticks (list (tick 2500 #t "asdgwegawegfgwiej")) #:far? #t))))) + +(define tick-tests + (test-suite + "tick-tests" + (test-case "test case 1" (check-draw-steps do-plot-1 tt-1-data)) + (test-case "test case 2" (check-draw-steps-3d do-plot-2 tt-2-data)) + (test-case "test case 3" (check-draw-steps do-plot-3 tt-3-data)) + (test-case "test case 4" (check-draw-steps do-plot-4 tt-4-data)) + (test-case "test case 5" (check-draw-steps do-plot-5 tt-5-data)) + (test-case "test case 6" (check-draw-steps do-plot-6 tt-6-data)) + (test-case "test case 7" (check-draw-steps do-plot-7 tt-7-data)) + (test-case "test case 8" (check-draw-steps do-plot-8 tt-8-data)) + (test-case "test case 9" (check-draw-steps do-plot-9 tt-9-data)) + (test-case "test case 10" (check-draw-steps do-plot-10 tt-10-data)) + (test-case "test case 11" (check-draw-steps do-plot-11 tt-11-data)) + (test-case "test case 12" (check-draw-steps do-plot-12 tt-12-data)) + (test-case "test case 13" (check-draw-steps do-plot-13 tt-13-data)) + (test-case "test case 14" (check-draw-steps do-plot-14 tt-14-data)) + (test-case "test case 15" (check-draw-steps do-plot-15 tt-15-data)) + (test-case "test case 16" (check-draw-steps do-plot-16 tt-16-data)) + (test-case "test case 17" (check-draw-steps do-plot-17 tt-17-data)) + (test-case "test case 18" (check-draw-steps do-plot-18 tt-18-data)) + (test-case "test case 19" (check-draw-steps do-plot-19 tt-19-data)) + (test-case "test case 20" (check-draw-steps-3d do-plot-20 tt-20-data)) + (test-case "test case 21" (check-draw-steps do-plot-21 tt-21-data)) + (test-case "test case 22" (check-draw-steps do-plot-22 tt-22-data)) + (test-case "test case 23" (check-draw-steps do-plot-23 tt-23-data)) + (test-case "test case 24" (check-draw-steps do-plot-24 tt-24-data)) + (test-case "test case 25" (check-draw-steps-3d do-plot-25 tt-25-data)) + (test-case "test case 26" (check-draw-steps do-plot-26 tt-26-data)) + (test-case "test case 27" (check-draw-steps-3d do-plot-27 tt-27-data)) + (test-case "test case 28" (check-draw-steps do-plot-28 tt-28-data)) + (test-case "test case 29" (check-draw-steps do-plot-29 tt-29-data)) + (test-case "test case 30" (check-draw-steps do-plot-30 tt-30-data)) + (test-case "test case 31" (check-draw-steps do-plot-31 tt-31-data)) + (test-case "test case 32" (check-draw-steps do-plot-32 tt-32-data)) + (test-case "test case 33" (check-draw-steps-3d do-plot-33 tt-33-data)) + (test-case "test case 34" (check-draw-steps-3d do-plot-34 tt-34-data)) + (test-case "test case 35" (check-draw-steps do-plot-35 tt-35-data)) + (test-case "test case 36" (check-draw-steps do-plot-36 tt-36-data)) + (test-case "test case 37" (check-draw-steps-3d do-plot-37 tt-37-data)) + (test-case "test case 38" (check-draw-steps do-plot-38 tt-38-data)) + (test-case "test case 39" (check-draw-steps-3d do-plot-39 tt-39-data)) + )) + +(module+ test + (require rackunit/text-ui) + (run-tests tick-tests)) diff --git a/plot/info.rkt b/plot/info.rkt index 53ccf221..0e47e029 100644 --- a/plot/info.rkt +++ b/plot/info.rkt @@ -8,3 +8,8 @@ (define pkg-desc "Functions (and docs and tests) for plotting") (define pkg-authors '(ntoronto)) + +(define test-responsibles '((all AlexHarsanyi@gmail.com))) + +(define license + '(Apache-2.0 OR MIT))