Skip to content

Commit ec64ed7

Browse files
committed
fix issue #10. Made some fix on multiple_xaxis option.
1 parent 86169f1 commit ec64ed7

File tree

7 files changed

+109
-167
lines changed

7 files changed

+109
-167
lines changed

example_basic/graph_widget.py

+14-25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from matplotlib.backends.backend_agg import FigureCanvasAgg
1717
from matplotlib.transforms import Bbox
1818
from kivy.metrics import dp
19+
import numpy as np
1920

2021
class MatplotFigure(Widget):
2122
"""Widget to show a matplotlib figure in kivy.
@@ -142,13 +143,12 @@ def hover(self, event) -> None:
142143

143144
#transform kivy x,y touch event to x,y data
144145
trans = self.axes.transData.inverted()
145-
xdata, ydata = trans.transform_point((event.x, event.y))
146+
xdata, ydata = trans.transform_point((event.x - self.pos[0], event.y - self.pos[1]))
146147

147148
#loop all register lines and find closest x,y data for each valid line
148149
distance=[]
149150
good_line=[]
150151
good_index=[]
151-
good_index2=[]
152152
for line in self.lines:
153153
#get only visible lines
154154
if line.get_visible():
@@ -157,19 +157,13 @@ def hover(self, event) -> None:
157157

158158
#check if line is not empty
159159
if len(self.x_cursor)!=0:
160-
#!!!! if numpy is available you can used this for faster results !!!!
161-
#case 1 : x are sorted
162-
#index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
163-
#case 2: x are not sorted
164-
#index = np.argsort(abs(self.x_cursor - xdata))[0]
165160

166161
#find closest data index from touch (x axis)
167162
if self.xsorted:
168-
index = sorted(range(len(abs(self.x_cursor - xdata))),
169-
key=abs(self.x_cursor - xdata).__getitem__)[0]
163+
index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
164+
170165
else:
171-
index = sorted(range(len(abs(self.x_cursor - xdata))),
172-
key=abs(self.x_cursor - xdata).__getitem__)[0]
166+
index = np.argsort(abs(self.x_cursor - xdata))[0]
173167

174168
#get x data from index
175169
x = self.x_cursor[index]
@@ -180,9 +174,7 @@ def hover(self, event) -> None:
180174
#get distance between line and touch (in pixels)
181175
ax=line.axes
182176
#left axis
183-
# xy_pixels_mouse = ax.transData.transform(np.vstack([xdata,ydata]).T)
184177
xy_pixels_mouse = ax.transData.transform([(xdata,ydata)])
185-
# xy_pixels = ax.transData.transform(np.vstack([x,y]).T)
186178
xy_pixels = ax.transData.transform([(x,y)])
187179
dx2 = (xy_pixels_mouse[0][0]-xy_pixels[0][0])**2
188180
dy2 = (xy_pixels_mouse[0][1]-xy_pixels[0][1])**2
@@ -201,11 +193,8 @@ def hover(self, event) -> None:
201193
#if minimum distance if lower than 50 pixels, get line datas with
202194
#minimum distance
203195
if min(distance)<dp(50):
204-
#!!! if numpy is available, argmin can be used form faster result !!!
205-
#idx_best=np.argmin(distance)
206-
207196
#index of minimum distance
208-
idx_best=distance.index(min(distance))
197+
idx_best=np.argmin(distance)
209198

210199
#get datas from closest line
211200
line=good_line[idx_best]
@@ -608,8 +597,8 @@ def reset_box(self):
608597
""" reset zoombox and apply zoombox limit if zoombox option if selected"""
609598
if min(abs(self._box_size[0]),abs(self._box_size[1]))>self.minzoom:
610599
trans = self.axes.transData.inverted()
611-
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0], self._box_pos[1]-self.pos[1]))
612-
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
600+
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0]-self.pos[0], self._box_pos[1]-self.pos[1]))
601+
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0]-self.pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
613602
self.do_update=True
614603

615604
self._box_size = 0, 0
@@ -646,26 +635,26 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
646635
self._alpha_rect=0
647636

648637
trans = self.axes.transData.inverted()
649-
xdata, ydata = trans.transform_point((event.x, event.y-pos_y))
638+
xdata, ydata = trans.transform_point((event.x-pos_x, event.y-pos_y))
650639

651640
xmin,xmax=self.axes.get_xlim()
652641
ymin,ymax=self.axes.get_ylim()
653642

654-
x0data, y0data = trans.transform_point((x0, y0-pos_y))
643+
x0data, y0data = trans.transform_point((x0-pos_x, y0-pos_y))
655644
if x0data>xmax or x0data<xmin or y0data>ymax or y0data<ymin:
656645
return
657646

658647
if xdata<xmin:
659648
x1_min = self.axes.transData.transform([(xmin,ymin)])
660649
if x1<x0:
661-
x1=x1_min[0][0]
650+
x1=x1_min[0][0]+pos_x
662651
else:
663652
x0=x1_min[0][0]
664653

665654
if xdata>xmax:
666655
x0_max = self.axes.transData.transform([(xmax,ymin)])
667656
if x1>x0:
668-
x1=x0_max[0][0]
657+
x1=x0_max[0][0]+pos_x
669658
else:
670659
x0=x0_max[0][0]
671660

@@ -688,10 +677,10 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
688677
self.pos_y_rect_ver=y0
689678

690679
x1_min = self.axes.transData.transform([(xmin,ymin)])
691-
x0=x1_min[0][0]
680+
x0=x1_min[0][0]+pos_x
692681

693682
x0_max = self.axes.transData.transform([(xmax,ymin)])
694-
x1=x0_max[0][0]
683+
x1=x0_max[0][0]+pos_x
695684

696685
self._alpha_ver=1
697686

example_big_data/graph_widget.py

+14-25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from matplotlib.backends.backend_agg import FigureCanvasAgg
1717
from matplotlib.transforms import Bbox
1818
from kivy.metrics import dp
19+
import numpy as np
1920

2021
class MatplotFigure(Widget):
2122
"""Widget to show a matplotlib figure in kivy.
@@ -142,13 +143,12 @@ def hover(self, event) -> None:
142143

