Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] pandas migration #1347

Closed
wants to merge 140 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
140 commits
Select commit Hold shift + click to select a range
bb960ae
Extend str in Variable.
sstanovnik Jun 10, 2016
5a8846c
pandas migration: first huge, breaking, table update.
sstanovnik Jun 17, 2016
97fab90
Enable strict read-only access on Table X/Y/meta views.
sstanovnik Jun 17, 2016
3e7a853
Further changes to Table, as per recent comments.
sstanovnik Jun 22, 2016
81ddf10
Add Table.attributes to the pandas persistence scheme.
sstanovnik Jun 23, 2016
89907af
Insert pandas into requirements-core.
sstanovnik Jun 23, 2016
b732ed7
Table constructors and other fixes.
sstanovnik Jun 23, 2016
7af5a67
OWSelectRows: transform usage of Filter into pandas syntax.
sstanovnik Jun 23, 2016
85f6920
Completely remove Filter.
sstanovnik Jun 23, 2016
b8ee3b5
Table Domain changes, Variable inference and miscellaneous fixes.
sstanovnik Jun 25, 2016
7d3e29b
Make indexing and weights work from empty Tables.
sstanovnik Jun 28, 2016
ebb5a1f
Remove RowInstance completely.
sstanovnik Jun 28, 2016
5853ec5
Remove and transform infrequently-used old syntax.
sstanovnik Jun 28, 2016
77bf036
Completely remove Instance.
sstanovnik Jun 28, 2016
43f1a7f
Remove Storage.
sstanovnik Jun 28, 2016
d7a159d
Some minor fixes and cleanup in Table.
sstanovnik Jun 28, 2016
8623abc
A multitude of small fixes of bugs shown by tests.
sstanovnik Jun 29, 2016
3f7369b
Use pandas' reader for csv and tab.
sstanovnik Jun 29, 2016
827d4e1
Tab reader fixes for less common behaviour.
sstanovnik Jun 30, 2016
36d5b94
Port ExcelReader to use pandas' Excel reader.
sstanovnik Jun 30, 2016
8535478
Improve DiscreteVariable discreteness determination and parsing.
sstanovnik Jun 30, 2016
ba08eaf
Transform values we interpret as null with actual null values when
sstanovnik Jun 30, 2016
ce5cf4f
Handle NA weights when setting them.
sstanovnik Jun 30, 2016
f3a064b
Use pandas' categorical coltype for DiscreteVariable.
sstanovnik Jul 1, 2016
c170ade
Convert TimeVariable functionality to pandas.
sstanovnik Jul 1, 2016
745ca03
Small fixes: sniffer size, NA weights handling.
sstanovnik Jul 1, 2016
4a656b1
Variable equality fix and TimeVariable test modification.
sstanovnik Jul 1, 2016
ac914f0
A lot of small fixes for issues found by tests.
sstanovnik Jul 4, 2016
eca5618
Fix handling null values in TimeVariable columns.
sstanovnik Jul 5, 2016
fae01ac
Improve reading tab and csv files.
sstanovnik Jul 5, 2016
601d82d
Remove an unneeded test.
sstanovnik Jul 5, 2016
99ecf47
Compatibility shims for SQL table.
sstanovnik Jul 5, 2016
135eb47
Make Data Table work, transfer basic stats to pandas.
sstanovnik Jul 5, 2016
78f0db1
Multiple fixes: TableSeries retain attributes, constructor works
sstanovnik Jul 11, 2016
699b240
Remove Value.
sstanovnik Jul 11, 2016
360d0df
Fix recent TimeVariable changes.
sstanovnik Jul 11, 2016
38b648c
Some basic fixes for subscripting pandas.
sstanovnik Jul 11, 2016
9a4ef13
Migrate distributions to pandas.
sstanovnik Jul 11, 2016
2711440
Ported contingency to pandas.
sstanovnik Jul 12, 2016
e6f0cd9
Remove statistics/util.py.
sstanovnik Jul 12, 2016
bef5741
Adapt distances and tests to work with the new Table.
sstanovnik Jul 13, 2016
81bad83
Adapt preprocessors (discretize, impute) to work with the new Table.
sstanovnik Jul 13, 2016
5020b89
Loads of test and compatibility fixes.
sstanovnik Jul 13, 2016
90c43ec
k-Means compatibility fixes.
sstanovnik Jul 13, 2016
2dab765
Transform Continuize for usage with pandas.
sstanovnik Jul 13, 2016
54677f0
Fix parsing files with discrete variables which specify values.
sstanovnik Jul 13, 2016
9146bfa
Discretization pandas compatibility, also test fixes.
sstanovnik Jul 14, 2016
494caf0
Evaluation - scoring test compatibility fix.
sstanovnik Jul 14, 2016
f43eb2c
Intepret missing value markers when reading from file.
sstanovnik Jul 14, 2016
d2297f8
Impute pandas adaptation, with tests.
sstanovnik Jul 14, 2016
fc5b426
Fix transforming discrete ordinal values into descriptor values.
sstanovnik Jul 14, 2016
7dde951
Distributions should use weights instead of counts.
sstanovnik Jul 14, 2016
238a838
Miscellaneous test adaptations.
sstanovnik Jul 14, 2016
9d5093d
Convert normalization, use groupby instead of value_count in distribu…
sstanovnik Jul 14, 2016
72e2eb0
Add copying to table constructors, very important!
sstanovnik Jul 14, 2016
dc8027d
Migrate randomization to pandas.
sstanovnik Jul 15, 2016
7317045
A small fix for caching table transformations.
sstanovnik Jul 15, 2016
8c10f2a
Miscellaneous test compatibility fixes.
sstanovnik Jul 15, 2016
9d3cf40
Migrate remover and its tests.
sstanovnik Jul 15, 2016
d019e8d
Simple tree and softmax adaptation.
sstanovnik Jul 15, 2016
db2a2a9
Only allow one of specified delimiters when reading file.
sstanovnik Jul 15, 2016
2b53079
Remove Value tests.
sstanovnik Jul 15, 2016
55d233a
Miscellaneous table test compatibility fixes.
sstanovnik Jul 15, 2016
5cd878f
Use 0 instead of NA when values don't exist in distributions.
sstanovnik Jul 18, 2016
1fde4f2
Feature scoring test compatibility.
sstanovnik Jul 18, 2016
aa1d4c6
A bucketload of fixes for widgets.
sstanovnik Jul 18, 2016
3efd943
Fix owcontinuize to use proper continuization behaviour.
sstanovnik Jul 19, 2016
f5ee17d
Don't intepret None as a missing value when reading a table.
sstanovnik Jul 19, 2016
a44e1e4
Use proper top-level imports. D'oh!
sstanovnik Jul 19, 2016
14efa24
Use a more robust way of computing basic stats.
sstanovnik Jul 19, 2016
74bc375
A small fix for the new single-class test.
sstanovnik Jul 19, 2016
bc64dbc
Fixes for some elusive tests.
sstanovnik Jul 19, 2016
d21a3e8
Port SQLTable to a pandas backend. Some breaking changes.
sstanovnik Jul 21, 2016
23d42c4
Completely overhaul the Table class inheritance structure.
sstanovnik Jul 21, 2016
5c23db1
Fix some broken Table imports.
sstanovnik Jul 22, 2016
6004bed
Basic SparseTable functionality.
sstanovnik Jul 27, 2016
bc84af8
Distributions for sparse tables.
sstanovnik Jul 27, 2016
c190a5a
A snail-paced implementationof contingency computation for sparse
sstanovnik Jul 27, 2016
5864dd1
Improved the reading capabilities.
sstanovnik Jul 27, 2016
30b7f13
Fix elusive tests.
sstanovnik Jul 27, 2016
7e5b420
Use add numexpr to requirements-core.
sstanovnik Jul 27, 2016
9b94cb1
Use actual values instead of indices when constructing discretes.
sstanovnik Jul 28, 2016
c672319
Merge domain when not rowstacking concatenated tables.
sstanovnik Jul 28, 2016
645e50b
Widget test adaptation and widget fixes.
sstanovnik Jul 28, 2016
ed500db
REVIEWME: 'fixed' displaying SQL tables.
sstanovnik Jul 29, 2016
cd93a3f
Test fixes, remove sql.compat.Value
sstanovnik Jul 29, 2016
0d7ee88
Hopefully fix some strange failing tests.
sstanovnik Jul 29, 2016
5d2f8a7
Remove val_from_str_add.
sstanovnik Jul 29, 2016
430be00
Add to_var_col, a slightly optimized version of to_val.
sstanovnik Jul 29, 2016
a9f63c2
Remove TableBase.DENSE and related indicators.
sstanovnik Jul 29, 2016
e1f708d
Remove PanelBase and SparseTablePanel.
sstanovnik Jul 29, 2016
d17088e
Docstring bonanza!
sstanovnik Aug 1, 2016
265b590
Remove some old, unused, deprecated things from TableBase.
sstanovnik Aug 1, 2016
21bcc56
Remove variable.to_val_col.
sstanovnik Aug 1, 2016
6f0f16e
Documentation slightly updated.
sstanovnik Aug 1, 2016
0bd7160
Increase test coverage, some bugfixes.
sstanovnik Aug 2, 2016
9c2c6ba
Improve distributions, also coverage.
sstanovnik Aug 2, 2016
4f6993b
Increase contingency coverage.
sstanovnik Aug 2, 2016
caa733d
Fix OWHeatmap and its recent tests.
sstanovnik Aug 2, 2016
4843efc
Bump minimum version of pandas above 0.18.0.
sstanovnik Aug 9, 2016
b3031c9
Sparse fixes and improvements.
sstanovnik Aug 9, 2016
411d027
Excel sheet naming.
sstanovnik Aug 9, 2016
7ad4909
A multitude of fixes.
sstanovnik Aug 10, 2016
25c5c2b
A truckload of changes.
sstanovnik Aug 11, 2016
496f808
Remove Table.append.
sstanovnik Aug 11, 2016
4f50571
From list with missing class fixes, indent, lesser __setitem__ breakage.
sstanovnik Aug 11, 2016
96755ab
Remove the many missing-value replaces.
sstanovnik Aug 11, 2016
811e3e9
Prevent multiple calls to __init__.
sstanovnik Aug 11, 2016
8517bf2
Proper finalization and domain filtering.
sstanovnik Aug 12, 2016
41ae304
Custom __str__ and __repr__, needs some work.
sstanovnik Aug 12, 2016
33afcf0
REVIEWME: custom __iter__, iterates over rows, breaks pandas contract.
sstanovnik Aug 12, 2016
dfc1aba
Merge Data fix, new fun TableBase.merge method!
sstanovnik Aug 12, 2016
2e156fa
Fix venn diagram.
sstanovnik Aug 12, 2016
2add840
Fix Data Table.
sstanovnik Aug 12, 2016
ac6539d
Switch inputs from Table to TableBase.
sstanovnik Aug 12, 2016
98c6353
Much better __str__, uses pandas magic.
sstanovnik Aug 16, 2016
2fd14db
Except Orange instead of pandas behaviour in constructors.
sstanovnik Aug 16, 2016
78e9450
Use pure nnumpy ops for transforming discretes into categoricals.
sstanovnik Aug 16, 2016
287b049
Change usages of checksum to hash.
sstanovnik Aug 16, 2016
f2ef9ba
Add a notificatoin comment and test for the iterrows wrapper.
sstanovnik Aug 16, 2016
fc9d867
Remove shuffle in favour of .sample(frac=1).
sstanovnik Aug 16, 2016
b576a7e
Consolidate usages of the _transferer hack.
sstanovnik Aug 16, 2016
d0a03dd
Comments and tests to setUpClass, other test fixes.
sstanovnik Aug 16, 2016
118a8d1
Add time component awareness to TimeVariable.
sstanovnik Aug 17, 2016
a70e2c5
Fix a failing doctest.
sstanovnik Aug 17, 2016
8dbc1c7
Improve time column display with month and day.
sstanovnik Aug 19, 2016
b22e0d8
Add a pandas git build to travis.
sstanovnik Aug 19, 2016
98b745f
Some general fixes, report test fixes.
sstanovnik Aug 19, 2016
50e0989
Requirements.txt requires a different requirement format.
sstanovnik Aug 19, 2016
b561d2f
Further improvements to the documentation.
sstanovnik Aug 19, 2016
27c596f
Revert 68b18c5: overriding __iter__.
sstanovnik Aug 19, 2016
6ea711a
Simplify weight assignment.
sstanovnik Aug 19, 2016
06bcc77
Cherry-pick: sstanovnik/orange3:benches.
sstanovnik Aug 19, 2016
2bfca35
Weight setting robustness.
sstanovnik Aug 21, 2016
6460ab0
Properer sparse handling.
sstanovnik Aug 21, 2016
259bfc1
Always convert weights to floats on assignment.
sstanovnik Aug 26, 2016
ac75022
Fix visualizing continuous variables in Data Table.
sstanovnik Aug 26, 2016
3317ff0
Significantly improve feature constructor performance.
sstanovnik Aug 26, 2016
fc48858
Domain editor fix and file reader hardening.
sstanovnik Aug 26, 2016
3e6030f
Fix a failing owkmeans test.
sstanovnik Aug 26, 2016
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
Prev Previous commit
Next Next commit
Some general fixes, report test fixes.
  • Loading branch information
