diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml deleted file mode 100644 index ad13ab2..0000000 --- a/.github/workflows/CI.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: CI -on: [push] -jobs: - - Build: - runs-on: ${{ matrix.os }} - permissions: - contents: write - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - gcc_v: [10] # Version of GFortran we want to use. - python-version: [3.9] - env: - FC: gfortran-${{ matrix.gcc_v }} - GCC_V: ${{ matrix.gcc_v }} - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Python - uses: actions/setup-python@v4 # Use pip to install latest CMake, & FORD/Jin2For, etc. - with: - python-version: ${{ matrix.python-version }} - - - name: Setup Graphviz - uses: ts-graphviz/setup-graphviz@v1 - - - name: Setup Fortran Package Manager - uses: fortran-lang/setup-fpm@v5 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Install Python dependencies - if: contains( matrix.os, 'ubuntu') - run: | - python -m pip install --upgrade pip - pip install numpy matplotlib ford - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name: Install GFortran Linux - if: contains( matrix.os, 'ubuntu') - run: | - sudo apt-get install lcov - sudo add-apt-repository ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get install -y gcc-${{ matrix.gcc_v }} gfortran-${{ matrix.gcc_v }} - sudo update-alternatives \ - --install /usr/bin/gcc gcc /usr/bin/gcc-${{ matrix.gcc_v }} 100 \ - --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${{ matrix.gcc_v }} \ - --slave /usr/bin/gcov gcov /usr/bin/gcov-${{ matrix.gcc_v }} - - # - name: Compile - # run: fpm build --profile release - - - name: Run tests - run: fpm test --profile release --flag -coverage - - - name: Create coverage report - run: | - mkdir -p ${{ env.COV_DIR }} - mv ./build/gfortran_*/*/* ${{ env.COV_DIR }} - lcov --capture --initial --base-directory . --directory ${{ env.COV_DIR }} --output-file ${{ env.COV_DIR }}/coverage.base - lcov --capture --base-directory . --directory ${{ env.COV_DIR }} --output-file ${{ env.COV_DIR }}/coverage.capture - lcov --add-tracefile ${{ env.COV_DIR }}/coverage.base --add-tracefile ${{ env.COV_DIR }}/coverage.capture --output-file ${{ env.COV_DIR }}/coverage.info - env: - COV_DIR: build/coverage - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - with: - files: build/coverage/coverage.info - - - name: Build documentation - run: ford ./ford.md - - - name: Deploy Documentation - if: github.ref == 'refs/heads/master' - uses: JamesIves/github-pages-deploy-action@v4.4.1 - with: - branch: gh-pages # The branch the action should deploy to. - folder: doc # The folder the action should deploy. diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0113cb0..0000000 --- a/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -bin/ -lib/ -doc/ -build/ -__pycache__ - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Generated Test Files -test/*.png -test/*.py - -# misc -.DS_Store -/env \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0fddab1..0000000 --- a/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -PYPLOT-FORTRAN: For generating plots from Fortran using Python's matplotlib.pyplot. - -Copyright (c) 2015-2022, Jacob Williams -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* The names of its contributors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index a6bda84..0000000 --- a/README.md +++ /dev/null @@ -1,110 +0,0 @@ - -============ - -A simple module for generating plots from Fortran using Python's matplotlib.pyplot. - -### Status - -[](https://github.com/jacobwilliams/pyplot-fortran/releases/latest) - -[](https://codecov.io/gh/jacobwilliams/pyplot-fortran) - -### Overview - -Currently, this module can be used to generate simple plots from Fortran. Eventually, it may be expanded to provide additional features and other types of plots. - -The way it works is simply to generate a Python script with the plotting code, which -is then executed from the command line using the Fortran ```execute_command_line``` function. - -### Compiling - -The module requires a modern Fortran compiler (it uses various Fortran 2003/2008 features such as deferred-length strings). It should work fine with the latest gfortran or ifort compilers. - -A `fpm.toml` file is provided for compiling pyplot-fortran with the [Fortran Package Manager](https://github.com/fortran-lang/fpm). For example, to build: - -``` -fpm build --profile release -``` - -By default, the library is built with double precision (`real64`) real values. Explicitly specifying the real kind can be done using the following processor flags: - -Preprocessor flag | Kind | Number of bytes ------------------ | ----- | --------------- -`REAL32` | `real(kind=real32)` | 4 -`REAL64` | `real(kind=real64)` | 8 -`REAL128` | `real(kind=real128)` | 16 - -For example, to build a single precision version of the library, use: - -``` -fpm build --profile release --flag "-DREAL32" -``` - -To run the unit tests: - -``` -fpm test -``` - -To use `pyplot-fortran` within your fpm project, add the following to your `fpm.toml` file: -```toml -[dependencies] -pyplot-fortran = { git="https://github.com/jacobwilliams/pyplot-fortran.git" } -``` - -or, to use a specific version: -```toml -[dependencies] -pyplot-fortran = { git="https://github.com/jacobwilliams/pyplot-fortran.git", tag = "3.3.0" } -``` - -To generate the documentation using [ford](https://github.com/Fortran-FOSS-Programmers/ford), run: ```ford ford.md``` - -### Supported plot types - -* `matplotlib.pyplot.plot` -- 2D/3D plot of lines and/or markers -* `matplotlib.pyplot.bar` -- bar plot -* `matplotlib.pyplot.contour` -- contour plot -* `matplotlib.pyplot.contourf` -- filled contour plot -* `matplotlib.pyplot.imshow` -- image plot -* `matplotlib.pyplot.hist` -- histogram plot -* `matplotlib.pyplot.errorbar` -- errorbar plot -* `mpl_toolkits.mplot3d.axes3d.Axes3D.plot_surface` -- surface plot -* `mpl_toolkits.mplot3d.axes3d.Axes3D.plot_wireframe` -- 3D wireframe - -### Example - -The following example generates a plot of the sine function: - -```fortran - program test - - use,intrinsic :: iso_fortran_env, only: wp => real64 - use pyplot_module - - implicit none - - real(wp),dimension(100) :: x,sx - type(pyplot) :: plt - integer :: i - - !generate some data: - x = [(real(i,wp), i=0,size(x)-1)]/5.0_wp - sx = sin(x) - - !plot it: - call plt%initialize(grid=.true.,xlabel='angle (rad)',& - title='Plot of $\sin(x)$',legend=.true.) - call plt%add_plot(x,sx,label='$\sin(x)$',linestyle='b-o',markersize=5,linewidth=2) - call plt%savefig('sinx.png', pyfile='sinx.py') - - end program test -``` - -### Documentation - - * The API documentation for the current ```master``` branch can be found [here](https://jacobwilliams.github.io/pyplot-fortran/). This is generated by processing the source files with [FORD](https://github.com/Fortran-FOSS-Programmers/ford). - -### See also - - * [Matplotlib](https://matplotlib.org) diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 20a843d..0000000 --- a/codecov.yml +++ /dev/null @@ -1,13 +0,0 @@ -comment: - layout: header, changes, diff, sunburst -coverage: - ignore: - - test - - doc - status: - patch: - default: - target: 20% - project: - default: - target: 70% diff --git a/css/font-awesome.css b/css/font-awesome.css new file mode 100644 index 0000000..4040b3c --- /dev/null +++ b/css/font-awesome.css @@ -0,0 +1,1672 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.2.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} diff --git a/css/font-awesome.min.css b/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/css/local.css b/css/local.css new file mode 100644 index 0000000..f1a3262 --- /dev/null +++ b/css/local.css @@ -0,0 +1,298 @@ +body { + padding-top: 70px; +} +table.nostretch { + width=100% +} +.nostretch td { + class='block' +} +.nostretch tr td{ + width:1%; + white-space:nowrap; +} + +html { + scroll-padding-top: 70px; +} + +ol.hierarchy { + min-height: 40px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.smallcaps { + font-variant: small-caps; +} +.well .sidebar { + padding: 8px 0 +} +.sidebar a { + padding: 0px,0px,0px,0px +} +.varlist>tbody>tr>td { + padding-left: 3px; + padding-right: 3px; +} +.varlist>tbody>tr>td:first-child, .varlist>thead>tr>td:first-child { + padding-left: 8px; +} +.varlist>tbody>td>td:last-child, .varlist>thead>tr>td:last-child { + padding-right: 8px; +} + +.highlight pre { + overflow-x: auto; + overflow-wrap: normal; + white-space: pre +} + +/* .hl is for when line numbers are included, .highlight is for all + other cases. */ +.hl pre { + counter-reset: line-numbering; + overflow-x: auto; + overflow-wrap: normal; + white-space: pre; + padding: 0; + padding-right: 9.5px; + overflow-y: hidden; + padding-bottom: 9.5px; +} + +.hl pre a::before { + content: counter(line-numbering); + counter-increment: line-numbering; + padding-right: 0.7em; /* space after numbers */ + margin-top: 4.5em; + width: 60px; + text-align: right; + opacity: 0.7; + display: inline-block; + color: #aaa; + background: #eee; + margin-right: 10px; + border-right: 1px solid #ccc; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.hl pre a:first-of-type::before { + padding-top: 9.5px; +} + +.hl pre a:last-of-type::before { + padding-bottom: 9.5px; +} + +.hl pre a:only-of-type::before { + padding: 9.5px; +} + +.hl pre a { + display: inline-block; + height: 4.5em; + margin: -4.5em 0 0; +} +.codesum h3 { + margin-top: 2px; + margin-bottom: 2px; +} + +h1.inline, h2.inline, h3.inline { + display: inline; +} + +.depwarn { + float: right; +} + +.anchor { + position: absolute; + margin: -4.5em; + visibility:hidden; +} + +.alert { + margin-left: 5px; + margin-right: 5px; + margin-top: 5px; +} + +.alert-title { + margin-top: 0; + color: inherit; +} + +div.toc { + font-size: 14.73px; + padding-left: 0px; + padding-right: 0px; +} + +div.toc a { + padding-left: 20px; + padding-right: 20px; + margin-right: 15px; + padding-top: 5px; + padding-bottom: 5px; +} + +div.toc li { + font-size: 0.95em; + padding-left: 15px; +} + +div.toc li.title { + font-size: 1em; +} + +div.toc hr { + margin-top: 12px; + margin-bottom: 10px; +} + +.in-well { + padding: 0px 0px; + margin-bottom: 0px; + float:right; +} + +table tr.submod>td { + border-top: none; + font-size: 13.5px; +} + +.graph-help { + font-size: 10px; +} + +.depgraph { + width: 100%; + max-width: 1140px; +} + +#sidebar a { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.highlighttable { + width: auto; + table-layout: fixed; +} + +ul.checklist { + list-style-type: none; +} + +ul.checklist input[type="checkbox"] { + margin-left: -20.8px; + margin-right: 4.55px; +} + +.gitter-chat-embed { + z-index: 100000; +} + +table.graph { + text-align: center; +} + + +.graph td.root { + border:2px solid black; + padding:10px; +} + +.graph td.triangle-right:after { + content: ""; + display: block; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + border-left: 7px solid black; +} + +.graph td.triangle-left:after { + content: ""; + display: block; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + border-right: 7px solid black; +} + +.graph td.node { + color: white; + padding:10px; + border-style: solid; + border-width: 3px 0px 3px 0px; + border-color: white; +} + +.graph td.node a{ + color: white; +} + +.graph td.dashedText, +.graph td.solidText { + padding: 0px 10px 0px 10px; + min-width: 40px; + color: black; + border-color: black; +} + +.graph td.dashedText { + border-bottom-style: dashed; +} + +.graph td.solidText { + border-bottom-style: solid; +} + +.graph td.dashedBottom, +.graph td.dashedTop, +.graph td.solidTop, +.graph td.solidBottom { + min-width: 40px; + color: transparent; + border-color: black; +} + +.graph td.dashedBottom { + border-bottom-style: dashed; +} + +.graph td.dashedTop { + border-top-style: dashed; +} + +.graph td.solidBottom { + border-bottom-style: solid; +} + +.graph td.solidTop { + border-top-style: solid; +} + +/* Ensure tables in Pages don't collapse horizontally */ +td, th { + padding-right: 10px; +} + +.nav>li>a { + padding-left: 10px; + padding-right: 10px; +} + +.nav > .nav { + margin-left: 16px; +} diff --git a/css/pygments.css b/css/pygments.css new file mode 100644 index 0000000..c4b2fd9 --- /dev/null +++ b/css/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.codehilite .hll { background-color: #ffffcc } +.codehilite { background: #f8f8f8; } +.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */ +.codehilite .err { border: 1px solid #FF0000 } /* Error */ +.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ +.codehilite .o { color: #666666 } /* Operator */ +.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #9C6500 } /* Comment.Preproc */ +.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #A00000 } /* Generic.Deleted */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.codehilite .gr { color: #E40000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #008400 } /* Generic.Inserted */ +.codehilite .go { color: #717171 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0044DD } /* Generic.Traceback */ +.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ +.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.codehilite .kt { color: #B00040 } /* Keyword.Type */ +.codehilite .m { color: #666666 } /* Literal.Number */ +.codehilite .s { color: #BA2121 } /* Literal.String */ +.codehilite .na { color: #687822 } /* Name.Attribute */ +.codehilite .nb { color: #008000 } /* Name.Builtin */ +.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.codehilite .no { color: #880000 } /* Name.Constant */ +.codehilite .nd { color: #AA22FF } /* Name.Decorator */ +.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #0000FF } /* Name.Function */ +.codehilite .nl { color: #767600 } /* Name.Label */ +.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.codehilite .nv { color: #19177C } /* Name.Variable */ +.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ +.codehilite .mb { color: #666666 } /* Literal.Number.Bin */ +.codehilite .mf { color: #666666 } /* Literal.Number.Float */ +.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ +.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ +.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ +.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ +.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ +.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ +.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ +.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.codehilite .sx { color: #008000 } /* Literal.String.Other */ +.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */ +.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ +.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ +.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #0000FF } /* Name.Function.Magic */ +.codehilite .vc { color: #19177C } /* Name.Variable.Class */ +.codehilite .vg { color: #19177C } /* Name.Variable.Global */ +.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ +.codehilite .vm { color: #19177C } /* Name.Variable.Magic */ +.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/favicon.png b/favicon.png new file mode 100644 index 0000000..4d6ad16 Binary files /dev/null and b/favicon.png differ diff --git a/fonts/FontAwesome.otf b/fonts/FontAwesome.otf new file mode 100644 index 0000000..81c9ad9 Binary files /dev/null and b/fonts/FontAwesome.otf differ diff --git a/fonts/fontawesome-webfont.eot b/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..84677bc Binary files /dev/null and b/fonts/fontawesome-webfont.eot differ diff --git a/fonts/fontawesome-webfont.svg b/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..d907b25 --- /dev/null +++ b/fonts/fontawesome-webfont.svg @@ -0,0 +1,520 @@ + + + \ No newline at end of file diff --git a/fonts/fontawesome-webfont.ttf b/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..96a3639 Binary files /dev/null and b/fonts/fontawesome-webfont.ttf differ diff --git a/fonts/fontawesome-webfont.woff b/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..628b6a5 Binary files /dev/null and b/fonts/fontawesome-webfont.woff differ diff --git a/fonts/glyphicons-halflings-regular.eot b/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000..4a4ca86 Binary files /dev/null and b/fonts/glyphicons-halflings-regular.eot differ diff --git a/fonts/glyphicons-halflings-regular.svg b/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 0000000..25691af --- /dev/null +++ b/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + \ No newline at end of file diff --git a/fonts/glyphicons-halflings-regular.ttf b/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000..67fa00b Binary files /dev/null and b/fonts/glyphicons-halflings-regular.ttf differ diff --git a/fonts/glyphicons-halflings-regular.woff b/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000..8c54182 Binary files /dev/null and b/fonts/glyphicons-halflings-regular.woff differ diff --git a/ford.md b/ford.md deleted file mode 100644 index b8bde2f..0000000 --- a/ford.md +++ /dev/null @@ -1,19 +0,0 @@ -project: pyplot-fortran -project_dir: src -output_dir: doc -media_dir: ./media -project_github: https://github.com/jacobwilliams/pyplot-fortran -summary: For generating plots from Fortran using Python's matplotlib.pyplot -author: Jacob Williams -github: https://github.com/jacobwilliams -predocmark_alt: > -predocmark: < -docmark_alt: -docmark: ! -display: public - protected - private -source: true -graph: true - -{!README.md!} \ No newline at end of file diff --git a/fpm.toml b/fpm.toml deleted file mode 100644 index 6bf0409..0000000 --- a/fpm.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "pyplot-fortran" -version = "3.1.0" -author = "Jacob Williams" -maintainer = "Jacob Williams" -copyright = "Copyright (c) 2015-2022, Jacob Williams" -license = "BSD-3" -description = "A simple module for generating plots from Fortran using Python's matplotlib.pyplot." -homepage = "https://github.com/jacobwilliams/pyplot-fortran" - -[library] -source-dir = "src" - -[install] -library = true - -[build] -auto-executables = false -auto-examples = false -auto-tests = true \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..fe6727d --- /dev/null +++ b/index.html @@ -0,0 +1,298 @@ + + + + +
+ + + + + + + +For generating plots from Fortran using Python's matplotlib.pyplot
+Find us on…
++ GitHub + + + + +
+A simple module for generating plots from Fortran using Python's matplotlib.pyplot.
+Currently, this module can be used to generate simple plots from Fortran. Eventually, it may be expanded to provide additional features and other types of plots.
+The way it works is simply to generate a Python script with the plotting code, which
+is then executed from the command line using the Fortran execute_command_line
function.
The module requires a modern Fortran compiler (it uses various Fortran 2003/2008 features such as deferred-length strings). It should work fine with the latest gfortran or ifort compilers.
+A fpm.toml
file is provided for compiling pyplot-fortran with the Fortran Package Manager. For example, to build:
fpm build --profile release
+
By default, the library is built with double precision (real64
) real values. Explicitly specifying the real kind can be done using the following processor flags:
Preprocessor flag | +Kind | +Number of bytes | +
---|---|---|
REAL32 |
+real(kind=real32) |
+4 | +
REAL64 |
+real(kind=real64) |
+8 | +
REAL128 |
+real(kind=real128) |
+16 | +
For example, to build a single precision version of the library, use:
+fpm build --profile release --flag "-DREAL32"
+
To run the unit tests:
+fpm test
+
To use pyplot-fortran
within your fpm project, add the following to your fpm.toml
file:
[dependencies]
+pyplot-fortran = { git="https://github.com/jacobwilliams/pyplot-fortran.git" }
+
or, to use a specific version:
+[dependencies]
+pyplot-fortran = { git="https://github.com/jacobwilliams/pyplot-fortran.git", tag = "3.3.0" }
+
To generate the documentation using ford, run: ford ford.md
matplotlib.pyplot.plot
-- 2D/3D plot of lines and/or markersmatplotlib.pyplot.bar
-- bar plotmatplotlib.pyplot.contour
-- contour plotmatplotlib.pyplot.contourf
-- filled contour plotmatplotlib.pyplot.imshow
-- image plotmatplotlib.pyplot.hist
-- histogram plotmatplotlib.pyplot.errorbar
-- errorbar plotmpl_toolkits.mplot3d.axes3d.Axes3D.plot_surface
-- surface plotmpl_toolkits.mplot3d.axes3d.Axes3D.plot_wireframe
-- 3D wireframeThe following example generates a plot of the sine function:
+ program test
+
+ use,intrinsic :: iso_fortran_env, only: wp => real64
+ use pyplot_module
+
+ implicit none
+
+ real(wp),dimension(100) :: x,sx
+ type(pyplot) :: plt
+ integer :: i
+
+ !generate some data:
+ x = [(real(i,wp), i=0,size(x)-1)]/5.0_wp
+ sx = sin(x)
+
+ !plot it:
+ call plt%initialize(grid=.true.,xlabel='angle (rad)',&
+ title='Plot of $\sin(x)$',legend=.true.)
+ call plt%add_plot(x,sx,label='$\sin(x)$',linestyle='b-o',markersize=5,linewidth=2)
+ call plt%savefig('sinx.png', pyfile='sinx.py')
+
+ end program test
+
master
branch can be found here. This is generated by processing the source files with FORD.Module | Source File | Description |
---|---|---|
pyplot_module | +pyplot_module.F90 | +For making simple x-y plots from Fortran. + It works by generating a Python script and executing it. |
+
Procedure | Location | Procedure Type | Description |
---|---|---|---|
add_3d_plot | +pyplot_module | +Subroutine | +Add a 3D x,y,z plot. |
+
add_bar | +pyplot_module | +Subroutine | +Add a bar plot. |
+
add_contour | +pyplot_module | +Subroutine | +Add a contour plot. |
+
add_errorbar | +pyplot_module | +Subroutine | +Add an x,y plot with errorbars. |
+
add_hist | +pyplot_module | +Subroutine | +Add a histogram plot. |
+
add_imshow | +pyplot_module | +Subroutine | +Add an image plot using |
+
add_plot | +pyplot_module | +Subroutine | +Add an x,y plot. |
+
add_sphere | +pyplot_module | +Subroutine | +Add a sphere to a 3D x,y,z plot. |
+
add_str | +pyplot_module | +Subroutine | +Add a string to the buffer. |
+
destroy | +pyplot_module | +Subroutine | +Destructor. |
+
execute | +pyplot_module | +Subroutine | +Write the buffer to a file, and then execute it with Python. |
+
finish_ops | +pyplot_module | +Subroutine | +Some final things to add before saving or showing the figure. |
+
initialize | +pyplot_module | +Subroutine | +Initialize a plot |
+
integer_to_string | +pyplot_module | +Subroutine | +Integer to string conversion. |
+
matrix_to_string | +pyplot_module | +Subroutine | +Real matrix (rank 2) to string. |
+
optional_int_to_string | +pyplot_module | +Subroutine | +Integer to string, specifying the default value if +the optional argument is not present. |
+
optional_logical_to_string | +pyplot_module | +Subroutine | +Logical to string, specifying the default value if +the optional argument is not present. |
+
plot_surface | +pyplot_module | +Subroutine | +Add a surface plot. |
+
plot_wireframe | +pyplot_module | +Subroutine | +Add a wireframe plot. |
+
real_to_string | +pyplot_module | +Subroutine | +Real scalar to string. |
+
savefig | +pyplot_module | +Subroutine | +Save the figure. |
+
showfig | +pyplot_module | +Subroutine | +Shows the figure. |
+
vec_to_string | +pyplot_module | +Subroutine | +Real vector to string. |
+
Type | Location | Extends | Description |
---|---|---|---|
pyplot | +pyplot_module | +None | +The main pyplot class. |
+
For making simple x-y plots from Fortran. + It works by generating a Python script and executing it.
+Note
+The default real kind (wp
) can be
+ changed using optional preprocessor flags.
+ This library was built with real kind:
+ real(kind=real64)
[8 bytes]
Type | +Visibility | Attributes | ++ | Name | +Initial | + | |
---|---|---|---|---|---|---|---|
+ + integer, + | +public, | ++parameter + | +:: | +pyplot_wp | += | +real64 | +
+ real kind used by this module [8 bytes] + |
+
+ + integer, + | +private, | ++parameter + | +:: | +wp | += | +pyplot_wp | +
+ local copy of |
+
+ + character(len=*), + | +private, | ++parameter + | +:: | +tmp_file | += | +'pyplot_module_temp_1234567890.py' | +
+ Default name of the temporary file +(this can also be user-specified). + |
+
+ + character(len=*), + | +private, | ++parameter + | +:: | +python_exe | += | +'python' | +
+ The python executable name. + |
+
+ + character(len=*), + | +private, | ++parameter + | +:: | +int_fmt | += | +'(I10)' | +
+ integer format string + |
+
+ + integer, + | +private, | ++parameter + | +:: | +max_int_len | += | +10 | +
+ max string length for integers + |
+
+ + character(len=*), + | +private, | ++parameter + | +:: | +real_fmt_default | += | +'(E30.16)' | +
+ default real number format string + |
+
+ + integer, + | +private, | ++parameter + | +:: | +max_real_len | += | +60 | +
+ max string length for reals + |
+
The main pyplot class.
+ +Type | +Visibility | Attributes | ++ | Name | +Initial | + | |
---|---|---|---|---|---|---|---|
+ + character(len=:), + | +private, | ++ allocatable + | +:: | +str | ++ | + |
+ string buffer + |
+
+ + character(len=1), + | +private | ++ + | +:: | +raw_str_token | += | +' ' | +
+ will be 'r' if using raw strings + |
+
+ + logical, + | +private | ++ + | +:: | +show_legend | += | +.false. | +
+ show legend into plot + |
+
+ + logical, + | +private | ++ + | +:: | +use_numpy | += | +.true. | +
+ use numpy python module + |
+
+ + logical, + | +private | ++ + | +:: | +use_oo_api | += | +.false. | +
+ use OO interface of matplotlib (incopatible with showfig subroutine) + |
+
+ + logical, + | +private | ++ + | +:: | +mplot3d | += | +.false. | +
+ it is a 3d plot + |
+
+ + logical, + | +private | ++ + | +:: | +polar | += | +.false. | +
+ it is a polar plot + |
+
+ + logical, + | +private | ++ + | +:: | +axis_equal | += | +.false. | +
+ equal scale on each axis + |
+
+ + logical, + | +private | ++ + | +:: | +axisbelow | += | +.true. | +
+ axis below other chart elements + |
+
+ + logical, + | +private | ++ + | +:: | +tight_layout | += | +.false. | +
+ tight layout option + |
+
+ + logical, + | +private | ++ + | +:: | +usetex | += | +.false. | +
+ enable LaTeX + |
+
+ + character(len=:), + | +private, | ++ allocatable + | +:: | +xaxis_date_fmt | ++ | + |
+ date format for the x-axis. Example: |
+
+ + character(len=:), + | +private, | ++ allocatable + | +:: | +yaxis_date_fmt | ++ | + |
+ date format for the y-axis. Example: |
+
+ + character(len=:), + | +private, | ++ allocatable + | +:: | +real_fmt | ++ | + |
+ real number formatting + |
+
procedure, public :: + initialize | +../../ initialize pyplot instance |
+
procedure, public :: + add_plot | +../../ add a 2d plot to pyplot instance |
+
procedure, public :: + add_errorbar | +../../ add a 2d error bar plot to pyplot instance |
+
procedure, public :: + add_3d_plot | +../../ add a 3d plot to pyplot instance |
+
procedure, public :: + add_sphere | +../../ add a 3d sphere to pyplot instance |
+
procedure, public :: + add_contour | +../../ add a contour plot to pyplot instance |
+
procedure, public :: + plot_wireframe | +../../ add a wireframe plot to pyplot instance |
+
procedure, public :: + plot_surface | +../../ add a surface plot to pyplot instance |
+
procedure, public :: + add_bar | +../../ add a barplot to pyplot instance |
+
procedure, public :: + add_imshow | +../../ add an image plot (using |
+
procedure, public :: + add_hist | +../../ add a histogram plot to pyplot instance |
+
procedure, public :: + savefig | +../../ save plots of pyplot instance |
+
procedure, public :: + showfig | +../../ show plots of pyplot instance |
+
procedure, public :: + destroy | +../../ destroy pyplot instance |
+
procedure, public :: + execute | +../../ execute pyplot commands |
+
procedure, public :: + add_str | +../../ add string to pytplot instance buffer |
+
procedure, public :: + finish_ops | +../../ some final ops before saving |
+
Destructor.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+
Add a string to the buffer.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +str | +
+ str to be added to pyplot handler buffer + |
+
Initialize a plot
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + logical, + | +intent(in), | +optional | + + | +:: | +grid | +
+ activate grid drawing + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xlabel | +
+ label of x axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +ylabel | +
+ label of y axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +zlabel | +
+ label of z axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +title | +
+ plot title + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +legend | +
+ plot legend + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +use_numpy | +
+ activate usage of numpy python module + |
+
+ + integer, + | +intent(in), | +optional, | + dimension(2) + | +:: | +figsize | +
+ dimension of the figure + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +font_size | +
+ font size + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +axes_labelsize | +
+ size of axis labels + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +xtick_labelsize | +
+ size of x axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +ytick_labelsize | +
+ size of y axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +ztick_labelsize | +
+ size of z axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +legend_fontsize | +
+ size of legend font + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +mplot3d | +
+ set true for 3d plots (cannot use with polar) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +axis_equal | +
+ set true for axis = 'equal' + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +polar | +
+ set true for polar plots (cannot use with mplot3d) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +real_fmt | +
+ format string for real numbers (examples: '(E30.16)' [default], '*') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +use_oo_api | +
+ avoid matplotlib's GUI by using the OO interface (cannot use with showfig) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +axisbelow | +
+ to put the grid lines below the other chart elements [default is true] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +tight_layout | +
+ enable tight layout [default is false] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +raw_strings | +
+ if True, all strings sent to Python are treated as +raw strings (e.g., r'str'). Default is False. + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +usetex | +
+ if True, enable LaTeX. (default if false) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xaxis_date_fmt | +
+ if present, used to set the date format for the x-axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yaxis_date_fmt | +
+ if present, used to set the date format for the y-axis + |
+
Add an x,y plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +color | +
+ RGB color tuple [0-1,0-1,0-1] + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a histogram plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ array of data + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +bins | +
+ number of bins + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +normed | +
+ boolean flag that determines whether bin counts are normalized [NO LONGER USED] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +cumulative | +
+ boolean flag that determines whether histogram represents the cumulative density of dataset + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a contour plot.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line [only used when |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ color of the contour line + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +filled | +
+ use filled control (default=False) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a surface plot.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ Color of the surface patches + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ The surface is made opaque by using antialiased=False + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a wireframe plot.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ Color of the surface patches + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ The surface is made opaque by using antialiased=False + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a 3D x,y,z plot.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +z | +
+ z values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a sphere to a 3D x,y,z plot.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +r | +
+ radius of the sphere + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +xc | +
+ x value of sphere center + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +yc | +
+ y value of sphere center + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +zc | +
+ z value of sphere center + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +n_facets | +
+ [default is 100] + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ line width + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ enabled anti-aliasing + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ color of the contour line + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add a bar plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x bar values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +height | +
+ height bar values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +width | +
+ width values + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +bottom | +
+ bottom values + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ plot color + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +yerr | +
+ yerr values + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +align | +
+ default: 'center' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add an image plot using imshow
.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Add an x,y plot with errorbars.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +xerr | +
+ x errorbar sizes + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +yerr | +
+ y errorbar sizes + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +color | +
+ RGB color tuple [0-1,0-1,0-1] + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
Integer to string, specifying the default value if +the optional argument is not present.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + integer, + | +intent(in), | +optional | + + | +:: | +int_value | +
+ integer value + |
+
+ + character(len=*), + | +intent(out) | ++ + | +:: | +string_value | +
+ integer value stringified + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +default_value | +
+ default integer value + |
+
Logical to string, specifying the default value if +the optional argument is not present.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + logical, + | +intent(in), | +optional | + + | +:: | +logical_value | ++ + | +
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +string_value | +
+ integer value stringified + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +default_value | +
+ default integer value + |
+
Integer to string conversion.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + integer, + | +intent(in), | +optional | + + | +:: | +i | +
+ integer value + |
+
+ + character(len=*), + | +intent(out) | ++ + | +:: | +s | +
+ integer value stringified + |
+
Real scalar to string.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+
Real vector to string.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+ |
+ + logical, + | +intent(in) | ++ + | +:: | +use_numpy | +
+ activate numpy python module usage + |
+ |
+ + logical, + | +intent(in), | +optional | + + | +:: | +is_tuple | +
+ if true [default], use '()', if false use '[]' + |
+
Real matrix (rank 2) to string.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+ |
+ + logical, + | +intent(in) | ++ + | +:: | +use_numpy | +
+ activate numpy python module usage + |
+
Write the buffer to a file, and then execute it with Python.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pytplot handler + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the python script to generate + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
Some final things to add before saving or showing the figure.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+
Save the figure.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +figfile | +
+ file name for the figure + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the Python script to generate + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +dpi | +
+ resolution of the figure for png +[note this is a string] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +transparent | +
+ transparent background (T/F) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +facecolor | +
+ the colors of the figure rectangle + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +edgecolor | +
+ the colors of the figure rectangle + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +orientation | +
+ 'landscape' or 'portrait' + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
Shows the figure.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the Python script to generate + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
Add a 3D x,y,z plot.
+Note
+Must initialize the class with mplot3d=.true.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +z | +
+ z values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_3d_plot(me, x, y, z, label, linestyle, markersize, linewidth, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + real(wp), dimension(:), intent (in) :: z !! z values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call vec_to_string(z, me%real_fmt, zstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !write the plot statement: + call me%add_str('ax.plot('//& + trim(xname)//','//& + trim(yname)//','//& + trim(zname)//','//& + trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'")') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_3d_plot: pyplot class not properly initialized.' + end if + + end subroutine add_3d_plot +
Add a bar plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x bar values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +height | +
+ height bar values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +width | +
+ width values + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +bottom | +
+ bottom values + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ plot color + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +yerr | +
+ yerr values + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +align | +
+ default: 'center' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_bar(me, x, height, label, width, bottom, color, & + yerr, align, xlim, ylim, xscale, yscale, istat) + + class(pyplot), intent(inout) :: me !! pyplot handler + real(wp), dimension(:), intent(in) :: x !! x bar values + real(wp), dimension(:), intent(in) :: height !! height bar values + character(len=*), intent(in) :: label !! plot label + real(wp), dimension(:), intent(in), optional :: width !! width values + real(wp), dimension(:), intent(in), optional :: bottom !! bottom values + character(len=*), intent(in), optional :: color !! plot color + real(wp), dimension(:), intent(in), optional :: yerr !! yerr values + character(len=*), intent(in), optional :: align !! default: 'center' + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x axis values stringified + character(len=:), allocatable :: ystr !! y axis values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: wstr !! width values stringified + character(len=:), allocatable :: bstr !! bottom values stringified + character(len=:), allocatable :: plt_str !! plot string + character(len=:), allocatable :: yerr_str !! yerr values stringified + character(len=*), parameter :: xname = 'x' !! x axis name + character(len=*), parameter :: yname = 'y' !! y axis name + character(len=*), parameter :: wname = 'w' !! width name + character(len=*), parameter :: bname = 'b' !! bottom name + character(len=*), parameter :: yerrname = 'yerr' !! yerr name + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(height, me%real_fmt, ystr, me%use_numpy) + if (present(width)) call vec_to_string(width, me%real_fmt, wstr, me%use_numpy) + if (present(bottom)) call vec_to_string(bottom, me%real_fmt, bstr, me%use_numpy) + if (present(yerr)) call vec_to_string(yerr, me%real_fmt, yerr_str, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + if (present(width)) call me%add_str(trim(wname)//' = '//wstr) + if (present(bottom)) call me%add_str(trim(bname)//' = '//bstr) + if (present(yerr)) call me%add_str(trim(yerrname)//' = '//yerr_str) + call me%add_str('') + + !create the plot string: + plt_str = 'ax.bar('//& + 'x='//trim(xname)//','//& + 'height='//trim(yname)//',' + if (present(yerr)) plt_str=plt_str//'yerr='//trim(yerrname)//',' + if (present(width)) plt_str=plt_str//'width='//trim(wname)//',' + if (present(bottom)) plt_str=plt_str//'bottom='//trim(bstr)//',' + if (present(color)) plt_str=plt_str//'color='//trim(me%raw_str_token)//'"'//trim(color)//'",' + if (present(align)) plt_str=plt_str//'align='//trim(me%raw_str_token)//'"'//trim(align)//'",' + plt_str=plt_str//'label='//trim(me%raw_str_token)//'"'//trim(label)//'")' + + !write the plot statement: + call me%add_str(plt_str) + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_bar: pyplot class not properly initialized.' + end if + + end subroutine add_bar +
Add a contour plot.
+Note
+This requires use_numpy
to be True.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line [only used when |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ color of the contour line + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +filled | +
+ use filled control (default=False) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_contour(me, x, y, z, linestyle, linewidth, levels, color, & + filled, cmap, colorbar, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line [only used when `filled=False`] + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! color of the contour line + logical, intent (in), optional :: filled !! use filled control (default=False) + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + character(len=:), allocatable :: contourfunc !! 'contour' or 'contourf' + logical :: is_filled !! if it is a filled contour plot + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !filled or regular: + contourfunc = 'contour' !default + is_filled = .false. + if (present(filled)) then + is_filled = filled + if (filled) contourfunc = 'contourf' !filled contour + end if + + !write the plot statement: + call me%add_str('CS = ax.'//contourfunc//'('//xname_//','//yname_//','//zname_//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + if (.not. is_filled) call me%add_str('ax.clabel(CS, fontsize=9, inline=1)') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_contour +
Add an x,y plot with errorbars.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +xerr | +
+ x errorbar sizes + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +yerr | +
+ y errorbar sizes + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +color | +
+ RGB color tuple [0-1,0-1,0-1] + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_errorbar(me, x, y, label, linestyle, xerr, yerr, markersize, linewidth, xlim, ylim, xscale, yscale, color, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + real(wp), dimension(:), intent (in), optional :: xerr !! x errorbar sizes + real(wp), dimension(:), intent (in), optional :: yerr !! y errorbar sizes + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + real(wp),dimension(:), intent (in), optional :: color !! RGB color tuple [0-1,0-1,0-1] + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: arg_str !! the arguments to pass to `plot` + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: xerrstr !! xerr values stringified + character(len=:), allocatable :: yerrstr !! yerr values stringified + character(len=:), allocatable :: color_str !! color values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: xerrname = 'xerr' !! xerr variable name for script + character(len=*), parameter :: yerrname = 'yerr' !! yerr variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + !errorbar sizes (optional): + if (present(xerr)) call vec_to_string(xerr, me%real_fmt, xerrstr, me%use_numpy) + if (present(yerr)) call vec_to_string(yerr, me%real_fmt, yerrstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str('') + if (present(xerr)) call me%add_str(trim(xerrname)//' = '//xerrstr) + if (present(yerr)) call me%add_str(trim(yerrname)//' = '//yerrstr) + if (present(xerr) .or. present(yerr)) call me%add_str('') + + !main arguments for plot: + arg_str = trim(xname)//','//& + trim(yname)//','//& + 'fmt='//trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'"' + + ! optional arguments: + if (present(xerr)) then + arg_str = arg_str//','//'xerr='//trim(xerrname) + end if + if (present(yerr)) then + arg_str = arg_str//','//'yerr='//trim(yerrname) + end if + if (present(color)) then + if (size(color)<=3) then + call vec_to_string(color(1:3), '*', color_str, use_numpy=.false., is_tuple=.true.) + arg_str = arg_str//',color='//trim(color_str) + end if + end if + + !write the plot statement: + call me%add_str('ax.errorbar('//arg_str//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_errorbar: pyplot class not properly initialized.' + end if + + end subroutine add_errorbar +
Add a histogram plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ array of data + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +bins | +
+ number of bins + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +normed | +
+ boolean flag that determines whether bin counts are normalized [NO LONGER USED] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +cumulative | +
+ boolean flag that determines whether histogram represents the cumulative density of dataset + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_hist(me, x, label, xlim, ylim, xscale, yscale, bins, normed, cumulative, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! array of data + character(len=*), intent (in) :: label !! plot label + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + integer, intent (in), optional :: bins !! number of bins + logical, intent (in), optional :: normed !! boolean flag that determines whether bin counts are normalized [NO LONGER USED] + logical, intent (in), optional :: cumulative !! boolean flag that determines whether histogram represents the cumulative density of dataset + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: cumulativestr !! + character(len=max_int_len) :: binsstr !! + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str('') + + !get optional inputs (if not present, set default value): + call optional_int_to_string(bins, binsstr, '10') + call optional_logical_to_string(cumulative, cumulativestr, 'False') + + !write the plot statement: + call me%add_str('ax.hist('//& + trim(xname)//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'bins='//trim(binsstr)//','//& + 'cumulative='//trim(cumulativestr)//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_hist +
Add an image plot using imshow
.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_imshow(me, x, xlim, ylim, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:,:),intent (in) :: x !! x values + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=*), parameter :: xname = 'x' !! x variable name for script + + !axis limits (optional): + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call matrix_to_string(x, me%real_fmt, xstr, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str('') + + !write the plot statement: + call me%add_str('ax.imshow('//trim(xname)//')') + call me%add_str('') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_imshow: pyplot class not properly initialized.' + end if + + end subroutine add_imshow +
Add an x,y plot.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +markersize | +
+ size of the plot markers + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +xlim | +
+ x-axis range + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(2) + | +:: | +ylim | +
+ y-axis range + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xscale | +
+ example: 'linear' (default), 'log' + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yscale | +
+ example: 'linear' (default), 'log' + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +color | +
+ RGB color tuple [0-1,0-1,0-1] + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_plot(me, x, y, label, linestyle, markersize, linewidth, xlim, ylim, xscale, yscale, color, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + real(wp),dimension(:), intent (in), optional :: color !! RGB color tuple [0-1,0-1,0-1] + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: arg_str !! the arguments to pass to `plot` + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: color_str !! color values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str('') + + !main arguments for plot: + arg_str = trim(xname)//','//& + trim(yname)//','//& + trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'"' + + ! optional arguments: + if (present(color)) then + if (size(color)<=3) then + call vec_to_string(color(1:3), '*', color_str, use_numpy=.false., is_tuple=.true.) + arg_str = arg_str//',color='//trim(color_str) + end if + end if + + !write the plot statement: + call me%add_str('ax.plot('//arg_str//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_plot +
Add a sphere to a 3D x,y,z plot.
+Note
+Must initialize the class with mplot3d=.true.
and use_numpy=.true.
.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +r | +
+ radius of the sphere + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +xc | +
+ x value of sphere center + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +yc | +
+ y value of sphere center + |
+ |
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +zc | +
+ z value of sphere center + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +n_facets | +
+ [default is 100] + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ line width + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ enabled anti-aliasing + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ color of the contour line + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine add_sphere(me, r, xc, yc, zc, n_facets, linewidth, antialiased, color, istat) + + implicit none + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), intent (in) :: r !! radius of the sphere + real(wp), intent (in) :: xc !! x value of sphere center + real(wp), intent (in) :: yc !! y value of sphere center + real(wp), intent (in) :: zc !! z value of sphere center + integer, intent (in), optional :: n_facets !! [default is 100] + integer, intent (in), optional :: linewidth !! line width + logical, intent (in), optional :: antialiased !! enabled anti-aliasing + character(len=*), intent (in), optional :: color !! color of the contour line + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: rstr !! `r` value stringified + character(len=:), allocatable :: xcstr !! `xc` value stringified + character(len=:), allocatable :: ycstr !! `yc` value stringified + character(len=:), allocatable :: zcstr !! `zc` value stringified + character(len=*), parameter :: xname = 'x' !! `x` variable name for script + character(len=*), parameter :: yname = 'y' !! `y` variable name for script + character(len=*), parameter :: zname = 'z' !! `z` variable name for script + + character(len=max_int_len) :: linewidth_str !! `linewidth` input stringified + character(len=:), allocatable :: antialiased_str !! `antialised` input stringified + character(len=max_int_len) :: n_facets_str !! `n_facets` input stringified + character(len=:), allocatable :: extras !! optional stuff string + + if (allocated(me%str)) then + + !get optional inputs (if not present, set default value): + call optional_int_to_string(n_facets, n_facets_str, '100') + extras = '' + if (present(linewidth)) then + call optional_int_to_string(linewidth, linewidth_str, '1') + extras = extras//','//'linewidth='//linewidth_str + end if + if (present(antialiased)) then + call optional_logical_to_string(antialiased, antialiased_str, 'False') + extras = extras//','//'antialiased='//antialiased_str + end if + if (present(color)) then + extras = extras//','//'color='//trim(me%raw_str_token)//'"'//trim(color)//'"' + end if + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call real_to_string(r , me%real_fmt, rstr) + call real_to_string(xc, me%real_fmt, xcstr) + call real_to_string(yc, me%real_fmt, ycstr) + call real_to_string(zc, me%real_fmt, zcstr) + + ! sphere code: + call me%add_str('u = np.linspace(0, 2 * np.pi, '//n_facets_str//')') + call me%add_str('v = np.linspace(0, np.pi, '//n_facets_str//')') + call me%add_str(xname//' = '//xcstr//' + '//rstr//' * np.outer(np.cos(u), np.sin(v))') + call me%add_str(yname//' = '//ycstr//' + '//rstr//' * np.outer(np.sin(u), np.sin(v))') + call me%add_str(zname//' = '//zcstr//' + '//rstr//' * np.outer(np.ones(np.size(u)), np.cos(v))') + call me%add_str('ax.plot_surface('//xname//', '//yname//', '//zname//extras//')') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_sphere: pyplot class not properly initialized.' + end if + + end subroutine add_sphere +
Add a string to the buffer.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +str | +
+ str to be added to pyplot handler buffer + |
+
subroutine add_str(me,str) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in) :: str !! str to be added to pyplot handler buffer + + integer :: n_old !! current `me%str` length + integer :: n_str !! length of input `str` + character(len=:),allocatable :: tmp !! tmp string for building the result + + ! original + !me%str = me%str//str//new_line(' ') + + if (len(str)==0) return + + ! the above can sometimes cause a stack overflow in the + ! intel Fortran compiler, so we replace with this: + if (allocated(me%str)) then + n_old = len(me%str) + n_str = len(str) + allocate(character(len=n_old+n_str+1) :: tmp) + tmp(1:n_old) = me%str + tmp(n_old+1:) = str//new_line(' ') + call move_alloc(tmp, me%str) + else + allocate(me%str, source = str//new_line(' ')) + end if + + end subroutine add_str +
Destructor.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+
subroutine destroy(me) + + class(pyplot),intent(inout) :: me !! pyplot handler + + if (allocated(me%str)) deallocate(me%str) + if (allocated(me%real_fmt)) deallocate(me%real_fmt) + + me%raw_str_token = ' ' + + end subroutine destroy +
Write the buffer to a file, and then execute it with Python.
+If user specifies a Python file name, then the file is kept, otherwise +a temporary filename is used, and the file is deleted after it is used.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pytplot handler + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the python script to generate + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
subroutine execute(me, pyfile, istat, python) + + class(pyplot), intent(inout) :: me !! pytplot handler + character(len=*), intent(in), optional :: pyfile !! name of the python script to generate + integer, intent (out),optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + integer :: iunit !! IO unit + character(len=:), allocatable :: file !! file name + logical :: scratch !! if a scratch file is to be used + integer :: iostat !! open/close status code + character(len=:), allocatable :: python_ !! python executable to use + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + scratch = (.not. present(pyfile)) + + !file name to use: + if (scratch) then + file = trim(tmp_file) !use the default + else + file = trim(pyfile) !use the user-specified name + end if + + if (file == '') then + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error: filename is blank.' + return + end if + + !open the file: + open(newunit=iunit, file=file, status='REPLACE', iostat=iostat) + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error opening file: '//trim(file) + return + end if + + !write to the file: + write(iunit, '(A)') me%str + + !to ensure that the file is there for the next + !command line call, we have to close it here. + close(iunit, iostat=iostat) + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error closing file: '//trim(file) + else + + if (present(python)) then + python_ = trim(python) + else + python_ = python_exe + end if + + !run the file using python: + if (file(1:1)/='"') then + ! if not already in quotes, should enclose in quotes + call execute_command_line(python_//' "'//file//'"') + else + call execute_command_line(python_//' '//file) + end if + + if (scratch) then + !delete the file (have to reopen it because + !Fortran has no file delete function) + open(newunit=iunit, file=file, status='OLD', iostat=iostat) + if (iostat==0) close(iunit, status='DELETE', iostat=iostat) + end if + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error closing file.' + end if + + end if + + !cleanup: + if (allocated(file)) deallocate(file) + + else + if (present(istat)) istat = -1 + end if + + end subroutine execute +
Some final things to add before saving or showing the figure.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+
subroutine finish_ops(me) + + class(pyplot),intent(inout) :: me !! pyplot handler + + if (me%show_legend) then + call me%add_str('ax.legend(loc="best")') + call me%add_str('') + end if + if (me%axis_equal) then + if (me%mplot3d) then + call me%add_str('ax.set_aspect("auto")') + call me%add_str('') + + call me%add_str('def set_axes_equal(ax):') + call me%add_str(' x_limits = ax.get_xlim3d()') + call me%add_str(' y_limits = ax.get_ylim3d()') + call me%add_str(' z_limits = ax.get_zlim3d()') + call me%add_str(' x_range = abs(x_limits[1] - x_limits[0])') + call me%add_str(' x_middle = np.mean(x_limits)') + call me%add_str(' y_range = abs(y_limits[1] - y_limits[0])') + call me%add_str(' y_middle = np.mean(y_limits)') + call me%add_str(' z_range = abs(z_limits[1] - z_limits[0])') + call me%add_str(' z_middle = np.mean(z_limits)') + call me%add_str(' plot_radius = 0.5*max([x_range, y_range, z_range])') + call me%add_str(' ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius])') + call me%add_str(' ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius])') + call me%add_str(' ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])') + call me%add_str('set_axes_equal(ax)') + + else + call me%add_str('ax.axis("equal")') + end if + call me%add_str('') + end if + if (allocated(me%xaxis_date_fmt) .or. allocated(me%yaxis_date_fmt)) then + call me%add_str('from matplotlib.dates import DateFormatter') + if (allocated(me%xaxis_date_fmt)) & + call me%add_str('ax.xaxis.set_major_formatter(DateFormatter("'//trim(me%xaxis_date_fmt)//'"))') + if (allocated(me%yaxis_date_fmt)) & + call me%add_str('ax.yaxis.set_major_formatter(DateFormatter("'//trim(me%yaxis_date_fmt)//'"))') + call me%add_str('') + end if + if (me%tight_layout) then + call me%add_str('fig.tight_layout()') + call me%add_str('') + end if + + end subroutine finish_ops +
Initialize a plot
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + logical, + | +intent(in), | +optional | + + | +:: | +grid | +
+ activate grid drawing + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xlabel | +
+ label of x axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +ylabel | +
+ label of y axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +zlabel | +
+ label of z axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +title | +
+ plot title + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +legend | +
+ plot legend + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +use_numpy | +
+ activate usage of numpy python module + |
+
+ + integer, + | +intent(in), | +optional, | + dimension(2) + | +:: | +figsize | +
+ dimension of the figure + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +font_size | +
+ font size + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +axes_labelsize | +
+ size of axis labels + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +xtick_labelsize | +
+ size of x axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +ytick_labelsize | +
+ size of y axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +ztick_labelsize | +
+ size of z axis tick lables + |
+
+ + integer, + | +intent(in), | +optional | + + | +:: | +legend_fontsize | +
+ size of legend font + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +mplot3d | +
+ set true for 3d plots (cannot use with polar) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +axis_equal | +
+ set true for axis = 'equal' + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +polar | +
+ set true for polar plots (cannot use with mplot3d) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +real_fmt | +
+ format string for real numbers (examples: '(E30.16)' [default], '*') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +use_oo_api | +
+ avoid matplotlib's GUI by using the OO interface (cannot use with showfig) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +axisbelow | +
+ to put the grid lines below the other chart elements [default is true] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +tight_layout | +
+ enable tight layout [default is false] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +raw_strings | +
+ if True, all strings sent to Python are treated as +raw strings (e.g., r'str'). Default is False. + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +usetex | +
+ if True, enable LaTeX. (default if false) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +xaxis_date_fmt | +
+ if present, used to set the date format for the x-axis + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +yaxis_date_fmt | +
+ if present, used to set the date format for the y-axis + |
+
subroutine initialize(me, grid, xlabel, ylabel, zlabel, title, legend, use_numpy, figsize, & + font_size, axes_labelsize, xtick_labelsize, ytick_labelsize, ztick_labelsize, & + legend_fontsize, mplot3d, axis_equal, polar, real_fmt, use_oo_api, axisbelow,& + tight_layout, raw_strings, usetex, xaxis_date_fmt, yaxis_date_fmt) + + class(pyplot), intent(inout) :: me !! pyplot handler + logical, intent(in), optional :: grid !! activate grid drawing + character(len=*), intent(in), optional :: xlabel !! label of x axis + character(len=*), intent(in), optional :: ylabel !! label of y axis + character(len=*), intent(in), optional :: zlabel !! label of z axis + character(len=*), intent(in), optional :: title !! plot title + logical, intent(in), optional :: legend !! plot legend + logical, intent(in), optional :: use_numpy !! activate usage of numpy python module + integer, dimension(2), intent(in), optional :: figsize !! dimension of the figure + integer, intent(in), optional :: font_size !! font size + integer, intent(in), optional :: axes_labelsize !! size of axis labels + integer, intent(in), optional :: xtick_labelsize !! size of x axis tick lables + integer, intent(in), optional :: ytick_labelsize !! size of y axis tick lables + integer, intent(in), optional :: ztick_labelsize !! size of z axis tick lables + integer, intent(in), optional :: legend_fontsize !! size of legend font + logical, intent(in), optional :: mplot3d !! set true for 3d plots (cannot use with polar) + logical, intent(in), optional :: axis_equal !! set true for axis = 'equal' + logical, intent(in), optional :: polar !! set true for polar plots (cannot use with mplot3d) + character(len=*), intent(in), optional :: real_fmt !! format string for real numbers (examples: '(E30.16)' [default], '*') + logical, intent(in), optional :: use_oo_api !! avoid matplotlib's GUI by using the OO interface (cannot use with showfig) + logical, intent(in), optional :: axisbelow !! to put the grid lines below the other chart elements [default is true] + logical, intent(in), optional :: tight_layout !! enable tight layout [default is false] + logical, intent(in), optional :: raw_strings !! if True, all strings sent to Python are treated as + !! raw strings (e.g., r'str'). Default is False. + logical, intent(in), optional :: usetex !! if True, enable LaTeX. (default if false) + character(len=*), intent(in), optional :: xaxis_date_fmt !! if present, used to set the date format for the x-axis + character(len=*), intent(in), optional :: yaxis_date_fmt !! if present, used to set the date format for the y-axis + + character(len=max_int_len) :: width_str !! figure width dummy string + character(len=max_int_len) :: height_str !! figure height dummy string + character(len=max_int_len) :: font_size_str !! font size dummy string + character(len=max_int_len) :: axes_labelsize_str !! size of axis labels dummy string + character(len=max_int_len) :: xtick_labelsize_str !! size of x axis tick labels dummy string + character(len=max_int_len) :: ytick_labelsize_str !! size of x axis tick labels dummy string + character(len=max_int_len) :: ztick_labelsize_str !! size of z axis tick labels dummy string + character(len=max_int_len) :: legend_fontsize_str !! size of legend font dummy string + character(len=:),allocatable :: python_fig_func !! Python's function for creating a new Figure instance + + character(len=*), parameter :: default_font_size_str = '10' !! the default font size for plots + + call me%destroy() + + if (present(raw_strings)) then + if (raw_strings) me%raw_str_token = 'r' + end if + + if (present(legend)) then + me%show_legend = legend + else + me%show_legend = .false. + end if + if (present(use_numpy)) then + me%use_numpy = use_numpy + else + me%use_numpy = .true. + end if + if (present(use_oo_api)) then + me%use_oo_api = use_oo_api + else + me%use_oo_api = .false. + end if + if (present(figsize)) then + call integer_to_string(figsize(1), width_str) + call integer_to_string(figsize(2), height_str) + end if + if (present(mplot3d)) then + me%mplot3d = mplot3d + else + me%mplot3d = .false. + end if + if (present(polar)) then + me%polar = polar + else + me%polar = .false. + end if + if (present(axis_equal)) then + me%axis_equal = axis_equal + else + me%axis_equal = .false. + end if + if (present(real_fmt)) then + me%real_fmt = trim(adjustl(real_fmt)) + else + me%real_fmt = real_fmt_default + end if + if (present(tight_layout)) then + me%tight_layout = tight_layout + else + me%tight_layout = .false. + end if + if (present(usetex)) then + me%usetex = usetex + else + me%usetex = .false. + end if + if (present(xaxis_date_fmt)) then + me%xaxis_date_fmt = xaxis_date_fmt + else + if (allocated(me%xaxis_date_fmt)) deallocate(me%xaxis_date_fmt) + end if + if (present(yaxis_date_fmt)) then + me%yaxis_date_fmt = yaxis_date_fmt + else + if (allocated(me%yaxis_date_fmt)) deallocate(me%yaxis_date_fmt) + end if + + call optional_int_to_string(font_size, font_size_str, default_font_size_str) + call optional_int_to_string(axes_labelsize, axes_labelsize_str, default_font_size_str) + call optional_int_to_string(xtick_labelsize, xtick_labelsize_str, default_font_size_str) + call optional_int_to_string(ytick_labelsize, ytick_labelsize_str, default_font_size_str) + call optional_int_to_string(ztick_labelsize, ztick_labelsize_str, default_font_size_str) + call optional_int_to_string(legend_fontsize, legend_fontsize_str, default_font_size_str) + + me%str = '' + + call me%add_str('#!/usr/bin/env python') + call me%add_str('') + + call me%add_str('import matplotlib') + if (me%use_oo_api) then + call me%add_str('from matplotlib.figure import Figure') + call me%add_str('from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas') + else + call me%add_str('import matplotlib.pyplot as plt') + endif + if (me%mplot3d) call me%add_str('from mpl_toolkits.mplot3d import Axes3D') + if (me%use_numpy) call me%add_str('import numpy as np') + call me%add_str('') + + call me%add_str('matplotlib.rcParams["font.family"] = "Serif"') + call me%add_str('matplotlib.rcParams["font.size"] = '//trim(font_size_str)) + call me%add_str('matplotlib.rcParams["axes.labelsize"] = '//trim(axes_labelsize_str)) + call me%add_str('matplotlib.rcParams["xtick.labelsize"] = '//trim(xtick_labelsize_str)) + call me%add_str('matplotlib.rcParams["ytick.labelsize"] = '//trim(ytick_labelsize_str)) + call me%add_str('matplotlib.rcParams["legend.fontsize"] = '//trim(legend_fontsize_str)) + if (me%usetex) call me%add_str('matplotlib.rcParams["text.usetex"] = True') + + call me%add_str('') + + if (me%use_oo_api) then + python_fig_func = 'Figure' + else + python_fig_func = 'plt.figure' + endif + if (present(figsize)) then !if specifying the figure size + call me%add_str('fig = '//python_fig_func//'(figsize=('//trim(width_str)//','//trim(height_str)//'),facecolor="white")') + else + call me%add_str('fig = '//python_fig_func//'(facecolor="white")') + end if + + if (me%mplot3d) then + call me%add_str('ax = fig.add_subplot(1, 1, 1, projection=''3d'')') + elseif (me%polar) then + call me%add_str('ax = fig.add_subplot(1, 1, 1, projection=''polar'')') + else + call me%add_str('ax = fig.add_subplot(1, 1, 1)') + end if + + if (present(grid)) then + if (grid) call me%add_str('ax.grid()') + end if + + if (present(axisbelow)) then + me%axisbelow = axisbelow + else + me%axisbelow = .true. ! default + end if + if (me%axisbelow) call me%add_str('ax.set_axisbelow(True)') + + if (present(xlabel)) call me%add_str('ax.set_xlabel('//trim(me%raw_str_token)//'"'//trim(xlabel)//'")') + if (present(ylabel)) call me%add_str('ax.set_ylabel('//trim(me%raw_str_token)//'"'//trim(ylabel)//'")') + if (present(zlabel)) call me%add_str('ax.set_zlabel('//trim(me%raw_str_token)//'"'//trim(zlabel)//'")') + if (present(title)) call me%add_str('ax.set_title('//trim(me%raw_str_token)//'"' //trim(title) //'")') + + call me%add_str('') + + end subroutine initialize +
Integer to string conversion.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + integer, + | +intent(in), | +optional | + + | +:: | +i | +
+ integer value + |
+
+ + character(len=*), + | +intent(out) | ++ + | +:: | +s | +
+ integer value stringified + |
+
subroutine integer_to_string(i, s) + + integer, intent(in), optional :: i !! integer value + character(len=*), intent(out) :: s !! integer value stringified + + integer :: istat !! IO status + + write(s, int_fmt, iostat=istat) i + + if (istat/=0) then + write(error_unit,'(A)') 'Error converting integer to string' + s = '****' + else + s = adjustl(s) + end if + + end subroutine integer_to_string +
Real matrix (rank 2) to string.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+ |
+ + logical, + | +intent(in) | ++ + | +:: | +use_numpy | +
+ activate numpy python module usage + |
+
subroutine matrix_to_string(v, fmt, str, use_numpy) + + real(wp), dimension(:,:), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + logical, intent(in) :: use_numpy !! activate numpy python module usage + + integer :: i !! counter + character(len=:),allocatable :: tmp !! dummy string + + str = '[' + do i=1, size(v,1) !rows + call vec_to_string(v(i,:), fmt, tmp, use_numpy) !one row at a time + str = str//trim(adjustl(tmp)) + if (i<size(v,1)) str = str // ',' + end do + str = str // ']' + + !convert to numpy array if necessary: + if (use_numpy) str = 'np.array('//str//')' + + end subroutine matrix_to_string +
Integer to string, specifying the default value if +the optional argument is not present.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + integer, + | +intent(in), | +optional | + + | +:: | +int_value | +
+ integer value + |
+
+ + character(len=*), + | +intent(out) | ++ + | +:: | +string_value | +
+ integer value stringified + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +default_value | +
+ default integer value + |
+
subroutine optional_int_to_string(int_value, string_value, default_value) + + integer, intent(in), optional :: int_value !! integer value + character(len=*), intent(out) :: string_value !! integer value stringified + character(len=*), intent(in) :: default_value !! default integer value + + if (present(int_value)) then + call integer_to_string(int_value, string_value) + else + string_value = default_value + end if + + end subroutine optional_int_to_string +
Logical to string, specifying the default value if +the optional argument is not present.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + logical, + | +intent(in), | +optional | + + | +:: | +logical_value | ++ + | +
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +string_value | +
+ integer value stringified + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +default_value | +
+ default integer value + |
+
subroutine optional_logical_to_string(logical_value, string_value, default_value) + + logical,intent(in),optional :: logical_value + character(len=:),allocatable,intent(out) :: string_value !! integer value stringified + character(len=*),intent(in) :: default_value !! default integer value + + if (present(logical_value)) then + if (logical_value) then + string_value = 'True' + else + string_value = 'False' + end if + else + string_value = default_value + end if + + end subroutine optional_logical_to_string +
Add a surface plot.
+Note
+This requires use_numpy
to be True.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ Color of the surface patches + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ The surface is made opaque by using antialiased=False + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine plot_surface(me, x, y, z, label, linestyle, linewidth, levels, color, & + cmap, colorbar, antialiased, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! Color of the surface patches + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + logical, intent (in), optional :: antialiased !! The surface is made opaque by using antialiased=False + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=:), allocatable :: antialiasedstr !! antialiased stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + call optional_logical_to_string(antialiased, antialiasedstr, 'False') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !write the plot statement: + call me%add_str('CS = ax.plot_surface'//'('//xname_//','//yname_//','//zname_//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'antialiased='//trim(antialiasedstr)//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine plot_surface +
Add a wireframe plot.
+Note
+This requires use_numpy
to be True.
Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +x | +
+ x values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +y | +
+ y values + |
+ |
+ + real(kind=wp), + | +intent(in), | ++ dimension(:,:) + | +:: | +z | +
+ z values (a matrix) + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +label | +
+ plot label + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +linestyle | +
+ style of the plot line + |
+ |
+ + integer, + | +intent(in), | +optional | + + | +:: | +linewidth | +
+ width of the plot line + |
+
+ + real(kind=wp), + | +intent(in), | +optional, | + dimension(:) + | +:: | +levels | +
+ contour levels to plot + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +color | +
+ Color of the surface patches + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +cmap | +
+ colormap if filled=True (examples: 'jet', 'bone') + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +colorbar | +
+ add a colorbar (default=False) + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +antialiased | +
+ The surface is made opaque by using antialiased=False + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
subroutine plot_wireframe(me, x, y, z, label, linestyle, linewidth, levels, color, & + cmap, colorbar, antialiased, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! Color of the surface patches + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + logical, intent (in), optional :: antialiased !! The surface is made opaque by using antialiased=False + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=:), allocatable :: antialiasedstr !! antialiased stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + call optional_logical_to_string(antialiased, antialiasedstr, 'False') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !write the plot statement: + call me%add_str('CS = ax.plot_wireframe'//'('//xname_//','//yname_//','//zname_//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'antialiased='//trim(antialiasedstr)//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine plot_wireframe +
Real scalar to string.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in) | ++ + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+
subroutine real_to_string(v, fmt, str) + + real(wp), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + + integer :: istat !! IO status + character(len=max_real_len) :: tmp !! dummy string + + if (fmt=='*') then + write(tmp, *, iostat=istat) v + else + write(tmp, fmt, iostat=istat) v + end if + if (istat/=0) then + write(error_unit,'(A)') 'Error in real_to_string' + str = '****' + else + str = trim(adjustl(tmp)) + end if + + end subroutine real_to_string +
Save the figure.
+Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +figfile | +
+ file name for the figure + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the Python script to generate + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +dpi | +
+ resolution of the figure for png +[note this is a string] + |
+
+ + logical, + | +intent(in), | +optional | + + | +:: | +transparent | +
+ transparent background (T/F) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +facecolor | +
+ the colors of the figure rectangle + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +edgecolor | +
+ the colors of the figure rectangle + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +orientation | +
+ 'landscape' or 'portrait' + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
subroutine savefig(me, figfile, pyfile, dpi, transparent, facecolor, edgecolor, orientation, istat, python) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in) :: figfile !! file name for the figure + character(len=*), intent(in), optional :: pyfile !! name of the Python script to generate + character(len=*), intent(in), optional :: dpi !! resolution of the figure for png + !! [note this is a string] + logical, intent(in), optional :: transparent !! transparent background (T/F) + character(len=*), intent(in), optional :: facecolor !! the colors of the figure rectangle + character(len=*), intent(in), optional :: edgecolor !! the colors of the figure rectangle + character(len=*), intent(in), optional :: orientation !! 'landscape' or 'portrait' + integer, intent (out), optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + character(len=:),allocatable :: tmp !! for building the `savefig` arguments. + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !finish up the string: + call me%finish_ops() + + !build the savefig arguments: + tmp = trim(me%raw_str_token)//'"'//trim(figfile)//'"' + if (present(dpi)) tmp = tmp//', dpi='//trim(dpi) + if (present(transparent)) then + if (transparent) then + tmp = tmp//', transparent=True' + else + tmp = tmp//', transparent=False' + end if + end if + if (present(facecolor)) tmp = tmp//', facecolor="'//trim(facecolor)//'"' + if (present(edgecolor)) tmp = tmp//', edgecolor="'//trim(edgecolor)//'"' + if (present(orientation)) tmp = tmp//', orientation="'//trim(orientation)//'"' + if (me%use_oo_api) then + call me%add_str('canvas = FigureCanvas(fig)') + call me%add_str('canvas.print_figure('//tmp//')') + else + call me%add_str('plt.savefig('//tmp//')') + endif + deallocate(tmp) + + !run it: + call me%execute(pyfile, istat=istat, python=python) + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'error in savefig: pyplot class not properly initialized.' + end if + + end subroutine savefig +
Shows the figure.
+ +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + class(pyplot), + | +intent(inout) | ++ + | +:: | +me | +
+ pyplot handler + |
+ |
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +pyfile | +
+ name of the Python script to generate + |
+
+ + integer, + | +intent(out), | +optional | + + | +:: | +istat | +
+ status output (0 means no problems) + |
+
+ + character(len=*), + | +intent(in), | +optional | + + | +:: | +python | +
+ python executable to use. (by default, this is 'python') + |
+
subroutine showfig(me, pyfile, istat, python) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in), optional :: pyfile !! name of the Python script to generate + integer, intent (out), optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + if (.not. allocated(me%str)) then + + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'error in showfig: pyplot class not properly initialized.' + + else if (me%use_oo_api) then + + if (present(istat)) istat = -2 + write(error_unit,'(A)') 'error in showfig: not compatible with "use_oo_api" option' + + else + + if (present(istat)) istat = 0 + + !finish up the string: + call me%finish_ops() + + !show figure: + call me%add_str('plt.show()') + + !run it: + call me%execute(pyfile, istat=istat, python=python) + + end if + + end subroutine showfig +
Real vector to string.
+ + +Type | +Intent | Optional | Attributes | ++ | Name | ++ |
---|---|---|---|---|---|---|
+ + real(kind=wp), + | +intent(in), | ++ dimension(:) + | +:: | +v | +
+ real values + |
+ |
+ + character(len=*), + | +intent(in) | ++ + | +:: | +fmt | +
+ real format string + |
+ |
+ + character(len=:), + | +intent(out), | ++ allocatable + | +:: | +str | +
+ real values stringified + |
+ |
+ + logical, + | +intent(in) | ++ + | +:: | +use_numpy | +
+ activate numpy python module usage + |
+ |
+ + logical, + | +intent(in), | +optional | + + | +:: | +is_tuple | +
+ if true [default], use '()', if false use '[]' + |
+
subroutine vec_to_string(v, fmt, str, use_numpy, is_tuple) + + real(wp), dimension(:), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + logical, intent(in) :: use_numpy !! activate numpy python module usage + logical,intent(in),optional :: is_tuple !! if true [default], use '()', if false use '[]' + + integer :: i !! counter + integer :: istat !! IO status + character(len=max_real_len) :: tmp !! dummy string + logical :: tuple + + if (present(is_tuple)) then + tuple = is_tuple + else + tuple = .false. + end if + + if (tuple) then + str = '(' + else + str = '[' + end if + + do i=1, size(v) + if (fmt=='*') then + write(tmp, *, iostat=istat) v(i) + else + write(tmp, fmt, iostat=istat) v(i) + end if + if (istat/=0) then + write(error_unit,'(A)') 'Error in vec_to_string' + str = '****' + return + end if + str = str//trim(adjustl(tmp)) + if (i<size(v)) str = str // ',' + end do + + if (tuple) then + str = str // ')' + else + str = str // ']' + end if + + !convert to numpy array if necessary: + if (use_numpy) str = 'np.array('//str//')' + + end subroutine vec_to_string +
!***************************************************************************************** +!> author: Jacob Williams +! date: 6/16/2017 +! license: BSD +! +! For making simple x-y plots from Fortran. +! It works by generating a Python script and executing it. +! +!# See also +! * Inspired by: [EasyPlot](https://pypi.python.org/pypi/EasyPlot) +! +!@note The default real kind (`wp`) can be +! changed using optional preprocessor flags. +! This library was built with real kind: +#ifdef REAL32 +! `real(kind=real32)` [4 bytes] +#elif REAL64 +! `real(kind=real64)` [8 bytes] +#elif REAL128 +! `real(kind=real128)` [16 bytes] +#else +! `real(kind=real64)` [8 bytes] +#endif + + module pyplot_module + + use, intrinsic :: iso_fortran_env + + implicit none + + private + +#ifdef REAL32 + integer,parameter,public :: pyplot_wp = real32 !! real kind used by this module [4 bytes] +#elif REAL64 + integer,parameter,public :: pyplot_wp = real64 !! real kind used by this module [8 bytes] +#elif REAL128 + integer,parameter,public :: pyplot_wp = real128 !! real kind used by this module [16 bytes] +#else + integer,parameter,public :: pyplot_wp = real64 !! real kind used by this module [8 bytes] +#endif + + integer,parameter :: wp = pyplot_wp !! local copy of `pyplot_wp` with a shorter name + + character(len=*), parameter :: tmp_file = 'pyplot_module_temp_1234567890.py' !! Default name of the temporary file + !! (this can also be user-specified). + + character(len=*), parameter :: python_exe ='python' !! The python executable name. + character(len=*), parameter :: int_fmt = '(I10)' !! integer format string + integer, parameter :: max_int_len = 10 !! max string length for integers + character(len=*), parameter :: real_fmt_default = '(E30.16)' !! default real number format string + integer, parameter :: max_real_len = 60 !! max string length for reals + + type, public :: pyplot + + !! The main pyplot class. + + private + + character(len=:), allocatable :: str !! string buffer + + character(len=1) :: raw_str_token = ' ' !! will be 'r' if using raw strings + + logical :: show_legend = .false. !! show legend into plot + logical :: use_numpy = .true. !! use numpy python module + logical :: use_oo_api = .false. !! use OO interface of matplotlib (incopatible with showfig subroutine) + logical :: mplot3d = .false. !! it is a 3d plot + logical :: polar = .false. !! it is a polar plot + logical :: axis_equal = .false. !! equal scale on each axis + logical :: axisbelow = .true. !! axis below other chart elements + logical :: tight_layout = .false. !! tight layout option + logical :: usetex = .false. !! enable LaTeX + + character(len=:),allocatable :: xaxis_date_fmt !! date format for the x-axis. Example: `"%m/%d/%y %H:%M:%S"` + character(len=:),allocatable :: yaxis_date_fmt !! date format for the y-axis. Example: `"%m/%d/%y %H:%M:%S"` + + character(len=:),allocatable :: real_fmt !! real number formatting + + contains + + ! public methods + procedure, public :: initialize !! initialize pyplot instance + + procedure, public :: add_plot !! add a 2d plot to pyplot instance + procedure, public :: add_errorbar !! add a 2d error bar plot to pyplot instance + procedure, public :: add_3d_plot !! add a 3d plot to pyplot instance + procedure, public :: add_sphere !! add a 3d sphere to pyplot instance + procedure, public :: add_contour !! add a contour plot to pyplot instance + procedure, public :: plot_wireframe!! add a wireframe plot to pyplot instance + procedure, public :: plot_surface !! add a surface plot to pyplot instance + procedure, public :: add_bar !! add a barplot to pyplot instance + procedure, public :: add_imshow !! add an image plot (using `imshow`) + procedure, public :: add_hist !! add a histogram plot to pyplot instance + procedure, public :: savefig !! save plots of pyplot instance + procedure, public :: showfig !! show plots of pyplot instance + procedure, public :: destroy !! destroy pyplot instance + + ! private methods + procedure :: execute !! execute pyplot commands + procedure :: add_str !! add string to pytplot instance buffer + procedure :: finish_ops !! some final ops before saving + + end type pyplot + + contains +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Destructor. + + subroutine destroy(me) + + class(pyplot),intent(inout) :: me !! pyplot handler + + if (allocated(me%str)) deallocate(me%str) + if (allocated(me%real_fmt)) deallocate(me%real_fmt) + + me%raw_str_token = ' ' + + end subroutine destroy +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a string to the buffer. + + subroutine add_str(me,str) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in) :: str !! str to be added to pyplot handler buffer + + integer :: n_old !! current `me%str` length + integer :: n_str !! length of input `str` + character(len=:),allocatable :: tmp !! tmp string for building the result + + ! original + !me%str = me%str//str//new_line(' ') + + if (len(str)==0) return + + ! the above can sometimes cause a stack overflow in the + ! intel Fortran compiler, so we replace with this: + if (allocated(me%str)) then + n_old = len(me%str) + n_str = len(str) + allocate(character(len=n_old+n_str+1) :: tmp) + tmp(1:n_old) = me%str + tmp(n_old+1:) = str//new_line(' ') + call move_alloc(tmp, me%str) + else + allocate(me%str, source = str//new_line(' ')) + end if + + end subroutine add_str +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Initialize a plot + + subroutine initialize(me, grid, xlabel, ylabel, zlabel, title, legend, use_numpy, figsize, & + font_size, axes_labelsize, xtick_labelsize, ytick_labelsize, ztick_labelsize, & + legend_fontsize, mplot3d, axis_equal, polar, real_fmt, use_oo_api, axisbelow,& + tight_layout, raw_strings, usetex, xaxis_date_fmt, yaxis_date_fmt) + + class(pyplot), intent(inout) :: me !! pyplot handler + logical, intent(in), optional :: grid !! activate grid drawing + character(len=*), intent(in), optional :: xlabel !! label of x axis + character(len=*), intent(in), optional :: ylabel !! label of y axis + character(len=*), intent(in), optional :: zlabel !! label of z axis + character(len=*), intent(in), optional :: title !! plot title + logical, intent(in), optional :: legend !! plot legend + logical, intent(in), optional :: use_numpy !! activate usage of numpy python module + integer, dimension(2), intent(in), optional :: figsize !! dimension of the figure + integer, intent(in), optional :: font_size !! font size + integer, intent(in), optional :: axes_labelsize !! size of axis labels + integer, intent(in), optional :: xtick_labelsize !! size of x axis tick lables + integer, intent(in), optional :: ytick_labelsize !! size of y axis tick lables + integer, intent(in), optional :: ztick_labelsize !! size of z axis tick lables + integer, intent(in), optional :: legend_fontsize !! size of legend font + logical, intent(in), optional :: mplot3d !! set true for 3d plots (cannot use with polar) + logical, intent(in), optional :: axis_equal !! set true for axis = 'equal' + logical, intent(in), optional :: polar !! set true for polar plots (cannot use with mplot3d) + character(len=*), intent(in), optional :: real_fmt !! format string for real numbers (examples: '(E30.16)' [default], '*') + logical, intent(in), optional :: use_oo_api !! avoid matplotlib's GUI by using the OO interface (cannot use with showfig) + logical, intent(in), optional :: axisbelow !! to put the grid lines below the other chart elements [default is true] + logical, intent(in), optional :: tight_layout !! enable tight layout [default is false] + logical, intent(in), optional :: raw_strings !! if True, all strings sent to Python are treated as + !! raw strings (e.g., r'str'). Default is False. + logical, intent(in), optional :: usetex !! if True, enable LaTeX. (default if false) + character(len=*), intent(in), optional :: xaxis_date_fmt !! if present, used to set the date format for the x-axis + character(len=*), intent(in), optional :: yaxis_date_fmt !! if present, used to set the date format for the y-axis + + character(len=max_int_len) :: width_str !! figure width dummy string + character(len=max_int_len) :: height_str !! figure height dummy string + character(len=max_int_len) :: font_size_str !! font size dummy string + character(len=max_int_len) :: axes_labelsize_str !! size of axis labels dummy string + character(len=max_int_len) :: xtick_labelsize_str !! size of x axis tick labels dummy string + character(len=max_int_len) :: ytick_labelsize_str !! size of x axis tick labels dummy string + character(len=max_int_len) :: ztick_labelsize_str !! size of z axis tick labels dummy string + character(len=max_int_len) :: legend_fontsize_str !! size of legend font dummy string + character(len=:),allocatable :: python_fig_func !! Python's function for creating a new Figure instance + + character(len=*), parameter :: default_font_size_str = '10' !! the default font size for plots + + call me%destroy() + + if (present(raw_strings)) then + if (raw_strings) me%raw_str_token = 'r' + end if + + if (present(legend)) then + me%show_legend = legend + else + me%show_legend = .false. + end if + if (present(use_numpy)) then + me%use_numpy = use_numpy + else + me%use_numpy = .true. + end if + if (present(use_oo_api)) then + me%use_oo_api = use_oo_api + else + me%use_oo_api = .false. + end if + if (present(figsize)) then + call integer_to_string(figsize(1), width_str) + call integer_to_string(figsize(2), height_str) + end if + if (present(mplot3d)) then + me%mplot3d = mplot3d + else + me%mplot3d = .false. + end if + if (present(polar)) then + me%polar = polar + else + me%polar = .false. + end if + if (present(axis_equal)) then + me%axis_equal = axis_equal + else + me%axis_equal = .false. + end if + if (present(real_fmt)) then + me%real_fmt = trim(adjustl(real_fmt)) + else + me%real_fmt = real_fmt_default + end if + if (present(tight_layout)) then + me%tight_layout = tight_layout + else + me%tight_layout = .false. + end if + if (present(usetex)) then + me%usetex = usetex + else + me%usetex = .false. + end if + if (present(xaxis_date_fmt)) then + me%xaxis_date_fmt = xaxis_date_fmt + else + if (allocated(me%xaxis_date_fmt)) deallocate(me%xaxis_date_fmt) + end if + if (present(yaxis_date_fmt)) then + me%yaxis_date_fmt = yaxis_date_fmt + else + if (allocated(me%yaxis_date_fmt)) deallocate(me%yaxis_date_fmt) + end if + + call optional_int_to_string(font_size, font_size_str, default_font_size_str) + call optional_int_to_string(axes_labelsize, axes_labelsize_str, default_font_size_str) + call optional_int_to_string(xtick_labelsize, xtick_labelsize_str, default_font_size_str) + call optional_int_to_string(ytick_labelsize, ytick_labelsize_str, default_font_size_str) + call optional_int_to_string(ztick_labelsize, ztick_labelsize_str, default_font_size_str) + call optional_int_to_string(legend_fontsize, legend_fontsize_str, default_font_size_str) + + me%str = '' + + call me%add_str('#!/usr/bin/env python') + call me%add_str('') + + call me%add_str('import matplotlib') + if (me%use_oo_api) then + call me%add_str('from matplotlib.figure import Figure') + call me%add_str('from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas') + else + call me%add_str('import matplotlib.pyplot as plt') + endif + if (me%mplot3d) call me%add_str('from mpl_toolkits.mplot3d import Axes3D') + if (me%use_numpy) call me%add_str('import numpy as np') + call me%add_str('') + + call me%add_str('matplotlib.rcParams["font.family"] = "Serif"') + call me%add_str('matplotlib.rcParams["font.size"] = '//trim(font_size_str)) + call me%add_str('matplotlib.rcParams["axes.labelsize"] = '//trim(axes_labelsize_str)) + call me%add_str('matplotlib.rcParams["xtick.labelsize"] = '//trim(xtick_labelsize_str)) + call me%add_str('matplotlib.rcParams["ytick.labelsize"] = '//trim(ytick_labelsize_str)) + call me%add_str('matplotlib.rcParams["legend.fontsize"] = '//trim(legend_fontsize_str)) + if (me%usetex) call me%add_str('matplotlib.rcParams["text.usetex"] = True') + + call me%add_str('') + + if (me%use_oo_api) then + python_fig_func = 'Figure' + else + python_fig_func = 'plt.figure' + endif + if (present(figsize)) then !if specifying the figure size + call me%add_str('fig = '//python_fig_func//'(figsize=('//trim(width_str)//','//trim(height_str)//'),facecolor="white")') + else + call me%add_str('fig = '//python_fig_func//'(facecolor="white")') + end if + + if (me%mplot3d) then + call me%add_str('ax = fig.add_subplot(1, 1, 1, projection=''3d'')') + elseif (me%polar) then + call me%add_str('ax = fig.add_subplot(1, 1, 1, projection=''polar'')') + else + call me%add_str('ax = fig.add_subplot(1, 1, 1)') + end if + + if (present(grid)) then + if (grid) call me%add_str('ax.grid()') + end if + + if (present(axisbelow)) then + me%axisbelow = axisbelow + else + me%axisbelow = .true. ! default + end if + if (me%axisbelow) call me%add_str('ax.set_axisbelow(True)') + + if (present(xlabel)) call me%add_str('ax.set_xlabel('//trim(me%raw_str_token)//'"'//trim(xlabel)//'")') + if (present(ylabel)) call me%add_str('ax.set_ylabel('//trim(me%raw_str_token)//'"'//trim(ylabel)//'")') + if (present(zlabel)) call me%add_str('ax.set_zlabel('//trim(me%raw_str_token)//'"'//trim(zlabel)//'")') + if (present(title)) call me%add_str('ax.set_title('//trim(me%raw_str_token)//'"' //trim(title) //'")') + + call me%add_str('') + + end subroutine initialize +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add an x,y plot. + + subroutine add_plot(me, x, y, label, linestyle, markersize, linewidth, xlim, ylim, xscale, yscale, color, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + real(wp),dimension(:), intent (in), optional :: color !! RGB color tuple [0-1,0-1,0-1] + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: arg_str !! the arguments to pass to `plot` + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: color_str !! color values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str('') + + !main arguments for plot: + arg_str = trim(xname)//','//& + trim(yname)//','//& + trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'"' + + ! optional arguments: + if (present(color)) then + if (size(color)<=3) then + call vec_to_string(color(1:3), '*', color_str, use_numpy=.false., is_tuple=.true.) + arg_str = arg_str//',color='//trim(color_str) + end if + end if + + !write the plot statement: + call me%add_str('ax.plot('//arg_str//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_plot +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jimmy Leta +! +! Add a histogram plot. + + subroutine add_hist(me, x, label, xlim, ylim, xscale, yscale, bins, normed, cumulative, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! array of data + character(len=*), intent (in) :: label !! plot label + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + integer, intent (in), optional :: bins !! number of bins + logical, intent (in), optional :: normed !! boolean flag that determines whether bin counts are normalized [NO LONGER USED] + logical, intent (in), optional :: cumulative !! boolean flag that determines whether histogram represents the cumulative density of dataset + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: cumulativestr !! + character(len=max_int_len) :: binsstr !! + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str('') + + !get optional inputs (if not present, set default value): + call optional_int_to_string(bins, binsstr, '10') + call optional_logical_to_string(cumulative, cumulativestr, 'False') + + !write the plot statement: + call me%add_str('ax.hist('//& + trim(xname)//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'bins='//trim(binsstr)//','//& + 'cumulative='//trim(cumulativestr)//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_hist +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a contour plot. +! +!@note This requires `use_numpy` to be True. + + subroutine add_contour(me, x, y, z, linestyle, linewidth, levels, color, & + filled, cmap, colorbar, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line [only used when `filled=False`] + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! color of the contour line + logical, intent (in), optional :: filled !! use filled control (default=False) + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + character(len=:), allocatable :: contourfunc !! 'contour' or 'contourf' + logical :: is_filled !! if it is a filled contour plot + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !filled or regular: + contourfunc = 'contour' !default + is_filled = .false. + if (present(filled)) then + is_filled = filled + if (filled) contourfunc = 'contourf' !filled contour + end if + + !write the plot statement: + call me%add_str('CS = ax.'//contourfunc//'('//xname_//','//yname_//','//zname_//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + if (.not. is_filled) call me%add_str('ax.clabel(CS, fontsize=9, inline=1)') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine add_contour +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a surface plot. +! +!@note This requires `use_numpy` to be True. + + subroutine plot_surface(me, x, y, z, label, linestyle, linewidth, levels, color, & + cmap, colorbar, antialiased, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! Color of the surface patches + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + logical, intent (in), optional :: antialiased !! The surface is made opaque by using antialiased=False + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=:), allocatable :: antialiasedstr !! antialiased stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + call optional_logical_to_string(antialiased, antialiasedstr, 'False') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !write the plot statement: + call me%add_str('CS = ax.plot_surface'//'('//xname_//','//yname_//','//zname_//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'antialiased='//trim(antialiasedstr)//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine plot_surface +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a wireframe plot. +! +!@note This requires `use_numpy` to be True. + + subroutine plot_wireframe(me, x, y, z, label, linestyle, linewidth, levels, color, & + cmap, colorbar, antialiased, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:), intent (in) :: x !! x values + real(wp),dimension(:), intent (in) :: y !! y values + real(wp),dimension(:,:), intent (in) :: z !! z values (a matrix) + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(:), intent (in), optional :: levels !! contour levels to plot + character(len=*), intent (in), optional :: color !! Color of the surface patches + character(len=*), intent (in), optional :: cmap !! colormap if filled=True (examples: 'jet', 'bone') + logical, intent (in), optional :: colorbar !! add a colorbar (default=False) + logical, intent (in), optional :: antialiased !! The surface is made opaque by using antialiased=False + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=:), allocatable :: levelstr !! levels vector stringified + character(len=:), allocatable :: antialiasedstr !! antialiased stringified + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + character(len=*), parameter :: xname_ = 'X' !! X variable name for contour + character(len=*), parameter :: yname_ = 'Y' !! Y variable name for contour + character(len=*), parameter :: zname_ = 'Z' !! Z variable name for contour + character(len=:), allocatable :: extras !! optional stuff + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call matrix_to_string(z, me%real_fmt, zstr, me%use_numpy) + if (present(levels)) call vec_to_string(levels, me%real_fmt, levelstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(linewidth, iline, '3') + call optional_logical_to_string(antialiased, antialiasedstr, 'False') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !convert inputs for contour plotting: + call me%add_str(xname_//', '//yname_//' = np.meshgrid('//trim(xname)//', '//trim(yname)//')') + call me%add_str(zname_//' = np.transpose('//zname//')') + + !optional arguments: + extras = '' + if (present(levels)) extras = extras//','//'levels='//levelstr + if (present(color)) extras = extras//','//'colors='//trim(me%raw_str_token)//'"'//color//'"' + if (present(linewidth)) extras = extras//','//'linewidths='//trim(adjustl(iline)) + if (present(cmap)) extras = extras//','//'cmap='//trim(me%raw_str_token)//'"'//cmap//'"' + + !write the plot statement: + call me%add_str('CS = ax.plot_wireframe'//'('//xname_//','//yname_//','//zname_//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'",'//& + 'antialiased='//trim(antialiasedstr)//','//& + 'linestyles='//trim(me%raw_str_token)//'"'//trim(adjustl(linestyle))//'"'//& + extras//')') + + if (present(colorbar)) then + if (colorbar) call me%add_str('fig.colorbar(CS)') + end if + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_plot: pyplot class not properly initialized.' + end if + + end subroutine plot_wireframe +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a 3D x,y,z plot. +! +!@note Must initialize the class with ```mplot3d=.true.``` + + subroutine add_3d_plot(me, x, y, z, label, linestyle, markersize, linewidth, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + real(wp), dimension(:), intent (in) :: z !! z values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: zstr !! z values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: zname = 'z' !! z variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + call vec_to_string(z, me%real_fmt, zstr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str(trim(zname)//' = '//zstr) + call me%add_str('') + + !write the plot statement: + call me%add_str('ax.plot('//& + trim(xname)//','//& + trim(yname)//','//& + trim(zname)//','//& + trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'")') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_3d_plot: pyplot class not properly initialized.' + end if + + end subroutine add_3d_plot +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a sphere to a 3D x,y,z plot. +! +!@note Must initialize the class with `mplot3d=.true.` and `use_numpy=.true.`. + + subroutine add_sphere(me, r, xc, yc, zc, n_facets, linewidth, antialiased, color, istat) + + implicit none + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), intent (in) :: r !! radius of the sphere + real(wp), intent (in) :: xc !! x value of sphere center + real(wp), intent (in) :: yc !! y value of sphere center + real(wp), intent (in) :: zc !! z value of sphere center + integer, intent (in), optional :: n_facets !! [default is 100] + integer, intent (in), optional :: linewidth !! line width + logical, intent (in), optional :: antialiased !! enabled anti-aliasing + character(len=*), intent (in), optional :: color !! color of the contour line + integer, intent (out), optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: rstr !! `r` value stringified + character(len=:), allocatable :: xcstr !! `xc` value stringified + character(len=:), allocatable :: ycstr !! `yc` value stringified + character(len=:), allocatable :: zcstr !! `zc` value stringified + character(len=*), parameter :: xname = 'x' !! `x` variable name for script + character(len=*), parameter :: yname = 'y' !! `y` variable name for script + character(len=*), parameter :: zname = 'z' !! `z` variable name for script + + character(len=max_int_len) :: linewidth_str !! `linewidth` input stringified + character(len=:), allocatable :: antialiased_str !! `antialised` input stringified + character(len=max_int_len) :: n_facets_str !! `n_facets` input stringified + character(len=:), allocatable :: extras !! optional stuff string + + if (allocated(me%str)) then + + !get optional inputs (if not present, set default value): + call optional_int_to_string(n_facets, n_facets_str, '100') + extras = '' + if (present(linewidth)) then + call optional_int_to_string(linewidth, linewidth_str, '1') + extras = extras//','//'linewidth='//linewidth_str + end if + if (present(antialiased)) then + call optional_logical_to_string(antialiased, antialiased_str, 'False') + extras = extras//','//'antialiased='//antialiased_str + end if + if (present(color)) then + extras = extras//','//'color='//trim(me%raw_str_token)//'"'//trim(color)//'"' + end if + + if (present(istat)) istat = 0 + + !convert the arrays to strings: + call real_to_string(r , me%real_fmt, rstr) + call real_to_string(xc, me%real_fmt, xcstr) + call real_to_string(yc, me%real_fmt, ycstr) + call real_to_string(zc, me%real_fmt, zcstr) + + ! sphere code: + call me%add_str('u = np.linspace(0, 2 * np.pi, '//n_facets_str//')') + call me%add_str('v = np.linspace(0, np.pi, '//n_facets_str//')') + call me%add_str(xname//' = '//xcstr//' + '//rstr//' * np.outer(np.cos(u), np.sin(v))') + call me%add_str(yname//' = '//ycstr//' + '//rstr//' * np.outer(np.sin(u), np.sin(v))') + call me%add_str(zname//' = '//zcstr//' + '//rstr//' * np.outer(np.ones(np.size(u)), np.cos(v))') + call me%add_str('ax.plot_surface('//xname//', '//yname//', '//zname//extras//')') + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_sphere: pyplot class not properly initialized.' + end if + + end subroutine add_sphere +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Add a bar plot. + + subroutine add_bar(me, x, height, label, width, bottom, color, & + yerr, align, xlim, ylim, xscale, yscale, istat) + + class(pyplot), intent(inout) :: me !! pyplot handler + real(wp), dimension(:), intent(in) :: x !! x bar values + real(wp), dimension(:), intent(in) :: height !! height bar values + character(len=*), intent(in) :: label !! plot label + real(wp), dimension(:), intent(in), optional :: width !! width values + real(wp), dimension(:), intent(in), optional :: bottom !! bottom values + character(len=*), intent(in), optional :: color !! plot color + real(wp), dimension(:), intent(in), optional :: yerr !! yerr values + character(len=*), intent(in), optional :: align !! default: 'center' + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x axis values stringified + character(len=:), allocatable :: ystr !! y axis values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: wstr !! width values stringified + character(len=:), allocatable :: bstr !! bottom values stringified + character(len=:), allocatable :: plt_str !! plot string + character(len=:), allocatable :: yerr_str !! yerr values stringified + character(len=*), parameter :: xname = 'x' !! x axis name + character(len=*), parameter :: yname = 'y' !! y axis name + character(len=*), parameter :: wname = 'w' !! width name + character(len=*), parameter :: bname = 'b' !! bottom name + character(len=*), parameter :: yerrname = 'yerr' !! yerr name + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(height, me%real_fmt, ystr, me%use_numpy) + if (present(width)) call vec_to_string(width, me%real_fmt, wstr, me%use_numpy) + if (present(bottom)) call vec_to_string(bottom, me%real_fmt, bstr, me%use_numpy) + if (present(yerr)) call vec_to_string(yerr, me%real_fmt, yerr_str, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + if (present(width)) call me%add_str(trim(wname)//' = '//wstr) + if (present(bottom)) call me%add_str(trim(bname)//' = '//bstr) + if (present(yerr)) call me%add_str(trim(yerrname)//' = '//yerr_str) + call me%add_str('') + + !create the plot string: + plt_str = 'ax.bar('//& + 'x='//trim(xname)//','//& + 'height='//trim(yname)//',' + if (present(yerr)) plt_str=plt_str//'yerr='//trim(yerrname)//',' + if (present(width)) plt_str=plt_str//'width='//trim(wname)//',' + if (present(bottom)) plt_str=plt_str//'bottom='//trim(bstr)//',' + if (present(color)) plt_str=plt_str//'color='//trim(me%raw_str_token)//'"'//trim(color)//'",' + if (present(align)) plt_str=plt_str//'align='//trim(me%raw_str_token)//'"'//trim(align)//'",' + plt_str=plt_str//'label='//trim(me%raw_str_token)//'"'//trim(label)//'")' + + !write the plot statement: + call me%add_str(plt_str) + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_bar: pyplot class not properly initialized.' + end if + + end subroutine add_bar +!***************************************************************************************** + +!***************************************************************************************** +!> +! Add an image plot using `imshow`. +! +!### Note +! * Based on code by Ricardo Torres, 4/2/2017. + + subroutine add_imshow(me, x, xlim, ylim, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp),dimension(:,:),intent (in) :: x !! x values + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: xstr !! x values stringified + character(len=*), parameter :: xname = 'x' !! x variable name for script + + !axis limits (optional): + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + + !convert the arrays to strings: + call matrix_to_string(x, me%real_fmt, xstr, me%use_numpy) + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str('') + + !write the plot statement: + call me%add_str('ax.imshow('//trim(xname)//')') + call me%add_str('') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_imshow: pyplot class not properly initialized.' + end if + + end subroutine add_imshow +!***************************************************************************************** + +!***************************************************************************************** +!> author: Alexander Sandrock +! +! Add an x,y plot with errorbars. + + subroutine add_errorbar(me, x, y, label, linestyle, xerr, yerr, markersize, linewidth, xlim, ylim, xscale, yscale, color, istat) + + class(pyplot), intent (inout) :: me !! pyplot handler + real(wp), dimension(:), intent (in) :: x !! x values + real(wp), dimension(:), intent (in) :: y !! y values + character(len=*), intent (in) :: label !! plot label + character(len=*), intent (in) :: linestyle !! style of the plot line + real(wp), dimension(:), intent (in), optional :: xerr !! x errorbar sizes + real(wp), dimension(:), intent (in), optional :: yerr !! y errorbar sizes + integer, intent (in), optional :: markersize !! size of the plot markers + integer, intent (in), optional :: linewidth !! width of the plot line + real(wp),dimension(2), intent (in), optional :: xlim !! x-axis range + real(wp),dimension(2), intent (in), optional :: ylim !! y-axis range + character(len=*), intent (in), optional :: xscale !! example: 'linear' (default), 'log' + character(len=*), intent (in), optional :: yscale !! example: 'linear' (default), 'log' + real(wp),dimension(:), intent (in), optional :: color !! RGB color tuple [0-1,0-1,0-1] + integer, intent (out),optional :: istat !! status output (0 means no problems) + + character(len=:), allocatable :: arg_str !! the arguments to pass to `plot` + character(len=:), allocatable :: xstr !! x values stringified + character(len=:), allocatable :: ystr !! y values stringified + character(len=:), allocatable :: xlimstr !! xlim values stringified + character(len=:), allocatable :: ylimstr !! ylim values stringified + character(len=:), allocatable :: xerrstr !! xerr values stringified + character(len=:), allocatable :: yerrstr !! yerr values stringified + character(len=:), allocatable :: color_str !! color values stringified + character(len=max_int_len) :: imark !! actual markers size + character(len=max_int_len) :: iline !! actual line width + character(len=*), parameter :: xname = 'x' !! x variable name for script + character(len=*), parameter :: yname = 'y' !! y variable name for script + character(len=*), parameter :: xerrname = 'xerr' !! xerr variable name for script + character(len=*), parameter :: yerrname = 'yerr' !! yerr variable name for script + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !axis limits (optional): + if (present(xlim)) call vec_to_string(xlim, me%real_fmt, xlimstr, me%use_numpy) + if (present(ylim)) call vec_to_string(ylim, me%real_fmt, ylimstr, me%use_numpy) + !errorbar sizes (optional): + if (present(xerr)) call vec_to_string(xerr, me%real_fmt, xerrstr, me%use_numpy) + if (present(yerr)) call vec_to_string(yerr, me%real_fmt, yerrstr, me%use_numpy) + + !convert the arrays to strings: + call vec_to_string(x, me%real_fmt, xstr, me%use_numpy) + call vec_to_string(y, me%real_fmt, ystr, me%use_numpy) + + !get optional inputs (if not present, set default value): + call optional_int_to_string(markersize, imark, '3') + call optional_int_to_string(linewidth, iline, '3') + + !write the arrays: + call me%add_str(trim(xname)//' = '//xstr) + call me%add_str(trim(yname)//' = '//ystr) + call me%add_str('') + if (present(xerr)) call me%add_str(trim(xerrname)//' = '//xerrstr) + if (present(yerr)) call me%add_str(trim(yerrname)//' = '//yerrstr) + if (present(xerr) .or. present(yerr)) call me%add_str('') + + !main arguments for plot: + arg_str = trim(xname)//','//& + trim(yname)//','//& + 'fmt='//trim(me%raw_str_token)//'"'//trim(linestyle)//'",'//& + 'linewidth='//trim(adjustl(iline))//','//& + 'markersize='//trim(adjustl(imark))//','//& + 'label='//trim(me%raw_str_token)//'"'//trim(label)//'"' + + ! optional arguments: + if (present(xerr)) then + arg_str = arg_str//','//'xerr='//trim(xerrname) + end if + if (present(yerr)) then + arg_str = arg_str//','//'yerr='//trim(yerrname) + end if + if (present(color)) then + if (size(color)<=3) then + call vec_to_string(color(1:3), '*', color_str, use_numpy=.false., is_tuple=.true.) + arg_str = arg_str//',color='//trim(color_str) + end if + end if + + !write the plot statement: + call me%add_str('ax.errorbar('//arg_str//')') + + !axis limits: + if (allocated(xlimstr)) call me%add_str('ax.set_xlim('//xlimstr//')') + if (allocated(ylimstr)) call me%add_str('ax.set_ylim('//ylimstr//')') + + !axis scales: + if (present(xscale)) call me%add_str('ax.set_xscale('//trim(me%raw_str_token)//'"'//xscale//'")') + if (present(yscale)) call me%add_str('ax.set_yscale('//trim(me%raw_str_token)//'"'//yscale//'")') + + call me%add_str('') + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error in add_errorbar: pyplot class not properly initialized.' + end if + + end subroutine add_errorbar +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Integer to string, specifying the default value if +! the optional argument is not present. + + subroutine optional_int_to_string(int_value, string_value, default_value) + + integer, intent(in), optional :: int_value !! integer value + character(len=*), intent(out) :: string_value !! integer value stringified + character(len=*), intent(in) :: default_value !! default integer value + + if (present(int_value)) then + call integer_to_string(int_value, string_value) + else + string_value = default_value + end if + + end subroutine optional_int_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Logical to string, specifying the default value if +! the optional argument is not present. + + subroutine optional_logical_to_string(logical_value, string_value, default_value) + + logical,intent(in),optional :: logical_value + character(len=:),allocatable,intent(out) :: string_value !! integer value stringified + character(len=*),intent(in) :: default_value !! default integer value + + if (present(logical_value)) then + if (logical_value) then + string_value = 'True' + else + string_value = 'False' + end if + else + string_value = default_value + end if + + end subroutine optional_logical_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Integer to string conversion. + + subroutine integer_to_string(i, s) + + integer, intent(in), optional :: i !! integer value + character(len=*), intent(out) :: s !! integer value stringified + + integer :: istat !! IO status + + write(s, int_fmt, iostat=istat) i + + if (istat/=0) then + write(error_unit,'(A)') 'Error converting integer to string' + s = '****' + else + s = adjustl(s) + end if + + end subroutine integer_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Real scalar to string. + + subroutine real_to_string(v, fmt, str) + + real(wp), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + + integer :: istat !! IO status + character(len=max_real_len) :: tmp !! dummy string + + if (fmt=='*') then + write(tmp, *, iostat=istat) v + else + write(tmp, fmt, iostat=istat) v + end if + if (istat/=0) then + write(error_unit,'(A)') 'Error in real_to_string' + str = '****' + else + str = trim(adjustl(tmp)) + end if + + end subroutine real_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Real vector to string. + + subroutine vec_to_string(v, fmt, str, use_numpy, is_tuple) + + real(wp), dimension(:), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + logical, intent(in) :: use_numpy !! activate numpy python module usage + logical,intent(in),optional :: is_tuple !! if true [default], use '()', if false use '[]' + + integer :: i !! counter + integer :: istat !! IO status + character(len=max_real_len) :: tmp !! dummy string + logical :: tuple + + if (present(is_tuple)) then + tuple = is_tuple + else + tuple = .false. + end if + + if (tuple) then + str = '(' + else + str = '[' + end if + + do i=1, size(v) + if (fmt=='*') then + write(tmp, *, iostat=istat) v(i) + else + write(tmp, fmt, iostat=istat) v(i) + end if + if (istat/=0) then + write(error_unit,'(A)') 'Error in vec_to_string' + str = '****' + return + end if + str = str//trim(adjustl(tmp)) + if (i<size(v)) str = str // ',' + end do + + if (tuple) then + str = str // ')' + else + str = str // ']' + end if + + !convert to numpy array if necessary: + if (use_numpy) str = 'np.array('//str//')' + + end subroutine vec_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Real matrix (rank 2) to string. + + subroutine matrix_to_string(v, fmt, str, use_numpy) + + real(wp), dimension(:,:), intent(in) :: v !! real values + character(len=*), intent(in) :: fmt !! real format string + character(len=:), allocatable, intent(out) :: str !! real values stringified + logical, intent(in) :: use_numpy !! activate numpy python module usage + + integer :: i !! counter + character(len=:),allocatable :: tmp !! dummy string + + str = '[' + do i=1, size(v,1) !rows + call vec_to_string(v(i,:), fmt, tmp, use_numpy) !one row at a time + str = str//trim(adjustl(tmp)) + if (i<size(v,1)) str = str // ',' + end do + str = str // ']' + + !convert to numpy array if necessary: + if (use_numpy) str = 'np.array('//str//')' + + end subroutine matrix_to_string +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! date: 8/16/2015 +! +! Write the buffer to a file, and then execute it with Python. +! +! If user specifies a Python file name, then the file is kept, otherwise +! a temporary filename is used, and the file is deleted after it is used. + + subroutine execute(me, pyfile, istat, python) + + class(pyplot), intent(inout) :: me !! pytplot handler + character(len=*), intent(in), optional :: pyfile !! name of the python script to generate + integer, intent (out),optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + integer :: iunit !! IO unit + character(len=:), allocatable :: file !! file name + logical :: scratch !! if a scratch file is to be used + integer :: iostat !! open/close status code + character(len=:), allocatable :: python_ !! python executable to use + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + scratch = (.not. present(pyfile)) + + !file name to use: + if (scratch) then + file = trim(tmp_file) !use the default + else + file = trim(pyfile) !use the user-specified name + end if + + if (file == '') then + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'Error: filename is blank.' + return + end if + + !open the file: + open(newunit=iunit, file=file, status='REPLACE', iostat=iostat) + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error opening file: '//trim(file) + return + end if + + !write to the file: + write(iunit, '(A)') me%str + + !to ensure that the file is there for the next + !command line call, we have to close it here. + close(iunit, iostat=iostat) + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error closing file: '//trim(file) + else + + if (present(python)) then + python_ = trim(python) + else + python_ = python_exe + end if + + !run the file using python: + if (file(1:1)/='"') then + ! if not already in quotes, should enclose in quotes + call execute_command_line(python_//' "'//file//'"') + else + call execute_command_line(python_//' '//file) + end if + + if (scratch) then + !delete the file (have to reopen it because + !Fortran has no file delete function) + open(newunit=iunit, file=file, status='OLD', iostat=iostat) + if (iostat==0) close(iunit, status='DELETE', iostat=iostat) + end if + if (iostat/=0) then + if (present(istat)) istat = iostat + write(error_unit,'(A)') 'Error closing file.' + end if + + end if + + !cleanup: + if (allocated(file)) deallocate(file) + + else + if (present(istat)) istat = -1 + end if + + end subroutine execute +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Some final things to add before saving or showing the figure. + + subroutine finish_ops(me) + + class(pyplot),intent(inout) :: me !! pyplot handler + + if (me%show_legend) then + call me%add_str('ax.legend(loc="best")') + call me%add_str('') + end if + if (me%axis_equal) then + if (me%mplot3d) then + call me%add_str('ax.set_aspect("auto")') + call me%add_str('') + + call me%add_str('def set_axes_equal(ax):') + call me%add_str(' x_limits = ax.get_xlim3d()') + call me%add_str(' y_limits = ax.get_ylim3d()') + call me%add_str(' z_limits = ax.get_zlim3d()') + call me%add_str(' x_range = abs(x_limits[1] - x_limits[0])') + call me%add_str(' x_middle = np.mean(x_limits)') + call me%add_str(' y_range = abs(y_limits[1] - y_limits[0])') + call me%add_str(' y_middle = np.mean(y_limits)') + call me%add_str(' z_range = abs(z_limits[1] - z_limits[0])') + call me%add_str(' z_middle = np.mean(z_limits)') + call me%add_str(' plot_radius = 0.5*max([x_range, y_range, z_range])') + call me%add_str(' ax.set_xlim3d([x_middle - plot_radius, x_middle + plot_radius])') + call me%add_str(' ax.set_ylim3d([y_middle - plot_radius, y_middle + plot_radius])') + call me%add_str(' ax.set_zlim3d([z_middle - plot_radius, z_middle + plot_radius])') + call me%add_str('set_axes_equal(ax)') + + else + call me%add_str('ax.axis("equal")') + end if + call me%add_str('') + end if + if (allocated(me%xaxis_date_fmt) .or. allocated(me%yaxis_date_fmt)) then + call me%add_str('from matplotlib.dates import DateFormatter') + if (allocated(me%xaxis_date_fmt)) & + call me%add_str('ax.xaxis.set_major_formatter(DateFormatter("'//trim(me%xaxis_date_fmt)//'"))') + if (allocated(me%yaxis_date_fmt)) & + call me%add_str('ax.yaxis.set_major_formatter(DateFormatter("'//trim(me%yaxis_date_fmt)//'"))') + call me%add_str('') + end if + if (me%tight_layout) then + call me%add_str('fig.tight_layout()') + call me%add_str('') + end if + + end subroutine finish_ops +!***************************************************************************************** + +!***************************************************************************************** +!> author: Jacob Williams +! +! Save the figure. +! +!### History +! * modified: Johannes Rieke 6/16/2017 +! * modified: Jacob Williams 6/16/2017 + + subroutine savefig(me, figfile, pyfile, dpi, transparent, facecolor, edgecolor, orientation, istat, python) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in) :: figfile !! file name for the figure + character(len=*), intent(in), optional :: pyfile !! name of the Python script to generate + character(len=*), intent(in), optional :: dpi !! resolution of the figure for png + !! [note this is a string] + logical, intent(in), optional :: transparent !! transparent background (T/F) + character(len=*), intent(in), optional :: facecolor !! the colors of the figure rectangle + character(len=*), intent(in), optional :: edgecolor !! the colors of the figure rectangle + character(len=*), intent(in), optional :: orientation !! 'landscape' or 'portrait' + integer, intent (out), optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + character(len=:),allocatable :: tmp !! for building the `savefig` arguments. + + if (allocated(me%str)) then + + if (present(istat)) istat = 0 + + !finish up the string: + call me%finish_ops() + + !build the savefig arguments: + tmp = trim(me%raw_str_token)//'"'//trim(figfile)//'"' + if (present(dpi)) tmp = tmp//', dpi='//trim(dpi) + if (present(transparent)) then + if (transparent) then + tmp = tmp//', transparent=True' + else + tmp = tmp//', transparent=False' + end if + end if + if (present(facecolor)) tmp = tmp//', facecolor="'//trim(facecolor)//'"' + if (present(edgecolor)) tmp = tmp//', edgecolor="'//trim(edgecolor)//'"' + if (present(orientation)) tmp = tmp//', orientation="'//trim(orientation)//'"' + if (me%use_oo_api) then + call me%add_str('canvas = FigureCanvas(fig)') + call me%add_str('canvas.print_figure('//tmp//')') + else + call me%add_str('plt.savefig('//tmp//')') + endif + deallocate(tmp) + + !run it: + call me%execute(pyfile, istat=istat, python=python) + + else + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'error in savefig: pyplot class not properly initialized.' + end if + + end subroutine savefig +!***************************************************************************************** + +!***************************************************************************************** +!> author: Johannes Rieke +! date: 6/16/2017 +! +! Shows the figure. + + subroutine showfig(me, pyfile, istat, python) + + class(pyplot), intent(inout) :: me !! pyplot handler + character(len=*), intent(in), optional :: pyfile !! name of the Python script to generate + integer, intent (out), optional :: istat !! status output (0 means no problems) + character(len=*), intent(in),optional :: python !! python executable to use. (by default, this is 'python') + + if (.not. allocated(me%str)) then + + if (present(istat)) istat = -1 + write(error_unit,'(A)') 'error in showfig: pyplot class not properly initialized.' + + else if (me%use_oo_api) then + + if (present(istat)) istat = -2 + write(error_unit,'(A)') 'error in showfig: not compatible with "use_oo_api" option' + + else + + if (present(istat)) istat = 0 + + !finish up the string: + call me%finish_ops() + + !show figure: + call me%add_str('plt.show()') + + !run it: + call me%execute(pyfile, istat=istat, python=python) + + end if + + end subroutine showfig +!***************************************************************************************** + +!***************************************************************************************** + end module pyplot_module +!***************************************************************************************** +