Skip to content

Commit

Permalink
add axis labels and minor grid; change grid colour to grey
Browse files Browse the repository at this point in the history
  • Loading branch information
alexhuntley committed Jul 30, 2021
1 parent e698480 commit b27b0c9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 20 deletions.
44 changes: 40 additions & 4 deletions plots/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,22 @@ def major_grid(pixel_extent):
mantissa = min_extent/10**exponent
major = 1.0
for m in (2.0, 5.0, 10.0):
if mantissa < m:
if m > mantissa:
major = m * 10**exponent
return major
minor = major / (4 if m == 2 else 5)
return major, minor

def graph_to_device(self, graph_pos):
normalised = (graph_pos + self.translation)/self.scale
gl_pos = normalised / self.viewport * self.viewport[0]
gl_pos[1] *= -1
return (gl_pos/2 + 0.5) * self.viewport

def device_to_graph(self, pixel):
gl_pos = 2*(pixel/self.viewport - 0.5)
gl_pos[1] *= -1
normalised = gl_pos * self.viewport / self.viewport[0]
return normalised*self.scale - self.translation

def gl_render(self, area, context):
area.make_current()
Expand All @@ -213,18 +226,41 @@ def gl_render(self, area, context):
glEnable(GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

major_grid, minor_grid = self.major_grid(pixel_extent[0])
shaders.glUseProgram(self.shader)
glUniform2f(self.uniform("viewport"), *self.viewport)
glUniform2f(self.uniform("translation"), *self.translation)
glUniform2f(self.uniform("pixel_extent"), *pixel_extent)
glUniform1f(self.uniform("scale"), self.scale)
glUniform1f(self.uniform("major_grid"), self.major_grid(pixel_extent[0]))
glUniform1f(self.uniform("major_grid"), major_grid)
glUniform1f(self.uniform("minor_grid"), minor_grid)
for slider in self.slider_rows:
glUniform1f(self.uniform(slider.name), slider.value)
glBindVertexArray(self.vao)
glDrawArrays(GL_TRIANGLES, 0, 18)
glBindVertexArray(0)
self.text_renderer.render(w, h)
with self.text_renderer.render(w, h) as r:
low = major_grid * np.floor(
self.device_to_graph(np.array([0, h]))/major_grid)
high = major_grid * np.ceil(
self.device_to_graph(np.array([w, 0]))/major_grid)
n = (high - low)/major_grid
pad = 4
for i in range(round(n[0])+1):
x = low[0] + i*major_grid
pos = self.graph_to_device(np.array([x, 0]))
pos[1] = np.clip(pos[1] + pad, pad, self.viewport[1] - r.top_bearing - pad)
if x:
r.render_text("%g" % x, pos, valign='top', halign='center')
for j in range(round(n[1])+1):
y = low[1] + j*major_grid
label = "%g" % y
pos = self.graph_to_device(np.array([0, y]))
pos[0] = np.clip(pos[0] - pad, r.width_of(label) + pad, self.viewport[0] - pad)
if y:
r.render_text(label, pos, valign='center', halign='right')
r.render_text("0", self.graph_to_device(np.zeros(2)) + np.array([-pad, pad]),
valign='top', halign='right')
return True

def uniform(self, name):
Expand Down
11 changes: 7 additions & 4 deletions plots/shaders/fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ out vec4 rgba;
uniform vec2 pixel_extent;
uniform float scale;
uniform float major_grid;
uniform float minor_grid;

#define pi 3.141592653589793
#define e 2.718281828459045
Expand Down Expand Up @@ -142,9 +143,11 @@ void main() {
{% endfor %}

float axis_width = pixel_extent.x;
color -= (1.0-vec3(0.2,0.2,1.0))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(graph_pos.x)));
color -= (1.0-vec3(0.2,0.2,1.0))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(graph_pos.y)));
color -= (1.0-vec3(0.8,0.8,1.0))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.x, major_grid))));
color -= (1.0-vec3(0.8,0.8,1.0))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.y, major_grid))));
color -= (1.0-vec3(0.2,0.2,0.2))*(1.0-smoothstep(axis_width*.6, axis_width*.65, abs(graph_pos.x)));
color -= (1.0-vec3(0.2,0.2,0.2))*(1.0-smoothstep(axis_width*.6, axis_width*.65, abs(graph_pos.y)));
color -= (1.0-vec3(0.7,0.7,0.7))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.x, major_grid))));
color -= (1.0-vec3(0.7,0.7,0.7))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.y, major_grid))));
color -= (1.0-vec3(0.9,0.9,0.9))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.x, minor_grid))));
color -= (1.0-vec3(0.9,0.9,0.9))*(1.0-smoothstep(axis_width, axis_width*1.05, abs(mod(graph_pos.y, minor_grid))));
rgba = vec4(color, 1);
}
2 changes: 1 addition & 1 deletion plots/shaders/text_frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ void main()
{
vec2 uv = vUV.xy;
float text = texture(u_texture, uv).r;
fragColor = vec4(textColor.rgb*text, text);
fragColor = vec4(vec3(1-text), clamp(text, 0.8, 1));
}
36 changes: 25 additions & 11 deletions plots/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import importlib.resources as resources
except ModuleNotFoundError:
import importlib_resources as resources
from contextlib import contextmanager