sstanovnik committed Aug 26, 2016
commit 98b745f19d87ef4e3d931ad46c7c6941f6827231
1 change: 1 addition & 0 deletions Orange/data/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ def header_test3(items):
# there is no header, just read the file
# and pass it to the proper constructor to infer columns
result = Table.from_dataframe(None, self.read_contents(skiprows=0))
result.consolidate(inplace=True)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, after the table is built, call

# Optimize underlying ndarrays
result.consolidate(inplace=True)

# TODO: Name can be set unconditionally when/if
# self.filename will always be a string with the file name.
Expand Down
47 changes: 19 additions & 28 deletions Orange/data/table/base.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import os
import zlib
from collections import Sequence
from threading import Lock
from numbers import Number
from io import StringIO

from itertools import chain
import numpy as np
import scipy.sparse as sp
import pandas as pd
import pandas.core.internals

from Orange.data import Domain, StringVariable, ContinuousVariable, \
DiscreteVariable, Variable, TimeVariable, filter_visible
from Orange.data import Domain, DiscreteVariable, Variable, TimeVariable, filter_visible
from Orange.util import flatten, deprecated


Expand Down Expand Up @@ -538,15 +534,9 @@ def from_list(cls, domain, rows, weights=None):
raise ValueError("Mismatching number of instances and weights.")
# check dimensions, pandas raises a very nondescript error
row_width = len(rows[0])
for r in rows:
if len(r) != row_width:
raise ValueError("Inconsistent number of columns.")

