Skip to content
Merged
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
34 changes: 33 additions & 1 deletion vcs/Canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -4585,12 +4585,44 @@ def setbgoutputdimensions(self, width=None, height=None, units='inches'):
# display ping

def put_png_on_canvas(
self, filename, zoom=1, xOffset=0, yOffset=0, *args, **kargs):
self, filename, zoom=1, xOffset=0, yOffset=0,
units="percent", fitToHeight=True, *args, **kargs):
"""
Display a PNG file on the canvas

:Example:

::

a=vcs.init()
# Put a png on Canvas
a.put_on_png_on_canvas("path.png",zoom=1, xOffset=0, yOffset=0, units="percent", fitToHeight=True)

:param file: Input image filename
:type file: str

:param zoom: scale factor
:type zoom: int

:param xOffset: Horizontal Offset
:type xOffset: float

:param yOffset: Vertical Offset
:type yOffset: float

:param units: Offsets units percent or pixels
:type units" str

:param fitToHeight: fits the picture (before scaling) to the canvas full height, if False then use png original size
:type fitToHeight: bool
"""
self.backend.put_png_on_canvas(
filename,
zoom,
xOffset,
yOffset,
units,
fitToHeight,
*args,
**kargs)

Expand Down
26 changes: 19 additions & 7 deletions vcs/VTKPlots.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,12 +980,14 @@ def trimData2D(self, data):
return self.cleanupData(data[op])

def put_png_on_canvas(
self, filename, zoom=1, xOffset=0, yOffset=0, *args, **kargs):
self, filename, zoom=1, xOffset=0, yOffset=0,
units="percent", fitToHeight=True, *args, **kargs):
return self.put_img_on_canvas(
filename, zoom, xOffset, yOffset, *args, **kargs)
filename, zoom, xOffset, yOffset, units, fitToHeight, *args, **kargs)

