Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
marceloprates authored Sep 6, 2021
2 parents 5a5140f fdb890c commit 25884a2
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 200 deletions.
2 changes: 1 addition & 1 deletion prettymaps/__init__.py
Original file line number Diff line number Diff line change
@@ -1 1 @@
from .draw import plot
from .draw import plot
134 changes: 69 additions & 65 deletions prettymaps/curved_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 8,9 @@ class CurvedText(mtext.Text):
"""
A text object that follows an arbitrary curve.
"""

def __init__(self, x, y, text, axes, **kwargs):
super(CurvedText, self).__init__(x[0],y[0],' ', **kwargs)
super(CurvedText, self).__init__(x[0], y[0], " ", **kwargs)

axes.add_artist(self)

Expand All @@ -21,29 22,28 @@ def __init__(self, x, y, text, axes, **kwargs):
##creating the text objects
self.__Characters = []
for c in text:
if c == ' ':
if c == " ":
##make this an invisible 'a':
t = mtext.Text(0,0,'a')
t = mtext.Text(0, 0, "a")
t.set_alpha(0.0)
else:
t = mtext.Text(0,0,c, **kwargs)
t = mtext.Text(0, 0, c, **kwargs)

#resetting unnecessary arguments
t.set_ha('center')
# resetting unnecessary arguments
t.set_ha("center")
t.set_rotation(0)
t.set_zorder(self.__zorder 1)
t.set_zorder(self.__zorder 1)

self.__Characters.append((c,t))
self.__Characters.append((c, t))
axes.add_artist(t)


##overloading some member functions, to assure correct functionality
##on update
def set_zorder(self, zorder):
super(CurvedText, self).set_zorder(zorder)
self.__zorder = self.get_zorder()
for c,t in self.__Characters:
t.set_zorder(self.__zorder 1)
for c, t in self.__Characters:
t.set_zorder(self.__zorder 1)

def draw(self, renderer, *args, **kwargs):
"""
Expand All @@ -53,12 53,12 @@ def draw(self, renderer, *args, **kwargs):
"""
self.update_positions(renderer)

def update_positions(self,renderer):
def update_positions(self, renderer):
"""
Update positions and rotations of the individual text elements.
"""

#preparations
# preparations

##determining the aspect ratio:
##from https://stackoverflow.com/a/42014041/2454357
Expand All @@ -71,94 71,98 @@ def update_positions(self,renderer):
## Ratio of display units
_, _, w, h = self.axes.get_position().bounds
##final aspect ratio
aspect = ((figW * w)/(figH * h))*(ylim[1]-ylim[0])/(xlim[1]-xlim[0])