# check row lengths
domain_columns = len(domain.variables) + len(domain.metas)
for r in rows:
if len(r) != domain_columns:
raise ValueError("Data and domain column count mismatch. ")
if row_width != domain_columns or any(len(r) != domain_columns for r in rows):
raise ValueError("Inconsistent number of columns.")

result = cls(data=rows,
columns=[a.name for a in chain(domain.attributes, domain.class_vars, domain.metas)])
Expand Down Expand Up @@ -1054,7 +1044,7 @@ def copy_rename_vars(vars, suffix):
result.domain = tmpdomain # we don't want to transfer the domain, specifically
return cls.from_dataframe(new_domain, result)

def merge(self, right, *args, **kwargs):
def merge(self, right, *args, suffixes=('_left', '_right'), **kwargs):
"""Merge two Tables. pd.DataFrame.merge wrapper.

Handles internal columns and domain merging. Renames duplicates appropriately.
Expand All @@ -1063,8 +1053,12 @@ def merge(self, right, *args, **kwargs):
----------
right : TableBase
The other Table to merge.
args
kwargs
args : tuple
Other pandas.DataFrame.merge arguments.
suffixes : tuple
Overrides the pandas.DataFrame.merge duplicate column suffixes with _left and _right.
kwargs : dict
Other pandas.DataFrame.merge keyword arguments.

Returns
-------
Expand All @@ -1075,11 +1069,8 @@ def merge(self, right, *args, **kwargs):
--------
pd.DataFrame.merge
"""
# rename default suffixes
suffix_left, suffix_right = kwargs.get('suffixes', ('_left', '_right'))
kwargs['suffixes'] = (suffix_left, suffix_right)
# let pandas do its thing
result = super().merge(right, *args, **kwargs)
result = super().merge(right, *args, suffixes=suffixes, **kwargs)

