Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contribute examples to etsdemo #751

Merged
merged 24 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6d38701
etsdemo boilerplate
aaronayres35 Jun 2, 2021
37f3fba
delete demo.py
aaronayres35 Jun 2, 2021
1ddbd95
move examples/demo/basic into chaco/examples
aaronayres35 Jun 2, 2021
b4c5757
move select examples from examples/demo/advanced into chaco/examples
aaronayres35 Jun 2, 2021
d9f98dd
move examples/demo/financial into chaco/examples
aaronayres35 Jun 2, 2021
e7f579c
move a bunch of selected examples from examples/demo into chaco/examp…
aaronayres35 Jun 2, 2021
1085ce7
typo
aaronayres35 Jun 2, 2021
f7bb562
add asynchronous_updates example
aaronayres35 Jun 2, 2021
bae6661
fix accidental placement into entry_points not package_data
aaronayres35 Jun 3, 2021
cdefe9a
add toolbar_plot and chaco_trait_editor examples
aaronayres35 Jun 3, 2021
6c73f53
update tox.ini
aaronayres35 Jun 3, 2021
97112f6
remove mayavi as an examples dep
aaronayres35 Jun 3, 2021
6096b08
define demo variable for use in etsdemo
aaronayres35 Jun 3, 2021
09d8d22
update hyetograph so that it works with etsdemo
aaronayres35 Jun 3, 2021
666598a
update various examples to work within etsdemo application
aaronayres35 Jun 3, 2021
465747a
add comment that qt_example.py will not work in etsdemo app
aaronayres35 Jun 3, 2021
2a26868
make scalar_image_function_inspector.py work in etsdemo
aaronayres35 Jun 3, 2021
4cdca8c
make a few other examples work inside etsdemo
aaronayres35 Jun 3, 2021
157500d
make examples using DemoFrame and demo_main work in etsdemo
aaronayres35 Jun 3, 2021
66d7c87
flake8
aaronayres35 Jun 3, 2021
67964ed
Update chaco/examples/tests/test_etsdemo_info.py
aaronayres35 Jun 7, 2021
55e42f0
rename ModelView as DemoModelView
aaronayres35 Jun 7, 2021
0b2ec29
fix scatter_inspector2
aaronayres35 Jun 7, 2021
6cd299c
remove todo list
aaronayres35 Jun 7, 2021
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
4 changes: 4 additions & 0 deletions chaco/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@
__version__ = "not-built"

__requires__ = ["traits", "traitsui", "pyface", "numpy", "enable"]

__extras_require__ = {
'examples': ['encore', 'scipy', 'pandas']
}
File renamed without changes.
34 changes: 34 additions & 0 deletions chaco/examples/_etsdemo_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!

""" This module provides functions to be advertised in the distribution
entry points.
"""

import pkg_resources


def info(request):
""" Return a configuration for contributing examples to the
Demo application.
Parameters
----------
request : dict
Information provided by the demo application.
Currently this is a placeholder.
Returns
-------
response : dict
"""
return {
"version": 1,
"name": "Chaco Examples",
"root": pkg_resources.resource_filename("chaco.examples", "demo"),
}
File renamed without changes.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@

import warnings

# Outstanding TODOs:
# - need to add line inspectors to side and bottom plots, and synchronize
# with center plot
# - need to set the various image plots to use the same colormap instance,
# and that colormap's range needs to be set to min/max of the entire cube
# - refactor create_window() so there is less code duplication
# - try to eliminate the use of model.xs, ys, zs in favor of bounds tuples
from numpy import amin, amax, zeros, fromfile, transpose, uint8

# Standard library imports
Expand Down Expand Up @@ -192,7 +185,7 @@ def normal_mouse_wheel(self, event):
self.wheel_cb(self, event.mouse_wheel)
rahulporuri marked this conversation as resolved.
Show resolved Hide resolved


class PlotFrame(DemoFrame):
class Demo(DemoFrame):