143144
#transform kivy x,y touch event to x,y data
144145
trans = self.axes.transData.inverted()
145-
xdata, ydata = trans.transform_point((event.x, event.y))
146+
xdata, ydata = trans.transform_point((event.x - self.pos[0], event.y - self.pos[1]))
146147

147148
#loop all register lines and find closest x,y data for each valid line
148149
distance=[]
149150
good_line=[]
150151
good_index=[]
151-
good_index2=[]
152152
for line in self.lines:
153153
#get only visible lines
154154
if line.get_visible():
@@ -157,19 +157,13 @@ def hover(self, event) -> None:
157157

158158
#check if line is not empty
159159
if len(self.x_cursor)!=0:
160-
#!!!! if numpy is available you can used this for faster results !!!!
161-
#case 1 : x are sorted
162-
#index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
163-
#case 2: x are not sorted
164-
#index = np.argsort(abs(self.x_cursor - xdata))[0]
165160

166161
#find closest data index from touch (x axis)
167162
if self.xsorted:
168-
index = sorted(range(len(abs(self.x_cursor - xdata))),
169-
key=abs(self.x_cursor - xdata).__getitem__)[0]
163+
index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
164+
170165
else:
171-
index = sorted(range(len(abs(self.x_cursor - xdata))),
172-
key=abs(self.x_cursor - xdata).__getitem__)[0]
166+
index = np.argsort(abs(self.x_cursor - xdata))[0]
173167

174168
#get x data from index
175169
x = self.x_cursor[index]
@@ -180,9 +174,7 @@ def hover(self, event) -> None:
180174
#get distance between line and touch (in pixels)
181175
ax=line.axes
182176
#left axis
183-
# xy_pixels_mouse = ax.transData.transform(np.vstack([xdata,ydata]).T)
184177
xy_pixels_mouse = ax.transData.transform([(xdata,ydata)])
185-
# xy_pixels = ax.transData.transform(np.vstack([x,y]).T)
186178
xy_pixels = ax.transData.transform([(x,y)])
187179
dx2 = (xy_pixels_mouse[0][0]-xy_pixels[0][0])**2
188180
dy2 = (xy_pixels_mouse[0][1]-xy_pixels[0][1])**2
@@ -201,11 +193,8 @@ def hover(self, event) -> None:
201193
#if minimum distance if lower than 50 pixels, get line datas with
202194
#minimum distance
203195
if min(distance)<dp(50):
204-
#!!! if numpy is available, argmin can be used form faster result !!!
205-
#idx_best=np.argmin(distance)
206-
207196
#index of minimum distance
208-
idx_best=distance.index(min(distance))
197+
idx_best=np.argmin(distance)
209198

210199
#get datas from closest line
211200
line=good_line[idx_best]
@@ -608,8 +597,8 @@ def reset_box(self):
608597
""" reset zoombox and apply zoombox limit if zoombox option if selected"""
609598
if min(abs(self._box_size[0]),abs(self._box_size[1]))>self.minzoom:
610599
trans = self.axes.transData.inverted()
611-
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0], self._box_pos[1]-self.pos[1]))
612-
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
600+
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0]-self.pos[0], self._box_pos[1]-self.pos[1]))
601+
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0]-self.pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
613602
self.do_update=True
614603

615604
self._box_size = 0, 0
@@ -646,26 +635,26 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
646635
self._alpha_rect=0
647636

648637
trans = self.axes.transData.inverted()
649-
xdata, ydata = trans.transform_point((event.x, event.y-pos_y))
638+
xdata, ydata = trans.transform_point((event.x-pos_x, event.y-pos_y))
650639

651640
xmin,xmax=self.axes.get_xlim()
652641
ymin,ymax=self.axes.get_ylim()
653642

654-
x0data, y0data = trans.transform_point((x0, y0-pos_y))
643+
x0data, y0data = trans.transform_point((x0-pos_x, y0-pos_y))
655644
if x0data>xmax or x0data<xmin or y0data>ymax or y0data<ymin:
656645
return
657646

658647
if xdata<xmin:
659648
x1_min = self.axes.transData.transform([(xmin,ymin)])
660649
if x1<x0:
661-
x1=x1_min[0][0]
650+
x1=x1_min[0][0]+pos_x
662651
else:
663652
x0=x1_min[0][0]
664653

665654
if xdata>xmax:
666655
x0_max = self.axes.transData.transform([(xmax,ymin)])
667656
if x1>x0:
668-
x1=x0_max[0][0]
657+
x1=x0_max[0][0]+pos_x
669658
else:
670659
x0=x0_max[0][0]
671660

@@ -688,10 +677,10 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
688677
self.pos_y_rect_ver=y0
689678

690679
x1_min = self.axes.transData.transform([(xmin,ymin)])
691-
x0=x1_min[0][0]
680+
x0=x1_min[0][0]+pos_x
692681

693682
x0_max = self.axes.transData.transform([(xmax,ymin)])
694-
x1=x0_max[0][0]
683+
x1=x0_max[0][0]+pos_x
695684

696685
self._alpha_ver=1
697686

example_cursor/graph_widget.py

+14-25
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from matplotlib.backends.backend_agg import FigureCanvasAgg
1717
from matplotlib.transforms import Bbox
1818
from kivy.metrics import dp
19+
import numpy as np
1920

