v = ["#73D055",
"#2D708E",
"#440154"]
def fiddlerPlot() :
sns.set()
fig = plt.figure(figsize = (10, 10))
ax = fig.add_subplot(xlim = (0, 1),
ylim = (0, 1))
#Title setup.
ax.set_title("Tour de Fiddler", fontsize = 28)
#X-axis setup.
ax.set_xlabel("Opponent Leg Feels", fontsize = 24)
ax.xaxis.set_major_formatter(PF(xmax = 1))
#Y-axis setup.
ax.set_ylabel("Your Leg Feels", fontsize = 24)
ax.yaxis.set_major_formatter(PF(xmax = 1))
ax.tick_params(labelsize = 18)
ax.add_patch(mpP([(0, 0), (0, 1), (1, 1), (0.5, 0.5), (0.5, 0)], label = "You Win", ec = v[0], fc = v[0]))
ax.add_patch(mpP([(0.5, 0), (0.5, 0.5), (1, 1), (1, 0), (0.5, 0)], label = "Opponent Wins", ec = v[2], fc = v[2]))
ax.legend(loc = 'lower center', bbox_to_anchor = (0.5, -0.175), ncol = 2, fancybox = True, shadow = True, fontsize = 18)
fig.savefig("2025.07.25Fiddler.png", bbox_inches = 'tight')
def getVertices(d) :
return(d[CH(d).vertices])
def ECplot() :
# Array of cube.
E = np.array(list(itertools.product(np.arange(0, 1.1, 0.5), repeat = 3)))
# Dotted Lines.
df = pd.DataFrame(E[[10, 1, 4, 3, 12, 9, 10, 13, 26, 24, 12, 13, 4, 8, 26, 20, 10]],
columns = ['x', 'y', 'z'])
df['hoverdata'] = df.apply(lambda row: f"Your Leg Feels : {str(int(row['z']*100))+'%'}<br>Opponent 1's Leg Feels : {str(int(row['y']*100))+'%'}<br>Opponent 2's Leg Feels : {str(int(row['x']*100))+'%'}", axis=1)
#You.
you_0 = E[[0, 1, 3, 4, 9, 10, 12, 13]]
you_1 = E[[1, 2, 4, 8, 10, 13, 20, 26]]
y_0 = [np.concatenate((getVertices(you_0),
getVertices(you_1))),
v[0],
'Your Win']
#Opponent 1.
opp_1 = E[[3, 4, 6, 8, 12, 13, 24, 26]]
o_1 = [getVertices(opp_1),
v[2],
'Opp. 1 Win']
#Opponent 2.
opp_2 = E[[9, 10, 12, 13, 18, 20, 24, 26]]
o_2 = [getVertices(opp_2),
v[1],
'Opp. 2 Win']
#Graph Object.
fig = go.Figure()
#Add the regions where each bicyclist dominates over the other two.
for m in [y_0, o_1, o_2] :
fig.add_trace(go.Mesh3d(x = m[0][:, 0],
y = m[0][:, 1],
z = m[0][:, 2],
color = m[1],
opacity = 0.5,
alphahull = 0,
hoverinfo = 'skip',
name = m[2],
showlegend = True))
#Border edges through space.
edges = px.line_3d(df,
x = 'x',
y = 'y',
z = 'z',
custom_data = ['hoverdata'])
fig.add_trace(edges.data[0])
fig.data[3].update(#selector = {'type' : 'trace'},
hovertemplate = "%{customdata[0]}",
line = {'width' : 5,
'color' : 'black',
'dash' : 'dot'})
#Set the perspective/viewpoint.
camera = {'up' : {'x' : 0, 'y' : 0, 'z' : 1},
'center' : {'x' : 0, 'y' : 0, 'z' : 0},
'eye' : {'x' : -2.1, 'y' : -1.5, 'z' : 0.25}}
#'eye' : {'x' : 1.55, 'y' : -1.55, 'z' : 1.35}}
#Update layout.
fig.update_layout(title = {'text': 'Tour de Fiddler',
'font_size': 36,
'x': 0.5,
'xanchor': 'center'},
scene = {'xaxis' : {'title' : "Opponent 2's Leg Feels",
'tickformat' : '.0%'},
'yaxis' : {'title' : "Opponent 1's Leg Feels",
'tickformat' : '.0%'},
'zaxis' : {'title' : "Your Leg Feels",
'tickformat' : '.0%'}},
legend = {'font' : {'size' : 18}},
scene_camera = camera,
autosize = False,
width = 800,
height = 800)
pio.write_html(fig,
file = "2025.07.25EC.html",
auto_open = True)
def heatMap() :
#Threshold percent of leg feels, number of opponents, your probability of winning.
data = pd.DataFrame(columns = ['p',
'n',
'y_w'])
for p in [i/1000 for i in range(0, 1001)] :
for n in [j for j in range(0, 101)]:
#You winning is the probability region where you sprint under everyone's threshold + your fraction of the remaining.
temp = p**(n+1)
you = temp + (1-temp) / (n+1)
data.loc[len(data)] = [p, n, you]
sns.set()
fig = plt.figure(figsize = (12, 8))
ax = fig.add_subplot(xlim = (0, 100),
ylim = (0, 1))
heatmap = plt.scatter(x = data['n'],
y = data['p'],
c = data['y_w'],
cmap = 'viridis_r',
marker = "s",
s = 120,
alpha = 0.8)
#Title setup.
ax.set_title('Tour de Fiddler Scenarios', fontsize = 24)
#X-axis setup.
ax.set_xlabel("# of Opponents", fontsize = 22)
#Y-axis setup.
ax.set_ylabel("Opponent's Manager's Threshold", fontsize = 22)
ax.yaxis.set_major_formatter(PF(xmax = 1))
ax.tick_params(axis = 'both', which = 'major', labelsize = 18)
#Colorbar.
cb = plt.colorbar(heatmap,
format = '%.2f')
cb.set_label('Probability of You Winning',
labelpad = -90,
rotation = 90,
fontsize = 22)
cb.ax.tick_params(labelsize = 18)
fig.savefig("2025.07.25Other.png", bbox_inches = 'tight')