Monthly Archives: October 2008

New Enthought Python Distribution (EPD)

A new version of EPD (py2.5 4.0.30002) is now available on Enthought’s download page.

Best Kept Secret

The following image really gets me excited about EPD:

No, I’m not talking about the crazy download sizes (which, BTW really grew with this release because of many more included docs). What excites me is something that gets little press about EPD (and writing applications using Python, in general) — EPD provides a common environment for running applications across several platforms. This is a huge win in Enthought’s business–I suspect others will see the light soon enough. A great example of a sophisticated application that is written once and runs everywhere is Mayavi (which is included with EPD as part of the Enthought Tool Suite). Here’s the proof:

On Windows:

On OS X:

(BTW, for those who’ve never heard of it, Mayavi is a fantastic 3D visualization application written by Prabhu Ramachandran with help from Gael Varoquaux and others.) I suspect this to be a boon for scientific and engineering application development going forward because it allows code to be shared across the religious groups of Windows, Linux and OS X users.

“Still not enough,” you say?

Alright, so we’re up to over 80 included packages. Since we’re going for a “kitchen-sink-included” distribution of Python, I’d be interested to hear of any feedback on what we need to include in EPD to meet our goal of the perfect scientific/data exploration environment. Suggestions for packages, as well as pointers to areas where more development is needed, are welcome. I already have SymPy (ticket) on my personal wishlist. Other packages, such as pywavelets (ticket) and PyAMG (ticket) have also been mentioned. Please comment below with any more suggestions.

EPD is a Subscription
I’ve written before about Enthought’s mission and strategy with open source software. I believe EPD’s role in this strategy is to provide a high quality, supported bundle that injects powerful open source tools into “the Enterprise.” The more commercial interest in EPD, the more resources we have to fund our chosen tool stack (and to fund our commitment to provide a quality distribution at no cost to academic users). Since EPD has many of the characteristics of a Linux distro (lots of included pieces that have to be vetted together, provenance issues to be sorted, focus on stability through iteration) we’ve chosen a subscription model (similar to RedHat’s approach) for commercial and governmental users. Of course all of EPD’s contents are available for free from their respective sources. We’ve found a targeted bundle to be helpful in our business, our hope is that others find it useful as well.

Chaco toolbars

I’ve always wanted a toolbar for Chaco to do simple tasks like copying a plot to the clipboard or saving a plot. A few months ago I decided to do something about it while working on a customer project. Today I finally got around to refactoring the toolbar and the one in BlockCanvas which it was based on. Its a little rough still, mostly because of mismatched icons, but it is fully functional. I’ve added an example to the Chaco examples, which this is a screenshot of. The best part is that the toolbar is extensible so you can make a toolbar with only the buttons you want. I have more plans for the toolbar which I’ll be discussing in the coming weeks…

Chaco Toolbar

What priorities should the EPD dev team have?

Like any software project, the EPD product is developed by a team that has limited resources. Given that fact, I’m wondering what the current userbase of EPD thinks is more important for us to spend our time on? Should we prioritize ourselves along the lines of:

  1. Tracking the current releases of all included projects, even if doing so breaks backwards-compatibility in terms of API and ABI?
  2. Or, should we apply our resources to fixing bugs and keeping a stable API and ABI?

I think of this as the same sort of division you might run into in regards to picking a Linux distribution. Are you more interested in a Fedora Core or a RedHat Enterprise Linux? Or are there other options and/or models for us to follow? Right now, I’d have to classify our position statement as doing (1) and, as available on explicitly identified releases, doing (2) as required. Is that what the user community needs and wants though?

We haven’t had much feedback along these lines, though we can read some into the various comments we get about “Why does EPD include that version of project X when it is 6 months old?” The problem with relying on those though is that you don’t hear from the people who want that stability of not upgrading to the latest and greatest all of the time. No one sends e-mails that say “Please don’t upgrade your product to that newly released version of component X”. Well, at least I’ve never received one like that.

I should point out that while I’m explicitly looking for feedback and discussion about this (probably best if done on the epd-users mailing list, though I will also try and monitor this blog post) any feedback from paying customers takes precedence. But hopefully that makes sense and doesn’t come as a shock to anyone. I will also admit that I’m somewhat expecting any responses to this to be self-selecting in that I expect most of the readers of this blog to fall into the “hobbyist”, “individual developer”, or “early adopter” camp and those groups tend to want the latest and greatest. They don’t mind the upgrade treadmill as much as large corporations. However, I’m still asking the question because I’m making assumptions and I’d much rather have some facts. Please speak up and let us know your thoughts!

