Quite the workout last time. Let’s see what it takes to repeat the other tranformation image types. Though I may for now skip the mosaic transform to transform type.
gnarly_t
I just copied some of the stuff over from the appropriate route and things seemed to work just fine for my test image.
elif 'gnarly' in r.d_rpt[r.do_nbr]['i_typ']:
# Generate transformed datasets
dt_x, dt_y, _ = make_transforms(r_xs, r_ys, "gnarly_t", do_qd2, lld_rot, trdy, y_mlt=y_mlt, do_t1=do_qd)
for i in range(len(dt_x)):
ax.plot(dt_x[i], dt_y[i], lw=g.ln_w, alpha=1)
ax.autoscale()
... ...
elif r.d_rpt[r.do_nbr]['i_typ'] == 'gnarly_t':
d_end = "top" if g.drp_f else "bottom"
p_data = {
'd_end': d_end, 'd_nbr': g.r_skp,
'ntr': g.nbr_tr, 'trang': lld_deg, 'trpt': f'(0, {round(trdy, 3)}) ({y_mlt})',
'trord2': do_qd2
}
Test
The data saved from the display page was:
gnarly_t
Curve Parameters
Wheels: 9 wheels (shape(s): rhombus (r))
Symmetry: k_fold = 4, congruency = 3
Frequencies: [-1, -9, -5, 15, 3, 11, -1, -5, 11]
Widths: [1, 0.6769585152867885, 0.657421016579852j, 0.6308918613542178j, 0.5101357922701247, 0.48555975482889846j, 0.46707223242611007, 0.2817619386262918, 0.1626706687783567j]
Heights: [1, 0.6259081347764245, 0.4991308174443422, 0.38208587908718655j, 0.22753198914071018j, 0.13975254705360463j, 0.125, 0.125j, 0.125]
Data points: 1024
Image Type Parameters
Drop data rows: 1 datarow
From: dropped from the 'top' of the curve dataset
Drawing Parameters
Colour map: inferno (0.75, 3)
BG colour map: gist_rainbow (0.15)
Line width (if used): 1
Image size: 8
Image DPI: 72
Transformations
Number of transforms: 8
Angles: [45.0, 90.0, 135.0, 180.0, 225.0, 270.0, 315.0, 360.0]
Base linear translation point: (0, 1.218) (0.5)
Order: [0, 2, 3, 4, 1, 7, 6, 5]
Colour Arrays
Background array: [[0.17556021 0.09677037 0.75796826 0.75292477] [0.50097762 0.12006618 0.33752684 0.38438516] [0.50038911 0.25366481 0.6676264 0.93126733] [0.01702525 0.33626939 0.90119215 0.42099212]]
Colour cycle: [(0.001462, 0.000466, 0.013866, 1.0), (0.013995, 0.011225, 0.071862, 1.0), (0.042253, 0.028139, 0.141141, 1.0), (0.081962, 0.043328, 0.215289, 1.0), (0.129285, 0.047293, 0.290788, 1.0), (0.183429, 0.040329, 0.354971, 1.0), (0.238273, 0.036621, 0.396353, 1.0), (0.290763, 0.045644, 0.418637, 1.0), (0.3415, 0.062325, 0.429425, 1.0), (0.391453, 0.080927, 0.433109, 1.0), (0.441207, 0.099338, 0.431594, 1.0), (0.491022, 0.117179, 0.425552, 1.0), (0.54092, 0.134729, 0.415123, 1.0), (0.590734, 0.152563, 0.40029, 1.0), (0.640135, 0.171438, 0.381065, 1.0), (0.688653, 0.192239, 0.357603, 1.0), (0.735683, 0.215906, 0.330245, 1.0), (0.780517, 0.243327, 0.299523, 1.0), (0.822386, 0.275197, 0.266085, 1.0), (0.860533, 0.311892, 0.230606, 1.0), (0.894305, 0.353399, 0.193584, 1.0), (0.923215, 0.399359, 0.155193, 1.0), (0.946965, 0.449191, 0.115272, 1.0), (0.965397, 0.502249, 0.073859, 1.0), (0.978422, 0.557937, 0.034931, 1.0), (0.985952, 0.61575, 0.025592, 1.0), (0.987874, 0.675267, 0.065257, 1.0), (0.984075, 0.736087, 0.129527, 1.0), (0.974638, 0.797692, 0.206332, 1.0), (0.960626, 0.859069, 0.29801, 1.0), (0.947594, 0.917399, 0.410665, 1.0), (0.954529, 0.965896, 0.540361, 1.0), (0.988362, 0.998364, 0.644924, 1.0), (0.946809, 0.924168, 0.426373, 1.0), (0.956834, 0.874129, 0.323974, 1.0), (0.971468, 0.813122, 0.227658, 1.0), (0.981173, 0.759135, 0.156863, 1.0), (0.986694, 0.70554, 0.095694, 1.0), (0.987622, 0.64532, 0.039886, 1.0), (0.983779, 0.593849, 0.02377, 1.0), (0.975677, 0.543798, 0.043618, 1.0), (0.961293, 0.488716, 0.084289, 1.0), (0.944285, 0.442772, 0.120354, 1.0), (0.923215, 0.399359, 0.155193, 1.0), (0.894305, 0.353399, 0.193584, 1.0), (0.865006, 0.316822, 0.226055, 1.0), (0.832299, 0.283913, 0.257383, 1.0), (0.791293, 0.250856, 0.29139, 1.0), (0.752794, 0.225706, 0.319085, 1.0), (0.712396, 0.203656, 0.344383, 1.0), (0.670599, 0.184153, 0.366879, 1.0), (0.621685, 0.164184, 0.388781, 1.0), (0.578304, 0.148039, 0.404411, 1.0), (0.534683, 0.132534, 0.416667, 1.0), (0.484789, 0.114974, 0.426548, 1.0), (0.441207, 0.099338, 0.431594, 1.0), (0.397674, 0.083257, 0.433183, 1.0), (0.347771, 0.064616, 0.430217, 1.0), (0.303568, 0.049396, 0.422182, 1.0), (0.258234, 0.038571, 0.406485, 1.0), (0.204209, 0.037632, 0.373238, 1.0), (0.15585, 0.044559, 0.325338, 1.0), (0.110536, 0.047399, 0.262912, 1.0), (0.066331, 0.038504, 0.186962, 1.0)]
And here are the original image and the repeat version.
Well that was amazingly easy.
mosaic_t
Had to add some more fields to the repeat image data dictionary. Also moved one to join the new ones. These are specific to mosaic images. I put them just before the fields specific to image transforms.
'c_nbr': '16',
'r_btw': '1',
'r_mlt': 'false',
'mlts': [],
In order to pass the current colour cycle index to the appropriate plotting function, I had to refactor it the same way I did in the previous post.
def btw_n_apart(axt, rxs, rys, dx=1, ol=True, r=False, fix=None, mlt=False, sect=1, u_ndx=None):
... ...
if not g.do_rpt or not g.c_ndx:
c_ndx = rng.integers(0, c_len-2)
g.c_ndx = c_ndx
else:
if u_ndx:
c_ndx = u_ndx
else:
c_ndx = g.c_ndx
And in the repeat route function, I added the following.
elif 'mosaic' in r.d_rpt[r.do_nbr]['i_typ']:
d_xs, d_ys, _ = make_transforms(r_xs, r_ys, 'mosaic_t', do_qd2, lld_rot, trdy, y_mlt=y_mlt)
# Generate transformed datasets
for ndx, i in enumerate(do_qd2):
sal.btw_n_apart(ax, d_xs[i], d_ys[i], dx=g.bw_dx, ol=g.bw_o, r=g.bw_r, fix=None, mlt=g.bw_m,
sect=g.bw_s, u_ndx=g.c_ndx[ndx])
ax.autoscale()
sal.cnt_btw += 1
... ...
elif r.d_rpt[r.do_nbr]['i_typ'] == 'mosaic_t':
p_data = {'bdx': g.bw_dx, 'bol': g.bw_o, 'bcs': g.bw_s,
'bmlt': g.u_rmlt != 'false', 'mlts': sal.c_mlts,
'ntr': g.nbr_tr, 'trang': lld_deg, 'trpt': f'(0, {round(trdy, 3)}) ({y_mlt})',
'trord2': do_qd2
}
Test
I didn’t have any mosaic_t
with the original image saved. So, I used the current code to generate one for testing purposes.
I won’t bother displaying the saved data; just the images.
And, that appears to work as desired. Also once again fairly easy. Guess I did the bulk of the work when sorting out repeating cycling line width image with transforms.
Wasn’t originally going to add the mosaic with colouring between transforms. But this is going well enough that I thought I’d give it a try.
mosaic_t2t
Ended up taking a bit more refactoring than I expected, but seem to have got it working. Mostly trying to sort exactly how the image was generated and how the various values were obtained. And, I one point I was using an incorrect value in a conditional. Almost all of the extra effort was due to a lack of good documentation on my part. I know it’s probably in old blog posts somewhere—but that’s not exactly good documentation.
Added a new field to the repeat data dictionary: 't2t_btw': [],
. Right after 'do_qd2'
. It tracks the rows that are coloured between on each iteration of colouring between two transforms. The selection of transforms is controlled by the values of do_qd
aand do_qd2
in the image data dictionary.
A wee refactor to set_rpt_data()
. The top and bottom rows below. Three, unchanged rows between are there for context.
g.bw_m = True if r.d_rpt[r.do_nbr]['r_mlt'] == 'true' else False
g.bw_dx = int(r.d_rpt[r.do_nbr]['r_btw'])
g.bw_s = int(r.d_rpt[r.do_nbr]['c_nbr'])
g.bw_o = True
g.bw_trws = r.d_rpt[r.do_nbr]['t2t_btw']
I was previously just assigning the value of r.d_rpt[r.do_nbr]['r_mlt']
to g.bw_m
. That’s a string, so g.bw_m
was always evaluating to true. Which was definitely messing with things.
Also refactored sal.btw_qds
, adding that optional colour cycle index parameter, u_ndx=None
. And refactoring the code to account for it appropriately (see above or previous post).
Then I made sure a call to the function didn’t generate a new set of values for g.bw_trws
if doing a repeat. Added the if
block below plus the else
block. The previous code is in the if
block.
if cnt_btw == 0:
if not g.do_rpt:
rys2_i = list(range(len(rys2)))
rng.shuffle(rys2_i)
g.bw_trws = []
rw1 = rng.choice(rys2_i)
g.bw_trws.append(rw1)
rys2_i.remove(rw1)
g.bw_trws.extend(rys2_i)
else:
rw1 = g.bw_trws[0]
rys2_i = g.bw_trws[1:]
if mlt:
In the repeat route I added the following in the pertinent locations. Do note that the elif 't2t'
has to go before the elif 'mosaic'
. If it goes after it will never be executed.
elif 't2t' in r.d_rpt[r.do_nbr]['i_typ']:
dt_x, dt_y, dt_y2 = make_transforms(r_xs, r_ys, 'mosaic_t2t', do_qd2, lld_rot, trdy, y_mlt=y_mlt, do_t1=do_qd)
# Generate transformed datasets
for i in range(g.nbr_tr):
if do_qd[i] == do_qd2[i]:
continue
rys2i = sal.btw_qds(ax, dt_x[i], dt_y[i], dt_y2[i], mlt=g.bw_m, sect=g.bw_s, u_ndx=g.c_ndx[i])
ax.autoscale()
elif 'mosaic' in r.d_rpt[r.do_nbr]['i_typ']:
... ...
elif r.d_rpt[r.do_nbr]['i_typ'] == 'mosaic_t2t':
p_data = {'bdx': g.bw_dx, 'bol': g.bw_o, 'bcs': g.bw_s,
'bmlt': g.u_rmlt != 'false', 'mlts': sal.c_mlts,
'ntr': g.nbr_tr, 'trang': lld_deg, 'trpt': f'(0, {round(trdy, 3)}) ({y_mlt})',
'trord': do_qd, 'trord2': do_qd2, 'trws': g.bw_trws
}
Test
As it has changed a bit over the last couple of posts, I decided to list the test image’s repeat data dictionary.
d_rpt.append(
{
'i_typ': 'mosaic_t2t',
'shape': 'q',
'shp_mlt': 'false',
'wheels': '10',
'k_f': 7,
'cgv': 6,
'freqs': [6, -15, -22, 34, 34, -1, 27, -8, 20, -22],
'wds': [1, 0.5839965910642135j, 0.4686729652631233, 0.24111609912316234, 0.2309935900589636j, 0.12585152503709113, 0.125, 0.125, 0.125j, 0.125],
'hts': [1, 0.5570160786587838, 0.5098948302264085j, 0.35865549348923187, 0.2703810613066595, 0.1656097105665913, 0.1419466650230957, 0.1352013445508208j, 0.125, 0.125],
'ln_sz': '6',
'cmap': 'gist_rainbow',
'c_cyc': [(1.0, 0.0, 0.16, 1.0), (1.0, 0.007419183889772136, 0.0, 1.0), (1.0, 0.17700052994170645, 0.0, 1.0), (1.0, 0.34658187599364076, 0.0, 1.0), (1.0, 0.5161632220455751, 0.0, 1.0), (1.0, 0.6857445680975094, 0.0, 1.0), (1.0, 0.8553259141494436, 0.0, 1.0), (0.9750927397986221, 1.0, 0.0, 1.0), (0.8055113937466878, 1.0, 0.0, 1.0), (0.6359300476947536, 1.0, 0.0, 1.0), (0.4663487016428193, 1.0, 0.0, 1.0), (0.29676735559088496, 1.0, 0.0, 1.0), (0.12718600953895065, 1.0, 0.0, 1.0), (0.0, 1.0, 0.04216740459624712, 1.0), (0.0, 1.0, 0.2108370229812356, 1.0), (0.0, 1.0, 0.3795066413662241, 1.0), (0.0, 1.0, 0.5481762597512125, 1.0), (0.0, 1.0, 0.716845878136201, 1.0), (0.0, 1.0, 0.8855154965211895, 1.0), (0.0, 0.9452259164535375, 1.0, 1.0), (0.0, 0.774722932651321, 1.0, 1.0), (0.0, 0.6042199488491045, 1.0, 1.0), (0.0, 0.43371696504688806, 1.0, 1.0), (0.0, 0.26321398124467155, 1.0, 1.0), (0.0, 0.09271099744245515, 1.0, 1.0), (0.07779198635976144, 0.0, 1.0, 1.0), (0.24829497016197802, 0.0, 1.0, 1.0), (0.4187979539641946, 0.0, 1.0, 1.0), (0.5893009377664112, 0.0, 1.0, 1.0), (0.7598039215686277, 0.0, 1.0, 1.0), (0.9303069053708444, 0.0, 1.0, 1.0), (1.0, 0.0, 0.8991901108269392, 1.0), (1.0, 0.0, 0.75, 1.0), (0.9516197783461214, 0.0, 1.0, 1.0), (0.8024296675191819, 0.0, 1.0, 1.0), (0.6319266837169654, 0.0, 1.0, 1.0), (0.4827365728900258, 0.0, 1.0, 1.0), (0.3335464620630857, 0.0, 1.0, 1.0), (0.16304347826086973, 0.0, 1.0, 1.0), (0.013853367433930218, 0.0, 1.0, 1.0), (0.0, 0.13533674339300916, 1.0, 1.0), (0.0, 0.3058397271952257, 1.0, 1.0), (0.0, 0.4550298380221651, 1.0, 1.0), (0.0, 0.6042199488491045, 1.0, 1.0), (0.0, 0.774722932651321, 1.0, 1.0), (0.0, 0.9239130434782604, 1.0, 1.0), (0.0, 1.0, 0.9276829011174367, 1.0), (0.0, 1.0, 0.7590132827324482, 1.0), (0.0, 1.0, 0.6114273666455833, 1.0), (0.0, 1.0, 0.46384145055871834, 1.0), (0.0, 1.0, 0.3162555344718534, 1.0), (0.0, 1.0, 0.14758591608686492, 1.0), (0.0, 1.0, 0.0, 1.0), (0.14838367779544248, 1.0, 0.0, 1.0), (0.3179650238473768, 1.0, 0.0, 1.0), (0.4663487016428193, 1.0, 0.0, 1.0), (0.6147323794382618, 1.0, 0.0, 1.0), (0.784313725490196, 1.0, 0.0, 1.0), (0.9326974032856385, 1.0, 0.0, 1.0), (1.0, 0.918918918918919, 0.0, 1.0), (1.0, 0.7493375728669847, 0.0, 1.0), (1.0, 0.6009538950715422, 0.0, 1.0), (1.0, 0.4525702172760997, 0.0, 1.0), (1.0, 0.2829888712241654, 0.0, 1.0)],
'c_lpha': 0.75,
'c_ndx': [29, 50, 60, 48, 29, 43, 36],
'do_bg': 'true',
'c_bg': 'Blues',
'abg': [[0.6786540244661128, 0.9827608866021652, 0.9890795035417875, 0.882687910132615], [0.5104683567649476, 0.13347974534624163, 0.2795811627180592, 0.23491472489732812], [0.06464296461431818, 0.8905987810315855, 0.39581471675120106, 0.6696642233040028], [0.03045516825782668, 0.8660007981155114, 0.7724032095627454, 0.4933969150825228]],
'bg_lpha': 0.3,
'npts': 1024,
'sz': 8,
'dpi': 72,
'how': '',
'clw_pct': 'false',
'clwc': '8',
'clwpp': '12',
'h_frq': 128,
'm_inc': None,
'u_agn': 'false',
'torb': 'top',
'drows': '0',
'c_nbr': '16',
'r_btw': '1',
'r_mlt': 'false',
'mlts': [],
'ntr': '7',
'lld_deg': [25.714285714285715, 77.14285714285714, 128.57142857142858, 180.0, 231.42857142857142, 282.85714285714283, 334.2857142857143],
'y_mlt': 0.5,
'trdy': 0.788,
'do_qd': [1, 2, 5, 3, 4, 6, 0],
'do_qd2': [2, 3, 0, 6, 5, 4, 1],
't2t_btw': [6, 2, 5, 3, 8, 4, 0, 1, 7],
'do_drpt': 'false',
'ani_step': 8,
}
)
The t2t_btw
field is generated from this line from the image display page:
Colouring between row 6 and [2, 5, 3, 8, 4, 0, 1, 7]
Image Data Output
One litte more thing.
The array to generate the background image is a mutli-dimensional Numpy array. When it is printed to the display page, it doesn’t have any commas separating the elements in the array. That has been a minor pain point when I am building the data dictionaries for repeat images. So, I have in sal.get_image_dtl()
replaced 'abg': g.abg
with 'abg': g.abg.tolist()
. Now it is a straight copy and paste. No messing around adding a bunch of commas.
Done
I think that’s it for this one and for the moment working on the repeat route. I do believe it may be time for another refactoring. Including some reasonable documentation. I would like to move all, or at least most, of the functions in the main module to other modules. And see if, for this project, I can reduce the spiro_plotlib
module it uses.
Wishing you success in your refactoring and app maintenance efforts.