I am trying to make a flow to show my experimental design. I have something that works, but I would like to add another layer at the bottom-which adds a question box to each group, which should be big enough to read. An example of what I have is image 1 hoping for is in image 2. Such that group 1 has a question and answer (with arrows) and group 2 and 3 has a question and 3 answers (with arrows). Of course, the arrows should be black and in the right place-its just hard to do in word!
Does anyone know how I can do this?
Image 1
Image 2
Code:
# install.packages("DiagrammeR")
#library(DiagrammeR)
schematic <- grViz("digraph lexicon {
# node definitions with substituted label text
node [fontname = Helvetica, shape = rectangle, style=filled,color=lightgrey]
tab1 [label = '##1']
tab2 [label = '##2']
tab3 [label = '##3']
tab4 [label = '##4']
tab5 [label = '##5']
node [shape = rectangle, fillcolor=PeachPuff]
tab6 [label = '##6']
node [shape = rectangle, fillcolor=CadetBlue]
tab7 [label = '##7']
node [shape = rectangle, fillcolor=Lavender]
tab8 [label = '##8']
node [fontname = Helvetica, shape = rectangle, style=bold]
m1 [label = 'Did not agree to participate n=18']
m2 [label = 'Under 18 years n=11']
m3 [label = 'No smoke in past 3 months n=8']
m4 [label = 'Did not complete survey n=155']
# creating horizontal lines
node [shape=none, width=0, height=0, label='']
{rank=same; tab1 -> m1}
{rank=same; tab2 -> m2}
{rank=same; tab3 -> m3}
{rank=same; tab4 -> m4}
# edge definitions with the node IDs
tab1 -> tab2 -> tab3 -> tab4 -> tab5->{tab6 tab7 tab8};
}
[1]: 'Raw Data n=434'
[2]: 'Agreed to participate n=406'
[3]: 'Over 18 years n=491'
[4]: 'smoke in past 3 months=403'
[5]: 'Final sample n=238'
[6]: 'Group1 n=82'
[7]: 'Group2 n=98'
[8]: 'Group3 n=88'
")
jpeg(file = "schematic.jpg")
schematic
You can just add some more nodes
schematic <- grViz("digraph lexicon {
# node definitions with substituted label text
node [fontname = Helvetica, shape = rectangle, style=filled,color=lightgrey]
tab1 [label = '##1']
tab2 [label = '##2']
tab3 [label = '##3']
tab4 [label = '##4']
tab5 [label = '##5']
node [shape = rectangle, fillcolor=PeachPuff]
tab6 [label = '##6']
node [shape = rectangle, fillcolor=CadetBlue]
tab7 [label = '##7']
node [shape = rectangle, fillcolor=Lavender]
tab8 [label = '##8']
node [fontname = Helvetica, shape = rectangle, style=bold]
m1 [label = 'Did not agree to participate n=18']
m2 [label = 'Under 18 years n=11']
m3 [label = 'No smoke in past 3 months n=8']
m4 [label = 'Did not complete survey n=155']
# ------> NEW NODES
node [fontname = Helvetica, shape = rectangle, style=bold, width = 2.5, height = 1, ALIGN = LEFT]
q1 [label = 'Question 1 \\l\n\n']
q2 [label = 'Question 2 \\l\n\n']
q3 [label = 'Question 3 \\l\n\n']
a11 [label = 'Answer 1 \\l\n\n']
a21 [label = 'Answer 1 \\l\n\n']
a22 [label = 'Answer 2 \\l\n\n']
a23 [label = 'Answer 3 \\l\n\n']
a31 [label = 'Answer 1 \\l\n\n']
a32 [label = 'Answer 2 \\l\n\n']
a33 [label = 'Answer 3 \\l\n\n']
# creating horizontal lines
node [shape=none, width=0, height=0, label='']
{rank=same; tab1 -> m1}
{rank=same; tab2 -> m2}
{rank=same; tab3 -> m3}
{rank=same; tab4 -> m4}
# edge definitions with the node IDs
tab1 -> tab2 -> tab3 -> tab4 -> tab5->{tab6 tab7 tab8};
#--------> ATTACH NEW NODES
tab6 -> q1 -> a11
tab7 -> q2 -> a21 -> a22 -> a23
tab8 -> q3 -> a31 -> a32 -> a33
}
[1]: 'Raw Data n=434'
[2]: 'Agreed to participate n=406'
[3]: 'Over 18 years n=491'
[4]: 'smoke in past 3 months=403'
[5]: 'Final sample n=238'
[6]: 'Group1 n=82'
[7]: 'Group2 n=98'
[8]: 'Group3 n=88'
")
jpeg(file = "schematic.jpg")
schematic
Related
As you can guess from the title, I am trying to solve the following problem.
Given a grid of size NxN and a circular object O of radius R with centre C at (x_c, y_c), find which Blocks are occupied by O.
An example is shown in the figure below:
In that example, I expect the output to be [1,2,5,6].
I would be very grateful if anyone has a suggestion or resources.
Find the range of rows affected:
miny = floor(y_c-r);
maxy = ceil(y_c+r)-1;
For each row, find the range of columns by intersecting the circle with the horizontal line through it that has the largest intersection. There are 3 cases:
for (y=miny; y<=maxy; ++y) {
if (y+1 < y_c)
ytest = y+1;
else if (y > y_c)
ytest = y;
else
ytest = y_c;
// solve (x-x_c)^2 + (ytest-y_c)^2 = r^2
ydist2 = (ytest-y_c)*(ytest-y_c);
xdiff = sqrt(r*r - ydist2);
minx = floor(x_c - xdiff);
maxx = ceil(x_c + xdiff)-1;
for (x=minx; x<=maxx; ++x)
output(x,y);
}
I used Python3 and OpenCv but it can be done in any language.
Source:
import cv2
import numpy as np
import math
def drawgrid(im,xv,yv,cx,cy,r):
#params: image,grid_width,grid_height,circle_x,circle_y,circle_radius
cellcoords = set() #i use set for unique values
h,w,d = im.shape
#cell width,height
cew = int(w/xv)
ceh = int(h/yv)
#center of circle falls in this cells's coords
nx = int(cx / cew )
ny = int(cy / ceh )
cellcoords.add((nx,ny))
for deg in range(0,360,1):
cirx = cx+math.cos(deg)*r
ciry = cy+math.sin(deg)*r
#find cell coords of the circumference point
nx = int(cirx / cew )
ny = int(ciry / ceh )
cellcoords.add((nx,ny))
#grid,circle colors
red = (0,0,255)
green = (0,255,0)
#drawing red lines
for ix in range(xv):
lp1 = (cew * ix , 0)
lp2 = (cew * ix , h)
cv2.line(im,lp1,lp2,red,1)
for iy in range(yv):
lp1 = (0 , ceh * iy)
lp2 = (w , ceh * iy)
cv2.line(im,lp1,lp2,red,1)
#drawing green circle
cpoint = (int(cx),int(cy))
cv2.circle(im,cpoint,r,green)
print("cells coords:",cellcoords)
imw=500
imh=500
im = np.ndarray((imh,imw,3),dtype="uint8")
drawgrid(im,9,5, 187,156 ,50)
cv2.imshow("grid",im)
cv2.waitKey(0)
output: cells coords: {(3, 2), (3, 1), (2, 1), (2, 2), (4, 1)}
cells coords are zero based x,y.
So ...
1° cell top left is at (0,0)
2° cell is at (1,0)
3° cell is at (2,0)
1° cell of 2° row is at (0,1)
2° cell of 2° row is at (1,1)
3° cell of 2° row is at (2,1)
and so on ...
Getting cell number from cell coordinates might be fun for you
I followed this example since I was having issues removing white borders.
OP was told to add highlightthickness and change x0, y0 and y1 to 0. This worked all but for 1 px of white space/line? Any ideas? Thanks.
from tkinter import *
master = Tk()
master.configure(bg='#333333')
master.wm_attributes("-topmost", 1)
TopLevel.overrideredirect(True)
w = Canvas(master, width=150, height=40, bd=0, highlightthickness=0, relief='ridge',)
w.config()
w.pack(fill='both')
color = 100
x0 = 0
y0 = 0
x1 = 150
y1 = 0
while y0 < 20 :
r = color
g = color
b = color
rgb = r, g, b
Hex = '#%02x%02x%02x' % rgb
w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
color = color - 2
y0 = y0 + 1
y1 = y1 + 1
color = 10
while y0 < 40 :
r = color
g = color
b = color
rgb = r, g, b
Hex = '#%02x%02x%02x' % rgb
w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
color = color + 4
y0 = y0 + 1
y1 = y1 + 1
mainloop()
I changed the 4. and 7. line, because PyCharm gave me an error:
from tkinter import *
master = Tk()
tl = Toplevel() # delete me if the issue still remains :)
master.configure(bg='#333333')
master.wm_attributes("-topmost", 1)
tl.overrideredirect(True) # delete me if the issue still remains :)
...
if the issue still remains, try deleting 4. and 7. line.
Shouldn't make any problems
I am getting a blank and white image instead of the desired output, help?
from PIL import Image
def draw_nested_rectangles():
height = int(input('Please enter the overall height: '))
width = int(input('Please enter the overall width: '))
size = (width,height)
pic = Image.new('RGB',size,'white')
firstRec(width,height)
secondRec(width,height)
thirdRec(width,height)
fourthRec(width,height)
pic.show()
def firstRec(width,height):
size = (width,height)
pic = Image.new('RGB', size, 'white')
blueProgression = 0
for x in range(width,width):
color = (0,0,blueProgression)
for y in range(height,height):
pic.putpixel((x,y),color)
blueProgression += 5
def secondRec(width,height):
size = (width,height)
pic = Image.new('RGB', size, 'white')
greenProgression = 255
for x in range(int(width*0.15),int(width*0.85)):
color = (0,greenProgression,0)
for y in range(int(height*0.15),int(height*0.85)):
pic.putpixel((x,y),color)
greenProgression -= 5
def thirdRec(width,height):
size = (width,height)
pic = Image.new('RGB', size, 'white')
greenProgression = 255
for x in range(int(width*0.30),int(width*0.70)):
color = (255,0,0)
for y in range(int(height*0.30),int(height*0.70)):
pic.putpixel((x,y),color)
def fourthRec(width,height):
size = (width,height)
pic = Image.new('RGB', size, 'white')
greenProgression = 255
for x in range(int(width*0.45),int(width*0.55)):
color = (255,255,255)
for y in range(int(height*0.45),int(height*0.55)):
pic.putpixel((x,y),color)
I want my output to be four nested triangles the first one being 100% of the width and height (starting off black on the right side and gradually increasing to blue) and the second being nested in the first being 70% of the original width and height (starting off black on the left side and gradually increasing to green) and the third being nested in and being 40% the original (pure red) while the last is nested in and being 10% (pure white)
TRY:-
from PIL import Image
def draw_nested_rectangles():
global pic
height = int(input('Please enter the overall height: '))
width = int(input('Please enter the overall width: '))
size = (width,height)
pic = Image.new('RGB', size, 'white')
firstRec(width, height)
secondRec(width, height)
thirdRec(width, height)
fourthRec(width, height)
pic.show()
def firstRec(width,height):
global pic
size = (width,height)
blueProgression = 0
for x in range(width,width):
color = (0,0,blueProgression)
for y in range(height,height):
pic.putpixel((x,y),color)
blueProgression += 5
def secondRec(width,height):
global pic
size = (width,height)
greenProgression = 255
for x in range(int(width*0.15),int(width*0.85)):
color = (0,greenProgression,0)
for y in range(int(height*0.15),int(height*0.85)):
pic.putpixel((x,y), color)
greenProgression -= 5
def thirdRec(width,height):
global pic
size = (width,height)
greenProgression = 255
for x in range(int(width*0.30),int(width*0.70)):
color = (255,0,0)
for y in range(int(height*0.30),int(height*0.70)):
pic.putpixel((x,y),color)
def fourthRec(width,height):
global pic
size = (width,height)
greenProgression = 255
for x in range(int(width*0.45),int(width*0.55)):
color = (255,255,255)
for y in range(int(height*0.45),int(height*0.55)):
pic.putpixel((x,y),color)
pic = 0
draw_nested_rectangles()
REASON FOR UNDESIRABLE OUTPUT:-
The reason why you were getting a blank image, rather then the one you expected is because, you were creating a separate pic image object inside each function, due to which all the function were working on separate image objects rather then a single one.
FIX:-
In order to get the desired output, you have to define the pic variable as global, inside each function that want to use it, by using the syntax global pic
SAMPLE INPUT:-
Please enter the overall height: 500
Please enter the overall width: 500
SAMPLE OUTPUT:-
I create SVG output with dot. When I set penwidth = 2 for nodes and edges, the arrowheads point slightly inside the boxes. Is there a way to avoid this? Maybe by drawing the nodes after the edges? Or by reducing the length of the edges/arrows to 95%? I've tried to find an attribute that would allow this, but could not find something that worked.
NOTE: Effect can't be seen when converting to png or jpg. Create SVG with dot -Tsvg file.dot > file.svg and view in browser.
This is my dot file:
digraph configure {
node [
shape = box,
fontname = "Courier",
style = "filled",
fillcolor = "#cccccc",
penwidth = 2
];
A [label = "configure.in"];
B [label = "autoconf\nGNU m4", fillcolor = ".7 .3 1.0"];
C [label = "configure"];
X [label = "cfg.hin", fillcolor = "#eeeeee"];
Y [label = "cfg.h", fillcolor = "#eeeeee"];
edge [
fontname = "Palatino-Italic",
fontsize = 9,
penwidth = 2,
arrowsize = 1
];
A -> B [label = " is input to"];
B -> C [label = " creates"];
subgraph cfg {
rank = same;
rankdir = LR;
X -> C [label = "is input to "];
C -> Y [label = "creates "];
}
}
I have a simple graphiz graph that I am trying to render with dot. It is a series of self-loops on a single state:
digraph FST {
size = "8.5,11";
label = "";
rankdir=LR;
bgcolor = "transparent";
center = 1;
rank = same;
margin = 0;
orientation = Portrait;
0 [label = "0", shape = doublecircle, style = bold, fontsize = 14, color="#339933"]
0 -> 0 [label = "a", fontsize = 14];
0 -> 0 [label = "b", fontsize = 14];
0 -> 0 [label = "cd", fontsize = 14];
0 -> 0 [label = "efg", fontsize = 14];
0 -> 0 [label = "a", fontsize = 14];
0 -> 0 [label = "q", fontsize = 14];
0 -> 0 [label = "xyzabc", fontsize = 14];
}
I compile this like:
$ cat self-loop.dot | dot -Tpng > self-loop.png
The edges however, overlap the labels and looks ridiculous. Is there some way to prevent the edges from doing this? To make them flare out more?
Resulting Graph
I have had no luck scouring forums or the graphviz documentation.
Multi-loops are a pain. Using ports (https://www.graphviz.org/doc/info/attrs.html#k:portPos) helps. Bur rankdir also causes problems, so I changed it.
digraph FST {
size = "8.5,11";
label = "";
//rankdir=LR; // note the change in rankdir!!
bgcolor = "transparent";
center = 1;
rank = same;
margin = 0;
orientation = Portrait;
0 [label = "0", shape = doublecircle, style = bold, fontsize = 14, color="#339933"]
0:nw -> 0:ne [label = "a", fontsize = 14];
0:nw -> 0:ne [label = "\nb", fontsize = 14];
0:nw -> 0:ne [label = "\ncd", fontsize = 14];
0:nw -> 0:ne [label = "\nefg ", fontsize = 14];
0:nw -> 0:ne [label = " a ", fontsize = 14];
0:nw -> 0:ne [label = " q ", fontsize = 14];
0:nw -> 0:ne [label = "xyzabc", fontsize = 14];
}
Giving: