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
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
The MIT License (MIT)

Copyright (c) 2015 Geert Barentsen
Copyright (c) 2015 Aleksa Sarai

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
36 changes: 35 additions & 1 deletion k2flix/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
""""Create movies or animated gifs from Kepler Target Pixel Files.

Author: Geert Barentsen
Contributor: Aleksa Sarai
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
Expand All @@ -13,6 +14,7 @@
import imageio
import argparse
import numpy as np
import io

import matplotlib
matplotlib.use('Agg')
Expand All @@ -26,6 +28,19 @@
from astropy.utils.console import ProgressBar
from astropy import log

def find_renderer(fig):
if hasattr(fig.canvas, "get_renderer"):
# Some renderers are nice and just given us get_renderer.
renderer = fig.canvas.get_renderer()
else:
# We have to hack around ones that don't by printing the figure to a
# temporary file object. We can then access the Agg renderer which is
# cached after writing it. Yes, this is ugly but there isn't really
# another way around it.
fig.canvas.print_figure(io.BytesIO())
renderer = fig._cachedRenderer
return renderer


class BadKeplerFrame(Exception):
"""Raised if a frame is empty."""
Expand Down Expand Up @@ -125,12 +140,15 @@ def annotated_image(self, frame=0, dpi=None, vmin=1, vmax=5000,
if dpi is None:
# Twitter timeline requires dimensions between 440x220 and 1024x512
dpi = 440 / float(flx.shape[0])
# DPI needs to be a multiple of two for ffmpeg.
dpi += dpi % 2
fontsize = 3. * flx.shape[0]
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message="(.*)invalid value(.*)")
flx[np.isnan(flx) | (flx < vmin)] = vmin
# Create the frame
fig = pl.figure(figsize=flx.shape, dpi=dpi)
fig = pl.figure(figsize=flx.shape[::-1], dpi=dpi)
rendr = find_renderer(fig)
ax = fig.add_subplot(111)
ax.matshow(flx, aspect='auto',
norm=LogNorm(vmin=vmin, vmax=vmax),
Expand All @@ -154,6 +172,22 @@ def annotated_image(self, frame=0, dpi=None, vmin=1, vmax=5000,
txt2.set_path_effects([path_effects.Stroke(linewidth=fontsize/6.,
foreground='black'),
path_effects.Normal()])

# Get text size to make sure it doesn't overlap.
txt_bbox = txt.get_window_extent(rendr)
txt2_bbox = txt2.get_window_extent(rendr)

# Then scale the figure to match.
old_size = fig.get_size_inches()
ratio = max((1 + margin) * ((txt_bbox.x1 - txt_bbox.x0) +
(txt2_bbox.x1 - txt2_bbox.x0)) / fig.dpi + 2,
old_size[0]) / old_size[0]
new_size = np.around(np.multiply(old_size, ratio))

# Size needs to be divisible by two for video.
new_size += np.mod(new_size, 2)
fig.set_size_inches(*new_size)

ax.set_xticks([])
ax.set_yticks([])
ax.axis('off')
Expand Down