Skip to content

Commit

Permalink
Merge pull request #1 from ioam/py3
Browse files Browse the repository at this point in the history
Python 3 support
  • Loading branch information
philippjfr committed May 12, 2014
2 parents 1a78af4 + 74ec669 commit 2a8ae81
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 156 deletions.
11 changes: 7 additions & 4 deletions .travis.yml
Expand Up @@ -2,11 +2,14 @@ language: python
python:
- "2.6"
- "2.7"

before_install:
- time pip install ipython==1.0 jinja2 tornado pyzmq
- "3.3"
- "3.4"

# no dependencies
install: true

script: nosetests
install:
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install ipython==1.0 jinja2 tornado pyzmq; fi
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install ipython jinja2 tornado pyzmq; fi

script: nosetests
8 changes: 4 additions & 4 deletions dataviews/__init__.py
Expand Up @@ -4,10 +4,10 @@
cwd = os.path.abspath(os.path.split(__file__)[0])
sys.path.insert(0, os.path.join(cwd, '..', 'param'))

from views import * # pyflakes:ignore (API import)
from dataviews import * # pyflakes:ignore (API import)
from sheetviews import * # pyflakes:ignore (API import)
from ndmapping import * # pyflakes:ignore (API import)
from .views import * # pyflakes:ignore (API import)
from .dataviews import * # pyflakes:ignore (API import)
from .sheetviews import * # pyflakes:ignore (API import)
from .ndmapping import * # pyflakes:ignore (API import)


def public(obj):
Expand Down
13 changes: 7 additions & 6 deletions dataviews/dataviews.py
Expand Up @@ -3,8 +3,8 @@

import param

from ndmapping import NdMapping, map_type
from views import View, Overlay, Annotation, Layout, GridLayout
from .ndmapping import NdMapping, map_type
from .views import View, Overlay, Annotation, Layout, GridLayout

