Skip to content

Commit

Permalink
Charts (pyvista#1432)
Browse files Browse the repository at this point in the history
* Fix double blocking of `plotter.show` in script mode on Windows

* Initial draft for charts support

* Fix vtk9 imports

* * Added Area, Bar, Box and Pie plots
* Added two examples

* Fix vtk9 imports

* Change RNG -> rng

* Apply suggestions from code review

Co-authored-by: Alex Kaszynski <[email protected]>

* * Added stacked bar and area plots
* Added 3D line, scatter and volume plots
* Charts can now be properly interacted with
* Wrapped vtk Pen, Brush and Axis
* Workaround for background color issues of charts

* Fix most failing tests

* fix deep clean

* ignore static checks

* fix static checks in charts

* * Small fixes
* Make 3D charts and plots private (not further supported for now)
* Add documentation, type hints and tests for Pen and Brush objects

* Fix documentation and static check

* Fix chart teardown tests

* add back in moved chart tests

* remove cache from matplotlib plot

* add examples and docs

* add docs

* Finish examples, fix interaction

* * Use chart.show in documentation examples.
* Add Axis documentation.

* fix docstring examples

* lazy import of matplotlib to improve import time

* * Add Chart documentation
* Fix failing tests

* * 'Patch' pie chart bug
* Add documentation for _Plot and _MultiCompPlot
* Fix _MultiCompPlot, BarPlot and StackPlot issues

* Complete remaining docs.

* Apply suggestions from code review

Co-authored-by: Andras Deak <[email protected]>

* Fix remaining doc errors.

* Fix numpydoc warnings

* Experimental overview table in Pen docs.

* * Fix mentioned sphinx errors
* Add marker style and color scheme tables

* Fix failing test

* Small doc changes

* Add axis tests

* * Small chart changes
* Added data properties to plots

* * Implement remaining 'common chart properties' on ChartMPL
* Add common chart tests

* Add common plot tests

* Add 2D chart and plots tests

* Cleanup renderer's legend (fixing failing tests)

* Add tests for pie and box plots and charts

* Add chartMPL test

* Add remaining tests + bug fixes

* Remove barplot's offset property (no effect)

* Doc fix, simplify adding multiple charts

* Fix doc building on Windows

* Documentation improvements

* Disable interaction on second right click

* Fix failing checks

* Revert static check changes

* Ignore static type errors.

* Fix remaining doc errors

* add font size; cleanup toctree in api docs

* Prepare for future upstream (vtk) changes to the charts API

* Apply suggestions from code review (part 1)

Co-authored-by: Andras Deak <[email protected]>

* Apply suggestions from code review (part 2)

* Apply suggestions from code review

Co-authored-by: Andras Deak <[email protected]>

* Fix parse_color doc and checks

* Apply suggestions from code review.

* Small doc improvements

* Small doc improvements, switch to doc_subs decorator

* skip doctests changing global theme

* Make pydocstyle happy

* Add @dcbr to AUTHORS

* Fix mypy complaints

* Fix axis label size, add axis tick label size

* Remove draft 3D charts implementation

* Update 3D charts comment

* Fix textActor cleanup in Plotter.deep_clean

* fix docstring length; add trivial test; improve doc linking

Co-authored-by: Alex Kaszynski <[email protected]>
Co-authored-by: Andras Deak <[email protected]>
Co-authored-by: banesullivan <[email protected]>
  • Loading branch information
4 people authored Dec 22, 2021
1 parent 1de3744 commit 61982bf
Show file tree
Hide file tree
Showing 24 changed files with 6,082 additions and 143 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ tests/ERROR_OUTPUT.txt
doc/examples/
doc/errors.txt
doc/images/auto-generated
doc/images/charts
**/myscreenshot.png
api-autogen/
_autosummary/
doc/getting-started/external_examples.rst
doc/api/plotting/charts/pen_line_styles.rst
doc/api/plotting/charts/plot_color_schemes.rst
doc/api/plotting/charts/scatter_marker_styles.rst
**/grid.vtu

# hypothesis
Expand Down
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ considered "The PyVista Developers":
- Eric Larson, (`@larsoner <https://github.com/larsoner>`_)
- Matthew Flamm, (`@MatthewFlamm <https://github.com/MatthewFlamm>`_)
- Darik Gamble, (`@darikg <https://github.com/darikg>`_)
- Bram De Cooman, (`@dcbr <https://github.com/dcbr>`_)
41 changes: 41 additions & 0 deletions doc/api/plotting/charts/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Charts
------
Charts API reference. These dedicated classes can be used to embed
charts in plotting windows. Note that using charts requires a VTK
version of at least 9.0 and in a future release will require
``vtk>=9.2``.

.. currentmodule:: pyvista

.. autosummary::
:toctree: _autosummary
:template: custom-class-template.rst

Chart2D
ChartBox
ChartPie
ChartMPL


To customize these charts, extra plot and utility classes are
available in the ``charts`` module. Note that users should
typically not instantiate these classes themselves, but rather
use the dedicated methods and properties from the chart
classes above.

.. currentmodule:: pyvista.plotting.charts

.. autosummary::
:toctree: _autosummary
:template: custom-class-template.rst

Pen
Brush
Axis
LinePlot2D
ScatterPlot2D
BarPlot
AreaPlot
StackPlot
BoxPlot
PiePlot
13 changes: 12 additions & 1 deletion doc/api/plotting/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ all plotting functionality in PyVista.
Renderer


Charts API
----------
Charts API reference. These dedicated classes can be used to embed
charts in plotting windows. Note that using charts requires a VTK version
of at least 9.0 and in a future release will require `vtk>=9.2`.

.. toctree::
:maxdepth: 2

charts/index


Widget API
----------
The :class:`pyvista.Plotter` class inherits all of the widget methods in
Expand All @@ -54,4 +66,3 @@ routines in PyVista.

conv_func


1 change: 1 addition & 0 deletions doc/api/utilities/utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Miscellaneous
.. autosummary::
:toctree: _autosummary

parse_color
start_xvfb


Expand Down
7 changes: 7 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import datetime
import locale
import os
import sys

# Otherwise VTK reader issues on some systems, causing sphinx to crash. See also #226.
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")

if sys.version_info >= (3, 0):
import faulthandler

faulthandler.enable()

sys.path.insert(0, os.path.abspath("."))
import make_chart_style_tables
import make_external_gallery

make_external_gallery.make_example_gallery()
make_chart_style_tables.make_all()

# -- pyvista configuration ---------------------------------------------------
import pyvista
Expand Down Expand Up @@ -76,6 +82,7 @@

'pyvista.plotting.axes',
'pyvista.plotting.camera',
'pyvista.plotting.charts',
'pyvista.plotting.helpers',
'pyvista.plotting.lights',
'pyvista.plotting.picking',
Expand Down
142 changes: 142 additions & 0 deletions doc/make_chart_style_tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import os

import pyvista as pv

TABLE_DIR = "api/plotting/charts"
IMAGE_DIR = "images/charts"


def make_table(file_name, header, get_token_row, tokens):
path = f"{TABLE_DIR}/{file_name}.rst"
if os.path.exists(path):
os.remove(path)
with open(path, "w", encoding="utf-8") as f:
f.write(header)
for i, (token, data) in enumerate(tokens.items()):
if data["descr"] is not None:
f.write(get_token_row(i, token, data))
pv.close_all()


def make_line_style_img(line_style, path):
p = pv.Plotter(off_screen=True, window_size=[100, 50])
p.background_color = 'w'
chart = pv.Chart2D()
chart.line([0, 1], [0, 0], color="b", width=3.0, style=line_style)
chart.hide_axes()
p.add_chart(chart)
_, img = p.show(screenshot=True, return_cpos=True)
# Crop the image and save it
p._save_image(img[18:25, 22:85, :], path, False)


def get_line_style_row(i, token, data):
row_template = """
* - ``"{}"``
- {}
- .. image:: /{}
"""
img_path = f"{IMAGE_DIR}/ls_{i}.png"
make_line_style_img(token, img_path)
return row_template.format(token, data["descr"], img_path)


def make_line_style_table():
header = """
.. list-table:: Line styles
:widths: 20 40 40
:header-rows: 1
* - Style
- Description
- Example
"""
make_table("pen_line_styles", header, get_line_style_row, pv.charts.Pen.LINE_STYLES)


def make_marker_style_img(marker_style, path):
p = pv.Plotter(off_screen=True, window_size=[100, 100])
p.background_color = 'w'
chart = pv.Chart2D()
chart.scatter([0], [0], color="b", size=9, style=marker_style)
chart.hide_axes()
p.add_chart(chart)
_, img = p.show(screenshot=True, return_cpos=True)
# Crop the image and save it
# p._save_image(img[18:25, 50:57, :], path, False) # window_size=[100,50] and marker_size=3
p._save_image(img[40:53, 47:60, :], path, False)


def get_marker_style_row(i, token, data):
row_template = """
* - ``"{}"``
- {}
- .. image:: /{}
"""
img_path = f"{IMAGE_DIR}/ms_{i}.png"
make_marker_style_img(token, img_path)
return row_template.format(token, data["descr"], img_path)


def make_marker_style_table():
header = """
.. list-table:: Marker styles
:widths: 20 40 40
:header-rows: 1
* - Style
- Description
- Example
"""
make_table("scatter_marker_styles", header, get_marker_style_row, pv.charts.ScatterPlot2D.MARKER_STYLES)


def make_color_scheme_img(color_scheme, path):
p = pv.Plotter(off_screen=True, window_size=[240, 120])
p.background_color = 'w'
chart = pv.Chart2D()
tmp_plot = chart.bar([0], [[1]]*2, color=color_scheme, orientation="H")
n_colors = len(tmp_plot.colors) # Use a temporary plot to determine the total number of colors in this scheme
plot = chart.bar([0], [[1]]*n_colors, color=color_scheme, orientation="H")
chart.remove_plot(tmp_plot)
plot.pen.color = 'w'
chart.x_range = [0, n_colors]
chart.hide_axes()
p.add_chart(chart)
_, img = p.show(screenshot=True, return_cpos=True)
# Crop the image and save it
p._save_image(img[34:78, 22:225, :], path, False)
return n_colors


def get_color_scheme_row(i, token, data):
row_template = """
* - ``"{}"``
- {}
- {}
- .. image:: /{}
"""
img_path = f"{IMAGE_DIR}/cs_{i}.png"
n_colors = make_color_scheme_img(token, img_path)
return row_template.format(token, data["descr"], n_colors, img_path)


def make_color_scheme_table():
header = """
.. list-table:: Color schemes
:widths: 15 50 5 30
:header-rows: 1
* - Color scheme
- Description
- # colors
- Example
"""
make_table("plot_color_schemes", header, get_color_scheme_row, pv.charts._MultiCompPlot.COLOR_SCHEMES)


def make_all():
os.makedirs(IMAGE_DIR, exist_ok=True)
make_line_style_table()
make_marker_style_table()
make_color_scheme_table()
Loading

0 comments on commit 61982bf

Please sign in to comment.