Skip to content

Commit 54e518c

Browse files
authored
Merge pull request #124 from Carifio24/dot-size-update
Update dotplot size calculation
2 parents 860134f + 46397c0 commit 54e518c

File tree

3 files changed

+102
-11
lines changed

3 files changed

+102
-11
lines changed

glue_plotly/common/dotplot.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,27 @@
55

66
from glue.core import BaseData
77

8-
from .common import color_info, dimensions
8+
from glue_plotly.common import color_info, dimensions
9+
from glue_plotly.viewers.common import PlotlyBaseView
910

1011

11-
def dot_radius(viewer, layer_state):
12+
def dot_size(viewer, layer_state):
1213
edges = layer_state.histogram[0]
1314
viewer_state = viewer.state
1415
diam_world = min([edges[i + 1] - edges[i] for i in range(len(edges) - 1)])
1516
width, height = dimensions(viewer)
17+
if isinstance(viewer, PlotlyBaseView):
18+
margins = viewer.figure.layout.margin
19+
if margins:
20+
height -= (margins.b + margins.t)
21+
width -= (margins.l + margins.r)
1622
diam = diam_world * width / abs(viewer_state.x_max - viewer_state.x_min)
1723
if viewer_state.y_min is not None and viewer_state.y_max is not None and viewer_state.y_min != viewer_state.y_max:
18-
max_diam_world_v = 1
19-
diam_pixel_v = max_diam_world_v * height / abs(viewer_state.y_max - viewer_state.y_min)
24+
diam_pixel_v = height / abs(viewer_state.y_max - viewer_state.y_min)
2025
diam = min(diam_pixel_v, diam)
2126
if not isfinite(diam):
2227
diam = 1
23-
return diam / 2
28+
return diam * 0.95
2429

2530

2631
def dot_positions(layer_state):
@@ -43,7 +48,7 @@ def dots_for_layer(viewer, layer_state, add_data_label=True):
4348

4449
x, y = dot_positions(layer_state)
4550

46-
radius = dot_radius(viewer, layer_state)
51+
radius = dot_size(viewer, layer_state)
4752
marker = dict(color=color_info(layer_state, mask=None), size=radius)
4853

4954
name = layer_state.layer.label

glue_plotly/common/tests/test_dotplot.py

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from glue_jupyter import JupyterApplication
12
from numpy import unique
23
from plotly.graph_objs import Scatter
34

@@ -6,7 +7,7 @@
67
from glue_qt.viewers.histogram import HistogramViewer
78

89
from glue_plotly.common import sanitize
9-
from glue_plotly.common.dotplot import dot_radius, traces_for_layer
10+
from glue_plotly.common.dotplot import dot_size, traces_for_layer
1011

1112
from glue_plotly.viewers.histogram.viewer import PlotlyHistogramView
1213
from glue_plotly.viewers.histogram.dotplot_layer_artist import PlotlyDotplotLayerArtist
@@ -16,9 +17,89 @@ class SimpleDotplotViewer(PlotlyHistogramView):
1617
_data_artist_cls = PlotlyDotplotLayerArtist
1718
_subset_artist_cls = PlotlyDotplotLayerArtist
1819

20+
def close(self, warn=False):
21+
self.figure.close()
22+
1923

2024
class TestDotplot:
2125

