In help(plt.bar) of matplotlib version 2.0.0, it says that the bars are
[...] with rectangles bounded by:
`left`, `left` + `width`, `bottom`, `bottom` + `height`
(left, right, bottom and top edges)
Yet, calling plt.bar(0, 1) produces
which does not start at left == 0, but instead at left - width/2 == -0.4. How to fix this?
Short answer:
plt.bar(0, 1, align="center")
Why:
The documentation on github says to use align=edge:
The default is now
(x - width/2, x + width/2, bottom, bottom + height)
[...] The align keyword-only argument controls if x is interpreted
as the center or the left edge of the rectangle.[...]
align : {'center', 'edge'}, optional, default: 'center'
If 'center', interpret the *x* argument as the coordinates
of the centers of the bars. If 'edge', aligns bars by
their left edges
To align the bars on the right edge pass a negative
*width* and ``align='edge'``
Related
I want my vue Konva Text element to completely fill the given height, like i expect of a rectangle.
This is issue becomes obvious when pairing with text images, (converting svg text to canvas) that properly match the given dimension
<v-text :config={
x: 50,
y: 50,
width: 1000,
height: 60,
fontSize: 60,
fontStyle: 'bold',
fontFamily 'Campton Book'
text: 'WELT'
}
/>
<v-rect
:config="{ x: 50, y: 50, fill: 'black', height: 60, width: 200 }"
/>
Second Part, is there any way to always pixel perfectly align the left side with the border? the x coordinate matches the border
Is this due to font constraints? What am I missing?
I tried to get the height of the text node to fix this positioning but this is the given height passed down as props
Text is defined as having parts above and below the baseline. Above is termed 'ascenders' amd below is 'descenders', which are required for lower case letters like j y g.
Setting the text fontSize to 60 does not say 'whatever the string, make it fill a space 60px high'. Instead it says 'Make text in a 60px font', which makes space for the descenders because they will generally be required.
If you know for sure that the text will be all caps, then a solution is to measure the height used and increase the font size by a computed factor so that the font fills the line height.
To do this you'll need to get the glyph measurements as follows:
const lineHeight = 60; // following your code
// make your text shape here...left out for brevity
const metrics = ctx.measureText('YOUR CAPS TEXT');
capsHeight = Math.abs(metrics.actualBoundingBoxAscent)
fontSize = lineHeight * lineHeight / capsHeight;
If I got that right, your 60px case should give a value around 75. That's based on the convention that ascenders are 80% of the line height. Now you set the font size of your shape to this new value and you should be filling the entire line height.
Regarding the left-alignment, this relies on what the font gurus call the a-b-c widths. The left gap is the a-space, the b is the character width (where the ink falls) and the c-space is the same as the a-space but on the right hand side.
Sadly unless someone else can tell me I am wrong, you don't get a-b-c widths in the canvas TextMetric. There is a workaround which is rather convoluted but viable. You would draw the text in black on an off-screen canvas filled with a transparent background. Then get the canvas pixel data and walk horizontal lines from the left of the canvas inspecting pixels and looking for the first colored pixel. Once you find it you have the measurement to offset the text shape horizontally.
I've made a list of my own texture objects so that I can access them accordingly. These are the two bitmap images I'm using:
Every time I load my program, it reads from the two bitmap files and stores their texture data into my global texture list. The grass tile one loads first and then the checkerboard with the 1.0 loads after it. The grass tile texture renders. Here is how it looks like in my program:
It appears as if It's rotated 180 degrees and flipped horizontally. I've checked my 2d projection, coordinates and they're alright. Up goes towards positive Y, right towards positive X which, is fine. Also, the colors are alright, the texture works!
However, if I choose to render the second texture, which is the black/magenta checkerboard, it looks like this in my program:
It's rotated and flipped as well, but the colors aren't being rendered properly either. Why does this happen? Here is my code:
Loading the texture from Bitmap:
Private Function LoadFromBitmap(ByVal Bitmap As Bitmap) As Integer
Dim Tex As Integer
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest)
GL.GenTextures(1, Tex)
GL.BindTexture(TextureTarget.Texture2D, Tex)
Dim Data As BitmapData = Bitmap.LockBits(New Rectangle(0, 0, Bitmap.Width, Bitmap.Height), ImageLockMode.ReadOnly, Imaging.PixelFormat.Format32bppArgb)
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Data.Width, Data.Height, 0, OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, Data.Scan0)
Bitmap.UnlockBits(Data)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, TextureMagFilter.Nearest)
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, TextureMinFilter.Nearest)
Return Tex
End Function
Rendering:
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
GL.Viewport(0, 0, ControlWidth, ControlHeight)
For X As Byte = 0 To EZSize(0) - 1
For Y As Byte = 0 To EZSize(1) - 1
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
Next
Next
GL.LoadIdentity()
GL.Flush()
GraphicsContext.CurrentContext.SwapInterval = True
GlControl1.SwapBuffers()
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
This causes that the color of the texels of the texture is "mixed" by the last color which you have set by glColor.
Set a "white" color before you render the texture, to solve your issue:
GL.Color3(Color.White)
The texture is flipped, because the lower left window coordinate is (0,0), but in the texture the upper right coordinate is (0, 0). You've to compensate that by flipping the v-component of the texture coordinate:
e.g.:
GL.Enable(EnableCap.Texture2D)
GL.BindTexture(TextureTarget.Texture2D, TextureList.Item(1).IntData)
GL.Color3(Color.White)
GL.Begin(PrimitiveType.Quads)
GL.TexCoord2(X, Y + 1) : GL.Vertex2(X, Y)
GL.TexCoord2(X + 1, Y + 1) : GL.Vertex2(X + 1, Y)
GL.TexCoord2(X + 1, Y) : GL.Vertex2(X + 1, Y + 1)
GL.TexCoord2(X, Y) : GL.Vertex2(X, Y + 1)
GL.End()
GL.Disable(EnableCap.Texture2D)
Likewise you can change the environment mode to GL_REPLACE, instead by glTexEnv:
GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, GL_REPLACE)
I'm just starting to learn opengl so I may not know all things. Using OpenTK with VB.net.
I have this code:
Dim pm As Matrix4 = Matrix4.CreatePerspectiveFieldOfView(1.57, 16 / 9, 0.1, 100)
GL.MatrixMode(MatrixMode.Projection)
GL.LoadMatrix(pm)
GL.Begin(PrimitiveType.Triangles)
GL.Vertex3(0, 0, -1) : GL.Color4(1.0!, 0!, 0!, 1.0!)
GL.Vertex3(1, 0, -1) : GL.Color4(0.0!, 1.0!, 0!, 1.0!)
GL.Vertex3(0, 1, -1) : GL.Color4(0.0!, 0.0!, 1.0!, 1.0!)
GL.End()
This correctly draws the triangle.
But when I change the z co-ordinate to +ve, they disappear. Like when GL.Vertex3(0, 0, +1), that vertex disappears. When all 3 vertices' z coords are +ve then nothing is visible.
I thought that this was because of some matrix stuff so I added a translation to the 'pm' matrix defined above:
Matrix4.CreateTranslation(0, 0, +1.0!, pm)
Still nothing happens.
But when all are -ve then all is good:
GL.Vertex3(0, 0, -10) : GL.Color4(1.0!, 0!, 0!, 1.0!)
GL.Vertex3(1, 0, -10) : GL.Color4(0.0!, 1.0!, 0!, 1.0!)
GL.Vertex3(0, 1, -10) : GL.Color4(0.0!, 0.0!, 1.0!, 1.0!)
Note: I've followed this guide. His code seems to have the same problem though no one addressed it. His code
Can someone explain this stuff to me? Thanks in advance.
In OpenGL one usually assumes that the camera is looking in -z direction (it's a convention, not a limit). Due to this, projection matrices are usually constructed in a way that they map the interval between [-nearPlane, -farPlane] to the visible depth region.
If you want to look in positive z, then you have to add a additional viewing matrix that rotates the camera by 180° around the y-axis (Or one that simply mirrors the z-axis but then the winding order changes).
I'm drawing a map of hexagons inside a UIView and the next step is to give it in isometric view. To do this, I transformed the map using the CGAffineTransform, rotation and scaling, reaching my goal.
Now, if the map becomes bigger, when i rotate it, the lower left corner goes out my screen, this is the frame before and after the transformation:
2012-03-07 17:08:06.160 PratoFiorito[941:f803] X: 0.000000 - Y: 0.000000 || Width: 1408.734619 - Height: 1640.000000
2012-03-07 17:08:06.163 PratoFiorito[941:f803] X: -373.523132 - Y: 281.054779 || Width: 2155.781006 - Height: 1077.890503
I simply can't understand what is the new point of origin and how I can calculate it to replace the view correctly. Somebody can help me?
I've got a little objective-c utility program that renders a convex hull. (This is to troubleshoot a bug in another program that calculates the convex hull in preparation for spatial statistical analysis). I'm trying to render a set of triangles, each with an outward-pointing vector. I can get the triangles without problems, but the vectors are driving me crazy.
I'd like the vectors to be simple cylinders. The problem is that I can't just declare coordinates for where the top and bottom of the cylinders belong in 3D (e.g., like I can for the triangles). I have to make them and then rotate and translate them from their default position along the z-axis. I've read a ton about Euler angles, and angle-axis rotations, and quaternions, most of which is relevant, but not directed at what I need: most people have a set of objects and then need to rotate the object in response to some input. I need to place the object correctly in the 3D "scene".
I'm using the Cocoa3DTutorial classes to help me out, and they work great as far as I can tell, but the rotation bit is killing me.
Here is my current effort. It gives me cylinders that are located correctly, but all point along the z-axis (as in this image:. We are looking in the -z direction. The triangle poking out behind is not part of the hull; for testing/debugging. The orthogonal cylinders are coordinate axes, more or less, and the spheres are to make sure the axes are located correctly, since I have to use rotation to place those cylinders correctly. And BTW, when I use that algorithm, the out-vectors fail as well, although in a different way, coming out normal to the planes, but all pointing in +z instead of some in -z)
from Render3DDocument.m:
// Make the out-pointing vector
C3DTCylinder *outVectTube;
C3DTEntity *outVectEntity;
Point3DFloat *sideCtr = [thisSide centerOfMass];
outVectTube = [C3DTCylinder cylinderWithBase: tubeRadius top: tubeRadius height: tubeRadius*10 slices: 16 stacks: 16];
outVectEntity = [C3DTEntity entityWithStyle:triColor
geometry:outVectTube];
Point3DFloat *outVect = [[thisSide inVect] opposite];
Point3DFloat *unitZ = [Point3DFloat pointWithX:0 Y:0 Z:1.0f];
Point3DFloat *rotAxis = [outVect crossWith:unitZ];
double rotAngle = [outVect angleWith:unitZ];
[outVectEntity setRotationX: rotAxis.x
Y: rotAxis.y
Z: rotAxis.z
W: rotAngle];
[outVectEntity setTranslationX:sideCtr.x - ctrX
Y:sideCtr.y - ctrY
Z:sideCtr.z - ctrZ];
[aScene addChild:outVectEntity];
(Note that Point3DFloat is basically a vector class, and that a Side (like thisSide) is a set of four Point3DFloats, one for each vertex, and one for a vector that points towards the center of the hull).
from C3DTEntity.m:
if (_hasTransform) {
glPushMatrix();
// Translation
if ((_translation.x != 0.0) || (_translation.y != 0.0) || (_translation.z != 0.0)) {
glTranslatef(_translation.x, _translation.y, _translation.z);
}
// Scaling
if ((_scaling.x != 1.0) || (_scaling.y != 1.0) || (_scaling.z != 1.0)) {
glScalef(_scaling.x, _scaling.y, _scaling.z);
}
// Rotation
glTranslatef(-_rotationCenter.x, -_rotationCenter.y, -_rotationCenter.z);
if (_rotation.w != 0.0) {
glRotatef(_rotation.w, _rotation.x, _rotation.y, _rotation.z);
} else {
if (_rotation.x != 0.0)
glRotatef(_rotation.x, 1.0f, 0.0f, 0.0f);
if (_rotation.y != 0.0)
glRotatef(_rotation.y, 0.0f, 1.0f, 0.0f);
if (_rotation.z != 0.0)
glRotatef(_rotation.z, 0.0f, 0.0f, 1.0f);
}
glTranslatef(_rotationCenter.x, _rotationCenter.y, _rotationCenter.z);
}
I added the bit in the above code that uses a single rotation around an axis (the "if (_rotation.w != 0.0)" bit), rather than a set of three rotations. My code is likely the problem, but I can't see how.
If your outvects don't all point in the correct directino, you might have to check your triangles' winding - are they all oriented the same way?
Additionally, it might be helpful to draw a line for each outvec (Use the average of the three vertices of your triangle as origin, and draw a line of a few units' length (depending on your scene's scale) into the direction of the outvect. This way, you can be sure that all your vectors are oriented correctly.
How do you calculate your outvects?
The problem appears to be in that glrotatef() expects degrees and I was giving it radians. In addition, clockwise rotation is taken to be positive, and so the sign of the rotation was wrong. This is the corrected code:
double rotAngle = -[outVect angleWith:unitZ]; // radians
[outVectEntity setRotationX: rotAxis.x
Y: rotAxis.y
Z: rotAxis.z
W: rotAngle * 180.0 / M_PI ];
I can now see that my other program has the inVects wrong (the outVects below are poking through the hull instead of pointing out from each face), and I can now track down that bug in the other program...tomorrow: