@@ -13,6 +13,10 @@ def __init__(
1313 offset_top : float = 0.0 ,
1414 offset_bottom : float = 0.0 ,
1515 fixed_range : Optional [List [float ]] = None ,
16+ x_min_range_width : Optional [float ] = None ,
17+ x_range_limit : Optional [List [float ]] = None ,
18+ y_min_range_width : Optional [float ] = None ,
19+ y_range_limit : Optional [List [float ]] = None ,
1620 ) -> None :
1721 self .roll_on_tick = roll_on_tick
1822 self .offset_left = offset_left
@@ -24,6 +28,10 @@ def __init__(
2428 self .crop_top_offset_to_data = False
2529 self .crop_bottom_offset_to_data = False
2630 self .fixed_range = fixed_range
31+ self .x_min_range_width = x_min_range_width
32+ self .x_range_limit = x_range_limit
33+ self .y_min_range_width = y_min_range_width
34+ self .y_range_limit = y_range_limit
2735 self .x_range : Dict [str , List [float ]] = {}
2836 self .y_range : Dict [str , List [float ]] = {}
2937 self .final_x_range = [0.0 , 0.0 ]
@@ -65,11 +73,12 @@ def get_x_range(self, data_connector, tick: int) -> List[float]:
6573 final_range [0 ] = x_range [0 ]
6674 if final_range [1 ] < x_range [1 ]:
6775 final_range [1 ] = x_range [1 ]
68- if final_range [0 ] == final_range [1 ]:
76+ if final_range [0 ] == final_range [1 ] and self . x_min_range_width is not None :
6977 # Pyqtgraph ViewBox.setRange doesn't like same value for min and max,
7078 # therefore in that case we must set some range
7179 final_range [0 ] -= 0.4
7280 final_range [1 ] += 0.4
81+ final_range = self ._update_range_width (self .x_range_limit , self .x_min_range_width , final_range )
7382 if self .final_x_range != final_range :
7483 self .final_x_range = final_range
7584 return self .final_x_range
@@ -88,11 +97,12 @@ def recalculate_x_range(self):
8897 final_range [1 ] = x_range [1 ]
8998 if final_range is None :
9099 final_range = [0 , 0 ]
91- if final_range [0 ] == final_range [1 ]:
100+ if final_range [0 ] == final_range [1 ] and self . x_min_range_width is not None :
92101 # Pyqtgraph ViewBox.setRange doesn't like same value for min and max,
93102 # therefore in that case we must set some range
94103 final_range [0 ] -= 0.4
95104 final_range [1 ] += 0.4
105+ final_range = self ._update_range_width (self .x_range_limit , self .x_min_range_width , final_range )
96106 if self .final_x_range != final_range :
97107 self .final_x_range = final_range
98108 return self .final_x_range
@@ -132,11 +142,12 @@ def get_y_range(self, data_connector, tick: int) -> List[float]:
132142 final_range [0 ] = y_range [0 ]
133143 if final_range [1 ] < y_range [1 ]:
134144 final_range [1 ] = y_range [1 ]
135- if final_range [0 ] == final_range [1 ]:
145+ if final_range [0 ] == final_range [1 ] and self . y_min_range_width is None :
136146 # Pyqtgraph ViewBox.setRange doesn't like same value for min and max,
137147 # therefore in that case we must set some range
138148 final_range [0 ] -= 0.4
139149 final_range [1 ] += 0.4
150+ final_range = self ._update_range_width (self .y_range_limit , self .y_min_range_width , final_range )
140151 if self .final_y_range != final_range :
141152 self .final_y_range = final_range
142153 return self .final_y_range
@@ -155,11 +166,12 @@ def recalculate_y_range(self):
155166 final_range [1 ] = y_range [1 ]
156167 if final_range is None :
157168 final_range = [0 , 0 ]
158- if final_range [0 ] == final_range [1 ]:
169+ if final_range [0 ] == final_range [1 ] and self . y_min_range_width is None :
159170 # Pyqtgraph ViewBox.setRange doesn't like same value for min and max,
160171 # therefore in that case we must set some range
161172 final_range [0 ] -= 0.4
162173 final_range [1 ] += 0.4
174+ final_range = self ._update_range_width (self .y_range_limit , self .y_min_range_width , final_range )
163175 if self .final_y_range != final_range :
164176 self .final_y_range = final_range
165177 return self .final_y_range
@@ -199,6 +211,25 @@ def _get_range(
199211 else :
200212 return None
201213
214+ def _update_range_width (self , bound , range_width , final_range ):
215+ if range_width is not None :
216+ if abs (final_range [0 ] - final_range [1 ]) < range_width :
217+ center_pt = (final_range [0 ] + final_range [1 ]) / 2
218+ final_range [0 ] = center_pt - range_width / 2
219+ final_range [1 ] = center_pt + range_width / 2
220+
221+ if bound is not None :
222+ final_range_width = abs (final_range [0 ] - final_range [1 ])
223+ if (bound [0 ] > final_range [1 ] and bound [0 ] > final_range [0 ]) or \
224+ (bound [1 ] < final_range [1 ] and bound [0 ] < final_range [0 ]) or \
225+ (bound [0 ] > final_range [0 ] and bound [1 ] < final_range [1 ]):
226+ final_range = bound
227+ elif bound [1 ] > final_range [0 ] and final_range [0 ] > bound [0 ]:
228+ final_range = [max (bound [1 ] - final_range_width , bound [0 ]), bound [1 ]]
229+ elif bound [0 ] < final_range [1 ] and final_range [1 ] < bound [1 ]:
230+ final_range = [bound [0 ], min (bound [0 ] + final_range_width , bound [1 ])]
231+ return final_range
232+
202233 def ignore_connector (self , data_connector , flag : bool ) -> None :
203234 if not flag :
204235 self .ignored_data_connectors .append (data_connector .__hash__ ())
0 commit comments