Varying marker label gaps for individual observations - label

I know that I can vary marker position using mlabv() and creating a position variable for individual points on my twoway scatter plot.
Is there a way to do a similar thing for mlabgap()?
I am trying to have certain points' labels a little further away from the rest to avoid overprinting.

http://www.stata.com/help.cgi?marker_label_options implies that the gap is constant in each graph call.
That does not rule out e.g.
scatter y x if group == 1. mlabel(foo) mlabgap(1) ///
|| scatter y x if group == 2, mlabel(foo) mlabgap(2)
Another trick is adding spaces as prefix or suffix to the marker label variable in various observations as needed.

Related

Store pixels from image along a line of points into an array

I have an image and I'm trying to store the pixel colors for a set of points along a line into an array.
The endpoints of the line and the distance between points is given. I know that the command line(x1,y1,x2,y2) draws a line between (x1,y1) and (x2,y2). I also know that .get() applied to an image returns the pixel color at the specified location.
I am unsure how to put it all together.
Essentially the problem is in two parts:
working out which pixel of the image you are over at each point along the line
Reading out that pixel value and storing it in an array
The second is fairly simple: https://processing.org/reference/PImage_get_.html will give you all the info you need about getting the pixel values at a certain coordinate.
The first is a maths problem essentially.
The line you draw will have the equation: Y = m * X + C where C is the intercept of the X axis and M is its gradient.
(One thing to remember is that the origin (0,0) for a processing sketch is at the top left)
https://www.mathsisfun.com/algebra/line-equation-2points.html is a good resource for this. The basic methodology is to calculate the gradient M and then set Y to 0 and equate m * X = -C

Create the appropriate space for variable axis labels