# transfer attrs from self
result.__finalize__(self)
Expand All @@ -1095,7 +1086,7 @@ def merge(self, right, *args, **kwargs):
# process a list of variables, appending suffix if not found in the
# resulting columns (that means it was a dup)
def suffix_dups(varlist, suffix):
return [v if v in result.columns else v.copy(new_name=v.name + suffix) for v in varlist]
return (v if v in result.columns else v.copy(new_name=v.name + suffix) for v in varlist)

# dedup because the target join valriable doesn't get renamed and there is
# only one column, wehile without this, the domain would have two
Expand All @@ -1105,12 +1096,12 @@ def dedup_inorder(varlist):

# merge domain
new_domain = Domain(
dedup_inorder(suffix_dups(self.domain.attributes, suffix_left) +
suffix_dups(right.domain.attributes, suffix_right)),
dedup_inorder(suffix_dups(self.domain.class_vars, suffix_left) +
suffix_dups(right.domain.class_vars, suffix_right)),
dedup_inorder(suffix_dups(self.domain.metas, suffix_left) +
suffix_dups(right.domain.metas, suffix_right))
dedup_inorder(chain(suffix_dups(self.domain.attributes, suffixes[0]),
suffix_dups(right.domain.attributes, suffixes[1]))),
dedup_inorder(chain(suffix_dups(self.domain.class_vars, suffixes[0]),
suffix_dups(right.domain.class_vars, suffixes[1]))),
dedup_inorder(chain(suffix_dups(self.domain.metas, suffixes[0]),
suffix_dups(right.domain.metas, suffixes[1])))
)
result.domain = new_domain

