holoviz / holoviews Goto Github PK
View Code? Open in Web Editor NEWWith Holoviews, your data visualizes itself.
Home Page: https://holoviews.org
License: BSD 3-Clause "New" or "Revised" License
With Holoviews, your data visualizes itself.
Home Page: https://holoviews.org
License: BSD 3-Clause "New" or "Revised" License
There are some cases where sublabels go missing, such as the missing "B" in:
http://ioam.github.io/holoviews/Tutorials/Containers#Gridspace
and the missing "A" in the first plot of:
http://ioam.github.io/holoviews/Tutorials/Composing_Data.html
Those seem like something to do with GridSpaces of Curve elements.They are also not present in:
http://ioam.github.io/holoviews/Tutorials/Options
but that seems like a different issue, because sublabel_format==None on that page. Maybe that's deliberate, but I don't see why there would be a different default value for output directly to disk than there is in the notebook.
And not sure why they aren't in the "Tipping data" section of:
http://ioam.github.io/holoviews/Tutorials/Pandas_Seaborn.html
Works:
hv.Image(near), bounds=(-40,-30,40,30))
Does not work:
hv.Image(near), bounds=[-40,-30,40,30])
Allow the bound parameter to be any iterable of lenght > 4.
I think it may be worth having an Issue kept open where anyone can submit any general comments or feedback without forcing people to open more specific issues. It might also be worth linking to this issue from the homepage...
This issue summarizes a fairly long discussion regarding the semantics of normalization. This issue is obviously related to issue #49. As we are all aware, generalizing normalization in an understandable and useful way is rather difficult!
In short, we distilled the concepts relevant to normalization into three stages: element selection, grouping and filtering:
Element selection: The first step is to find all the elements matching the {type}.{group}.{label}
specification. At the very minimum an element type will be supplied which means normalization is only ever performed between elements of the same type.
Element grouping: This is the procedure by which a set of elements within the same selection (defined in the first step) are collected into a set which may then be normalized across. We currently have two such options we have called 'axiswise' and 'framewise'.
Note that these two options could be replaced by far more options by container type. E.g 'holomapwise', 'gridwise', 'layoutwise'. My understanding is that 'axiswise' is essentially a way of specifying both 'gridwise' and 'layoutwise' (whereas 'framewise' is essentially 'holomapwise').
You can currently group everything available together (default), group together by frame, group together by axis or do not grouping at all (i.e. each element is normalized without looking at any other element).
Right now, it isn't obvious to me if this relates to the {type}.{group}.{label}
selection where the type is a container type.
Dimension Filtering:
This is the granularity we are currently missing. Once we have determined which elements are to be grouped together we need to decide which of the available dimensions on those elements should be normalized together. Right now all the available dimensions are normalized together.
We have suggested two types of filtering 'semantic' and 'visualization'. The former correspond to our existing distinction between key and value dimensions (which does partition all dimensions nicely). The latter corresponds to a distinction between dimensions that only exists once visualized.
Our currently suggested categories are 'spatial' and (for a better suggestion!) 'other' - the former correspond to the dimensions spanned by the (normally!) cartesian axes of the plots whereas the latter corresponds to everything else.
Of course the finest granularity is to specify each dimension to normalize by name but this is verbose and brittle (dimension names are easily changed!).
Initial Summary:
I won't go on - hopefully this is enough to get a useful discussion started! That said, I will share one insight - even though holomaps have key dimensions, you never see them directly which is why these dimensions are never normalized. What may be normalized across is the group of elements contained in a holomap and the thing that is normalized is a dimension that maps to some visualizable quantity on the screen (spatial axis extents, pixel color/luminance etc).
EDIT: I should also mention that we acknowledged that the term 'normalization' is horribly overloaded. One of my tentative suggestions was to call the selection + grouping process 'linking'. As in you specify which elements are to be 'linked' together before normalizing their dimensions as appropriate.
With our new identifier sanitization system, you can set labels that start with underscores or with special characters not normally allowed in attribute names. The result is a string that starts with a single underscore (never two though!) for use in the tree object (e.g. AttrTree
, Layout
, `Overlayor
OptionTree``).
All this is fairly general but I am worried that this behavior may end up being confusing to users. The issue with attributes starting with a single underscore aren't presented for tab-completion in the notebook - at least not until you know that you have to suggest the initial underscore yourself.
This means that it may appear to users that elements on their Layouts have vanished even though they are actually available (but hidden). I have no way of changing the IPython tab-completion behavior so one suggestion may be to generate a warning to discourage labels/group strings starting with underscores or special characters.
There could be a way to disable this warning but I'm not sure this is necessarily a good idea - the lack of obvious tab-completion when there is a leading underscore is present could be pretty confusing. It is better (in my opinion) to always warn people who are setting unsuitable labels/groups that they are doing something that is allowed but potentially very confusing to other people.
One other idea is that we could implement our own __dir__
method which does give us some control over what IPython presents for tab-completion (still not underscore though). For instance, we could stop showing all the tab-completable attributes once a hidden one has been specified (the dictionary style interface is still available). At least this would help avoid tree where only some of the paths are easily visible while others are hidden.
Thoughts?
I want to put a Text object with a different color than black. Is this possible?
hv.help(hv.Text, visualization=True)
Does not give clues
Currently Arrow
elements can only point along the cardinal directions.
Right now, the _getitem__
in Overlay is inherited from layout which is causing various issues:
I think we need to write an appropriate __getitem__
for Overlays. Note that as Overlays are heterogeneous containers there will be cases where slicing won't work:
__getitem__
itself.I don't like the default style we use across ioam packages very much and think the readthedocs template would be a much better alternative. I've mocked up what this would look like here. It's pretty trivial to switch over but it requires writing proper toctrees, which has not been consistently across ioam packages. I'd suggest switching over this package now and if Jim finds some time to write toctrees for topographica we can switch all the other packages as well.
Is it possible to create plots with errorbars, like plt.errorbar does?
For ImaGen, we are demonstrating all of the various pattern types available by dumping them all out:
from imagen import *
from imagen.random import *
from imagen.image import *
np.sum([x()[:] for x in locals().values() if isinstance(x,type)
and issubclass(x,PatternGenerator) and not x.abstract]).cols(5)
But for enough patterns, this fails unless we turn off sublabels:
%opts Layout [sublabel_format=""] Image (cmap='gray') [show_xaxis=None show_yaxis=None show_frame=True]
because the chr() call eventually gets into unicode errors, as it goes away from alphabetic characters. Should use modulo to go A..Z then AA, AB, etc.
d={x: (z1 * hv.VLine(x) + z1.sample(B=x) )
for x in np.linspace(0.2, 0.8, 10)}
hv.Overlay.collate(d, key_dimensions=['B']).cols(2)
In the left graph the ticks on the x-axis are incorrect. These are the values that I gave in with: hv.Dimension('Chemical potential', unit='meV', range=(0, 35))
.
I like to use unicode characters in my plots. In order to obtain this:
from __future__ import unicode_literals
However, now the HoloMap doesn't work anymore.
Here an example from the tutorials page. When skipping the first line, this works like a charm, however, the first import breaks it al:
from __future__ import unicode_literals
import numpy as np
import holoviews as hv
%load_ext holoviews.ipython
def sine(x, phase=0, freq=100):
return np.sin((freq * x + phase))
phases = np.linspace(0,2*np.pi,11) # Explored phases
freqs = np.linspace(50,150,5) # Explored frequencies
dist = np.linspace(-0.5,0.5,202) # Linear spatial sampling
x,y = np.meshgrid(dist, dist)
grid = (x**2+y**2) # 2D spatial sampling
dimensions = ['Phase', 'Frequency']
keys = [(p,f) for p in phases for f in freqs]
items = [(k, hv.Image(sine(grid, *k), value_dimensions=['Amplitude'])) for k in keys]
circular_wave = hv.HoloMap(items, key_dimensions=dimensions)
circular_wave
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-1-dc5f36c4abcf> in <module>()
14 dimensions = ['Phase', 'Frequency']
15 keys = [(p,f) for p in phases for f in freqs]
---> 16 items = [(k, hv.Image(sine(grid, *k), value_dimensions=['Amplitude'])) for k in keys]
17 circular_wave = hv.HoloMap(items, key_dimensions=dimensions)
18 circular_wave
/usr/local/lib/python2.7/dist-packages/holoviews/element/raster.pyc in __init__(self, data, bounds, xdensity, ydensity, **params)
325
326 SheetCoordinateSystem.__init__(self, bounds, xdensity, ydensity)
--> 327 Element2D.__init__(self, data, extents=self.lbrt, bounds=bounds, **params)
328
329 if len(self.data.shape) == 3:
/usr/local/lib/python2.7/dist-packages/holoviews/core/element.pyc in __init__(self, data, extents, **params)
144 self._xlim = None if extents is None else (extents[0], extents[2])
145 self._ylim = None if extents is None else (extents[1], extents[3])
--> 146 super(Element2D, self).__init__(data, **params)
147
148 @property
/usr/local/lib/python2.7/dist-packages/holoviews/core/element.pyc in __init__(self, data, **params)
43
44 def __init__(self, data, **params):
---> 45 super(Element, self).__init__(data, **params)
46
47
/usr/local/lib/python2.7/dist-packages/holoviews/core/dimension.pyc in __init__(self, data, **params)
432 else:
433 dimensions = [d if isinstance(d, Dimension) else Dimension(d)
--> 434 for d in params.pop(group)]
435 params[group] = dimensions
436 super(Dimensioned, self).__init__(data, **params)
/usr/local/lib/python2.7/dist-packages/holoviews/core/dimension.pyc in __init__(self, name, **params)
85 else:
86 existing_params = {'name': name}
---> 87 super(Dimension, self).__init__(**dict(existing_params, **params))
88
89
/usr/local/lib/python2.7/dist-packages/param/parameterized.pyc in __init__(self, **params)
1002 self.__generate_name()
1003
-> 1004 self._setup_params(**params)
1005 object_count += 1
1006
/usr/local/lib/python2.7/dist-packages/param/parameterized.pyc in override_initialization(parameterized_instance, *args, **kw)
939 original_initialized=parameterized_instance.initialized
940 parameterized_instance.initialized=False
--> 941 fn(parameterized_instance,*args,**kw)
942 parameterized_instance.initialized=original_initialized
943 return override_initialization
/usr/local/lib/python2.7/dist-packages/param/parameterized.pyc in _setup_params(self, **params)
1383 self.warning("Setting non-parameter attribute %s=%s using a mechanism intended only for parameters",name,val)
1384 # i.e. if not desc it's setting an attribute in __dict__, not a Parameter
-> 1385 setattr(self,name,val)
1386
1387
/usr/local/lib/python2.7/dist-packages/param/parameterized.pyc in __set__(self, obj, val)
528 def __set__(self,obj,val):
529 if not isinstance(val,str) and not (self.allow_None and val is None):
--> 530 raise ValueError("String '%s' only takes a string value."%self._attrib_name)
531
532 super(String,self).__set__(obj,val)
ValueError: String 'name' only takes a string value.
Code:
XX,YY = np.mgrid[0:60,0:80]
hv.Image(XX+YY).sample(y=-0.4)
IndexError Traceback (most recent call last)
in ()
1 XX,YY = np.mgrid[0:60,0:80]
----> 2 hv.Image(XX+YY).sample(y=-0.4)
/usr/local/lib/python2.7/dist-packages/holoviews/element/raster.pyc in sample(self, samples, *_sample_values)
111 # Sample data
112 x_vals = sorted(set(self.dimension_values(dimension)))
--> 113 data = list(zip(x_vals, self.data[sample]))
114 params['key_dimensions'] = other_dimension
115 return Curve(data, *_params)
IndexError: index 72 is out of bounds for axis 0 with size 60
There is still more available information to exploit for tab completion!
We can't tab-complete values for style keywords in the %opts
magic as those are backend dependent but we do assume that any plotting classes (regardless of the exact backend) will be using param.
At the minimum, tab-completion options for param.ObjectSelector
declarations would be quite nice. As for other parameters, you could tab-complete the current value of the parameter (i.e. typically the default unless set by the user).
Currently it isn't as easy as it should be to define placeholders in Layouts. For instance, you may always want a four element Layout but the third item may sometimes be missing.
We have considered introducing the concept of 'empty' elements for this but haven't committed to this approach as we want as few changes to our Element constructors as possible.
To add to the growing list of bugs related to to style system: :-S
%%opts Path {+framewise} Path (color='g' linewidth=1)
from holoviews import Path, HoloMap
hmap = HoloMap()
for i in range(1,8):
hmap[i] = Path([zip(range(i*5), range(i*5))])
hmap
Obviously not an optimal definition with Path
repeated twice but it ought to work. The bug is that currently it acts as if {+framewise}
wasn't specified. Probably related to #43
Currently __getitem__
on Histogram is raises a NotImplementedError
because the slicing semantics aren't obvious. I think we can do a few useful things though:
What is less obvious is what scalar indexing represents (e.g. hist[0.5]
). I can think of two behaviors:
I think the second behavior is the most logical and consistent. Anyway, if I don't hear any objections in the next day, I'll go ahead and implement these semantics!
I've noticed that the fps option isn't being respected:
%%output holomap='gif' fps=1
holomap
Should be an easy fix once I have the time to look at it!
I tried:
H1 = np.random.randn(4, 4)
H2 = np.random.randn(4, 4)
x = np.linspace(0, 1, 100)
eigenvals = np.array([np.linalg.eigvalsh(H1 * alpha + H2 * (1 - alpha)) for alpha in x])
Conts = hv.NdOverlay({i: hv.Contours([zip(x, eigenvals[:, i])]) for i in range(4)})
Where slicing works like:
Conts + Conts.select(x=(0, 0.5), y=(-1,1))
Although this fails:
Conts[:][0:0.5, -1:1]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-187-20fd24baf2a1> in <module>()
----> 1 Conts[:][0:0.5, -1:1]
/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/core/ndmapping.pyc in __getitem__(self, indexslice)
528 items = [(k, v) for k, v in items
529 if condition(values.index(k[cidx]) if values else k[cidx])]
--> 530 items = [(k, self._dataslice(v, data_slice)) for k, v in items]
531 if len(items) == 0:
532 raise KeyError('No items within specified slice.')
/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/core/ndmapping.pyc in _dataslice(self, data, indices)
208 """
209 if isinstance(data, Dimensioned) and indices:
--> 210 return data[indices]
211 elif len(indices) > 0:
212 self.warning('Cannot index into data element, extra data'
/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/element/path.pyc in __getitem__(self, key)
49 if not all(isinstance(k, slice) for k in key):
50 raise IndexError("%s only support slice indexing" %
---> 51 self.__class__.__name__)
52 xkey, ykey = key
53 xstart, xstop = xkey.start, xkey.stop
IndexError: Contours only support slice indexing
When I do
images = {(phi, theta):
hv.Image(data[phi, theta])
for theta in range(len(thetas))
for phi in range(len(phis))}
curves = {(phi, theta):
hv.Curve(curve_data[phi, theta])
for theta in range(len(thetas))
for phi in range(len(phis))}
total = {(phi, theta): images[phi, theta] * curves[phi, theta]
for theta in range(len(thetas))
for phi in range(len(phis))}
and then:
%%opts Image (cmap='gist_heat_r') style(origin='lower') Curve (linewidth=1)
hv.HoloMap(total, key_dimensions=['phi', 'theta'])
(origin='lower')
doesn't work.
however when I first evaluate
%%opts Image (origin='lower')
images[0,0]
then the evaluation of hv.HoloMap(total)
does work with the options that I set.
For something with a script_repr
attribute, param's script_repr
expects to be able to call something.script_repr()
with certain kw args:
elif hasattr(val,'script_repr'):
rep=val.script_repr(imports=imports, prefix=prefix+" ",qualify=True, unknown_value=unknown_value)
BoundingBox doesn't support all of those kw args:
https://github.com/ioam/holoviews/blob/master/holoviews/core/boundingregion.py#L106
def script_repr(self, imports=[], prefix=" "):
topo_t000000.00_c1>>> from param.parameterized import script_repr
topo_t000000.00_c2>>> from holoviews.core.boundingregion import BoundingBox
topo_t000000.00_c3>>> script_repr(BoundingBox(),[])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/ceball/code/ioam/topographica/topographica in <module>()
----> 1 script_repr(BoundingBox(),[])
/home/ceball/code/ioam/topographica/external/param/param/parameterized.pyc in script_repr(val, imports, prefix, settings, unknown_value, qualify)
817
818 rep=val.script_repr(imports=imports, prefix=prefix+" ",
--> 819 qualify=True, unknown_value=unknown_value)
820
821 else:
TypeError: script_repr() got an unexpected keyword argument 'qualify'
Unfortunately I didn't at least say in the param release notes that anything with a script_repr
method would need some changes, because I didn't actually notice the interface had changed (although now I look at the PR's diff it is very obvious). (I suppose we could modify param's script_repr
to support the old signature of script_repr methods too, but it doesn't seem worth it.)
P. S. While debugging, I was so happy to find that boundingregion and sheetcoords are in holoviews rather than topographica - and hence no longer my problem, so I can throw away my piece of paper with 100 to-do items about Slice on it - that I almost wanted to commit the changes myself ;)
It would be nice to plot an 2D array of data as curves.
For example in an eigenvalue problem where I generate multiple y-values at one x-value. This is very easily done with matplotlib:
H1 = np.random.randn(10, 10)
H2 = np.random.randn(10, 10)
x = np.linspace(0, 1, 100)
eigenvals = [np.linalg.eigvalsh(H1 * alpha + H2 * (1 - alpha)) for alpha in x]
plt.plot(x, eigenvals)
Here eigenvals.shape = (100, 10)
.
To plot these curves with I need to first transform the data, such that the data is of the shape (N, 2)
.
With my other scripts the following line does the trick:
hv.Curve([(B, mu) for eig_list in eigenvals.T for B, mu in zip(x, eig_list)])
but for some reason this does something strange...
Another solution that does work is:
from operator import mul
list_curves = [hv.Curve(zip(x,eigenvals[:,i])) for i in range(10)]
reduce(mul, list_curves)
We will want a tutorial on Collector
and Collator
which are currently undocumented.
In short:
Collector
lets you collect HoloViews data structures over some dimension that is difficult to traverse using a set of callable objects (functions, callable classes) on each step. For instance, this is useful if you are collecting data in real-time (and need to periodically run a number of measurements) or if you are running a slow simulator, you wish to collect multiple analyses at each simulation time increment (instead of running the simulator N times).Collator
lets you collate disparate HoloViews objects that are already available (e.g. in memory or on disk) into a cohesive structure with unified dimension structure. This is useful for collating lots of pickle files that may be generated on a cluster using a batch job system (e.g Sun Grid Engine).This would be a natural entry point to Lancet where we can discuss how to use HoloViews with external software running either locally or on compute clusters.
After new install (IPython notebook version 3+) Python 2+ I get the above error (Suspect IPython 3 issue)
from holoviews import *
%load_ext holoviews.ipython
:0: FutureWarning: IPython widgets are experimental and may change in the future.
then
type object 'BlockLexer' has no attribute 'default_rules'
30 @undoc
31 class MathBlockLexer(mistune.BlockLexer):
---> 32 default_rules = ['block_math', 'latex_environment'] + mistune.BlockLexer.default_rules
33
34 def init(self, rules=None, **kwargs):
The current example shows using Seaborn and Pandas and describes wrapping the Pandas dataframe with the holoviews Dframe. Unfortunately I find it confusing..
I'd appreciate a simple pd.dataframe to Dframe description with plotting example? Where it is clear how to reference the Pandas data as input to plotting methods. I'm currently exploring a horrendous DataFrame but can split it down into manageable pieces.... Maybe it is clear and it is just me,, But I suspect that there will be a lot of us trying to apply pandas data since we already have it ready to go...
Changeing the cmap of an image of a label does not work well:
No error, cmap changed, but label lost:
Image(data)(style={'cmap':'gray'}, label='A')
Error:
Image(data, label='A')(style={'cmap':'gray'})
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-99-094bbee28a14> in <module>()
8 else:
9 return far + near + pump
---> 10 show_images((7,8,10,9))
<ipython-input-99-094bbee28a14> in show_images(index)
4 pump = Image(read_near(files[index[2]]), label='M'+files[index[2]])
5 if len(index) > 3:
----> 6 dmk = Image(read_dmk(files[index[3]]), label='M'+files[index[3]])(style={'cmap':'gray'})
7 return far + near + pump + dmk
8 else:
/usr/local/lib/python2.7/dist-packages/holoviews/core/element.pyc in __call__(self, **kwargs)
135 for k,d in kwargs.items():
136 options[identifier][k] = d
--> 137 return super(Element, self).__call__(options)
138
139
/usr/local/lib/python2.7/dist-packages/holoviews/core/dimension.pyc in __call__(self, options, **kwargs)
615 """
616 deep_clone = self.map(lambda x: x.clone(id=x.id))
--> 617 StoreOptions.set_options(deep_clone, options, **kwargs)
618 return deep_clone
619
/usr/local/lib/python2.7/dist-packages/holoviews/core/options.pyc in set_options(cls, obj, options, **kwargs)
1068 spec, compositor_applied = StoreOptions.expand_compositor_keys(options)
1069
-> 1070 custom_trees = StoreOptions.create_custom_trees(obj, spec)
1071 Store.custom_options.update(custom_trees)
1072 for tree_id in custom_trees.keys():
/usr/local/lib/python2.7/dist-packages/holoviews/core/options.pyc in create_custom_trees(cls, obj, options)
961
962 return {k:cls.apply_customizations(options, t) if options else t
--> 963 for k,t in clones.items()}
964
965
/usr/local/lib/python2.7/dist-packages/holoviews/core/options.pyc in <dictcomp>((k, t))
961
962 return {k:cls.apply_customizations(options, t) if options else t
--> 963 for k,t in clones.items()}
964
965
/usr/local/lib/python2.7/dist-packages/holoviews/core/options.pyc in apply_customizations(cls, spec, options)
899 customization = {k:(Options(**v) if isinstance(v, dict) else v)
900 for k,v in spec[key].items()}
--> 901 options[str(key)] = customization
902 return options
903
/usr/local/lib/python2.7/dist-packages/holoviews/core/tree.pyc in __setitem__(self, identifier, val)
147 self.__setattr__(identifier, val)
148 elif isinstance(identifier, str) and self.parent is None:
--> 149 self.set_path(tuple(identifier.split('.')), val)
150 elif isinstance(identifier, tuple) and self.parent is None:
151 self.set_path(identifier, val)
/usr/local/lib/python2.7/dist-packages/holoviews/core/tree.pyc in set_path(self, path, val)
100
101 if not all(p[0].isupper() for p in path):
--> 102 raise Exception("All paths elements must be capitalized.")
103
104 if len(path) > 1:
Exception: All paths elements must be capitalized.
HoloViews makes common operation and visualizations very easy. That said, HoloViews needs to be flexible enough to scale to finely tweaked or highly customized visualizations.
Here are our current recommendations:
Plot
class and if necessary a new Element
type, typically extending from some existing class. Obviously the most work but extremely worthwhile, as your new plot will then compose nicely with the rest of HoloViews
(automatic support for layouts, overlays, animation, the options system and more!).We should definitely consider authoring a new notebook tutorial on this topic.
I try to overlay a cross-section with some points. However, it matters in which order I create the overlay:
Works
fs = Raster(np.array([[1]]))
hv.Overlay([hv.Scatter([[1,1]]),fs.sample(y=0),fs.sample(y=0)])
Does not work
fs = Raster(np.array([[1]]))
hv.Overlay([fs.sample(y=0),hv.Scatter([[1,1]]),fs.sample(y=0)])
Traceback (most recent call last):
File "/home/xx/src/holoviews/holoviews/ipython/display_hooks.py", line 197, in wrapped
**kwargs)
File "/home/xx/src/holoviews/holoviews/ipython/display_hooks.py", line 227, in element_display
**opts(element, get_plot_size(element, size)))()
File "/home/xx/src/holoviews/holoviews/plotting/element.py", line 514, in __init__
self.subplots = self._create_subplots(ranges)
File "/home/xx/src/holoviews/holoviews/plotting/element.py", line 528, in _create_subplots
cyclic_index, _ = next(style_iter[style_key])
StopIteration
:Overlay
.Curve.I :Curve [x] (z)
.Scatter.I :Scatter [x] (y)
.Curve.II :Curve [x] (z)
I use master, with the last commit a696bd2
I tried the example
((fractal * HLine(y=0)).hist() + fractal.sample(y=0))
on my own data, but .hist()
doesn't handle np.NaN
values.
Traceback (most recent call last):
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/ipython/display_hooks.py", line 203, in wrapped
**kwargs)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/ipython/display_hooks.py", line 279, in layout_display
return display_figure(fig)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/ipython/display_hooks.py", line 168, in display_figure
figdata = renderer.figure_data(fig, figure_format)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/plotting/__init__.py", line 252, in figure_data
fig.canvas.print_figure(bytes_io, **kw)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/backend_bases.py", line 2168, in print_figure
bbox = a.get_window_extent(renderer)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/patches.py", line 491, in get_window_extent
return self.get_path().get_extents(self.get_transform())
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/path.py", line 518, in get_extents
transform = transform.frozen()
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/transforms.py", line 2067, in frozen
return blended_transform_factory(self._x.frozen(), self._y.frozen())
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/transforms.py", line 2201, in blended_transform_factory
return BlendedAffine2D(x_transform, y_transform)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/matplotlib/transforms.py", line 2148, in __init__
assert y_transform.is_separable
AssertionError
Is it possible to make it ignore these values?
Plotting a HoloMaps for my (big) dataset takes nearly 10 minutes, so I thought I could use IPython.widgets.interact
to create the plots on the fly like:
from IPython.html.widgets import interact
import holoviews as hv
def plot_graphs(xsize, ysize):
return hv.Image(np.random.randn(xsize, ysize))
interact(plot_graphs, xsize=(0, 100, 10), ysize=(0, 100, 10))
Unfortunately this doesn't plot anything. Would it be difficult to support this? Or potentially an option which doesn't pregenerates all plots in one go?
This conversation has been moved from the inline comments on commit 5f28a33
chris-english commented on 5f28a33 12 days ago
Very happy to explore your Dataviews Tutorial. Imagining really, really new to, well everything, python, linux, topographica, but a burning desire to get one's head around topographica and its many worthy parts some things can go wrong for the uninitiated (like myself, and soon my students...).
My first issues were with modules not found (dataviews), and fixed through appending sys.path for dataviews and param.
That said, in the section - SheetViews, the default backend selected is backend_tkagg.py, which leads to TclError: couldn't connect to display ":0". The sinusoid data is printed but not visualized. Putting %matplotlib inline, in a cell prior to plotting means all your work can be seen by us nubes.
Thanks for your documenting efforts.
Chris English
Our core API is now solid (otherwise we wouldn't claim to be version 1.0!) but there are still a few corners of the code where parameter names can be improved and made clearer. We want to fix these names as soon as possible, before too many people (including us!) become reliant on them.
Here is the current list of changes I would personally like to see.
Plot.show_xaxis -> Plot.xaxis
: Sounds like a boolean when in fact it is a list of options. Also shorter.Plot.show_yaxis -> Plot.yaxis
: Same as above.Please add any other suggestions you may have or entirely new suggestions below! In addition, I have submitted a feature request to param that would help make minor API changes easier: holoviz/param#112
Should be a quick fix to the appropriate style definition...
kwargs = {'key_dimensions':[B_dim],
'value_dimensions':[E_dim],
'extents':bounds}
hv.Overlay.from_values([hv.Curve(zip(x, y[i]), **kwargs) for i in range(10)])
kwargs = {'key_dimensions':[B_dim],
'value_dimensions':[E_dim],
'extents':bounds,
'label':'Test label'
'group':'Test group'}
hv.Overlay.from_values([hv.Curve(zip(x, y[i]), **kwargs) for i in range(10)])
Currently, the Raster and Image function do not respect the aspect ratio of the data.
Raster should have aspect='equal', such that pixels stay square, because almost everything samples with a square grid.
For Image, the optimal default behaviour is less clear. By default, the coordinates are transformed to continues coordinates. This means that equal and square are the same when no bounds are specified.
I propose that the aspect parameter of Image will be set by default to the aspect of the data.
We have no real breakdown of the different widget types, backend options, figure types etc.. We should probably add a Tutorial notebook to explain how to select different backends and what trade-offs they have compared to each other.
In the options ipynb is showns how to show the cmap of a single image:
Image(data)(style={'cmap':'Greens'})
This works not for Raster! Then the cmap is not changed:
Raster(data)(style={'cmap':'Greens'})
I think (hope) I didn't make a mistake, but the next code produces an error:
%%opts Image plot[figure_inches=(7,7)]
data = np.mgrid[:100,:100][0]+2*np.mgrid[:100,:100][1]
hv.Image(data, bounds=(0,0,100,100),
key_dimensions=[hv.Dimension('x', range=(-200,200)),
hv.Dimension('y', range=(-200,200))])
Error message:
Traceback (most recent call last):
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/ipython/display_hooks.py", line 197, in wrapped
**kwargs)
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/ipython/display_hooks.py", line 227, in element_display
**opts(element, get_plot_size(element, size)))()
File "/home/bnijholt/python/env_stable/lib/python2.7/site-packages/holoviews/plotting/__init__.py", line 70, in opts
return dict(figure_inches=size, **Store.lookup_options(obj, 'plot').options)
TypeError: type object got multiple values for keyword argument 'figure_inches'
https://ioam.github.io/holoviews/Tutorials/Introduction:
Dimensions of your data. The key_dimensions describe how your data can be indexed. The value_dimensions describe what the resulting indexed data represents. A numerical Dimension can have a name, type, range, and unit. This information allows HoloViews to rescale and label axes and allows HoloViews be smart in how it processes your data.
The syntax to get the right ranges in an image is different however:
data = np.mgrid[:100,:100][0]+2*np.mgrid[:100,:100][1]
img = hv.Image(data, key_dimensions=[
hv.Dimension('xa', range=(0,100)),
hv.Dimension('ya', range=(0,100))
])
data = np.mgrid[:100,:100][0]+2*np.mgrid[:100,:100][1]
hv.Image(data, bounds=(0,0,100,100))
The first one is what I would expect from Holoviews, but the implemented one is shorter, and closer the the matplotlib.imshow implementation. I opt that both work, aka, that bounds is a shortcut for defining the ranges via the dimension function.
When you overlay annotations, you typically lose the title as the labels of the different layers don't match so no label is set.
Although this behavior is fine for many element types, it doesn't make sense for Annotation
elements where you are annotating some data that lies underneath the annotation layers. In this case, the group and labels of the annotation(s) should be ignored so that you can see the title of the data that has been annotated.
hv.help(object, visualization=True)
Says:
To see the options info for one of these target specifications,
which are of the form {type}[.{group}[.{label}]], do holoviews.info({type}).
But hv.info does not exists
The output of the following snippet is affected by the declared ranges when it shouldn't be (the table should only be affected by the shape of the array and the declared bounds):
import holoviews as hv
import numpy as np
data = np.ones((3,3))
hv.Image(data, bounds=(0,0,100,100),
key_dimensions=[hv.Dimension('x', range=(-200,200)),
hv.Dimension('y', range=(-200,200))]).table()
There are a few things we should improve in our next PyPI release:
pip install holoviews[core]
and holoviews[all]
.requirements.txt
at least for holoviews[all]
Right now we have the four normalization options +axiswise, -axiswise, +framewise, -framewise
. Although these four modes are already quite flexible as they apply by {type}.{group}.{label}
there are always more possible ways to normalize things!
The most flexible (but verbose!) approach would be to have the four normalization options specified for each dimension by dimension name. Although flexible, this would require a lot more work in the '%%opts' magic parser and would be quite brittle (e.g if you rename your dimensions!).
Having discussed this with Philipp we think there is a useful middle-ground - use the existing split between key dimensions and value dimensions. This would get rid of the situated
parameter for instance, replacing that with the more general notion of normalizing by key dimension.
Here is how it would work in the magic:
+axiswise, -axiswise, +framewise, -framewise
# Current semantics (i.e all dimensions)
+axiswise[K], -axiswise[K], +framewise[K], -framewise[K]
# Apply to key dimensions only
+axiswise[V], -axiswise[V], +framewise[V], -framewise[V]
# Applyi to value dimensions only
Note that there are equivalences e.g -axiswise[K]
is equivalent to +axiswise[V]
as specifying key 'on' is the same as specifying value 'off'.
This is compatible with the current approach and here is what it would map to as a normalization option as accessed by the plotting code:
axiswise=True|False|'key'|'value'
Looking at this, this might be a good opportunity to have the magic syntax match the option more closely. I.e the +
and -
prefix are just shortcuts for the boolean options only. I.e the magic would support:
+axiswise, -axiswise, +framewise, -framewise
axiswise='key', axiswise='value', framewise='key', framewise='value'
And if you don't want to use the short syntax:
axiswise=True, axiswise=False, framewise=True, framewise=False
Any thoughts? This shouldn't be too much effort to implement, is compatible with what we already have and would certainly be useful in some cases (as well as getting rid of the situate
parameter).
Edit:
Instead of using the dimension names, one day we could support doing it by dimension index instead, e.g:
axiswise=[0,2]
Not very clear what that means but certainly less brittle than using the dimension name!
One of the major benefits of using HoloViews over basic plotting libraries is that it allows the user to optionally provide metadata about their data via Dimension objects. This makes HoloViews job of correctly labeling charts and coordinating different subplots easy. Currently we provide the facility to specify the unit of a Dimension as a string, which is used in the axis labels, title and the widgets. However a proper unit integration would provide a huge number of benefits including unit conversion for display, easily combining different quantities and so on.
What shape this integration would take is still very much an open question but there are a number of promising units libraries already out there. Specifically Pint, a pure Python, dependency free, BSD licensed units library, seems like a good starting point as it provides NumPy integration and seems much less complex than other libraries like Unum or quantities.
We should aim to deliver such an integration for the next major release of HoloViews and use this issue to begin brainstorming how it might work.
Here is a very simple adaptation of the Histogram example from the Elements tutorial:
import numpy as np
from holoviews import Histogram
np.random.seed(1)
data = [np.random.normal() for i in range(10000)]
frequencies, edges = np.histogram(data, 20)
Histogram(frequencies, edges)(plot={'show_grid':True})
Although only a plot option is set (to show the grid), the color of the Histogram changes to the horrible default blue (instead of our cyan color). Must be a bug in the options system...
hv.Image
and hv.VLine
both have x bounds from (0,2).
When I do:
d={x: (fractal * hv.VLine(x)) for x in dots}
hv.HoloMap(d, key_dimensions=['B'])[0:1]
Only the VLine will go to one, but the Image is still from 0 to 2.
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.