-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscaling_plotter.py
More file actions
190 lines (162 loc) · 7.38 KB
/
scaling_plotter.py
File metadata and controls
190 lines (162 loc) · 7.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.widgets import Slider
# these need to first be defined outide of any function since we are treating them as global later
nu = 1.; beta = 1/8.; gamma = 1.75; z = 1. # ising values
# nu = 1.; beta = .2; gamma = 1.6 # s3 values
def scaling_plotter(data,plot,xc,nu0=1.,gamma0=1.75,beta0=.125,z0=2.1667,raw=False,d=2,title="",cmap=cm.coolwarm):
"""
makes interactive scaling plots for various critical exponents.
data: a dictionary with the following entries
* "Ls": system sizes
* "xs": raw error rates (not reduced to pc) for each system size (#Ls x #(x data points) matrix)
* "chis": susceptibilities
* "mags": magnetizations
* "binds": binder cumulants
* "trels": memory lifetimes
plot: quantitiy to plot, one of ["binds" "mags" "chis" "trels"]
xc: value of critical point
nu,gamma,beta: estimates for critical exponents
raw: if true, just plots the raw data without scaling
d: dimension; used only for checking hyperscaling relations
title: plot title
critical exponents tuned using key presses. left/right tunes nu, right/left tunes gamma, and ,/. tunes beta
"""
# cmap = cm.coolwarm
### asthetics for plots ##
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Computer Modern Roman'] + plt.rcParams['font.serif']
mew = 1.
ms = 6.5 / 1.
lw = 2.2 #* 0
a = .8
fig,ax = plt.subplots(figsize=(2.5,2.5))
ax.minorticks_off()
Ls = data["Ls"]; chis = data["chis"]; mags = data["mags"]; binds = data["binds"]; trels = data["trels"]
### plot raw unscaled data ###
if raw:
for l in range(len(Ls)):
col = cmap((l+1) / len(Ls))
L = Ls[l]
xs = data["xs"][l]; ts = (xs - xc)/xc
ys = data[plot][l] # stuff to plot at this system size
if plot == "trels":
ys = L**0/ys # want to plot the inverse memory lifetime
ax.set_yscale('log'); ax.set_xscale('log')
ax.plot(xs,ys,c=col,label=r'$%d$'%Ls[l],marker='o',mec='k',mew=mew,ms=ms,lw=lw)
ax.set_xlabel(r'$p$'); ax.set_ylabel(r'$1/t_{\sf mem}$')
if plot == "mags":
ax.set_ylabel(r'$M$')
elif plot == "chis":
ax.set_ylabel(r'$\chi$')
elif plot == "binds":
ax.set_ylabel(r'$B$')
ax.legend(title=r'$L$',title_fontsize=12)
ax.set_title(title)
### plot scaled data (in an interactive way) ###
else:
lines0 = [] # will hold the plot lines; dynamically updated
# draw lines with guessed values of critical exponents
for l in range(len(Ls)):
col = cmap((l+1) / len(Ls))
L = Ls[l]
xs = data["xs"][l]
ts = (xs-xc)/xc # reduced temperatures
ys = data[plot][l] # stuff to plot at this system size
if plot == "binds":
line0, = ax.plot(ts * Ls[l]**(1/nu0),ys,c=col,label=r'$%d$'%Ls[l],marker='o',mfc=col,mew=mew,ms=ms,lw=lw*0,alpha=a)
elif plot == "chis":
line0, = ax.plot(ts * Ls[l]**(1/nu0),ys * L**(-gamma0 / nu0),c=col,label=r'$%d$'%Ls[l],marker='o',mfc=col,mew=mew,ms=ms,lw=lw*0,alpha=a)
elif plot == "mags":
line0, = ax.plot(ts * Ls[l]**(1/nu0),ys * L**(beta0 / nu0),c=col,label=r'$%d$'%Ls[l],marker='o',mfc=col,mew=mew,ms=ms,lw=lw*0,alpha=a)
elif plot == "trels":
ys = 1/ys # want to plot the inverse memory lifetime
line0, = ax.plot(ts * Ls[l]**(1/nu0),ys * L**(z0),c=col,label=r'$%d$'%Ls[l],marker='o',mfc=col,mew=mew,ms=ms,lw=lw*0,alpha=a)
lines0.append(line0)
def update(nu,beta,gamma,z):
print("nu = ",nu)
print("gamma = ",gamma)
print("beta = ",beta)
print("z = ",z)
print("beta(hs) = ",(d*nu-gamma)/2)
print("eta (hs) = ",2-gamma/nu)
print("Delta_ep = ",d-1/nu) # dimension of lightest Z2 neutral field
print(" ")
# will need to dynamically update the plot ranges
xmin = 1e10
xmax = -1e10
ymin = 1e10
ymax = -1e10
for l in range(len(Ls)):
L = Ls[l]
xdat = (data["xs"][l]-xc)/xc * L**(1/nu)
if plot == "chis":
ydat = data["chis"][l] * L**(-gamma/nu)
elif plot == "mags":
ydat = data["mags"][l] * L**(beta/nu)
elif plot == "binds":
ydat = data["binds"][l]
elif plot == "trels":
ydat = (1/data["trels"][l]) * L**(z)
xmin = min(xmin,np.min(xdat))
xmax = max(xmax,np.max(xdat))
ymin = min(ymin,np.min(ydat))
ymax = max(ymax,np.max(ydat))
# update the line data
lines0[l].set_xdata(xdat)
lines0[l].set_ydata(ydat)
ax.set_xlim(xmin*1.05,xmax*1.05)
ax.set_ylim(ymin*.95,ymax*1.05)
fig.canvas.draw_idle()
# Create dynamic title with current exponent values
if plot == "binds":
dynamic_title = title + r"$\, \, | \, \, \nu = %.3f$"%nu
elif plot == "chis":
dynamic_title = title + r"$\, \, | \, \, \nu = %.3f$"%nu
elif plot == "mags":
dynamic_title = title + r"$\, \, | \, \, \beta = %.3f$"%beta
elif plot == "trels":
dynamic_title = title + r"$\, \, | \, \, z = %.3f$"%z
else:
dynamic_title = title # fallback for any other plot types
ax.set_title(dynamic_title)
# define a function that updates values of critical exponents based on arrow key presses
def on_key(event):
global nu,beta,gamma,z
d = .005 # incriment by which exponents are tuned
numin = 0; numax = 4
gammamin = 0; gammamax = 4
betamin = 0; betamax = 4
zmin = .75; zmax = 4
if event.key == 'l':
z = max(zmin,z-d)
elif event.key == ':':
z = min(zmax,z+d)
if event.key == 'left':
nu = max(numin,nu - d)
elif event.key == 'right':
nu = min(numax,nu + d)
elif event.key == 'up':
gamma = min(gammamax,gamma+d)
elif event.key == 'down':
gamma = max(gammamin,gamma-d)
elif event.key == '.':
beta = max(betamin,beta-d)
elif event.key == ',':
beta = min(betamax,beta+d)
update(nu,beta,gamma,z)
fig.canvas.mpl_connect('key_press_event', lambda event : on_key(event))
ax.legend(title=r'$L$',title_fontsize=14)
if plot == "binds":
ylab = r'$B$'
elif plot == "chis":
ylab = r'$L^{-\gamma/\nu}\chi$'
elif plot == "mags":
ylab = r'$L^{\beta/\nu} m$'
elif plot == "trels":
ylab = r'$L^z / t_{\sf mem}$'
ax.set(xlabel=r'$\overline{p}L^{1/\nu}$',ylabel = ylab)
if plot == "trels":
ax.set_yscale('log')
plt.show()