When I'm generating graphics for publications and talks, I tend to use ggplot2. However, for very large data sets where I want to generate a quick plot or for courses where students don't have a good grounding in R, I use the base graphics.
Are there any nice (simple!) ways of spicing up R graphics? For example, do you use a nice combination of colours and line types. I tend to do something like:
#Functional but not that nice
plot(x1,y1, type="l")
lines(x2, y2, col=2, lty=2)
In particular, I'm thinking about the plot, hist, and density functions, but I suppose this question applies to all base R graphics.
Learn to use par. At the very least, make the y-axis label horizontal with par(las = 1). Manually adjusting margins with the mar and oma settings of par are also useful.
Use hue-chroma-luminance (HCL) colours, via the vcd package, especially for plots involving area (histograms or whatever).
The first half of Paul Murrell's R Graphics gives you advice on customising base graphics. If you want more general advice on drawing good graphs, Stephen Few's Now You See It is my personal favourite, and Edward Tufte's books are all staples.
As an alternative to teaching base graphics, you could use latticist to make lattice easier to learn.
I often skip position 3 in the default palette (green) because it generates dichromat-unfriendly plots. I should probably use palette(palette()[c(1:2,4:8,3)]) to do this automatically, but I tend to just do it by hand. I recommend the RColorBrewer package too.
Andrew Gelman (a pretty well-known statistician at Columbia with a very entertaining blog) would like you to adjust the margin and tick spacing.
Related
For one of my classes, I made a 3D graphing application (using Visual Basic). It takes in a string (z=f(x,y)) as input, parses it into RPN notation, then evaluates and graphs the equation. While it did work, it took about 20 seconds to graph. I would have liked to add slide bars to rotate the graph vertically and horizontally, but it was definitely too slow to allow that.
Does anyone know what programming languages would be best for this type of thing? Ideally, I will be able to smoothly rotate the function once it is graphed.
Also, I’m trying to find a better way to rotate the function. Right now, I evaluate it at a bunch of points, and then plot the points to the screen. Every time it is rotated, it must be re-evaluated and plot all the new points. This takes just as long as the original graph process, as it basically treats it as a completely new function.
Lastly, I need a better way to display the graph. Currently (using VB with visual studio) I plot 200,000 points to a chart, but this does not look great by any means. Eventually, I would like to be able to change color based on height, and other graphics manipulation to make it look better.
To be clear, I am not asking for someone to do any of this for me, but rather the means to go about coding this in an efficient way. I will greatly appreciate any advice anyone can give to help with any of these three concerns.
So I will explain how I would go about it using C++ and OpenGL. This doesn't mean those are the tools that you must use, it's just those are standard graphics tools.
Your function's surface is essentially a 2D manifold, which has the nice property of having an intuitive mapping to a 2D space. What is commonly referred to as UV mapping.
What you should do is pick the ranges for the rectangle domain you want to display (minimum x, maximum x, minimum y, maximum y) And make 2 nested for loops of the form:
// Pseudocode
for (x=minimum; x<maximum; x++)
for (y=minimum; y=maximum; y++)
3D point = (x,y, f(x,y))
Store all of these points into a container (std vector for c++ works fine) and this will be your "mesh".
This is done once, prior to rendering. You then render those points using, for example GL_POINTS, and rotate your graph mesh using rotations on the GPU.
This will only show scattered points, not a surface.
If you also wish to show the surface of your function, and not just the points, you can triangulate that set of points fairly easily.
Group each 4 contiguous vertices (i.e the vertices at indices <x,y>, <x+1,y>, <x+1,y>, <x+1,y+1>) and create the 2 triangles:
(<x,y>, <x+1,y>, <x,y+1>), (<x+1,y>, <x+1,y+1>, <x,y+1>)
This will fill triangulate the surface of your mesh.
Essentially you only need to build your mesh once, and this way rendering should be 60 fps for something with 20 000 vertices, regardless of whether you only render points or triangles too.
Programming language is mostly not relevant, so VB itself is probably not the issue. You can have the same issues in Python, C#, C++, etc. Of course you must master the programming language you choose.
One key aspect is using the right algorithms and data-structures. Proper use of memory allocations and memory layout for maximizing CPU (and GPU) cache are also key. Then you must take advantage of the platform and hardware capabilities (GPU and Multithreading). For the last point you definetely need to use a graphics library such as OpenGL or Vulkan.
I have a spatial dataset that consists of a large number of point measurements (n=10^4) that were taken along regular grid lines (500m x 500m) and some arbitrary lines and blocks in between. Single measurements taken with a spacing of about 0.3-1.0m (varying) along these lines (see example showing every 10th point).
The data can be assumed to be normally distributed but shows a strong small-scale variability in some regions. And there is some trend with elevation (r=0.5) that can easily be removed.
Regardless of the coding platform, I'm looking for a good or "the optimal" way to interpolate these points to a regular 25 x 25m grid over the entire area of interest (5000 x 7000m). I know about the wide range of kriging techniques but I wondered if somebody has a specific idea on how to handle the "oversampling along lines" with rather large gaps between the lines.
Thank you for any advice!
Leo
Kriging technique does not perform well when the points to interpolate are taken on a regular grid, because it is necessary to have a wide range of different inter-points distances in order to well estimate the covariance model.
Your case is a bit particular... The oversampling over the lines is not a problem at all. The main problem is the big holes you have in your grid. If think that these holes will create problems whatever the interpolation technique you use.
However it is difficult to predict a priori if kriging will behave well. I advise you to try it anyway.
Kriging is only suited for interpolating. You cannot extrapolate with kriging metamodel, so that you won't be able to predict values in the bottom left part of your figure for example (because you have no point here).
To perform kriging, I advise you to use the following tools (depending the languages you're more familiar with):
DiceKriging package in R (the one I use preferably)
fields package in R (which is more specialized on spatial fields)
DACE toolbox in matlab
Bonus: a link to a reference book about kriging which is available online: http://www.gaussianprocess.org/
PS: This type of question is more statistics oriented than programming and may be better suited to the stats.stackexchange.com website.
Crayon Physics Deluxe is a commercial game that came out recently. Watch the video on the main link to get an idea of what I'm talking about.
It allows you to draw shapes and have them react with proper physics. The goal is to move a ball to a star across the screen using contraptions and shapes you build.
While the game is basically a wrapper for the popular Box2D Physics Engine, it does have one feature that I'm curious about how it is implemented.
Its drawing looks very much like a Crayon. You can see the texture of the crayon and as it draws it varies in thickness and darkness just like an actual crayon drawing would look like.
(source: kloonigames.com)
(source: kloonigames.com)
The background texture is freely available here.
What kind of algorithm would be used to render those lines in a way that looks like a Crayon? Is it a simple texture applied with a random thickness and darkness or is there something more going on?
I remember reading (a long time ago) a short description of an algorithm to do so:
for the general form of the line, you split the segment in two at a random point, and move this point slightly away from it's position (the variation depending on the distance of the point to the extremity). Repeat recursively/randomly. In this way, you lines are not "perfect" (straight line)
for a given segment you can "overshoot" a little bit, by extending one extremity or the other (or both). In this way, you don't have perfect joints. If i remember well, the best was to extends the original extremities, but you can do this for the sub-segment if you want to visibly split them.
draw the lines with pattern/stamp
there was also the (already mentioned) possibility to drawn with different starting and ending opacity (to mimic the tendency to release the pen at the end of drawing)
You can use a different size for the stamp on the beginning and the end of the line (also to mimic the tendency to release the pen at the end of drawing). For the same effect, you can also draw the line twice, with a small variation for one of the extremity (be careful with the alpha in this case, as the line will be drawn twice)
Last, for a given line, you can do the previous modifications several times (ie draw the line twice, with different variations) : human tend to repeat a line if they make some mistakes.
Regards
If you blow the image up you can see a repeating stamp-pattern .. there's probably a small assortment that it uses as it moves from a to b - might even rotate them ..
The wavering of the line can't be all that difficult to do. Divide into a bunch of random segments, pick positions slightly away from the direct route and draw splines.
Here's a paper that uses a lot of math to simulate the deposition of wax on paper using a model of friction. But I think your best bet is to just use a repeating pattern, as another reader mentioned, and vary the opacity according to pressure.
For the imperfect line drawing parts, I have a blog entry describing how to do it using bezier curves.
You can base darkness on speed. That's just measuring the distance traveled by the cursor between this frame and the last frame (remember Pythagorean theorem) and then when you go to draw that line segment on screen, adjust the alpha (opacity) according to the distance you measured.
There is a paper available called Mimicking Hand Drawn Pencil Lines which covers a bit of what you are after. Although it doesn't present a very detailed view of the algorithm, the authors do cover the basics of the steps that they used.
This paper includes high level descriptions of how they generated the lines, as well as how they generated the textures for the lines, and they get results which are similar to what you want.
This article on rendering chart series to look like XKCD comics has an algorithm for perturbing lines which may be relevant. It doesn't cover calculating the texture of a crayon drawn line, but it does offer an approach to making a straight line look imperfect in a human-like way.
Example output:
I believe the easiest way would simply be to use a texture with random darkness (some gradients, maybe) throughout, and set size randomly.
I'm toying with the idea of volumetric particles. By 'volumetric' I don't mean actually 3D model per particle - usually it's more expensive and harder to blend with other particles. What I mean is 2D particles that will look as close as possible to be volumetric.
Right now what I/we have tried is particles with additional local Z texture (spherical for example), and we conduct the alpha transparency according to the combination of the alpha value and the closeness by Z which is improved by the fact that particle does not have a single planar Z.
I think a cool add would be interaction with lighting (and shadows as well), but here the question is how will the lighting formula look like (taking transparency into account, let's assume that we are talking about smoke and dust/clouds and not additive blend) - any suggestions would be welcomed.
I also though about adding normal so I can actually squeeze all in two textures:
Diffuse & Alpha texture.
Normal & 256 level precision Z channel texture.
I ask this question to see what other directions can be thought of and to get your ideas regarding the proper lighting equation that might be used.
It sounds like you are asking for information on techniques for the simulation of participating media: "Participating media may absorb, emit and/or scatter light. The simplest participating medium only absorbs light. That means that light passing through the medium is attenuated depending on the density of the medium."
Here are some links to some example images and to Frisvad, Christensen, Jensen's the SIGGRAPH 2007 paper (including the PDF).
A nice paper on using spherical billboards to represent volumetric effects:
http://www.iit.bme.hu/~szirmay/firesmoke_link.htm
Doesn't handle particpating media, though.
See Volume Rendering and Voxel.
I have an array of mouse points, a stroke width, and a softness. I can draw soft circles and soft lines. Which algorithm should I use for drawing my array of points? I want crossed lines to look nice as well as end points.
I would definitely choose the Bezier for that purpose, and in particular I will implement the piecewise cubic Bezier - it is truly easy to implement and grasp and it is widely used by 3D Studio max and Photoshop.
Here is a good source for it:
http://local.wasp.uwa.edu.au/~pbourke/surfaces_curves/bezier/cubicbezier.html
Assuming that you have an order between the points, in order to set the four control points you should go as follows:
I define the tangent between point P[i] and point P[i+1]
T1 = (P[i+1] - P[i-1])
T2 = (P[i+2] - P[i])
And to create the piecewise between two points I do the following:
Control Point Q1: P[i]
Control Point Q2: the point lying along the tangent from Q1 => Q1 + 0.3T1
Control Point Q3: the point lying along the tangent to Q4 => Q4 - 0.3T2
Control Point Q4: P[i+1]
The reason I chose 0.3T is arbitrary in order to give it enough 'strength' but not too much, you can use more elaborated methods that will take care of acceleration (C2 continuity) as well.
Enjoy
Starting from Gooch & Gooch's Non-Photorealistic Rendering, you might find Pham's work useful - see PDF explaining algorithm.
There's a nice overview article by Tateosian which explains the additional techniques in less detail with pretty pictures.Bezier curve drawing alone doesn't produce the effects you want (depending on how fancy you want to get). However, I'd certainly start with Paul's work and see if just using that to draw with your soft brush is good enough.
Be warned there are lots of patents in this space, sigh.
I think maybe you're looking for a spline algorithm.
Here is a spline tutorial, which you might find helpfull:
[http://www.doc.ic.ac.uk/~dfg/AndysSplineTutorial/index.html]
The subject is also covered in most books on graphics programming.
Cheers.
I figured it out - use a very soft gradient circle, draw repeatedly to make a stroke, blend using multiply.