def put_img_on_canvas(
self, filename, zoom=1, xOffset=0, yOffset=0, *args, **kargs):
self, filename, zoom=1, xOffset=0, yOffset=0,
units="percent", fitToHeight=True, *args, **kargs):
self.hideGUI()
readerFactory = vtk.vtkImageReader2Factory()
reader = readerFactory.CreateImageReader2(filename)
Expand All @@ -1002,11 +1004,21 @@ def put_img_on_canvas(
cam.ParallelProjectionOn()
width = (ext[1] - ext[0]) * spc[0]
height = (ext[3] - ext[2]) * spc[1]
xoff = width * xOffset / zoom / 200.
yoff = height * yOffset / zoom / 200.
if units[:7].lower() == "percent":
xoff = width * xOffset / zoom / 200.
yoff = height * yOffset / zoom / 200.
elif units[:6].lower() == "pixels":
xoff = xOffset / zoom
yoff = yOffset / zoom
else:
raise RuntimeError("vtk put image does not understand %s for offset units" % units)
xc = origin[0] + .5 * (ext[0] + ext[1]) * spc[0]
yc = origin[1] + .5 * (ext[2] + ext[3]) * spc[1]
yd = (ext[3] - ext[2]) * spc[1]
if fitToHeight:
yd = (ext[3] - ext[2]) * spc[1]
else:
sz = self.renWin.GetSize()
yd = sz[1]
d = cam.GetDistance()
cam.SetParallelScale(.5 * yd / zoom)
cam.SetFocalPoint(xc + xoff, yc + yoff, 0.)
Expand Down Expand Up @@ -1165,7 +1177,7 @@ def png(self, file, width=None, height=None,

sz = self.renWin.GetSize()
if width is not None and height is not None:
if self.renWin.GetSize() != (width, height):
if sz != (width, height):
user_dims = (self.canvas.bgX, self.canvas.bgY, sz[0], sz[1])
# We need to set canvas.bgX and canvas.bgY before we do renWin.SetSize
# otherwise, canvas.bgX,canvas.bgY will win
Expand Down
210 changes: 188 additions & 22 deletions vcs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,181 @@
import cdms2
import genutil
import vtk
import struct


from colors import rgb2str, str2rgb, matplotlib2vcs # noqa

indent = 1
sort_keys = True
# Deprecated color map names mapping
vcs_deprecated_colormap_names = {
"blue2darkred": "bl_to_darkred",
"blue2darkorange": "bl_to_drkorang",
"blue2grey": "blue_to_grey",
"blue2green": "blue_to_grn",
"blue2orange": "blue_to_orange",
"blue2orange2red": "blue_to_orgred",
"brown2blue": "brown_to_blue",
"green2magenta": "grn_to_magenta",
"lightblue2darkblue": "ltbl_to_drkbl",
"rainbownogreen": "rainbow_no_grn",
"white2blue": "white_to_blue",
"white2green": "white_to_green",
"white2magenta": "white_to_magenta",
"white2red": "white_to_red",
"white2yellow": "white_to_yellow",
"blue2darkred": "bl_to_darkred",
"blue2darkorange": "bl_to_drkorang",
"blue2grey": "blue_to_grey",
"blue2green": "blue_to_grn",
"blue2orange": "blue_to_orange",
"blue2orange2red": "blue_to_orgred",
"brown2blue": "brown_to_blue",
"green2magenta": "grn_to_magenta",
"lightblue2darkblue": "ltbl_to_drkbl",
"rainbownogreen": "rainbow_no_grn",
"white2blue": "white_to_blue",
"white2green": "white_to_green",
"white2magenta": "white_to_magenta",
"white2red": "white_to_red",
"white2yellow": "white_to_yellow",
}

defaultColorsRange = range(256)


def get_png_dims(fnm):
"""given the path to a png, return width, height"""
try:
data = open(fnm, "rb").read()
w, h = struct.unpack('>LL', data[16:24])
width = int(w)
height = int(h)
except Exception:
width = None
height = None
return width, height


class Logo(object):
"""
Creates a 'logo' object

This also to draw a logo either from a text string or a picture (png) file.
Picture will be shrunk to fit within the canvas if it's too big to fit

:Example:

.. doctest:: utils_Logo

>>> import vcs
>>> import os
>>> import sys
>>> x=vcs.init()
>>> x.open()
>>> logo1 = vcs.utils.Logo(os.path.join(sys.prefix,"share","vcs","uvcdat.png"))
>>> logo1.x=.7
>>> logo1.y=.8

>>> logo2 = vcs.utils.Logo("My Test Logo")
>>> logo2.x = .2
>>> logo2.y = .2

>>> logo1.plot(x)
>>> logo2.plot(x)
"""
def __init__(self, source=None, x=.93, y=.95, width=None, height=None):
"""
Initialize a new "logo" object to be plotted later on a canvas

:param source: text string or path to png file representing the logo
:type source: str

:param x: x position of the logo's center in fraction of canvas (0<x<1)
:type x: float

:param y: y position of the logo's center in fraction of canvas (0<y<1)
:type y: float

:param width: width in pixels we want the log to be
:type width: int

:param height: height in pixels we want the log to be
:type height: int
"""
if source is None:
self.source = None
elif vcs.queries.istext(source):
self.source = source
elif isinstance(source, basestring):
self.source_width, self.source_height = get_png_dims(source)
if self.source_width is not None:
self.source = source
else:
self.source = vcs.createtext()
if height is None:
self.source.height = 20
else:
self.source.height = height
self.source.halign = 'center'
self.source.valign = 'half'
# Set the texttable
self.source.font = 2
self.source.color = [5, 10, 67, 100.0]
self.source.string = source
self.x = x
self.y = y
self.width = width
self.height = height

def plot(self, canvas, bg=True):
"""
Plot the log onto a given Canvas

:Example:

.. doctest:: utils_Logo_plot

>>> import vcs
>>> import os
>>> import sys
>>> x=vcs.init()
>>> x.open()
>>> logo1 = vcs.utils.Logo(os.path.join(sys.prefix,"share/vcs/uvcdat.png"))
>>> logo1.x=.7
>>> logo1.y=.8

>>> logo2 = vcs.utils.Logo("My Test Logo")
>>> logo2.x = .2
>>> logo2.y = .2

>>> logo1.plot(x)
>>> logo2.plot(x)


:param canvas: Canvas onto which you desire plotting the logo
:type canvas: vcs.Canvas.Canvas

:param bg: do we plot in background (offscreen) mode or not? True/False
:type bg: bool
"""
if isinstance(self.source, basestring):
cnv_info = canvas.canvasinfo()
if self.width is not None:
scale = float(self.width) / self.source_width
elif self.height is not None:
scale = float(self.height) / self.source_height
else:
xdist = cnv_info["width"] - self.x * cnv_info["width"]
xscale = xdist / self.source_width * 2.
ydist = cnv_info["height"] - self.y * cnv_info["height"]
yscale = ydist / self.source_height * 2.
scale = min(xscale, yscale)

xoff = - (cnv_info["width"] / 2. - self.source_width / 2. * xscale)
yoff = - (cnv_info["height"] / 2. -
self.source_height / 2. * yscale)
canvas.put_png_on_canvas(
self.source,
zoom=scale,
xOffset=xoff,
yOffset=yoff,
units="pixels",
fitToHeight=False)
elif vcs.queries.istext(self.source):
self.source.x = [self.x]
self.source.y = [self.y]
if self.height is not None:
self.source.height = self.height
canvas.plot(self.source, bg=bg)


def process_range_from_old_scr(code, g):
irg = code.find("range")
if irg > -1:
Expand Down Expand Up @@ -737,7 +885,8 @@ def loadTemplate(nm, vals):


def loadVCSItem(typ, nm, json_dict={}):
if typ in vcs._protected_elements.keys() and nm in vcs._protected_elements[typ]:
if typ in vcs._protected_elements.keys(
) and nm in vcs._protected_elements[typ]:
# protected element do not overload
return
tp = typ
Expand Down Expand Up @@ -779,7 +928,8 @@ def loadVCSItem(typ, nm, json_dict={}):
setattr(gm, a, v)

if nm in vcs_deprecated_colormap_names:
cmd = "gm = vcs.create%s('%s')" % (typ, vcs_deprecated_colormap_names[nm])
cmd = "gm = vcs.create%s('%s')" % (
typ, vcs_deprecated_colormap_names[nm])
exec(cmd)
setattr(gm, a, v)

Expand Down Expand Up @@ -1022,7 +1172,8 @@ def __split2contiguous(levels):
if il != 0:
lv2 = levels[il - 1]
if lv2[1] != lv[0]:
raise VCSUtilsError("Error intervals are NOT contiguous from " + str(lv2[1]) + " to " + str(lv[0]))
raise VCSUtilsError(
"Error intervals are NOT contiguous from " + str(lv2[1]) + " to " + str(lv[0]))
tmplevs.append(lv[0])
tmplevs.append(levels[-1][1])
return tmplevs
Expand Down Expand Up @@ -1100,7 +1251,14 @@ def mklabels(vals, output='dict'):
aa = numpy.ma.power(10., -idigleft)
while abs(round(aa * vals[i]) - aa * vals[i]) > .000001:
aa = aa * 10.
idig = numpy.ma.maximum(idig, numpy.ma.floor(numpy.ma.log10(aa * numpy.ma.power(10., idigleft))))
idig = numpy.ma.maximum(
idig,
numpy.ma.floor(
numpy.ma.log10(
aa *
numpy.ma.power(
10.,
idigleft))))
idig = int(idig)

# Now does the writing part
Expand Down Expand Up @@ -1851,7 +2009,7 @@ def creategraphicsmethod(gtype, gname='default', name=None):
# datawc_ can be a float or a cdtime.reltime
# TODO: Investigate why datawc is converted to a cdtime.reltime
def getDataWcValue(v):
if (type(v) is type(cdtime.reltime(0, 'months since 1900'))): # noqa
if (isinstance(v, type(cdtime.reltime(0, 'months since 1900')))): # noqa
return v.value
else:
return v
Expand Down Expand Up @@ -2026,7 +2184,12 @@ def download_sample_data_files(path=None):
import hashlib
if path is None:
path = vcs.sample_data
samples = open(os.path.join(vcs.prefix, "share", "vcs", "sample_files.txt")).readlines()
samples = open(
os.path.join(
vcs.prefix,
"share",
"vcs",
"sample_files.txt")).readlines()
for sample in samples:
good_md5, name = sample.split()
local_filename = os.path.join(path, name)
Expand All @@ -2044,7 +2207,10 @@ def download_sample_data_files(path=None):
attempts = 5
continue
print "Downloading:", name, "in", local_filename
r = requests.get("http://uvcdat.llnl.gov/cdat/sample_data/" + name, stream=True)
r = requests.get(
"http://uvcdat.llnl.gov/cdat/sample_data/" +
name,
stream=True)
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk: # filter local_filename keep-alive new chunks
Expand Down
1 change: 1 addition & 0 deletions vcs/vcs2vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ def setInfToValid(geoPoints, ghost):
ghost.SetValue(i, vtk.vtkDataSetAttributes.HIDDENPOINT)
return anyInfinity


def removeHiddenPoints(grid):
ghost = grid.GetPointGhostArray()
if (not ghost):
Expand Down