Expand Down Expand Up @@ -1150,7 +1141,7 @@ def iterrows(self):

def __hash__(self):
# TODO: inconsistent when dtype=object
return hash(bytes(self.values))
return hash(bytes(self._to_numpy(X=True, Y=True)))

@deprecated('pandas-style column access: t[["colname1", "colname2"]]')
def get_column_view(self, index):
Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/data/owcolor.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ def was(n, o):
format(name, values)
return rows

if not self.data:
if self.data is None:
return
domain = self.data.domain
orig_domain = self.orig_domain
Expand Down
4 changes: 2 additions & 2 deletions Orange/widgets/data/owimageviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ def clear(self):

def setupScene(self):
self.error()
if self.data:
if self.data is not None:
attr = self.stringAttrs[self.imageAttr]
titleAttr = self.allAttrs[self.titleAttr]
instances = [inst for inst in self.data
Expand Down Expand Up @@ -1090,7 +1090,7 @@ def onSelectionChanged(self):
self.commit()

def commit(self):
if self.data:
if self.data is not None:
if self.selectedIndices:
selected = self.data[self.selectedIndices]
else:
Expand Down
4 changes: 3 additions & 1 deletion Orange/widgets/data/owpaintdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,16 +1003,18 @@ def _check_and_set_data(data):
return

X = np.array([scale(vals) for vals in data.X[:, :2].T]).T
yi = -1
try:
y = next(cls for cls in data.domain.class_vars if cls.is_discrete)
yi += 1
except StopIteration:
if data.domain.class_vars:
self.Warning.continuous_target()
self.input_classes = ["C1"]
y = np.zeros(len(data))
else:
self.input_classes = y.values
y = data[:, y].Y
y = data.Y if data.domain.class_var else data.Y[:, yi]

self.input_has_attr2 = len(data.domain.attributes) >= 2
if not self.input_has_attr2:
Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/data/owpurgedomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def list_opts(opts):
("Features", list_opts(self.feature_options)),
("Classes", list_opts(self.class_options)),
("Metas", list_opts(self.meta_options))))
if self.data:
if self.data is not None:
self.report_items("Statistics", (
(label, getattr(self, value))
for label, value in self.stat_labels
Expand Down
4 changes: 2 additions & 2 deletions Orange/widgets/data/owrank.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ def updateDelegates(self):
)

def send_report(self):
if not self.data:
if self.data is None:
return
self.report_domain("Input", self.data.domain)
self.report_table("Ranks", self.ranksView, num_format="{:.3f}")
Expand Down Expand Up @@ -542,7 +542,7 @@ def create_scores_table(self, labels):
# Reshape to 2d array as Table does not like 1d arrays
feature_names = feature_names[:, None]

table = Orange.data.Table(domain, scores, metas=feature_names)
table = Orange.data.Table(domain, scores, None, feature_names)
table.name = "Feature Scores"
return table

Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/data/owselectcolumns.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ def reset(self):
self.update_domain_role_hints()

def send_report(self):
if not self.data or not self.output_data:
if self.data is None or self.output_data is None:
return
in_domain, out_domain = self.data.domain, self.output_data.domain
self.report_domain("Input data", self.data.domain)
Expand Down
4 changes: 2 additions & 2 deletions Orange/widgets/data/owselectrows.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def add_datetime(contents):
self.cond_list.setCellWidget(oper_combo.row, 2, button)
else:
combo = QtGui.QComboBox()
combo.addItems([""] + var.values)
combo.addItems([""] + [str(v) for v in var.values])
if lc[0]:
combo.setCurrentIndex(int(var.to_val(lc[0])))
else:
Expand Down Expand Up @@ -455,7 +455,7 @@ def sp(s, capitalize=True):
sp(len(data.domain.variables) + len(data.domain.metas))))