# These are the indices into the cube that each of the image plot views
# will show; the default values are non-zero just to make it a little
Expand Down Expand Up @@ -466,6 +459,6 @@ def cleanup_data():
if __name__ == "__main__":
# Save demo so that it doesn't get garbage collected when run within
# existing event loop (i.e. from ipython).
demo = demo_main(PlotFrame, size=(800, 700), title="Cube analyzer")
demo = demo_main(Demo, size=(800, 700), title="Cube analyzer")
if run_cleanup:
cleanup_data()
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,8 @@ class TimerController(HasTraits):
# The plot view which will be affected by timed animation
view = Instance(PlotUI)

# The ModelView instance that contains the animation options:
model_view = Instance("ModelView")
# The DemoModelView instance that contains the animation options:
model_view = Instance("DemoModelView")

# Whether the view is animated:
animated = DelegatesTo("model_view")
Expand Down Expand Up @@ -556,7 +556,7 @@ def randomize(new_direction=1, color_change=False):
metadata["selections"] = x, y


class ModelView(HasTraits):
class DemoModelView(HasTraits):

model = Instance(Model)
view = Instance(PlotUI)
Expand Down Expand Up @@ -614,19 +614,15 @@ def _start_timer(self):

def edit_traits(self, *args, **kws):
self._start_timer()
return super(ModelView, self).edit_traits(*args, **kws)
return super(DemoModelView, self).edit_traits(*args, **kws)

def configure_traits(self, *args, **kws):
self._start_timer()
return super(ModelView, self).configure_traits(*args, **kws)
return super(DemoModelView, self).configure_traits(*args, **kws)


def show_plot(**kwargs):
model = Model(**kwargs)
view = PlotUI(**kwargs)
modelview = ModelView(model=model, view=view)
modelview.configure_traits()
demo = DemoModelView(model=Model(), view=PlotUI())


if __name__ == "__main__":
show_plot()
demo.configure_traits()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would look / work a lot better as a popup, but that leads to very strange errors due to etsdemo internals. Doing so I get the following error:

Traceback (most recent call last):
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traitsui/qt4/instance_editor.py", line 428, in edit_instance
    view, kind=factory.kind, id=factory.id
  File "<string>", line 603, in edit_traits
  File "<string>", line 599, in _start_timer
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traits/trait_types.py", line 3360, in validate
    self.resolve_class(object, name, value)
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traits/trait_types.py", line 3462, in resolve_class
    super().resolve_class(object, name, value)
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traits/trait_types.py", line 3178, in resolve_class
    self.validate_failed(object, name, value)
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traits/trait_types.py", line 3207, in validate_failed
    self.error(object, name, value)
  File "/Users/aayres/.edm/envs/test-chaco/lib/python3.6/site-packages/traits/base_trait_handler.py", line 75, in error
    object, name, self.full_info(object, name, value), value
traits.trait_errors.TraitError: The 'model_view' trait of a TimerController instance must be a ModelView or None, but a value of <___main___.ModelView object at 0x7fa7c4a40150> <class '___main___.ModelView'> was specified.
Abort trap: 6

we have a trait defined as a = Instance("B") where B is a class defined elsewhere in the module. However, due to etsdemo messing with locals to change __name__ to ___name___, we end up passing an instance of ___name___.B which traits catches as an invalid value...
I do not know how to resolve this. Perhaps we just leave it as demo embedded in the etsdemo ui for now (it is resizable anyway so if you stretch the etsdemo ui out enough you can see the full demo).

@rahulporuri any ideas on how we could resolve this? It is awkward because you need to do Instance("ModelView") not Instance(ModelView) because ModelView is defined after TimerController in the file, and ModelView also has a trait which is Instance(TimerController) so we can't simply move the class to be defined above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. if possible, can we rename it to something other than ModelView because that slightly confuses things
  2. I don't think it's bad to use Instance("ModelView") instead of Instance(ModelView). I think there are definitely valid usecases (like here) where a class is defined later in the module which needs to be used here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note:
switching to

model_view = Instance(
       "chaco.examples.demo.advanced.scalar_image_function_inspector.DemoModelView"  # noqa: E501
   )