def find_minmax(lims, olims):
"""
Expand Down Expand Up @@ -60,7 +60,8 @@ class Curve(DataLayer):


def __init__(self, data, **kwargs):
super(Curve, self).__init__(np.array(data), **kwargs)
data = data if isinstance(data, np.ndarray) else np.array(list(data))
super(Curve, self).__init__(data, **kwargs)


@property
Expand Down Expand Up @@ -378,7 +379,7 @@ def split_axis(self, x_axis):
self._check_key_type = False # Speed optimization

x_ndim = self.dim_index(x_axis)
keys = self._data.keys()
keys = list(self._data.keys())
x_vals, dim_values = self._split_keys_by_axis(keys, x_axis)

split_data = map_type()
Expand Down Expand Up @@ -466,7 +467,7 @@ def sample(self, samples=[], x_axis=None, group_by=[]):
# Generate labels
legend_label = ', '.join(self.dim_dict[name].pprint_value(val)
for name, val in overlay_items)
ylabel = x_axis_data.values()[0].label
ylabel = list(x_axis_data.values())[0].label
label, xlabel, ylabel = self._curve_labels(x_axis,
samples[sample_ind],
ylabel)
Expand Down Expand Up @@ -563,7 +564,7 @@ def __init__(self, data, **kwargs):
super(Table, self).__init__(data=data, **kwargs)

# Assume OrderedDict if not a vanilla Python dict
self.headings = self.data.keys()
self.headings = list(self.data.keys())
if type(self.data) == dict:
self.headings = sorted(self.headings)

Expand Down
77 changes: 39 additions & 38 deletions dataviews/ipython.py
@@ -1,3 +1,4 @@
import matplotlib as mpl
import matplotlib.pyplot as plt
try: from matplotlib import animation
except: animation = None
Expand All @@ -14,12 +15,14 @@
from tempfile import NamedTemporaryFile
from functools import wraps
import traceback, itertools, string
import base64
import sys

from dataviews import Stack
from plots import Plot, GridLayoutPlot, viewmap, channel_modes
from sheetviews import GridLayout, CoordinateGrid
from views import View, Overlay, Annotation, Layout
from options import options, channels, PlotOpts, StyleOpts, ChannelOpts
from .dataviews import Stack
from .plots import Plot, GridLayoutPlot, viewmap, channel_modes
from .sheetviews import GridLayout, CoordinateGrid
from .views import View, Overlay, Annotation, Layout
from .options import options, channels, PlotOpts, StyleOpts, ChannelOpts

# Variables controlled via the %view magic
PERCENTAGE_SIZE, FPS, FIGURE_FORMAT = 100, 20, 'png'
Expand Down Expand Up @@ -88,15 +91,15 @@ def _set_animation_options(self, anim_spec):
format_choice, fps_str = ((anim_spec, None) if (':' not in anim_spec)
else anim_spec.rsplit(':'))
if format_choice not in self.anim_formats:
print "Valid animations types: %s" % ', '.join(self.anim_formats)
print("Valid animations types: %s" % ', '.join(self.anim_formats))
return False
elif fps_str is None:
VIDEO_FORMAT = format_choice
return True
try:
fps = int(fps_str)
except:
print "Invalid frame rate: '%s'" % fps_str
print("Invalid frame rate: '%s'" % fps_str)
return False

VIDEO_FORMAT, FPS = format_choice, fps
Expand All @@ -111,7 +114,7 @@ def _set_size(self, size_spec):
except: size = None

if (size is None) or (size < 0):
print "Percentage size must be an integer larger than zero."
print("Percentage size must be an integer larger than zero.")

This comment has been minimized.

Copy link
@jbednar

jbednar May 12, 2014

Member

Shouldn't nearly all of these print statements be done using Param's logging facilities, which would thus be the same between Python 2 and 3 anyway? Some ware warnings, some are errors, and some are just debugging information, but only a few (e.g. print(self.usage_info)) seem like things that should be using print directly.

This comment has been minimized.

Copy link
@jlstevens

jlstevens May 12, 2014

Contributor

These classes are not Parameterized so self.warn etc won't be available. We could use the param.main object which would be better for the reasons you mentioned. So yes, this would be an improvement but it isn't a priority at this point (everywhere else in dataviews we are logging things with param properly).

This comment has been minimized.

Copy link
@jbednar

jbednar via email May 12, 2014

Member
return False
else:
PERCENTAGE_SIZE = size
Expand All @@ -123,7 +126,7 @@ def _parse_settings(self, opts):
fig_fmt = [('svg' in opts), ('png' in opts)]
if all(fig_fmt):
success = False
print "Please select either png or svg for static output"
print("Please select either png or svg for static output")
elif True in fig_fmt:
figure_format = ['svg', 'png'][fig_fmt.index(True)]
FIGURE_FORMAT= figure_format
Expand Down Expand Up @@ -156,12 +159,12 @@ def view(self, line, cell=None):

if cell is None and success:
info = (VIDEO_FORMAT.upper(), FIGURE_FORMAT.upper(), PERCENTAGE_SIZE, FPS)
print "Displaying %s animation and %s figures [%d%% size, %s FPS]" % info
print("Displaying %s animation and %s figures [%d%% size, %s FPS]" % info)
elif cell and success:
self.shell.run_cell(cell)
[FIGURE_FORMAT, VIDEO_FORMAT, PERCENTAGE_SIZE, FPS] = start_opts
else:
print self.usage_info
print(self.usage_info)



Expand Down Expand Up @@ -258,9 +261,9 @@ def option_completer(cls, k,v):
line_tail = line[len('%%channels'):]
op_name = line_tail[::-1].rsplit('[')[1][::-1].strip().split()[-1]
if op_name in channel_modes:
return channel_modes[op_name].params().keys()
return list(channel_modes[op_name].params().keys())
else:
return channel_modes.keys()
return list(channel_modes.keys())


@magics_class
Expand Down Expand Up @@ -308,7 +311,7 @@ def collect(cls, obj, attr='style'):
for subview in obj:
group.update(cls.collect(subview, attr))
elif isinstance(obj, Stack) and not issubclass(obj.type, Overlay):
key_lists = [cls.collect(el, attr).keys() for el in obj]
key_lists = [list(cls.collect(el, attr).keys()) for el in obj]
values = set(el for els in key_lists for el in els)
for val in values:
group.update({val:obj.type})
Expand Down Expand Up @@ -363,7 +366,7 @@ def set_view_options(cls, obj):

# Implements the %%labels magic
if cls.show_labels:
labels = cls.collect(obj, 'label').keys()
labels = list(cls.collect(obj, 'label').keys())
info = (len(labels), labels.count(''))
summary = ("%d objects inspected, %d without labels. "
"The set of labels found:<br><br>&emsp;" % info)
Expand Down Expand Up @@ -576,10 +579,10 @@ def _line_magic(self, line):
if not kwarg_map:
info = (len(options.style.keys()),
len([k for k in options.style.keys() if k.startswith('Custom')]))
print "There are %d style options defined (%d custom object styles)." % info
print("There are %d style options defined (%d custom object styles)." % info)
info = (len(options.plotting.keys()),
len([k for k in options.plotting.keys() if k.startswith('Custom')]))
print "There are %d plot options defined (%d custom object plot settings)." % info
print("There are %d plot options defined (%d custom object plot settings)." % info)
return

self._define_options(kwarg_map, verbose=verbose)
Expand Down Expand Up @@ -654,20 +657,23 @@ def animate(anim, writer, mime_type, anim_kwargs, extra_args, tag):
with NamedTemporaryFile(suffix='.%s' % mime_type) as f:
anim.save(f.name, writer=writer, **anim_kwargs)
video = open(f.name, "rb").read()
anim._encoded_video = video.encode("base64")
anim._encoded_video = base64.b64encode(video).decode("utf-8")
return tag.format(b64=anim._encoded_video,
mime_type=mime_type)


def HTML_video(plot):
anim = plot.anim(fps=FPS)
writers = animation.writers.avail
for fmt in [VIDEO_FORMAT] + ANIMATION_OPTS.keys():
for fmt in [VIDEO_FORMAT] + list(ANIMATION_OPTS.keys()):
if ANIMATION_OPTS[fmt][0] in writers:
try:
return animate(anim, *ANIMATION_OPTS[fmt])
except: pass
return "<b>Could not generate %s animation</b>" % VIDEO_FORMAT
msg = "<b>Could not generate %s animation</b>" % VIDEO_FORMAT
if sys.version_info[0] == 3 and mpl.__version__[:-2] in ['1.2', '1.3']:
msg = "<b>Python 3 Matplotlib animation support broken &lt;= 1.3</b>"
raise Exception(msg)


def first_frame(plot):
Expand All @@ -691,7 +697,7 @@ def figure_display(fig, size=None, message=None):

mime_type = 'svg+xml' if FIGURE_FORMAT.lower()=='svg' else 'png'
prefix = 'data:image/%s;base64,' % mime_type
b64 = prefix + print_figure(fig, FIGURE_FORMAT).encode("base64")
b64 = prefix + base64.b64encode(print_figure(fig, FIGURE_FORMAT)).decode("utf-8")
if size is not None:
html = "<center><img height='%d' width='%d' src='%s'/><center/>" % (size, size, b64)
else:
Expand All @@ -700,11 +706,6 @@ def figure_display(fig, size=None, message=None):
return html if (message is None) else '<b>%s</b></br>%s' % (message, html)


def figure_fallback(plotobj):
message = ('Cannot import matplotlib.animation' if animation is None
else 'Failed to generate matplotlib animation')
fig = plotobj()
return figure_display(fig, message=message)


#===============#
Expand All @@ -723,13 +724,17 @@ def display_hook(fn):
@wraps(fn)
def wrapped(view, **kwargs):
try:
retval = fn(view, **kwargs)
return fn(view, **kwargs)
except:
if ENABLE_TRACEBACKS:
traceback.print_exc()
return retval
return wrapped

def render(plot):
try:
return render_anim(plot)
except Exception as e:
return str(e)+'<br/>'+figure_display(plot())

@display_hook
def animation_display(anim):
Expand All @@ -748,9 +753,7 @@ def stack_display(stack, size=256):
fig = stackplot()
return figure_display(fig)

try: return render_anim(stackplot)
except: return figure_fallback(stackplot)

return render(stackplot)

@display_hook
def layout_display(grid, size=256):
Expand All @@ -767,8 +770,7 @@ def layout_display(grid, size=256):
fig = gridplot()
return figure_display(fig)

try: return render_anim(gridplot)
except: return figure_fallback(gridplot)
return render(gridplot)

@display_hook
def projection_display(grid, size=256):
Expand All @@ -778,14 +780,13 @@ def projection_display(grid, size=256):
size_factor*grid.shape[0]*get_plot_size()[0])
magic_info = process_view_magics(grid)
if magic_info: return magic_info
opts = dict(options.plotting(grid.values()[-1]).opts, size=grid_size)
opts = dict(options.plotting(list(grid.values())[-1]).opts, size=grid_size)
gridplot = viewmap[grid.__class__](grid, **opts)
if len(gridplot)==1:
fig = gridplot()
return figure_display(fig)

try: return render_anim(gridplot)
except: return figure_fallback(gridplot)
return render(gridplot)

@display_hook
def view_display(view, size=256):
Expand Down Expand Up @@ -829,13 +830,13 @@ def update_matplotlib_rc():

def load_ipython_extension(ip, verbose=True):

if verbose: print message
if verbose: print(message)

global _loaded
if not _loaded:
_loaded = True

param_ext.load_ipython_extension(ip)
param_ext.load_ipython_extension(ip, verbose=False)

ip.register_magics(ViewMagic)
ip.register_magics(OptsMagic)
Expand Down

0 comments on commit 2a8ae81

Please sign in to comment.