26+
def setup_method(self, method):
27+
x = [86, 86, 76, 78, 93, 100, 90, 87, 73, 61, 71, 68, 78,
28+
9, 87, 32, 34, 2, 57, 79, 48, 5, 8, 19, 7, 78,
29+
16, 15, 58, 34, 20, 63, 96, 97, 86, 92, 35, 59, 75,
30+
0, 53, 45, 59, 74, 59, 4, 69, 76, 97, 77, 24, 99,
31+
50, 6, 1, 55, 13, 40, 27, 17, 92, 72, 40, 29, 64,
32+
38, 77, 11, 91, 23, 59, 92, 5, 88, 15, 90, 40, 100,
33+
47, 28, 3, 44, 89, 75, 13, 94, 95, 43, 17, 88, 6,
34+
94, 100, 28, 45, 36, 63, 14, 90, 66]
35+
self.data = Data(label="dotplot", x=x)
36+
self.app = JupyterApplication()
37+
self.app.session.data_collection.append(self.data)
38+
self.viewer = self.app.new_data_viewer(SimpleDotplotViewer)
39+
self.viewer.add_data(self.data)
40+
self.mask, self.sanitized = sanitize(self.data['x'])
41+
42+
viewer_state = self.viewer.state
43+
viewer_state.hist_n_bin = 18
44+
viewer_state.x_axislabel_size = 14
45+
viewer_state.y_axislabel_size = 8
46+
viewer_state.x_ticklabel_size = 18
47+
viewer_state.y_ticklabel_size = 20
48+
viewer_state.x_min = 0
49+
viewer_state.x_max = 100
50+
viewer_state.y_min = 0
51+
viewer_state.y_max = 15
52+
viewer_state.x_axislabel = 'X Axis'
53+
viewer_state.y_axislabel = 'Y Axis'
54+
55+
self.layer = self.viewer.layers[0]
56+
self.layer.state.color = '#0e1dab'
57+
self.layer.state.alpha = 0.85
58+
59+
def teardown_method(self, method):
60+
self.viewer.close(warn=False)
61+
self.viewer = None
62+
self.app = None
63+
64+
def test_basic_dots(self):
65+
traces = traces_for_layer(self.viewer, self.layer.state)
66+
assert len(traces) == 1
67+
dots = traces[0]
68+
assert isinstance(dots, Scatter)
69+
70+
assert len(unique(dots.x)) == 18
71+
expected_y = (1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 1,
72+
2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, 3, 1, 2,
73+
3, 4, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2,
74+
3, 4, 5, 1, 2, 1, 2, 3, 4, 5, 6, 7, 1, 2,
75+
3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8,
76+
1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3,
77+
4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5,
78+
6, 7, 8)
79+
80+
assert dots.y == expected_y
81+
82+
# Default figure is 900x600, with margins of 50 on each side
83+
width = 900 - 50 - 50
84+
height = 600 - 50 - 50
85+
diam = 0.95 * min(height / 15, width / 18)
86+
assert dots.marker.size == diam
87+
88+
def test_dot_radius_defined(self):
89+
"""
90+
This test makes sure that we correctly get the default value for the dot radius
91+
when both axes have no range.
92+
"""
93+
self.viewer.state.x_min = 1
94+
self.viewer.state.x_max = 1
95+
self.viewer.state.y_min = 1
96+
self.viewer.state.y_max = 1
97+
98+
assert dot_size(self.viewer, self.layer.state) == 0.95
99+
100+
101+
class TestDotsHistogram:
102+
22103
def setup_method(self, method):
23104
x = [86, 86, 76, 78, 93, 100, 90, 87, 73, 61, 71, 68, 78,
24105
9, 87, 32, 34, 2, 57, 79, 48, 5, 8, 19, 7, 78,
@@ -75,7 +156,12 @@ def test_basic_dots(self):
75156
6, 7, 8)
76157

77158
assert dots.y == expected_y
78-
assert dots.marker.size == 16 # Default figure is 640x480
159+
160+
# Default figure is 640x480
161+
width = 640
162+
height = 480
163+
diam = 0.95 * min(height / 15, width / 18)
164+
assert dots.marker.size == diam
79165

80166
def test_dot_radius_defined(self):
81167
"""
@@ -87,4 +173,4 @@ def test_dot_radius_defined(self):
87173
self.viewer.state.y_min = 1
88174
self.viewer.state.y_max = 1
89175

90-
assert dot_radius(self.viewer, self.layer.state) == 0.5
176+
assert dot_size(self.viewer, self.layer.state) == 0.95

glue_plotly/viewers/histogram/dotplot_layer_artist.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from glue.viewers.histogram.state import HistogramLayerState
1010
from glue_plotly.common.common import fixed_color
1111

12-
from glue_plotly.common.dotplot import dot_positions, dot_radius, dots_for_layer
12+
from glue_plotly.common.dotplot import dot_positions, dot_size, dots_for_layer
1313

1414
__all__ = ["PlotlyDotplotLayerArtist"]
1515

@@ -123,7 +123,7 @@ def _update_visual_attributes(self, changed, force=False):
123123

124124
def _update_visual_attrs_for_trace(self, trace):
125125
marker = trace.marker
126-
marker.update(opacity=self.state.alpha, color=fixed_color(self.state), size=dot_radius(self.view, self.state))
126+
marker.update(opacity=self.state.alpha, color=fixed_color(self.state), size=dot_size(self.view, self.state))
127127
trace.update(marker=marker,
128128
visible=self.state.visible,
129129
unselected=dict(marker=dict(opacity=self.state.alpha)))

0 commit comments

Comments
 (0)