did not solve the issue. I will leave it as a demo not a pop up for now

Empty file.
File renamed without changes.
File renamed without changes
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,9 @@ class Demo(HasTraits):
)


demo = Demo()
filled, horizon = _create_plot_components()
demo = Demo(horizon=horizon, filled=filled)

if __name__ == "__main__":

filled, horizon = _create_plot_components()
demo.horizon = horizon
demo.filled = filled
if __name__ == "__main__":
demo.configure_traits()
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def _plot_default(self):
return plot


demo = MinorTickDemo()


if __name__ == "__main__":
demo = MinorTickDemo()
demo.configure_traits()
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,40 @@ def show_data(data_idx):
return show_data


if __name__ == "__main__":
def _create_plot_component():
# Create a fake dataset from which 2 dimensions will be displayed in a
# scatter plot:
x = np.random.uniform(0.0, 10.0, 50)
y = np.random.uniform(0.0, 5.0, 50)
data = pd.DataFrame(
{"x": x, "y": y, "dataset": np.random.choice(list("abcdefg"), 50)}
)
plot_data = ArrayPlotData(x=x, y=y)
plot = Plot(plot_data)
scatter = plot.plot(("x", "y"), type="scatter")[0]

# Attach the inspector and its overlays
inspector = DataframeScatterInspector(component=scatter, data=data)
scatter.tools.append(inspector)

text_overlay = DataframeScatterOverlay(
component=plot,
inspector=inspector,
bgcolor="black",
alpha=0.6,
text_color="white",
border_color="none",
)
plot.overlays.append(text_overlay)

def _create_plot_component():
# Create a fake dataset from which 2 dimensions will be displayed in a
# scatter plot:
x = np.random.uniform(0.0, 10.0, 50)
y = np.random.uniform(0.0, 5.0, 50)
data = pd.DataFrame(
{"x": x, "y": y, "dataset": np.random.choice(list("abcdefg"), 50)}
)
plot_data = ArrayPlotData(x=x, y=y)
plot = Plot(plot_data)
scatter = plot.plot(("x", "y"), type="scatter")[0]

# Attach the inspector and its overlays
inspector = DataframeScatterInspector(component=scatter, data=data)
scatter.tools.append(inspector)

text_overlay = DataframeScatterOverlay(
component=plot,
inspector=inspector,
bgcolor="black",
alpha=0.6,
text_color="white",
border_color="none",
)
plot.overlays.append(text_overlay)

# Optional: add an overlay on the point to confirm what is hovered over
# Note that this overlay magically knows about hovered points by
# listening to renderer events rather than inspector events:
point_overlay = ScatterInspectorOverlay(
component=scatter, hover_color="red", hover_marker_size=6
)
scatter.overlays.append(point_overlay)
return plot
# Optional: add an overlay on the point to confirm what is hovered over
# Note that this overlay magically knows about hovered points by
# listening to renderer events rather than inspector events:
point_overlay = ScatterInspectorOverlay(
component=scatter, hover_color="red", hover_marker_size=6
)
scatter.overlays.append(point_overlay)
return plot


