Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/plot-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ jobs:
pip install -e .
bash -x ./admin-tools/make-JSON-tables.sh
remake -x develop-full
- name: install Mathic3 vectorizedplot Module
run: |
git clone --depth 1 https://github.com/Mathics3/Mathics3-Module-vectorizedplot.git
cd Mathics3-Module-vectorizedplot
python -m pip install --no-build-isolation -e .
cd ..
- name: Test Mathics
run: |
make plot-detailed-tests
37 changes: 5 additions & 32 deletions mathics/builtin/drawing/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import palettable

import mathics.eval.drawing.plot3d
import mathics.eval.drawing.plot3d_vectorized
from mathics.builtin.graphics import Graphics
from mathics.builtin.options import options_to_rules
from mathics.core.atoms import Integer, Integer0, MachineReal, String
Expand Down Expand Up @@ -39,29 +38,11 @@
from mathics.eval.drawing.plot import get_plot_range
from mathics.eval.nevaluator import eval_N

# The vectorized plot function generates GraphicsComplex using NumericArray,
# which no consumer will currently understand. So lets make it opt-in for now.
# If it remains opt-in we'll probably want some combination of env variables,
# Set option such as $UseVectorizedPlot, and maybe a non-standard Plot3D option.
# For now an env variable is simplest.
# TODO: work out exactly how to deploy.


# can be set via environment variable at startup time,
# or changed dynamically by setting the use_vectorized_plot flag
use_vectorized_plot = os.getenv("MATHICS3_USE_VECTORIZED_PLOT", False)


# get the plot eval function for the given class,
# depending on whether vectorized plot functions are enabled
# get the plot eval function for the given class
def get_plot_eval_function(cls):
function_name = "eval_" + cls.__name__
plot_module = (
mathics.eval.drawing.plot3d_vectorized
if use_vectorized_plot
else mathics.eval.drawing.plot3d
)
fun = getattr(plot_module, function_name)
fun = getattr(mathics.eval.drawing.plot3d, function_name)
return fun


Expand Down Expand Up @@ -519,17 +500,9 @@ def error(*args, **kwargs):
evaluation.message(builtin.get_name(), "invmaxrec", max_depth, 15)
self.max_depth = max_depth

# PlotRange option
# Normalize to always return a list of either numeric,
# Symbol (for vectorized plots), or str (for classic plogs)
# TODO: convert classic plots to use Symbol instead of str also
if use_vectorized_plot:
preserve_symbols = True
symbol_type = Symbol
else:
# TODO: get rid of these
preserve_symbols = False
symbol_type = str
# TODO: get rid of these
preserve_symbols = False
symbol_type = str
plot_range = builtin.get_option(options, str(SymbolPlotRange), evaluation)
plot_range = eval_N(plot_range, evaluation).to_python(
preserve_symbols=preserve_symbols
Expand Down
12 changes: 4 additions & 8 deletions mathics/builtin/drawing/plot_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from mathics.core.symbols import SymbolTrue
from mathics.core.systemsymbols import SymbolLogPlot, SymbolPlotRange, SymbolSequence
from mathics.eval.drawing.plot import eval_Plot
from mathics.eval.drawing.plot_vectorized import eval_Plot_vectorized

from . import plot

Expand Down Expand Up @@ -78,20 +77,18 @@ def eval(self, functions, ranges, evaluation: Evaluation, options: dict):
except ValueError:
return None

# for classic plot we cache results, but for vectorized we can't
# because ndarray is unhashable, and in any case probably isn't useful
# cache results
# TODO: does caching results in the classic case have demonstrable performance benefit?
apply_function = self.apply_function
if not plot.use_vectorized_plot:
apply_function = lru_cache(apply_function)
apply_function = lru_cache(apply_function)

# additional options specific to this class
plot_options.functions = self.get_functions_param(functions)
plot_options.apply_function = apply_function
plot_options.use_log_scale = self.use_log_scale
plot_options.expect_list = self.expect_list
if plot_options.plot_points is None:
default_plot_points = 1000 if plot.use_vectorized_plot else 57
default_plot_points = 57
plot_options.plot_points = default_plot_points

# pass through the expanded plot_range options
Expand All @@ -102,8 +99,7 @@ def eval(self, functions, ranges, evaluation: Evaluation, options: dict):
if plot_options.use_log_scale:
options[str(SymbolLogPlot)] = SymbolTrue

# this will be either the vectorized or the classic eval function
eval_function = eval_Plot_vectorized if plot.use_vectorized_plot else eval_Plot
eval_function = eval_Plot
with np.errstate(all="ignore"): # suppress numpy warnings
graphics = eval_function(plot_options, options, evaluation)
return graphics
Expand Down
2 changes: 1 addition & 1 deletion mathics/builtin/drawing/plot_plot3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def eval(

# supply default value
if plot_options.plot_points is None:
default_plot_points = (200, 200) if plot.use_vectorized_plot else (7, 7)
default_plot_points = (7, 7)
plot_options.plot_points = default_plot_points

# subclass must set eval_function and graphics_class
Expand Down
Loading
Loading