#points of the curve in figure coordinates:
x_fig,y_fig = (
np.array(l) for l in zip(*self.axes.transData.transform([
(i,j) for i,j in zip(self.__x,self.__y)
]))
aspect = ((figW * w) / (figH * h)) * (ylim[1] - ylim[0]) / (xlim[1] - xlim[0])

# points of the curve in figure coordinates:
x_fig, y_fig = (
np.array(l)
for l in zip(
*self.axes.transData.transform(
[(i, j) for i, j in zip(self.__x, self.__y)]
)
)
)

#point distances in figure coordinates
x_fig_dist = (x_fig[1:]-x_fig[:-1])
y_fig_dist = (y_fig[1:]-y_fig[:-1])
r_fig_dist = np.sqrt(x_fig_dist**2 y_fig_dist**2)
# point distances in figure coordinates
x_fig_dist = x_fig[1:] - x_fig[:-1]
y_fig_dist = y_fig[1:] - y_fig[:-1]
r_fig_dist = np.sqrt(x_fig_dist ** 2 y_fig_dist ** 2)

#arc length in figure coordinates
l_fig = np.insert(np.cumsum(r_fig_dist),0,0)
# arc length in figure coordinates
l_fig = np.insert(np.cumsum(r_fig_dist), 0, 0)

#angles in figure coordinates
rads = np.arctan2((y_fig[1:] - y_fig[:-1]),(x_fig[1:] - x_fig[:-1]))
# angles in figure coordinates
rads = np.arctan2((y_fig[1:] - y_fig[:-1]), (x_fig[1:] - x_fig[:-1]))
degs = np.rad2deg(rads)


rel_pos = 10
for c,t in self.__Characters:
#finding the width of c:
for c, t in self.__Characters:
# finding the width of c:
t.set_rotation(0)
t.set_va('center')
bbox1 = t.get_window_extent(renderer=renderer)
t.set_va("center")
bbox1 = t.get_window_extent(renderer=renderer)
w = bbox1.width
h = bbox1.height

#ignore all letters that don't fit:
if rel_pos w/2 > l_fig[-1]:
# ignore all letters that don't fit:
if rel_pos w / 2 > l_fig[-1]:
t.set_alpha(0.0)
rel_pos = w
continue

elif c != ' ':
elif c != " ":
t.set_alpha(1.0)

#finding the two data points between which the horizontal
#center point of the character will be situated
#left and right indices:
il = np.where(rel_pos w/2 >= l_fig)[0][-1]
ir = np.where(rel_pos w/2 <= l_fig)[0][0]
# finding the two data points between which the horizontal
# center point of the character will be situated
# left and right indices:
il = np.where(rel_pos w / 2 >= l_fig)[0][-1]
ir = np.where(rel_pos w / 2 <= l_fig)[0][0]

#if we exactly hit a data point:
# if we exactly hit a data point:
if ir == il:
ir = 1

#how much of the letter width was needed to find il:
used = l_fig[il]-rel_pos
# how much of the letter width was needed to find il:
used = l_fig[il] - rel_pos
rel_pos = l_fig[il]

#relative distance between il and ir where the center
#of the character will be
fraction = (w/2-used)/r_fig_dist[il]
# relative distance between il and ir where the center
# of the character will be
fraction = (w / 2 - used) / r_fig_dist[il]

##setting the character position in data coordinates:
##interpolate between the two points:
x = self.__x[il] fraction*(self.__x[ir]-self.__x[il])
y = self.__y[il] fraction*(self.__y[ir]-self.__y[il])
x = self.__x[il] fraction * (self.__x[ir] - self.__x[il])
y = self.__y[il] fraction * (self.__y[ir] - self.__y[il])

#getting the offset when setting correct vertical alignment
#in data coordinates
# getting the offset when setting correct vertical alignment
# in data coordinates
t.set_va(self.get_va())
bbox2 = t.get_window_extent(renderer=renderer)
bbox2 = t.get_window_extent(renderer=renderer)

bbox1d = self.axes.transData.inverted().transform(bbox1)
bbox2d = self.axes.transData.inverted().transform(bbox2)
dr = np.array(bbox2d[0]-bbox1d[0])
dr = np.array(bbox2d[0] - bbox1d[0])

#the rotation/stretch matrix
# the rotation/stretch matrix
rad = rads[il]
rot_mat = np.array([
[math.cos(rad), math.sin(rad)*aspect],
[-math.sin(rad)/aspect, math.cos(rad)]
])
rot_mat = np.array(
[
[math.cos(rad), math.sin(rad) * aspect],
[-math.sin(rad) / aspect, math.cos(rad)],
]
)

##computing the offset vector of the rotated character
drp = np.dot(dr,rot_mat)
drp = np.dot(dr, rot_mat)

#setting final position and rotation:
t.set_position(np.array([x,y]) drp)
# setting final position and rotation:
t.set_position(np.array([x, y]) drp)
t.set_rotation(degs[il])

t.set_va('center')
t.set_ha('center')
t.set_va("center")
t.set_ha("center")

#updating rel_pos to right edge of character
rel_pos = w-used
# updating rel_pos to right edge of character
rel_pos = w - used
Loading

0 comments on commit 25884a2

Please sign in to comment.