2021
class MatplotFigure(Widget):
2122
"""Widget to show a matplotlib figure in kivy.
@@ -142,13 +143,12 @@ def hover(self, event) -> None:
142143

143144
#transform kivy x,y touch event to x,y data
144145
trans = self.axes.transData.inverted()
145-
xdata, ydata = trans.transform_point((event.x, event.y))
146+
xdata, ydata = trans.transform_point((event.x - self.pos[0], event.y - self.pos[1]))
146147

147148
#loop all register lines and find closest x,y data for each valid line
148149
distance=[]
149150
good_line=[]
150151
good_index=[]
151-
good_index2=[]
152152
for line in self.lines:
153153
#get only visible lines
154154
if line.get_visible():
@@ -157,19 +157,13 @@ def hover(self, event) -> None:
157157

158158
#check if line is not empty
159159
if len(self.x_cursor)!=0:
160-
#!!!! if numpy is available you can used this for faster results !!!!
161-
#case 1 : x are sorted
162-
#index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
163-
#case 2: x are not sorted
164-
#index = np.argsort(abs(self.x_cursor - xdata))[0]
165160

166161
#find closest data index from touch (x axis)
167162
if self.xsorted:
168-
index = sorted(range(len(abs(self.x_cursor - xdata))),
169-
key=abs(self.x_cursor - xdata).__getitem__)[0]
163+
index = min(np.searchsorted(self.x_cursor, xdata), len(self.y_cursor) - 1)
164+
170165
else:
171-
index = sorted(range(len(abs(self.x_cursor - xdata))),
172-
key=abs(self.x_cursor - xdata).__getitem__)[0]
166+
index = np.argsort(abs(self.x_cursor - xdata))[0]
173167

174168
#get x data from index
175169
x = self.x_cursor[index]
@@ -180,9 +174,7 @@ def hover(self, event) -> None:
180174
#get distance between line and touch (in pixels)
181175
ax=line.axes
182176
#left axis
183-
# xy_pixels_mouse = ax.transData.transform(np.vstack([xdata,ydata]).T)
184177
xy_pixels_mouse = ax.transData.transform([(xdata,ydata)])
185-
# xy_pixels = ax.transData.transform(np.vstack([x,y]).T)
186178
xy_pixels = ax.transData.transform([(x,y)])
187179
dx2 = (xy_pixels_mouse[0][0]-xy_pixels[0][0])**2
188180
dy2 = (xy_pixels_mouse[0][1]-xy_pixels[0][1])**2
@@ -201,11 +193,8 @@ def hover(self, event) -> None:
201193
#if minimum distance if lower than 50 pixels, get line datas with
202194
#minimum distance
203195
if min(distance)<dp(50):
204-
#!!! if numpy is available, argmin can be used form faster result !!!
205-
#idx_best=np.argmin(distance)
206-
207196
#index of minimum distance
208-
idx_best=distance.index(min(distance))
197+
idx_best=np.argmin(distance)
209198

210199
#get datas from closest line
211200
line=good_line[idx_best]
@@ -608,8 +597,8 @@ def reset_box(self):
608597
""" reset zoombox and apply zoombox limit if zoombox option if selected"""
609598
if min(abs(self._box_size[0]),abs(self._box_size[1]))>self.minzoom:
610599
trans = self.axes.transData.inverted()
611-
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0], self._box_pos[1]-self.pos[1]))
612-
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
600+
self.x0_box, self.y0_box = trans.transform_point((self._box_pos[0]-self.pos[0], self._box_pos[1]-self.pos[1]))
601+
self.x1_box, self.y1_box = trans.transform_point((self._box_size[0]+self._box_pos[0]-self.pos[0], self._box_size[1]+self._box_pos[1]-self.pos[1]))
613602
self.do_update=True
614603

615604
self._box_size = 0, 0
@@ -646,26 +635,26 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
646635
self._alpha_rect=0
647636

648637
trans = self.axes.transData.inverted()
649-
xdata, ydata = trans.transform_point((event.x, event.y-pos_y))
638+
xdata, ydata = trans.transform_point((event.x-pos_x, event.y-pos_y))
650639

651640
xmin,xmax=self.axes.get_xlim()
652641
ymin,ymax=self.axes.get_ylim()
653642

654-
x0data, y0data = trans.transform_point((x0, y0-pos_y))
643+
x0data, y0data = trans.transform_point((x0-pos_x, y0-pos_y))
655644
if x0data>xmax or x0data<xmin or y0data>ymax or y0data<ymin:
656645
return
657646

658647
if xdata<xmin:
659648
x1_min = self.axes.transData.transform([(xmin,ymin)])
660649
if x1<x0:
661-
x1=x1_min[0][0]
650+
x1=x1_min[0][0]+pos_x
662651
else:
663652
x0=x1_min[0][0]
664653

665654
if xdata>xmax:
666655
x0_max = self.axes.transData.transform([(xmax,ymin)])
667656
if x1>x0:
668-
x1=x0_max[0][0]
657+
x1=x0_max[0][0]+pos_x
669658
else:
670659
x0=x0_max[0][0]
671660

@@ -688,10 +677,10 @@ def draw_box(self, event, x0, y0, x1, y1) -> None:
688677
self.pos_y_rect_ver=y0
689678

690679
x1_min = self.axes.transData.transform([(xmin,ymin)])
691-
x0=x1_min[0][0]
680+
x0=x1_min[0][0]+pos_x
692681

693682
x0_max = self.axes.transData.transform([(xmax,ymin)])
694-
x1=x0_max[0][0]
683+
x1=x0_max[0][0]+pos_x
695684

696685
self._alpha_ver=1
697686

0 commit comments

Comments
 (0)