How to control matplotlib annotate (arrow more specifically) in terms of size of figure? - matplotlib

I'd like to draw arrows in my plots, iif there is enough size for the arrow to be displayed properly (ie, with arrow and tail in the right position). Is there any way to control this in code?
For a better explanations, here is the problem explained in 3 examples: in this 1st figure, the arrow shouldn't be displayed as the arrow should go from the dotted line to the solid black line, and in this case there is not enough space for a proper visualisation.
When the same image is zoomed, the arrow behaves correctly though:
Here goes a final example, with a figure in its normal size (without zoom) where the arrow behaves correctly and should be drawn.
In conclusion, in case 1 I would like the arrow not to be drawn (not enough space for a correct visualisation) and to be drawn in the other cases.

Related

Psychtoolbox scale slider

I'm trying to make a slider for a simple scale where the user can see mouse movement ONLY in the horizontal axis (fixed y location on the horizontal scale).
In more detail: When the scale appears, I want the cursor to appear as a short vertical line (aka slider) in the center of the horizontal scale.
When the user moves the mouse, the slider should move accordingly on the horizontal axis (without reflecting any changes in the vertical axis, i.e. it should stay on the scale)
I'm stuck on both changing the appearance of the cursor to a vertical line slider and on limiting the cursor's movement to the horizontal axis.
Here's what I've tried:
I can successfully place the cursor with SetMouse.
I tried ShowCursor to change the appearance of the cursor, but this only has a few named options and the numbered ones are not portable across OSs ("mapping of numbers to shapes is operating system dependent"), which I need. Any other ideas on how to change the cursor to a vertical line slider?
As for limiting the movement to horizontal, I couldn't find any PTB functions that seem to do this. I did find some workarounds in Matlab to make user GUIs, but it seems these can't be used with PTB's screen. Any ideas would be great!
I'm a still very new to PTB so thank you so much for your help!
I wrote a function for exactly that called slideScale. If you want to see how it works see the test script.
The crucial thing for you is to create a loop, which runs until a click has been made and record the position of the cursor for instance with the function GetMouse(), which gives you the x- and y-coordinates of the cursor. Then, the only thing you basically need is to update the position of your vertical line using the x-coordinate you recorded with GetMouse() without changing the y-coordinates, for which you can just use a fixed value.

How to build a Head Up Display in OpenSceneGraph that resizes depending on the screen's resolution?

I'm pretty new to OpenSceneGraph and I have the following problem:
I'm trying to build a 2D Head Up Display out of several images, so that it can resize depending on the screen's resolution. That means I have extra images for the corners and one image for the bar that connects the corners and so on.
Well, that's the idea. But I have no clue how to do that in OpenSceneGraph.
Can anybody help me?
So, when the window resizes, you'll get an event from osgViewer telling you about the change.
You need to resize your viewport when the window size changes, so your HUD geometry has some idea of what the pixel-size of the display is (most of the HUD examples setup for a nominal 1024x768 screen and then just let that stretch around as the window is resized, pretending like the new viewport is still 1024x768).
Once you've resized the viewpoer, you need to rearrange your geometry. Your corner pieces need to be laid out at the fixed pixel size you want them to always appear, then you need your connecting elements to change size, horizontally or vertically, to fill the space between the corner pieces. You usually rely on texture stretching or repeating to fill the space as the piece of geometry gets stretched.
If none of that makes any sense, I can describe more.

Drawing two shadows on text (Core Graphics)