# Code based on:
Expand All @@ -40,7 +41,7 @@ def __init__(self):
self.width, self.height = 0, 0
self.characters = []
self.initgl()
self.fontsize = 12
self.fontsize = 14
self.makefont(resources.open_binary('plots.res', 'DejaVuSans.ttf'),
self.fontsize)

Expand Down Expand Up @@ -76,22 +77,23 @@ def makefont(self, filename, fontsize):
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glActiveTexture(GL_TEXTURE0)

self.top_bearing = 0
for c in range(128):
face.load_char(chr(c), freetype.FT_LOAD_RENDER)
glyph = face.glyph
bitmap = glyph.bitmap
size = bitmap.width, bitmap.rows
bearing = glyph.bitmap_left, glyph.bitmap_top
self.top_bearing = max(self.top_bearing, bearing[1])
advance = glyph.advance.x

# create glyph texture
texObj = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texObj)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
#databuffer = np.zeros((cx, width*16), dtype=np.ubyte)
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, *size, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap.buffer)

self.characters.append((texObj, size, bearing, advance))
Expand All @@ -102,23 +104,35 @@ def makefont(self, filename, fontsize):
def uniform(self, name):
return glGetUniformLocation(self.shaderProgram, name)

@contextmanager
def render(self, width, height):
self.width, self.height = width, height
glUseProgram(self.shaderProgram)
proj = glm.ortho(0, self.width, self.height, 0, -1, 1)
glUniformMatrix4fv(self.uniform("projection"),
1, GL_FALSE, glm.value_ptr(proj))

glUniform3f(self.uniform("textColor"), 0.2, .2, .2)
self.render_text("This is sample text", (0, 12), 1, (1, 0))

def render_text(self, text, pos, scale, dir):
yield self

def width_of(self, text, scale=1):
return sum((self.characters[ord(c)][3] >> 6)*scale for c in text)

def render_text(self, text, pos, scale=1, dir=(1,0), halign='left', valign='bottom'):
offset = glm.vec3()
if halign in ('center', 'right'):
width = self.width_of(text, scale)
offset.x -= width
if halign == 'center':
offset.x /= 2
if valign in ('center', 'top'):
offset.y += self.top_bearing
if valign == 'center':
offset.y /= 2
glActiveTexture(GL_TEXTURE0)
glBindVertexArray(self.vao)
angle_rad = math.atan2(dir[1], dir[0])
rotateM = glm.rotate(glm.mat4(1), angle_rad, glm.vec3(0, 0, 1))
transOriginM = glm.translate(glm.mat4(1), glm.vec3(*pos, 0))

transOriginM = glm.translate(glm.mat4(1), glm.vec3(*pos, 0) + offset)
glUniform3f(self.uniform("textColor"), .0, .0, .0)
char_x = 0
for c in text:
c = ord(c)
Expand Down

0 comments on commit b27b0c9

Please sign in to comment.