I have two arrays of strings: these two arrays contain the labels that are to be inserted on the x and y axis (these labels will be those of a heatmap).
nutsNames corresponds to the x axis (left to right) and the yearsNames corresponds to the y axis (top to bottom).
As the data may vary, I would like to create a way that fits the data.
So the problem is the positioning of the elements on the axes and the svg size.
What I would like to get is something like this:
The image shows two examples of different data.
(I don't want to show axes, I put them only to understand what is their direction).
Here is the plunker.
I thought about finding the longest string in nutsNames and multiplying it by a constant (which I don't know how to define) to create the minimum necessary width of the svg.
A similar thing I did it for years.
Obviously the code doesn't work.
What you can do is input some dummy numbers for the width,height and margins and let it draw the elements first. Now since all your axis labels are in a g , you can get the width of gs for x and y labels.
The group<g> tag wraps the contents inside it so getting its width/height will automatically give you the width/height of the largest text inside it.
Now you have the width and height of those gs, all that's left is to change the dimensions of the svg accordingly.
Try adding or removing labels in your data. Here's your Plunker

Creating Polygonal Objects with VB6

I am developing an application, where I need to be able to draw floor plans but I need the lines drawn to act more or less as object. For instance I need to be able to click on a Line, or in case that it is associated with a room, to highlight all the lines from a room.
I need not code samples necessarily, but also some quidance or ideas.
Thank You in advance!
create classes such as Line, Room etc.
Room contains a list of Lines.
A Line has the draw() and contains(x as integer, y as integer) methods.
To implement contains:
You can figure out the equation of the line given the starting and ending point. Then you could calculate the distance of a point (x0,y0) from that line (ax + by +c = 0) using the formula distance = abs(a*x0 + b*y0 + c) / sqrt(a * a + b*b)
if the distance is 4 pixels or less then contains should be true.
similar to the line, curves have an equation describing them.
For example Beziers and B-splines have corresponding equations.
Using those equations you can draw them and figure out the distance of the mouse from them.
For Bezier curves see:
http://blog.gludion.com/2009/08/distance-to-quadratic-bezier-curve.html
The circle for example it's the easiest.
distance = abs(radius - sqrt((mouseX - centerX)^2 + (mouseY - centerY)^2)

Distance between set of lines

Say that my images are simple shapes - set of lines, dots, curves, and simple objects,
How do I calculate the distance between images - so length is important but total scale is non important, location of line\curve is important, angles is important etc
Attached image For example:
My comparison object is a cube on the top left, score are fictitious just for this example.
that the distance to the Cylinder is 80 (has 2 lines but top geometry is different)
The bottom left cube score is 100 since it exact match lines with different scale.
The bottom right Rectangle score is 90 since it has exact match lines on the top but different scale lines on the side.
I am looking for algorithm name or general approach that will help me to start to think towards a solution....
Thank you for your help.
Here is something to get you started. When jumping into new problems, I don't see much value in trying a lot of complex steps just because they are available somewhere to use. So my focus is on using relatively simple things, that will fail in more varied situations, but hopefully you will see its value and get some sense of the problem.
The approach is fully based on corner detection; two typical methods for this detection are the Harris detector or the one by Shi and Tomasi described in the paper "Good Features to Track", 1994. I will use the second one, just because there is a ready implementation in OpenCV, newer Matlab, and possibly many other places. Its implementation on these packages also allows for easier parameter adjustment, regarding corner quality and minimum distance between corners. So, suppose you can detect all corner points correctly, how do you measure how close one shape is to another one based on these points ? The images have arbitrary size, so my idea is to normalize the point coordinates to the range [0, 1]. This solves for the scaling issue, which is desired according to the original description. Now we have to compare point sets in the range [0, 1]. Here we go for the simplest thing: consider one point p from the shape a, what is the closest point in shape b ? We assume it is one with the minimum absolute different between this point p and any point in b. If we sum all the values, we get a scoring between shapes. The lower the score, the more similar the shapes (according to this approach).
Here are some shapes I drew:
Here are the detected corners:
As you can clearly see in this last set of images, the method will easily confuse a rectangle/square with a cylinder. To handle that you will need to combine the approach with other descriptors. Initially, a simple one that you might consider is the ratio between the shape's area and its bounding box area (which would give 1 for rectangle, and lower for cylinder).
With the method described above, here are the measurements between the first and second shapes, first and third shapes, ..., respectively: 0.02358485, 0.41350339, 0.30128458 0.4980852, 0.18031262. The second cube is a resized version of the first one, and as you see, they are very similar by this metric. The last shape is a resized version of the first cube but without keeping the aspect ratio, and the metric gives a much higher difference.
If you want to play with the code that performs this, here it is (in Python, depends on OpenCV, numpy):
import sys
import cv2 as cv
import numpy
inp = []
for fname in sys.argv[1:]:
img_color = cv.imread(fname)
img = cv.cvtColor(img_color, cv.COLOR_RGB2GRAY)
inp.append((img_color, img))
ptsets = []
# Corner detection parameters.
params = (
200, # max number of corners
0.01, # minimum quality level of corners
10, # minimum distance between corners
)
# Params for visual circle markers.
circle_radii = 3
circle_color = (255, 0, 0)
for i, (img_color, img) in enumerate(inp):
height, width = img.shape
cornerMap = cv.goodFeaturesToTrack(img, *params)
corner = numpy.array([c[0] for c in cornerMap])
for c in corner:
cv.circle(img_color, tuple(c), circle_radii, circle_color, -1)
# Just to visually check for correct corners.
cv.imwrite('temp_%d.png' % i, img_color)
# Convert corner coordinates to [0, 1]
cornerUnity = (corner - corner.min()) / (corner.max() - corner.min())
# You might want to use other descriptors here. XXX
ptsets.append(cornerUnity)
def compare_ptsets(p):
res = numpy.zeros(len(p))
base = p[0]
for i in xrange(1, len(p)):
sum_min_diff = sum(numpy.abs(p[i] - value).min() for value in base)
res[i] = sum_min_diff
return res
res = compare_ptsets(ptsets)
print res
The process to be followed depends on what depth of features you are going to consider and accuracy required.
If you want something more accurate, search some technical papers like this which can give a concrete and well-proven approach or algorithm.
EDIT:
The idea from Waltz algorithm (one method in AI) can be tweaked. This is just my thought. Interpret the original image, generate some constraints out of it. For each candidate, find out the number of constraints it satisfies. The one which satisfies more constraints will be the most similar to the original image.
Try to calculate mass center for each figure. Treat each point of figure as particle with mass equal 1.
Then calculate each distance as sqrt((x1-x2)^2 + (y1-y2)^2), where (xi, yi) is mass center coordinate for figure i.

Method for combining tiled squares defined as points into vectors

If I tile squares, and the squares can be defined by their coordinates, how can I simplify shapes made of multiple squares into vectors that define each edge of the entire shape? Pseudo-code or general terms are fine.
The first thing I can think of is (probably not the most efficient way) :
1) Get the bounding box of your entire tiling - which is min(x), min(y) to max(x), max(y) for all x and y of your tiles
2) For every row, start with STATE==EMPTY, iterate over each column : STATE changes to FULL when you hit a square, and EMPTY when you find a hole. Every time STATE goes from EMPTY to FULL, save the left hand line segment of that square and every time STATE goes from FULL to EMPTY, save the right hand line segment of that square.
3) Repeat above in the Y axis
Now you have a set containing only the outermost line segments, you can combine those that are co-linear etc and get the overall shape.
This will work for non-convex shapes and also if you have holes in your tiling.

Resources