def send_report(self):
if not self.data:
if self.data is None:
self.report_paragraph("No data.")
return

Expand Down
20 changes: 0 additions & 20 deletions Orange/widgets/data/tests/test_owmergedata.py

This file was deleted.

2 changes: 1 addition & 1 deletion Orange/widgets/evaluate/owtestlearners.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ def commit(self):

def send_report(self):
"""Report on the testing schema and results"""
if not self.data or not self.learners:
if self.data is None or not self.learners:
return
if self.resampling == self.KFold:
stratified = 'Stratified ' if self.cv_stratified else ''
Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/unsupervised/owcorrespondence.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def _setup_plot(self):
self.plot.addItem(item)

for name, point in zip(v.values, points):
item = pg.TextItem(name, anchor=(0.5, 0))
item = pg.TextItem(str(name), anchor=(0.5, 0))
self.plot.addItem(item)
item.setPos(point[0], point[1])

Expand Down
3 changes: 1 addition & 2 deletions Orange/widgets/unsupervised/owpca.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,7 @@ def commit(self):
metas = numpy.array([['PC{}'.format(i + 1)
for i in range(self.ncomponents)]],
dtype=object).T
components = Table(dom, self._pca.components_[:self.ncomponents],
metas=metas)
components = Table(dom, self._pca.components_[:self.ncomponents], None, metas)
components.name = 'components'