I'm tying to draw two different shadows on some text to create an embossed effect. Here's the portion of my drawInRect where I draw the text with the first shadow (all the variables used are already defined):
CGContextSetShadowWithColor(context, textInnerShadowOffset, textInnerShadowBlurRadius, textInnerShadowColor.CGColor);
[textColor setFill];
[self.text drawInRect:rect withFont:self.font lineBreakMode:self.lineBreakMode alignment:self.textAlignment];
But now I'm faced with the problem of drawing the second shadow. I assume I'll need to change the shadow and draw the text again, but I need to do so without adding another copy of the text.
How can I draw text without really drawing the text itself? Changing the fill color to clearColor doesn't work. I've seen people use clipping masks for this, but AFAICT that will only work for simple shapes, not text.
Alternatively, is there an easier way to draw two shadows on the same text?
Two options, depending on the exact effect you want:
If you want the first, "upper" shadow to also contribute to the second, "lower" shadow underneath it, use a transparency layer.
Set your CGContext's shadow for the "lower" shadow
Create a transparency layer using CGContextBeginTransparencyLayer
Set the context's shadow for the "upper" shadow
Draw your text
End the transparency layer using CGContextEndTransparencyLayer
(Note that transparency layers can be quite expensive. It's best to call CGContextBeginTransparencyLayerWithRect and pass in as small a rect as you can.)
If you want the shadows to be independent -- the only thing that contributes to each shadow is the text -- you'll need to use a trick.
Set up the shadow with an additional large offset, big enough so that you can draw the text outside of the bounds of your context and have the shadow land in the correct place. That way you'll see only the shadow, but not the text.
Figure out what offset is "big enough". It will probably depend on the size of the context you're drawing into (based on your view), and maybe the bounds of the text.
Or, just fudge it: pick an absurdly large value like 5000 pt.
Set up your shadow. Add the big offset to its normal y offset.
Draw the text, offset vertically by the big offset.
Repeat 1-3 for each "lower" shadow, from back to front. Afterwards, draw the text and the "uppermost" shadow last, without the offset.

How to create letterpress effect?

I'm looking to implement something like the famous "letterpress" effect in my application. Here's what I'm talking about: (just a quick example made in PShop)
As you can see, it looks like it's pressed into the background. I wonder if it's possible to do something like this on the Mac dynamically. Is there a way? Thanks!
You can do the gradient fill portion of the text using the code I provide in this answer. Check the coordinate space first, because I described that for the iPhone, which has an inverted Y axis when compared to the Mac's normal Quartz coordinates.
The text is first used to create a clipping path, and the gradient is drawn within that path.
As far as the internal shadow, you might be able to draw this after the gradient is drawn by using CGContextSetShadowWithColor() with an appropriate downward offset and black color, then drawing the text again using just the stroke of the text. deanWombourne has some sample code for a similar task in his answer here.
Draw the text with a normal font to create a black and white bitmap of the text.
Draw another image that is is the same size and completely filled with the gray-to-white gradient you have above.
Create a completely white image with the same size as your other images.
Draw your back and white text image (1) onto the white image (3) with NSCompositeDestinationOut.
This gives you a white image with your text cut out.
Draw the white image with the text cut out on top of the gradient image and apply a shadow while drawing.

Rectangles & Parsing in vb.net

This is kinda....a two part question. The first one is much more important than the second one, both of these are in the same project, and in vb.net.
How can I constrain the bounds of a rectangle object, which is controlled by a mouse, so it cannot be drawn outside a PictureBox? It is kindof a standard lasso control, the user can click and drag and it will draw a box from the initial click point to the mouse's current location. The starting point is at (rectX,rectY), and the box is drawn to the bottom right using rectDimX and rectDimY (to set the width and height) to see how much of a change has occurred with the mouse. Basically, its what you get with a click and drag on a Windows desktop. The issue here is that the rectangle is able to be drawn outside the PictureBox it is being drawn on, and the next part of the code attempts to reference this location, and then fails with an OutOfMemory exception. This leads me to my second question:
How can I make the rectangle draw in more than the fourth quadrant, which is only positive numbers? If it goes anywhere else, it does not show the rectangle, though it does still have the correct values. I know i could code this four times based on starting location and mouse location, but that would be a huge hassle and a rewrite of the whole rectangle code.
Is there an easy solution for either of these? The first one is a much bigger hassle, as it will be very time consuming if there is no easy way.
Thanks for the help!
For the first part of your question, even if the user drags the mouse beyond the edge of your picture box, you don't have to use those coordinates for your drawing routine. Simply do something like
If (DrawingPoint.X > PictureBox.Right)
DrawingPoint.X = PictureBox.Right // Right-hand limit of picture box
End If
And similar for the Y direction.
As for the negative numbers while drawing, you want to translate screen coordinates to client area coordinates. Have a look at ScreenToClient and ClientToScreen.