# =============================================================================
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
interval.
"""


from traits.api import HasTraits
from traits.etsconfig.api import ETSConfig

if ETSConfig.toolkit == "wx":
from traitsui.wx.editor import Editor
else:
from traitsui.qt4.editor import Editor

from traitsui.api import EditorFactory
from traitsui.api import EditorFactory, Item, View

from enable.api import ColorTrait, Window

Expand Down Expand Up @@ -173,18 +173,15 @@ def update_editor(self):
IntervalEditor = IntervalEditorFactory


# --- Demonstration ---

if __name__ == "__main__":
from traits.api import HasTraits
from traitsui.api import View, Item

class IntervalTest(HasTraits):
class IntervalTest(HasTraits):
interval = Interval(low=0, high=1)

traits_view = View(
Item("interval", editor=IntervalEditor()), resizable=True
)

it = IntervalTest()
it.configure_traits()

demo = IntervalTest()

if __name__ == "__main__":
demo.configure_traits()
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def create_dates(numpoints, units="days"):
return dates


class PlotFrame(DemoFrame):
class Demo(DemoFrame):
def _create_price_plots(self, times, prices, mini_height=75):
"""Creates the two plots of prices and returns them. One of the
plots can be zoomed and panned, and the other plot (smaller) always
Expand Down Expand Up @@ -221,5 +221,5 @@ def _create_component(self):
# Save demo so that it doesn't get garbage collected when run within
# existing event loop (i.e. from ipython).
demo = demo_main(
PlotFrame, size=(800, 600), title="Stock price and volume"
Demo, size=(800, 600), title="Stock price and volume"
)
19 changes: 12 additions & 7 deletions examples/demo/hyetograph.py → chaco/examples/demo/hyetograph.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from chaco.api import ArrayPlotData, Plot
from enable.api import ComponentEditor
from traits.api import (
Bool,
HasTraits,
Instance,
Int,
Expand Down Expand Up @@ -43,6 +44,12 @@ class Hyetograph(HasTraits):

nrcs_plot = Instance(Plot)

initialized = Bool(False)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.initialized = True

def _intensity_plot_default(self):
intensity_plot = Plot(ArrayPlotData(x=self.timeline, y=self.intensity))
intensity_plot.x_axis.title = "Time (hr)"
Expand Down Expand Up @@ -104,7 +111,7 @@ def calculate_runoff(self):
vr[i] = 0
self.nrcs = vr

@observe('duration, year_storm, county, curve_number')
@observe('duration, year_storm, county, curve_number, initialized')
def _perform_calculations(self, event=None):
self.calculate_intensity()
self.calculate_runoff()
Expand All @@ -126,10 +133,6 @@ def _update_polt_type(self, event):
self.intensity_plot.invalidate_and_redraw()
self.nrcs_plot.invalidate_and_redraw()

def start(self):
self._perform_calculations()
self.configure_traits()

traits_view = View(
Item('plot_type'),
Item("intensity_plot", editor=ComponentEditor()),
Expand All @@ -144,6 +147,8 @@ def start(self):
)


popup = Hyetograph()


if __name__ == "__main__":
hyetograph = Hyetograph()
hyetograph.start()
popup.configure_traits()
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

The origin parameter sets a plot's default origin to the specified corner
of the plot window. These positions has the following behavior:
* 'left' : index increases left to right
* 'right' : index increases right to left
* 'top' : index increases top to bottom
* 'bottom' : index increases bottom to top

* 'left' : index increases left to right
* 'right' : index increases right to left
* 'top' : index increases top to bottom
* 'bottom' : index increases bottom to top
Comment on lines +6 to +10
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was previously giving an indentation warning inside the etsdemo app


The orientation parameter switches the x- and y-axes. Alternatively, you can
think of this as a transpose about the origin.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,25 @@ def _offset_changed(self, off):
self.multi_line_plot_renderer._amplitude_changed()


# Sample rate.
fs = 500
# Total time.
T = 5.0
num_samples = fs * T
t = np.arange(num_samples) / fs

channels = np.arange(12)
# Frequencies of the sine functions in each channel.
freqs = 3 * (channels[:, None] + 1)
y = np.sin(freqs * t)

# Create an instance of DataModel. This is the data to
# be plotted with a MultiLinePlot.
data = DataModel(x_index=t, y_index=channels, data=y)

# Create the demo class, and show it.
demo = MultiLinePlotDemo(model=data)


if __name__ == "__main__":
# Sample rate.
fs = 500
# Total time.
T = 5.0
num_samples = fs * T
t = np.arange(num_samples) / fs

channels = np.arange(12)
# Frequencies of the sine functions in each channel.
freqs = 3 * (channels[:, None] + 1)
y = np.sin(freqs * t)

# Create an instance of DataModel. This is the data to
# be plotted with a MultiLinePlot.
data = DataModel(x_index=t, y_index=channels, data=y)

# Create the demo class, and show it.
demo = MultiLinePlotDemo(model=data)
demo.configure_traits()
Loading