def ticks_pyx(tick_pos_list, ticklevel, axis_min, axis_max, exclude_list=[]): ticks_pyx_out = [] tick_prev_x = None for tick in tick_pos_list: exclude = False if gp_math.islessthan(tick[0], axis_min) or gp_math.isgreaterthan( tick[0], axis_max): continue # Don't put ticks beyond axis ends for i in range(len(exclude_list) ): # Stop minor ticks from colliding with major ticks if gp_math.isequal( tick[0], exclude_list[i][0], 1e-8 ): # Experimentally, 1e8 seems to be the tolerance that PyX uses exclude = True break if (tick_prev_x != None) and gp_math.isequal(tick[0], tick_prev_x, 1e-8): exclude = True if not exclude: if (ticklevel == 0): label = tick[1] else: label = "" ticks_pyx_out.append( dcfpyx.graph.axis.tick.tick(tick[0], label=label, ticklevel=ticklevel)) tick_prev_x = tick[0] return ticks_pyx_out
def log_ticks_realise(min, step, max, log_base): if (step in [0, 1]): return [] ticks_range = max - min ticks_out = [] tick = min while (not gp_math.isgreaterthan( tick, max)) and (len(ticks_out) < TICKS_MAXIMUM): ticks_out.append([tick, log_textoutput(tick, None, log_base)]) tick = tick * step return ticks_out
def linear_ticksep(axis_min, axis_max, log_base, length, sep, ticks_overlay=[]): # Work out order of magnitude of range of axis OoM = math.pow(log_base, math.ceil(math.log(axis_max - axis_min, log_base))) # Round the limits of the axis outwards to nearest round number min_outer = math.floor(axis_min / OoM) * OoM max_outer = math.ceil(axis_max / OoM) * OoM # How many ticks do we want, assuming one every sep cm? number_ticks = math.floor(length / sep) + 1 if (number_ticks > TICKS_MAXIMUM): number_ticks = TICKS_MAXIMUM # 100 ticks max if (number_ticks < 2): number_ticks = 2 # 2 ticks min best_tickscheme = [] # Having expanded our range out to nearest factor of 10 larger than range, # e.g. (-10 --> 10) out to (-100 --> 100), we now try a series of possible # divisions of this interval, with increasing numbers of ticks. # Offsets mean that we can put ticks, e.g. at 0.1, 0.4, 0.7, if that is # useful. # Below is arranged in order of preference. for [mantissa_footprint, ticksep, offset] in tickschemes( OoM, log_base, False): # List of [ Tick sep, Offset from min_outer ]s ts_min = min_outer + offset ticks = [] for i in range(0, int(1.5 + float(max_outer - min_outer) / ticksep)): x = ts_min + i * ticksep ticks.append([x, log_textoutput(x, None, log_base) ]) # Make a list of ticks, with format [x, label] # Remove any ticks which fall off the end of the axis while (len(ticks) > 0) and gp_math.islessthan(ticks[0][0], axis_min): ticks = ticks[1:] while (len(ticks) > 0) and gp_math.isgreaterthan( ticks[-1][0], axis_max): ticks = ticks[:-1] # Make sure that this set of ticks overlays ticks_overlay matched = True for [xo, lo] in ticks_overlay: matched = False for i in range(len(ticks)): [x, l] = ticks[i] if (x == xo): ticks = ticks[:i] + ticks[i + 1:] matched = True break if not matched: break if not matched: continue if (len(ticks) > number_ticks): break # If we have too many ticks, we've already found are best ticking scheme if (len(ticks) > len(best_tickscheme)): best_tickscheme = ticks # If this scheme produces no more ticks than last, the first was better. return best_tickscheme
def log_ticksep(axis_min, axis_max, log_base, length, sep, ticks_overlay=[]): # Work out order of magnitude of range of axis in log space axis_minl = math.log(axis_min, log_base) axis_maxl = math.log(axis_max, log_base) OoM = math.pow(10.0, math.ceil(math.log10(axis_maxl - axis_minl))) # Round the log-limits of the axis outwards to nearest round number min_outer = math.floor(axis_minl / OoM) * OoM max_outer = math.ceil(axis_maxl / OoM) * OoM # How many ticks do we want, assuming one every sep cm? number_ticks = math.floor(length / sep) + 1 if (number_ticks > TICKS_MAXIMUM): number_ticks = TICKS_MAXIMUM # 100 ticks max if (number_ticks < 2): number_ticks = 2 # 2 ticks min best_tickscheme = [] # Having expanded our range out to nearest factor of 10 larger than range, # e.g. (-10 --> 10) out to (-100 --> 100), we now try a series of possible # divisions of this interval, with increasing numbers of ticks. # Offsets mean that we can put ticks, e.g. at 0.1, 0.4, 0.7, if that is # useful. # Below is arranged in order of preference. for [mantissa_footprint, ticksep, offset] in tickschemes(OoM, 10.0, log_base): ts_min = min_outer + offset ticks = [] for i in range(0, int(1.5 + (max_outer - min_outer) / ticksep)): # NB: We store x positions in log form until we've trimmed the ends to user's range, to prevent overflows for m in mantissa_footprint: exponent = ts_min + i * ticksep x = exponent + math.log(m, log_base) ticks.append([x, log_textoutput(m, exponent, log_base)]) # Remove any ticks which fall off the end of the axis while (len(ticks) > 0) and gp_math.islessthan(ticks[0][0], axis_minl): ticks = ticks[1:] while (len(ticks) > 0) and gp_math.isgreaterthan( ticks[-1][0], axis_maxl): ticks = ticks[:-1] # Now exponentiate x positions, having trimmed our list to user range for tick in ticks: tick[0] = math.pow(log_base, tick[0]) # Make sure that this set of ticks overlays ticks_overlay matched = True for [xo, lo] in ticks_overlay: matched = False for i in range(len(ticks)): [x, l] = ticks[i] if (x == xo): ticks = ticks[:i] + ticks[i + 1:] matched = True break if not matched: break if not matched: continue # The following line is a FUDGE to make log axes look favourably upon putting minor ticks at every unit mantissa if (len(mantissa_footprint) == (log_base - 1)) and (ticks_overlay != []): if (len(ticks) > (number_ticks * 3)): break best_tickscheme = ticks elif (len(mantissa_footprint) > 1) and (ticks_overlay != []) and (len(ticks) > number_ticks): continue else: if (len(ticks) > number_ticks): break # If we have too many ticks, we've already found are best ticking scheme if (len(ticks) > len(best_tickscheme)): best_tickscheme = ticks # If this scheme produces no more ticks than last, the first was better. return best_tickscheme