Idle Wizard Wiki:Charts
Jump to navigation
Jump to search
Code to render the charts for various equations
#!/usr/bin/env python3
# coding: utf-8
#
# by Darktyle
import matplotlib.pyplot as plt
import numpy as np
from math import pow, sqrt, log10
'''
All values from default can be overridden
values that are 'none' in 'default' have to be set in each plot definintion
'''
plots = {
'default' : {
'title' : None, # default title
'func' : None, # function to plot. For example: lambda x: x * 2
'xlim' : (0, 20000), # touple of the form (start, end, stepsize) or (start, end) for x-values
'xlabel' : 'Number of casts', # x-label
'ylabel' : 'Production bonus at 100% spell efficiency (%)', # y-label
'xlog' : False, # should the x-scale be logarithmic?
'ylog' : False, # should the y-scale be logarithmic?
},
'TS' : {
'title' : 'True Sorcery bonus based on casts',
'xlim' : (0, 160000),
'func' : lambda x: pow(x + 1, 0.58) * 100,
},
'ROP' : {
'title' : 'Ritual of Power bonus based on casts',
'func' : lambda x: pow(x + 1, 0.39) * 100,
},
'UK' : {
'title' : 'Unclean Knowledge bonus based on casts',
'func' : lambda x: pow(x + 1, 0.41) * 55,
},
'Ebon Truncheon' : {
'title' : 'Ebon Truncheon bonus based on autoclicks',
'func' : lambda x: pow(x + 1, 0.35) * 20,
'xlabel' : 'Number of autoclicks',
},
'RoN' : {
'title' : 'Rules of Nature bonus based on casts',
'func' : lambda x: (x * 2) + 500,
},
'FoN' : {
'title' : 'Force of Nature bonus based on autoclicks',
'func' : lambda x: pow(x + 1, 0.35) * 100,
'xlabel' : 'Number of autoclicks',
},
'RWYS' : {
'title' : 'Reap What You Sow bonus based on total pet XP',
'xlim' : (1e10, 1e13, 1e7),
'func' : lambda x: pow(x * 0.4, 0.72) * 0.01,
'xlabel' : 'Pet XP (total)',
'xlog' : True,
},
'RP' : {
'title' : 'Radiant Pools bonus based on casts',
'func' : lambda x: pow(x + 1, 0.61) * 255,
},
'NF' : {
'title' : 'Nightfall bonus based on casts',
'func' : lambda x: pow(log10(x + 1), 0.98) * 2100,
},
'Golem XP' : {
'title' : 'Golem base XP based on upgrades purchased',
'xlim' : (0, 420),
'func' : lambda x: pow(x, 1/3) * 0.5,
'xlabel' : 'Upgrades',
'ylabel' : 'XP gain',
},
'Mysteries' : {
'title' : 'Mysteries gained based on total mana (logarithmic)',
'xlim' : (0, 200),
'func' : lambda x: sqrt((pow(10, x)/125000000000 + 1) - 1) / 2,
'xlabel' : 'Mana gained (log)',
'ylabel' : 'Mysteries',
'ylog' : True,
},
}
'''
Some configuration for colors and output format
'''
font = {'color' : '#D5D4D4',
'size' : 14,
}
rcopts = {
'lines.dotted_pattern' : '1, 5',
'axes.edgecolor' : '#B0B0B0',
'xtick.color' : '#D5D4D4',
'ytick.color' : '#D5D4D4',
'grid.color': 'black',
'grid.linestyle': ':',
}
lwidth = 2.5
lcolor = 'y'
outformat = 'svg'
def main(plots):
'''
Plot each element from 'plots' but the default.
'default' is passed as the 3rd parameter
'''
for pltname, pltdef in plots.items():
if pltname != 'default':
makeplot(pltname, pltdef, plots['default'])
def makeplot(name, pltdef, default):
''' Create the plot according to 'pltdef', fallback to 'default' if an option is missing '''
if pltdef.get('title', None) == None:
print("No title provided for '{}'. Cannot plot anything".format(name))
return
outfile = pltdef.get('title', None) + '.' + outformat
print("Creating '{}'...".format(outfile))
xlim = pltdef.get('xlim', default.get('xlim', None))
# if there is a stepsize defined, use that too
if len(xlim) > 2:
xvals = range(int(xlim[0]), int(xlim[1]), int(xlim[2]))
else:
xvals = range(int(xlim[0]), int(xlim[1]))
yvals = [pltdef.get('func', lambda x: x)(x) for x in xvals]
fig = plt.figure()
plt.rc_context(rcopts)
# plot the calculated values
plt.plot(xvals, yvals, lcolor, lw=lwidth)
plt.xlabel(pltdef.get('xlabel', default.get('xlabel', '')), fontdict=font)
plt.ylabel(pltdef.get('ylabel', default.get('ylabel', '')), fontdict=font)
plt.title(pltdef.get('title'), fontdict=font)
# if x or y scale should be logarithmic, set it here
if pltdef.get('xlog', default.get('xlog', False)):
plt.xscale('log')
if pltdef.get('ylog', default.get('ylog', False)):
plt.yscale('log')
plt.grid(True, which='both')
ax = fig.add_subplot(111)
for axis in ['top','bottom','left','right']:
ax.spines[axis].set_linestyle(':')
# set limits
ymax = max(yvals)
yticks = ax.get_yticks()
ax.set_xlim(int(xlim[0]), int(xlim[1]))
if ymax < yticks[-2]:
ax.set_ylim(0, yticks[-2])
else:
ax.set_ylim(0, yticks[-1])
# save figure to file
plt.tight_layout()
plt.savefig(outfile, format=outformat, transparent=True)
plt.close(fig)
if __name__ == '__main__':
main(plots)