self._pca_projector.component = self.ncomponents
Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/utils/owlearnerwidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def send_report(self):
if model_parameters:
self.report_items("Model parameters", model_parameters)

if self.data:
if self.data is not None:
self.report_data("Data", self.data)

# GUI
Expand Down
2 changes: 1 addition & 1 deletion Orange/widgets/visualize/owboxplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ def strudel(self, dist):
else:
tooltip = "{}: {}".format(attr.values[i], int(dist[i]))
rect.setToolTip(tooltip)
text = QtGui.QGraphicsTextItem(attr.values[i])
text = QtGui.QGraphicsTextItem(str(attr.values[i]))
box.addToGroup(text)
cum += v
return box
Expand Down
6 changes: 3 additions & 3 deletions Orange/widgets/visualize/owdistributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def display_contingency(self):
scvar = cont.sum(axis=1)
#a cvar with sum=0 with allways have distribution counts 0,
#therefore we can divide it by anything
scvar[scvar==0] = 1
scvar[scvar == 0] = 1
for i, (value, dist) in enumerate(zip(var.values, cont.T)):
maxh = max(maxh, max(dist))
maxrh = max(maxrh, max(dist/scvar))
Expand All @@ -484,9 +484,9 @@ def display_contingency(self):
else dist/maxh, colors)
self.plot.addItem(item)
tooltip = "\n".join("%s: %.*f" % (n, 3 if self.relative_freq else 1, v)
for n,v in zip(cvar_values, dist/scvar if self.relative_freq else dist ))
for n,v in zip(cvar_values, dist/scvar if self.relative_freq else dist))
item.tooltip = ("Normalized frequency " if self.relative_freq else "Frequency ") \
+ "(" + cvar.name + "=" + value + "):" \
+ "(" + cvar.name + "=" + str(value) + "):" \
+ "\n" + tooltip
self.tooltip_items.append((self.plot, item))

Expand Down
8 changes: 4 additions & 4 deletions Orange/widgets/visualize/owsieve.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def update_graph(self):
"""Update the graph."""

def text(txt, *args, **kwargs):
return CanvasText(self.canvas, "", html_text=to_html(txt),
return CanvasText(self.canvas, "", html_text=to_html(str(txt)),
*args, **kwargs)

def width(txt):
Expand Down Expand Up @@ -359,15 +359,15 @@ def _oper(attr_name, txt):
"<b>{attrX}{xeq}{xval_name}</b>: {obs_x}/{n} ({p_x:.0f} %)".
format(attrX=to_html(attr_x),
xeq=_oper(attr_x, xval_name),
xval_name=to_html(xval_name),
xval_name=to_html(str(xval_name)),
obs_x=fmt(chi.probs_x[x] * n),
n=int(n),
p_x=100 * chi.probs_x[x]) +
"<br/>" +
"<b>{attrY}{yeq}{yval_name}</b>: {obs_y}/{n} ({p_y:.0f} %)".
format(attrY=to_html(attr_y),
yeq=_oper(attr_y, yval_name),
yval_name=to_html(yval_name),
yval_name=to_html(str(yval_name)),
obs_y=fmt(chi.probs_y[y] * n),
n=int(n),
p_y=100 * chi.probs_y[y]) +
Expand All @@ -393,7 +393,7 @@ def _oper(attr_name, txt):

chi = ChiSqStats(self.discrete_data, attr_x, attr_y)
n = chi.n
max_ylabel_w = max((width(val) for val in disc_y.values), default=0)
max_ylabel_w = max((width(str(val)) for val in disc_y.values), default=0)
max_ylabel_w = min(max_ylabel_w, 200)
x_off = width(attr_x) + max_ylabel_w
y_off = 15
Expand Down