EPD with Py2.5 v4.0.30002 RC2 build available

Hello,

We’ve recently posted the RC2 build of EPD (the Enthought Python Distribution) with Python 2.5 version 4.0.30002 to the EPD website.

You can check out the release notes here:

https://svn.enthought.com/epd/wiki/Python2.5.2/4.0.300/RC2

Please help us test it out and provide feedback on the EPD Trac instance: https://svn.enthought.com/epd or via e-mail to epd-support@enthought.com. If everything goes well, we are planning a final release for this coming Tuesday, October 21st.

About EPD
The Enthought Python Distribution (EPD) is a “kitchen-sink-included” distribution of the Python Programming Language, including over 60 additional tools and libraries. The EPD bundle includes NumPy, SciPy, IPython, 2D and 3D visualization, database adapters, and a lot of other tools right out of the box.

http://www.enthought.com/products/epd.php

It is currently available as a single-click installer for Windows XP (x86), Mac OS X (a universal binary for OS X 10.4 and above), and RedHat 3 and 4 (x86 and amd64).

EPD is free for academic use. An annual subscription and installation support are available for individual commercial use. An enterprise subscription with support for particular deployment environments is also available for commercial purchase.

Making a Chaco highlight legend

Last week I posted an example of how to use an interactive Chaco tool to highlight selected plots, this week I’m providing a working example using it.

First we need to define the tool, which inherits from Enable’s BaseTool. We override the normal_mouse_move method, which is called every time the mouse moves when neither mouse button is down. The normal_mouse_move method performs a hit test on the legend, highlighting the selected lines and dimming the others.

[sourcecode language=python]
class HighlightLegend(BaseTool):
_selected_plot = Any
_selected_renderers = List

def _get_hit_plots(self, event):
legend=self.component
if legend is None or not legend.is_in(event.x, event.y):
return []

label = legend.get_label_at(event.x, event.y)
if label is None:
return []

index = legend._cached_labels.index(label)
label_name = legend._cached_label_names[index]
return legend.plots[label_name]

def normal_mouse_move(self, event):
new = set(self._get_hit_plots(event))
old = set(self._selected_renderers)

if old == new:
new = set()

# select the new ones:
for renderer in new – old:
self._select(renderer)

# deselect the old ones that are not new
for renderer in old – new:
self._deselect(renderer)

self._selected_renderers = list(new)

def _select(self, selected):
“”” Decorates a plot to indicate it is selected “””
for plot in reduce(operator.add, selected.container.plots.values()):
if plot != selected:
plot.alpha /= 3
else:
plot.line_width *= 2

plot.request_redraw()

def _deselect(self, selected):
for plot in reduce(operator.add, selected.container.plots.values()):
if plot != selected:
plot.alpha *= 3
else:
plot.line_width /= 2

plot.request_redraw()
[/sourcecode]

All that is left to do is attach the new tool to the legend. In this example a plot is created with 2 data series then the plot is made visible and hooked up to the new tool

[sourcecode language=python]
class MyPlot(HasTraits):
plot = Instance(Plot)

traits_view = View(Item(‘plot’, editor=ComponentEditor()))

def __init__(self, index, series1, series2, **kw):
super(MyPlot, self).__init__(**kw)

plot_data = ArrayPlotData(index=index)
plot_data.set_data(‘series1’, series1)
plot_data.set_data(‘series2’, series2)
self.plot = Plot(plot_data)
self.plot.plot((‘index’, ‘series1’))
self.plot.plot((‘index’, ‘series2’))

self.plot.legend.visible = True
self.plot.legend.tools.append(HighlightLegend(self.plot.legend))
[/sourcecode]

By popular demand, here are two screenshots, one without any highlighting, and another with one series highlighted:
not highlighed
highlighted

Plot highlighting using alpha values

I recently added support for changing the alpha of a plot after it has been constructed. Combined with a selection tool you get a really nice highlight feature. In this example, when a plot is selected I double its width and set the alpha of the other plots to 1/3 of their normal value.

plot with alpha

[sourcecode language=”python”]
def _select(self, selected):
“”” Decorates a plot to indicate it is selected “””
for plot in reduce(operator.add, selected.container.plots.values()):
if plot != selected:
plot.alpha /= 3
else:
plot.line_width *= 2

plot.request_redraw()

def _deselect(self, selected):
for plot in reduce(operator.add, selected.container.plots.values()):
if plot != selected:
plot.alpha *= 3
else:
plot.line_width /= 2

plot.request_redraw()
[/sourcecode]