holoviz-topics / earthsim Goto Github PK
View Code? Open in Web Editor NEWTools for working with and visualizing environmental simulations.
Home Page: https://earthsim.holoviz.org
License: BSD 3-Clause "New" or "Revised" License
Tools for working with and visualizing environmental simulations.
Home Page: https://earthsim.holoviz.org
License: BSD 3-Clause "New" or "Revised" License
Parameterize Jupyter-notebook workflows, to allow parameter sweeps to be automated and allow Jupyter notebooks to be used as components in larger workflows.
This problem is somewhat related to erdc/quest#37
OSError Traceback (most recent call last)
<ipython-input-3-0248b6b2bc3e> in <module>()
1 intensities = [128, 256, 512]
----> 2 simulations = {intensity: get_simulation(rain_intensity=intensity) for intensity in intensities}
<ipython-input-3-0248b6b2bc3e> in <dictcomp>(.0)
1 intensities = [128, 256, 512]
----> 2 simulations = {intensity: get_simulation(rain_intensity=intensity) for intensity in intensities}
<ipython-input-2-d6c12e1e309c> in get_simulation(**params)
14 sim.model_creator.elevation_grid_path = get_file_from_quest(data_dir, sim.elevation_service, 'elevation', sim.model_creator.mask_shapefile)
15
---> 16 model = sim.model_creator()
17 model.project_manager.setCard('FLOOD_GRID',
18 '{0}.fgd'.format(sim.model_creator.project_name),
/mnt/c/Users/erin/code/build-dir/EarthSim/earthsim/gssha/model.py in __call__(self, **params)
145 def __call__(self,**params):
146 p = param.ParamOverrides(self,params)
--> 147 return GSSHAModel(**self._map_kw(p))
148
149
/mnt/c/Users/erin/code/build-dir/EarthSim/earthsim/gssha/model.py in _map_kw(self, p)
134
135 def _map_kw(self,p):
--> 136 kw = super(CreateGSSHAModel,self)._map_kw(p)
137 kw['mask_shapefile'] = p.mask_shapefile
138 kw['grid_cell_size'] = p.grid_cell_size
/mnt/c/Users/erin/code/build-dir/EarthSim/earthsim/gssha/model.py in _map_kw(self, p)
96 kw['project_directory'] = os.path.abspath(os.path.join(p.project_base_directory, p.project_name))
97 # Currently allows overwriting existing files
---> 98 os.makedirs(kw['project_directory'],exist_ok=True)
99 kw['project_name'] = p.project_name
100 return kw
~/miniconda/envs/earthsim/lib/python3.5/os.py in makedirs(name, mode, exist_ok)
239 return
240 try:
--> 241 mkdir(name, mode)
242 except OSError:
243 # Cannot rely on checking for EEXIST, since the operating system
OSError: [Errno 22] Invalid argument: '/mnt/c/Users/erin/code/build-dir/EarthSim/examples/topics/vicksburg_parameterized_rain_intensity:128'
Completely deleting a path or polygon will leave an empty list in the Latitude/Longitude data list from the stream. The empty list will persist even when more polygons are added (i.e. the next new polygon doesn't fill the empty list).
This isn't detrimental, just slightly annoying. Perhaps it shouldn't be happening in the first place?
The env cannot be set up on Windows as-is since the gssha package is only available for Linux and OSX (https://anaconda.org/gbrener/gssha).
There are other gssha-related Windows issues as well. Namely the fact that earthsim is on py3.5, requires gsshapy, and gsshapy requires pangaea which is not available for Windows py3.5. (https://github.com/ContinuumIO/EarthSim/issues/124)
I'd like to add elements (we'll just say points for now, but in the future, this will include polys/paths) to the visualized map via input to the dynamic table. What would be the process for accomplishing that?
My initial thinking is that I'll need a button to "add row". But how that button should link into the table stream is not clear. The table stream self.poly_table = DynamicMap(self.load_table, streams=streams)
is linked to the load_table callback. If I force an entry, won't that break the dynamic mapping?
Its almost like the current setup is that the dynamic table linkage is a one way street, always listening for more information from the the map. But I need this to be a two-way street. I need the table to listen for information from the map and I need the map to listen for information from the table. Does that make sense? Is that possible?
Provide a Django interface for Param for use in Tethys.
It's possible we aren't seeing messages for debugging this, but at least at the moment if we specify a mesh control point with an associated size that exceeds the boundary of the visible area, it's simply ignored. E.g. these two points have the same size, but only the one with room around it is having any effect:
Seems to me that people will very often wish to put large sizes near the borders of a polygon, as that's the area of the simulation least core to what's being simulated, so it strikes me as likely to be a problem in practice. In any case, there should be warnings whenever a user input is being ignored.
As far as I can tell latest versions of quest are broken, when I try to request a feature from a USGS NLCD source it tries to make a request and then executes the following code from quest/services/usgs_nlcd.py, which results in a pandas KeyError:
r = requests.get(base_url, params=params)
features = pd.DataFrame(r.json()['items'])
features = features.loc[~features.title.str.contains('Imperv')]
features = features.loc[~features.title.str.contains('by State')]
features = features.loc[~features.title.str.contains('Tree Canopy')]
features['geometry'] = features['spatial'].apply(_bbox2poly)
features['download_url'] = features.webLinks.apply(_parse_links)
#features['extract_from_zip'] = '.tif'
features['filename'] = features['download_url'].str.split('FNAME=', expand=True)[1]
E KeyError: 1
I'm trying to read in a hotstart file (.hot) (formatted exactly the same as a result file (.dat)). I'm working off the same concepts in Visualizing_Meshes.ipynb. I can get it load in and plot. The TriMesh color contours appear to be linked to the ioh values like I want, but I can't get it redim.range
and colorbar=True
to have any effect. Here is the basic workflow:
Read an AdH 3dm mesh and reproject the points
tris, verts = read_3dm_mesh(fpath,skiprows=2)
points = gv.operation.project_points(gv.Points(verts, vdims=['z'], crs=coord_sys))
Add the hotstart data to the points (ioh) and plot
%%opts TriMesh (cmap='RdYlBu') [color_index='ioh', colorbar=True]
fpath = os.path.join(path, filename + '.hot')
hotstart = read_mesh2d(fpath)
depth_points = points.add_dimension('ioh', 0, hotstart[0].values[:, 0], vdim=True)
hot_trimesh = gv.TriMesh((tris, depth_points))
viz.tiles * datashade(hot_trimesh, aggregator=ds.mean('ioh')).redim.range(ioh=(0, 6))
It looks like aggregator=ds.mean('ioh')
is working correctly, but .redim.range(ioh=(0,6)
has no effect. I also have no colorbar.
Also, there are no errors, but I am getting this warning:
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\IPython\core\interactiveshell.py:2903: DtypeWarning: Columns (0) have mixed types. Specify dtype option on import or set low_memory=False. if self.run_code(code, result):
In order to create boundary conditions, I need access to the edges (or node numbers that make up the edges) of certain segments of a given mesh. This can be achieved either by:
I'm using #46
From the annotators:
self.polys = self.path_type(polys, crs=crs)
self.poly_stream = PolyDraw(source=self.polys, data={})
I have a drawing where I bring in projected data via the annotators to be drawn with the initial load. My poly data is drawn in the proper geographic location. It is stored using xs
and ys
as keys in poly_stream
:
Now if I draw another poly on the map and reprint the poly_stream, you can see that it changed my dictionary keys to Latitude
and Longitude
.
The first click of the reset button in the notebook drawing tools causes the original zoom level to be restored. Clicking the reset button when the drawing is at the original extents results in the image to be distorted (or is it a projection reversion?) and does not clear user inputs (but is it supposed to?).
"Reset" is a vague term. There are actually several tasks that I see fitting into that category:
Clear - remove all drawings from the image but keep zoom level (tiles only)
Zoom extents - zoom to the extents of the drawing/original extents
Reset - return it to the original state in which it was drawn including zoom level, remove user drawn items (tiles and original data)
When I use the %%opts
for Path, it throws a warning when I initialize my PolyAndPointAnnotator with an existing polygon and does not appear to be effective (it is not colored red). The warning is WARNING: Unknown elements Paths not registered with any of the loaded backends.
%%opts Paths (color='red' alpha=0.5 selection_alpha=0.9 nonselection_alpha=0.6)
viz = PolyAndPointAnnotator(path_type=gv.Path, polys=[boundary_poly],
crs=coord_sys,extent=(np.NaN,)*4, tile_url='http://tile.stamen.com/terrain/{Z}/{X}/{Y}.jpg')
(viz.tiles * viz.polys * viz.poly_view.options(apply_ranges=False) * viz.points +
viz.poly_table + viz.point_table).options(shared_datasource=True).cols(1)
The EarthSim project is explicitly designed to be a sandbox where we work out initial solutions to problems in earth-related simulation, first in a very specific form in example notebooks (in examples/topics
), then with somewhat generalized code pulled out into a python module (in earthsim
) and documented in the user guide. Wherever possible, code should then eventually migrate out of earthsim
and into a more general purpose library, as long as the code can be expressed in a way that is no longer specific to the particular earth-simulation use case where it originated.
The GeoAnnotators
classes in earthsim/annotators.py
are currently in the middle of such a trajectory, as they can be used as-is for a variety of different purposes but are fundamentally limited in that they require a map to be present and that each such class has a certain fixed number of drawing tools and associated streams, each with hard-coded configuration parameters tied to them at the annotator class level.
From a brief survey of the code involved, it looks to me like it might be possible to generalize this approach so that it supports any number of associated tools with matching data streams, provided as a list, rather than having a fixed supported set of such tools. Each tool/stream would be configured individually, not at the Annotator class level, and the Annotator would iterate through them, link them up as appropriate, and so on. I have not tested this approach, and there are likely to be some tricky issues involved, but it seems like something along these lines could eventually move into HoloViews (if not geo-specific) or at least GeoViews (if the coordinate-system support needs to be handled within these classes) (or maybe one in each project).
Making such a change would not only minimize the code needed to be maintained in EarthSim, but would also likely reduce the amount of user code needed in their own applications, because right now users are likely to have to copy the Annotator classes and edit them for their own use, and a general approach might avoid the need for such minor variations.
We currently have the capability to read an existing *.3dm mesh, create a new mesh using filigree and allow filigree to create a hard copy of the mesh, but we do not have the capability to write out a mesh via verts and tris variables.
I'm not sure whether this would go in earthsim/filigree.py
or filigree
cli itself. I expect this is would be an ERDC task. Can @kajiglet or @dharhas give some direction?
@ceball This repo doesn't have a wiki and it doesn't appear that I can create one with my permissions level. Can we get one on the new repo when we migrate?
Question: what is the main difference between the dynamic tables with the annotators and Holoviews dynamic tables? Is it that the source data for the annotator tables use the streams from the drawing tools?
Extend the Param library to allow relationship dependencies to be declared between Parameters of objects in the same class, making it simpler to write fully featured front-end dashboards without complex glue logic.
In the Annotators.ipynb on the PointAndPolyAnnotator drawing, if you create a point on the map and then go to the dynamic table below and edit the location of that point, the point disappears from the map (at least I can't find it - even after moving it 1 meter) but remains in the table. This looks like a bug.
In addition to allowing dynamic updates by editing table values, it could be very useful to be able to toggle what is shown in the visualization via the table(s).
Should I be using parambokeh or paramnb to display widgets? What's the difference?
Is it possible to annotate a Path stream?
I'm looking at the GeoAnnotator class and it seems like in order to visualize anything along with the annotators, they need to passed in to the annotator class and the annotator class will construct it. That said, there is no mechanism there to add a path to my drawing (only points and polys). Is there some other workaround for this?
I need to draw a multi-point line, is that possible with the drawing tools or do I need to adapt PointDraw
and/or PolyDraw
?
I could use some help understanding the parambokeh.Widgets()
call. I thought that it would automatically render as a widget any param variables in the class. However, the following snippet:
bounds = hv.Bounds(gv.util.project_extents((-91, 32.2, -90.8, 32.4), ccrs.PlateCarree(), ccrs.GOOGLE_MERCATOR))
annot = PointAnnotator(polys=[bounds])
dashboard = FiligreeMeshDashboard(draw_helper=annot)
parambokeh.Widgets(dashboard)
and...
class FiligreeMeshDashboard(FiligreeMesh):
crs = param.ClassSelector(class_=ccrs.Projection, precedence=-1)
draw_helper = param.ClassSelector(class_=GeoAnnotator, precedence=-1)
update_mesh = param.Action(default=lambda self: self.event(), precedence=1,
doc="""Button triggering mesh generation.""")
Results it only one widget, a button for update_mesh
. There are two other variables , crs
and draw_helper
which are not rendered as widgets, however, they ARE param variables. Both the param.ClassSelector
and param.Action
inherit from param.parameterized.Parameterized()
so the difference must be somewhere in the middle.
How does parambokeh choose which param variables to render as widgets?
Hover information is more useful if expressed in lat/lon as are entries presentable/editable via tables.
Closed path can have a meaningful polarity depending on whether they are defined clockwise or anti-clockwise. A similar notion can apply to open paths depending on the direction they are drawn.
This information can be important and it would be useful to have an indicator (typically an arrow) to indicate the 'direction' of the path. Such a visual indicator is something you would probably want to toggle as necessary.
The wheel zoom functionality can be used to zoom a single axis. When one is displaying map data or projected data, its never appropriate to zoom a single axis. All zooming should be forced to the scaled zoom.
Instead of installing via pip.
holoviews 1.9.4 is available on ioam now (and I guess will be on conda-forge soon). We're working on a geoviews package.
There are a few expansions to the Path tool that would be useful for me. I'm not sure how doable these are, but this can just be a starting point for discussion.
In a recent meeting it was suggested that multiple tables might be used to define paths and polygons: one table to define attributes at the path level and then another table (or multiple tables?) that allow the definition of attributes of the vertices along the path(s).
Installing erdc's stevedore appears to clobber six with its own bundled version. The version of six included by stevedore is not up to date enough for e.g. matplotlib, so we get problems like this:
$ wget https://anaconda.org/erdc/stevedore/1.6.0/download/noarch/stevedore-1.6.0-py_0.tar.bz2
$ tar -tf stevedore-1.6.0-py_0.tar.bz2
Scripts/.stevedore-pre-link.bat
bin/.stevedore-pre-link.sh
info/files
info/index.json
info/recipe.json
info/recipe/bld.bat
info/recipe/build.sh
info/recipe/meta.yaml
link.py
site-packages/argparse-1.3.0.dist-info/DESCRIPTION.rst
site-packages/argparse-1.3.0.dist-info/METADATA
site-packages/argparse-1.3.0.dist-info/RECORD
site-packages/argparse-1.3.0.dist-info/WHEEL
site-packages/argparse-1.3.0.dist-info/metadata.json
site-packages/argparse-1.3.0.dist-info/top_level.txt
site-packages/argparse.py
site-packages/six-1.9.0.dist-info/DESCRIPTION.rst
site-packages/six-1.9.0.dist-info/METADATA
site-packages/six-1.9.0.dist-info/RECORD
site-packages/six-1.9.0.dist-info/WHEEL
site-packages/six-1.9.0.dist-info/metadata.json
site-packages/six-1.9.0.dist-info/top_level.txt
site-packages/six.py
site-packages/stevedore-1.6.0-py2.7.egg-info/PKG-INFO
site-packages/stevedore-1.6.0-py2.7.egg-info/SOURCES.txt
site-packages/stevedore-1.6.0-py2.7.egg-info/dependency_links.txt
site-packages/stevedore-1.6.0-py2.7.egg-info/entry_points.txt
site-packages/stevedore-1.6.0-py2.7.egg-info/not-zip-safe
site-packages/stevedore-1.6.0-py2.7.egg-info/pbr.json
site-packages/stevedore-1.6.0-py2.7.egg-info/requires.txt
site-packages/stevedore-1.6.0-py2.7.egg-info/top_level.txt
site-packages/stevedore/__init__.py
site-packages/stevedore/dispatch.py
site-packages/stevedore/driver.py
site-packages/stevedore/enabled.py
site-packages/stevedore/example/__init__.py
site-packages/stevedore/example/base.py
site-packages/stevedore/example/fields.py
site-packages/stevedore/example/load_as_driver.py
site-packages/stevedore/example/load_as_extension.py
site-packages/stevedore/example/setup.py
site-packages/stevedore/example/simple.py
site-packages/stevedore/extension.py
site-packages/stevedore/hook.py
site-packages/stevedore/named.py
site-packages/stevedore/sphinxext.py
site-packages/stevedore/tests/__init__.py
site-packages/stevedore/tests/extension_unimportable.py
site-packages/stevedore/tests/manager.py
site-packages/stevedore/tests/test_callback.py
site-packages/stevedore/tests/test_dispatch.py
site-packages/stevedore/tests/test_driver.py
site-packages/stevedore/tests/test_enabled.py
site-packages/stevedore/tests/test_example_fields.py
site-packages/stevedore/tests/test_example_simple.py
site-packages/stevedore/tests/test_extension.py
site-packages/stevedore/tests/test_hook.py
site-packages/stevedore/tests/test_named.py
site-packages/stevedore/tests/test_sphinxext.py
site-packages/stevedore/tests/test_test_manager.py
site-packages/stevedore/tests/utils.py
When I feed polygons and points into an annotator to be included in the initial draw, I almost never format the data correctly. For example, polygons are something like a list of a list of tuples or a list of a list of lists. Anyway, its fine to require the data in a certain format, but the error message I get when I have incorrect formatting is not helpful for me. Its so deep inside holoviews I think it has something to do with the way I'm asking it to draw. It throws me off every time (and I've done this A LOT). I would humbly suggest some better feedback for improper formatting if its something that wouldn't be too challenging.
---------------------------------------------------------------------------
DataError Traceback (most recent call last)
<ipython-input-26-865f1abbfbbc> in <module>()
6 ann = PolyAndPointAnnotator(tile_url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}',
7 extent=(125, 39.0, 127, 39.82),
----> 8 crs=coord_sys, polys=[poly], points=[point])
9 ann.tiles * ann.polys * ann.poly_view * ann.points
c:\projects\ers\github\earthsim_pyviz\newmaster\earthsim\earthsim\annotators.py in __init__(self, poly_data, **params)
137
138 def __init__(self, poly_data={}, **params):
--> 139 super(PolyAnnotator, self).__init__(**params)
140 self.poly_table_stream = CDSStream(data=poly_data, rename={'data': 'table_data'})
141 self.poly_sel_stream = Selection1D(source=self.polys)
c:\projects\ers\github\earthsim_pyviz\newmaster\earthsim\earthsim\annotators.py in __init__(self, **params)
206
207 def __init__(self, **params):
--> 208 super(PointAnnotator, self).__init__(**params)
209 style = dict(editable=True)
210 plot = dict(width=self.width, height=self.table_height)
c:\projects\ers\github\earthsim_pyviz\newmaster\earthsim\earthsim\annotators.py in __init__(self, polys, points, crs, **params)
48 self.poly_stream = PolyDraw(source=self.polys, data={})
49 self.vertex_stream = PolyEdit(source=self.polys)
---> 50 self.points = Points(points, self.polys.kdims, crs=crs)
51 self.point_stream = PointDraw(source=self.points, data={})
52
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\geoviews-1.5.0a1.post8+g581151f.dirty-py3.5.egg\geoviews\element\geo.py in __init__(self, data, kdims, vdims, **kwargs)
93 elif crs:
94 kwargs['crs'] = crs
---> 95 super(_Element, self).__init__(data, kdims=kdims, vdims=vdims, **kwargs)
96
97
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\data\__init__.py in __init__(self, data, kdims, vdims, **kwargs)
195 validate_vdims = kwargs.pop('_validate_vdims', True)
196 initialized = Interface.initialize(type(self), data, kdims, vdims,
--> 197 datatype=kwargs.get('datatype'))
198 (data, self.interface, dims, extra_kws) = initialized
199 super(Dataset, self).__init__(data, **dict(kwargs, **dict(dims, **extra_kws)))
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\data\interface.py in initialize(cls, eltype, data, kdims, vdims, datatype)
209 % (intfc.__name__, e))
210 error = ' '.join([error, priority_error])
--> 211 raise DataError(error)
212
213 return data, interface, dims, extra_kws
DataError: None of the available storage backends were able to support the supplied data format.
In Cell 4 of the "Specifying_Meshes.ipynb", the "update_mesh" button is successfully creating new meshes for all polygons. However, it does not clear out the existing meshes. I suspect there is something wrong with the reset_mesh
method or maybe the stream also needs to be cleared?
Support for automatic conversion of a Jupyter notebook to a shareable dashboard, with a fixed report-style layout
I see that datashade(tri_mesh.edgepaths)
colors the boundary edges a different color. Where is it getting boundary detection from?
I can create a couple simple param widgets:
class reservoirLevel(param.Parameterized):
select_type = param.ObjectSelector(default="Depth",objects=["Water level","Depth"], precedence=1)
value = param.Number(5.8, precedence=2)
hotstart_exists = param.Boolean(False, doc="Use existing hotstart file", precedence=3)
parambokeh.Widgets(reservoirLevel)
But if I try to add these to a drawing with the overlay feature +
, I'm getting the following error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-cff6a06211a4> in <module>()
13 # visualize
14 (viz.tiles * datashade(trimesh2.edgepaths) * viz.polys * viz.poly_view.options(apply_ranges=False) * viz.points +
---> 15 viz.poly_table + viz.point_table + parambokeh.Widgets(reservoirLevel)).options(shared_datasource=True).cols(1)
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\layout.py in __add__(self, other)
548
549 def __add__(self, other):
--> 550 return Layout.from_values([self, other])
551
552
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\layout.py in from_values(cls, vals)
388 elements or just a single viewable element.
389 """
--> 390 return cls(items=cls._process_items(vals))
391
392
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\layout.py in _process_items(cls, vals)
404 items = []
405 counts = defaultdict(lambda: 1)
--> 406 cls._unpack_paths(vals, items, counts)
407 items = cls._deduplicate_items(items)
408 return items
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\layout.py in _unpack_paths(cls, objs, items, counts)
445 continue
446 new = path is None or len(path) == 1
--> 447 path = get_path(item) if new else path
448 new_path = make_path_unique(path, counts, new)
449 items.append((new_path, obj))
C:\ProgramData\Anaconda3\envs\ers\lib\site-packages\holoviews\core\util.py in get_path(item)
1383 path = path[:1]
1384 else:
-> 1385 path = (item.group, item.label) if item.label else (item.group,)
1386 return tuple(capitalize(fn(p)) for (p, fn) in zip(path, sanitizers))
1387
AttributeError: 'NoneType' object has no attribute 'label'
The error appears after the widget displays, but none of the other plotting displayed. Is it not possible/recommended to add widgets this way?
From this example notebook: https://github.com/pyviz/EarthSim/blob/master/examples/user_guide/Visualizing_Meshes.ipynb
I have the following snippets:
import datashader as ds
from holoviews.operation.datashader import datashade, rasterize
datashade(trimesh, aggregator=ds.mean('z'))
I'm trying to understand the difference between datashade
and datashader
. Why are they in two totally different repositories, but required for the generation of a single datashaded drawing?
The slider controls for animations/time varying mapping are not working correctly. Specifically, once you start playing an animation, the slider quickly spins through several loops while the image slowly changes from one to another. There seems to be a significant delay in the movement of the slider and the changing of the image. If I tell it to loop, let the slider move through two loops, then click stop, it will slowly play through all the images in the two loops instead of stopping immediately. Does that make sense? It basically has the feel of being unresponsive to my stop click.
Is this related to the dataset size or is there a time delay mismatch between the animation and the slider?
I'm trying to use a "simple" dynamic map function to regenerate a filigree mesh based on the size input by the slider widget. However, sliding either ends up hanging the notebook (it's still "thinking") or if it finishes, it doesn't actually update the map (size is always 30)
Am I doing something wrong with my specification of the dynamic map function?
# create mesh equivalent to case100.txt/.2dm
poly_exterior = [
[-150.0, -140.0],
[-150.0, -130.0],
[-150.0, -120.0],
[-150.0, -110.0],
[-150.0, -100.0],
[-150.0, -90.0],
[-150.0, -80.0],
[-150.0, -70.0],
[-150.0, -60.0],
[-150.0, -50.0],
[-150.0, -40.0],
[-150.0, -30.0],
[-150.0, -20.0],
[-150.0, -10.0],
[-150.0, 0.0],
[-150.0, 10.0],
[-150.0, 20.0],
[-150.0, 30.0],
[-150.0, 40.0],
[-150.0, 50.0],
[-150.0, 60.0],
[-150.0, 70.0],
[-150.0, 80.0],
[-150.0, 90.0],
[-150.0, 100.0],
[-150.0, 110.0],
[-150.0, 120.0],
[-150.0, 130.0],
[-150.0, 140.0],
[-150.0, 150.0],
[-150.0, 160.0],
[-150.0, 170.0],
[-150.0, 180.0],
[-150.0, 190.0],
[-150.0, 200.0],
[-150.0, 210.0],
[-150.0, 220.0],
[-150.0, 230.0],
[-150.0, 240.0],
[-150.0, 250.0],
[-150.0, 260.0],
[-150.0, 270.0],
[-150.0, 280.0],
[-150.0, 290.0],
[-150.0, 300.0],
[-150.0, 310.0],
[-150.0, 320.0],
[-150.0, 330.0],
[-150.0, 340.0],
[-150.0, 350.0],
[-140.0, 350.0],
[-130.0, 350.0],
[-120.0, 350.0],
[-110.0, 350.0],
[-100.0, 350.0],
[-90.0, 350.0],
[-80.0, 350.0],
[-70.0, 350.0],
[-60.0, 350.0],
[-50.0, 350.0],
[-40.0, 350.0],
[-30.0, 350.0],
[-20.0, 350.0],
[-10.0, 350.0],
[0.0, 350.0],
[10.0, 350.0],
[20.0, 350.0],
[30.0, 350.0],
[40.0, 350.0],
[50.0, 350.0],
[60.0, 350.0],
[70.0, 350.0],
[80.0, 350.0],
[90.0, 350.0],
[100.0, 350.0],
[110.0, 350.0],
[120.0, 350.0],
[130.0, 350.0],
[140.0, 350.0],
[150.0, 350.0],
[160.0, 350.0],
[170.0, 350.0],
[180.0, 350.0],
[190.0, 350.0],
[200.0, 350.0],
[210.0, 350.0],
[220.0, 350.0],
[230.0, 350.0],
[240.0, 350.0],
[250.0, 350.0],
[260.0, 350.0],
[270.0, 350.0],
[280.0, 350.0],
[290.0, 350.0],
[300.0, 350.0],
[310.0, 350.0],
[320.0, 350.0],
[330.0, 350.0],
[340.0, 350.0],
[350.0, 350.0],
[350.0, 340.0],
[350.0, 330.0],
[350.0, 320.0],
[350.0, 310.0],
[350.0, 300.0],
[350.0, 290.0],
[350.0, 280.0],
[350.0, 270.0],
[350.0, 260.0],
[350.0, 250.0],
[350.0, 240.0],
[350.0, 230.0],
[350.0, 220.0],
[350.0, 210.0],
[350.0, 200.0],
[350.0, 190.0],
[350.0, 180.0],
[350.0, 170.0],
[350.0, 160.0],
[350.0, 150.0],
[350.0, 140.0],
[350.0, 130.0],
[350.0, 120.0],
[350.0, 110.0],
[350.0, 100.0],
[350.0, 90.0],
[350.0, 80.0],
[350.0, 70.0],
[350.0, 60.0],
[350.0, 50.0],
[350.0, 40.0],
[350.0, 30.0],
[350.0, 20.0],
[350.0, 10.0],
[350.0, 0.0],
[350.0, -10.0],
[350.0, -20.0],
[350.0, -30.0],
[350.0, -40.0],
[350.0, -50.0],
[350.0, -60.0],
[350.0, -70.0],
[350.0, -80.0],
[350.0, -90.0],
[350.0, -100.0],
[350.0, -110.0],
[350.0, -120.0],
[350.0, -130.0],
[350.0, -140.0],
[350.0, -150.0],
[340.0, -150.0],
[330.0, -150.0],
[320.0, -150.0],
[310.0, -150.0],
[300.0, -150.0],
[290.0, -150.0],
[280.0, -150.0],
[270.0, -150.0],
[260.0, -150.0],
[250.0, -150.0],
[240.0, -150.0],
[230.0, -150.0],
[220.0, -150.0],
[210.0, -150.0],
[200.0, -150.0],
[190.0, -150.0],
[180.0, -150.0],
[170.0, -150.0],
[160.0, -150.0],
[150.0, -150.0],
[140.0, -150.0],
[130.0, -150.0],
[120.0, -150.0],
[110.0, -150.0],
[100.0, -150.0],
[90.0, -150.0],
[80.0, -150.0],
[70.0, -150.0],
[60.0, -150.0],
[50.0, -150.0],
[40.0, -150.0],
[30.0, -150.0],
[20.0, -150.0],
[10.0, -150.0],
[0.0, -150.0],
[-10.0, -150.0],
[-20.0, -150.0],
[-30.0, -150.0],
[-40.0, -150.0],
[-50.0, -150.0],
[-60.0, -150.0],
[-70.0, -150.0],
[-80.0, -150.0],
[-90.0, -150.0],
[-100.0, -150.0],
[-110.0, -150.0],
[-120.0, -150.0],
[-130.0, -150.0],
[-140.0, -150.0],
[-150.0, -150.0]
]
poly_holes = [
[[0.0, 0.0],
[10.0, 0.0],
[20.0, 0.0],
[30.0, 0.0],
[40.0, 0.0],
[50.0, 0.0],
[60.0, 0.0],
[70.0, 0.0],
[80.0, 0.0],
[90.0, 0.0],
[90.0, 10.0],
[90.0, 20.0],
[90.0, 30.0],
[90.0, 40.0],
[80.0, 40.0],
[70.0, 40.0],
[60.0, 40.0],
[50.0, 40.0],
[50.0, 50.0],
[50.0, 60.0],
[50.0, 70.0],
[50.0, 80.0],
[50.0, 90.0],
[50.0, 100.0],
[50.0, 110.0],
[50.0, 120.0],
[50.0, 130.0],
[50.0, 140.0],
[50.0, 150.0],
[60.0, 150.0],
[70.0, 150.0],
[80.0, 150.0],
[90.0, 150.0],
[100.0, 150.0],
[110.0, 150.0],
[120.0, 150.0],
[130.0, 150.0],
[140.0, 150.0],
[150.0, 150.0],
[150.0, 140.0],
[150.0, 130.0],
[150.0, 120.0],
[150.0, 110.0],
[150.0, 100.0],
[150.0, 90.0],
[150.0, 80.0],
[150.0, 70.0],
[150.0, 60.0],
[150.0, 50.0],
[150.0, 40.0],
[140.0, 40.0],
[130.0, 40.0],
[120.0, 40.0],
[110.0, 40.0],
[110.0, 30.0],
[110.0, 20.0],
[110.0, 10.0],
[110.0, 0.0],
[120.0, 0.0],
[130.0, 0.0],
[140.0, 0.0],
[150.0, 0.0],
[160.0, 0.0],
[170.0, 0.0],
[180.0, 0.0],
[190.0, 0.0],
[200.0, 0.0],
[200.0, 10.0],
[200.0, 20.0],
[200.0, 30.0],
[200.0, 40.0],
[200.0, 50.0],
[200.0, 60.0],
[200.0, 70.0],
[200.0, 80.0],
[200.0, 90.0],
[200.0, 100.0],
[200.0, 110.0],
[200.0, 120.0],
[200.0, 130.0],
[200.0, 140.0],
[200.0, 150.0],
[200.0, 160.0],
[200.0, 170.0],
[200.0, 180.0],
[200.0, 190.0],
[200.0, 200.0],
[190.0, 200.0],
[180.0, 200.0],
[170.0, 200.0],
[160.0, 200.0],
[150.0, 200.0],
[140.0, 200.0],
[130.0, 200.0],
[120.0, 200.0],
[110.0, 200.0],
[100.0, 200.0],
[90.0, 200.0],
[80.0, 200.0],
[70.0, 200.0],
[60.0, 200.0],
[50.0, 200.0],
[40.0, 200.0],
[30.0, 200.0],
[20.0, 200.0],
[10.0, 200.0],
[0.0, 200.0],
[0.0, 190.0],
[0.0, 180.0],
[0.0, 170.0],
[0.0, 160.0],
[0.0, 150.0],
[0.0, 140.0],
[0.0, 130.0],
[0.0, 120.0],
[0.0, 110.0],
[0.0, 100.0],
[0.0, 90.0],
[0.0, 80.0],
[0.0, 70.0],
[0.0, 60.0],
[0.0, 50.0],
[0.0, 40.0],
[0.0, 30.0],
[0.0, 20.0],
[0.0, 10.0]]
]
p = Polygon(poly_exterior, poly_holes)
# x, y, size
coords = [
[-200.0, 400.0, 20.0],
[400.0, 400.0, 20.0],
[-200.0, -200.0, 20.0],
[400.0, -200.0, 10.0],
[100.0, 100.0, 20.0],
[-75.0, -75.0, 10.0],
[275.0, -75.0, 10.0],
]
def update_mesh(size):
mesh = filigree.FiligreeMesh()
sz = mesh.create_size_function(coords, 'linear')
mesh.add_polygon(p, size_function=sz)
mesh.add_refine_point(-75.0, 275.0, size, 1)
mesh.add_refine_point(275.0, 275.0, size, 0)
verts, tris = mesh.create_mesh()
points = hv.Points(verts, vdims=['z'])
return hv.TriMesh((tris, points))
dmap = hv.DynamicMap(update_mesh, kdims=['size'])
dmap.redim.range(size=(30,40))
Support for manual conversion of a Jupyter notebook to a shareable dashboard
In cell 9, in the time_field def, the line
angle = np.arctan(vy/vx)
should be changed to
angle = np.arctan2(vy, vx)
Since we need to visualize vectors on all four quadrants. Otherwise, the visualization of the results is incorrect since its limited to [-90 90]
Is it possible to reproject the points such that the dynamic table of annotations "automatically" does the conversion between PlateCaree and Mercator? Basically, I want the displayed table to be in geographic lat/long. If conversion on the fly is possible, where would that sit?
I'm working with the PointAnnotator right now, but it seems like I'd have to have an additional layer in which to put the conversion. I was thinking maybe something like inside of PolyAnnotator.load_table? I'll be honest... the poly annotator is completely confusing to me so I'm hesitant to head that direction without confirmation that 1) it can be done, 2) its a good idea, and 3) that's where it should sit
Hey all,
Cool project -- I only just noticed it.
One thing you may want to do is consider making use of the gridded package:
https://github.com/NOAA-ORR-ERD/gridded
Not as mature (and certainly not as publicised) as I'd like, but the core idea of a unifying API for working with various types of gridded data could really help with visualization projects, etc.
And it integrated pyugrid and pysgrid, so can handle much of the file I/O for you (as well as providing a standard framework for making new file format readers / writers)
Perhaps you've pretty much written the parts of it that you need already, in which case, maybe I should see about borrowing your code, but it does provide some nice code for interpolating, etc, that could be useful.
(hmm, maybe I could plug EarthSim into gridded for visualization instead... I've been planning on using MPL, cartopy, etc)
On the plus side, gridded's immaturity means there's lots of room for tailoring the API and functionality to your needs :-)
Anyway -- keep up the good work, and if you do take a look at gridded, I'd love to get any feedback.
-CHB
I want to have a dynamic table including the latitude and longitude of the points on the drawn Path or Polygon. I think there might be two basic approaches -
I've spent several days and several different approaches trying to get this (or anything similar) to work for me and have had no success. Can someone weigh in on what might be the best direction for me to take - either one of the above suggestions or something else entirely. Then perhaps I can narrow in my efforts. Thanks!
My cell magic opts for the polygon don't appear to be working/having any effect on my visualizations via the annotators. I believe we are moving away from cell magic %%opts and towards the .options
, right? Have cell magics been phased out, is my .options
specification overriding it, or is something else going on here?
%%opts Polygons (color='red' alpha=0.5 selection_alpha=0.8 nonselection_alpha=0.2)
viz = PolyAndPointAnnotator(path_type=gv.Path, polys=[boundary_poly], crs=coord_sys,extent=(np.NaN,)*4)
(viz.tiles * viz.polys * viz.poly_view.options(apply_ranges=False) * viz.points * datashade(trimesh.edgepaths) + viz.poly_table + viz.point_table).options(shared_datasource=True).cols(1)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.