I use R and ggplot2 to produce graphs for my thesis. I can port them to tikz objects using the tikzdevice or to a pdf using the pdf device very easily, and in each case, specifying the width and height of the overall plot is straightforward.
However, I am actually more interested in specifying the width of the plot AREA (ie the inner box), since differences in this (particularly for plots on the same page) are more easily detected by the eye, even if they are a couple of points different in the final document.
Of course, the source of this issue can be easily put down to the axis labels that vary depending on the content.
My question is, How can I define 'fixed' axis label widths as a global option, or define the width to be exported as the inner plotting area for ggplot2 objects....
Related
One of the features of the R plotting machinery that I use more often is png(file=..., width=..., height=..., res=...).
Normally, I set precise values within the function, e.g. png("out.png", height=1500, width=2500, res=250).
I am now making a tool that makes an automatic plot from the provided dataset, but the tool is agnostic in respect to the number of rows it has to show in the plot, i.e. it plots what it receives. Sometimes, the plot has a large white area around it. Some other times, the canvas is too small and some rows fall outside.
I'm trying to fix this by calculating height and width according to the number of rows in the dataframe, but I find this approach error prone and suboptimal.
For example, inkscape has a nice function called "Resize page to drawing or selection" which will resize the canvas to match the boundaries of the plot. You can even pass a certain tolerance value so that your plot will still have some white around it.
Does R have this possibility, perhaps within ggsave() if not within png()?
I'm looping through a spatial feature dataframe and creating hundreds of maps from each column using ggplot2. Depending on the data present in the column, the legend for each map may be a different size, making the plot size different for each map. Although subtle, you can see below that the first map is offset to the left relative to the second map because of the longer label in the legend
I'd like to maintain the size of the plot area (in this case, the map area) so that all the saved maps are consistently sized and lined up when flipping through them. I've looked through questions and answers on here, but all I've been able to find are solutions for how to preserve aspect/ratio of different plots on the same image/document as described here. I'd like to be able to save each map as its own file.
Can anyone give me suggestions about how to keep the plot size consistent regardless of legend width when saving these plots as images using ggplot2?
I currently am one of the few R users in my company, which consists predominantly of stata users. One problem I've had with making plots using ggplot2 is that the default (theme_grey()) settings have much smaller axis font and a smaller legend than what is found in stata. Moreover, in presentations I find people have trouble reading the legend and titles from a distance.
I'm aware that ggplot2 has a theming system that allows for relative sizing. What I'd ideally like to do is to create a new default theme that I'd apply to all my plots that would make legends and axis titles larger. Importantly, however, very often the graphs I make have varying dimensions when output to pdf (e.g. 8 inch x 10 inch) or ( 10 inch x 13 inch). Since I'd like to apply this theme globally, I need it to produce good/easy to read output irrespective of the dimensions I specify when outputting to pdf.
I'd really appreciate any suggestions for how to do this/how to approach the problem using ggplot2's theming system.
Thanks!
The theme system can easily scale all the (themed) text, but not in a device sized aware way. The various theme sets, including theme_bw(), have an argument base_size which is the baseline size, in points, of fonts to use for the text. Some text is rendered at that size, and some is rendered at sizes relative to that (for example, axis labels and legend labels are rendered at 80% of the baseline size). So by specifying the base_size argument, you can scale all that text.
However, the base_size is in absolute points, not in a size which is relative to the device size. So the larger the device size, the smaller the text is relative to that.
I have just started playing with the quantmod package. The documentation is however, quite sparse (perhaps understandably, since it is OSS).
I am currently using barChart() which is a nice wrapper around chartSeries() and does most of what I want, but the default chart it produces are not quite what I want. To be specific, I want to tweak the charts produced by barChart() to suit my needs - however, since I am a newbie, I don't know whether my "tweaks" can be provided as options to the wrapper barChart(), or if I need to call chartSeries() directly, with specific arguments.
I have been tearing my hair out trying to do the following:
replace the horrible {start date}/{end date} text in the top right hand of the chart produced by barChart() with text of my own choosing
specify the formating to be used on the X axis (for example, show only the last two digits of the century. i.e. '98, '99, '00, '01 etc)
'Force' both top chart and the bottom chart to have their Y values printed on the left hand side of the chart
Add an aditional series to the bottom chart
Use different up/down colors for the bottom chart (defaults the using the same up/down colors for both top and bottom charts)
Plot just the top chart (no bottom chart)
Specify X axis, Y axis grid line spacings for top chart, for bottom chart
Write the image to an alternative output (e.g. png image or pdf document) instead of the graphics device
Can anyone help with any (or all) of the above?.
This functionality isn't available (patches welcome).
This functionality isn't available (patches welcome).
This functionality isn't available (patches welcome).
See the sparse documentation for ?addTA, specifically the on argument.
Plot the bottom chart as two separate up/down series, using two different colors, or perhaps chartTheme.
Not sure what you mean; just don't plot the bottom chart...
See the sparse documentation for the major.ticks argument to chartSeries. I don't think you can change the y axis grid line spacings, and the x axis spacing will be the same for the top and bottom chart.
See ?png and ?pdf.
To change or remove the bottom chart,
check the TA argument of chartSeries function
(there is an example in the manual);
to change the colours,
check the theme argument
(there is an example in the manual);
to write to a png or pdf file,
use the png or pdf functions,
as with other plotting functions.
To fine-tune the axes and labels, it is probably easier to bypass
chartSeries altogether and plot the data yourself, with base graphics,
lattice or ggplot2.
We are currently using R to automatically generate various kinds of boxplots.
The problem we have is that the length of our labels varies considerably between different plots and classes in one plot.
Is there a way to automatically adjust the plot so that all the labels will fit it nicely?
Specifying a worst case mar isn't feasible because in some plots the labels are considerably shorter than in others.
Lattice is the graphics library most likely to be helpful here. I say that for two reasons: (i) lattice is based on the grid system, and by accessing grid's graphical primitives, you can get much finer control over, among other things, the location of your panel output; and (ii) there's more to work with--the R standard graphics package has 70 different parameters, while Lattice has 371--by my count anyway, (length(names(unlist(trellis.par.get())))), yet those 371 are not in a flat structure like they are in the base package, but instead are collected in a hierarchical structure (with 30 or so parameter groups at the top level).
What you want is relative positioning of your axis labels. I would recommend going down one level for this sort of task. So to do what you want, just change the relevant grob slots then just redraw the two grobs (using the R interactive prompt):
library(lattice)
library(grid)
bwplot(~runif(200, 10, 99), xlab="x-axis label", ylab="y-axis label")
# move the x-axis label to the far left
grid.edit("[.]xlab$", grep=T, x=unit(0, "npc"), just="left", redraw=T)
# move it to the far right
grid.edit("[.]xlab$", grep=T, x=unit(1, "npc"), just="right", redraw=T)
# move it to the center
grid.edit("[.]xlab$", grep=T, x=unit(0.5, "npc"), just="center", redraw=T)
# same for y-axis
grid.edit("[.]ylab$", grep=T, y=unit(0.5, "npc"), just="center", redraw=T)
"[.].xlab$", grid.edit takes a gPath object (just a path traversing a gTree, which is just a grob that contains other grobs); because i didn't know where in the gPath my object of interest resides (the x-axis/y-axis label, i used a regular expression form for the object;
"grep=T", just tells grid.edit to treat the previous parameter as a regular expression;
"x=unit(0.5, 'npc')", specifying viewport coordinates here (in this case, just the x value); 'npc' ('normalized parent coordinates', which is the default) treats the viewport origin as (0,0), and assigns it a width & height of 1 unit each. Hence, i've specified the center of the viewport along the x axis.
With the base plotting system, a quick solution could be to rotate the x-labels to be vertical, using las=2 or las=3. Of course this also only works if your labels are not extremely long, but beyond a certain label length you will run into trouble with any type of plot anyway (shortening labels would be the way to go then).
But I agree with #doug that for more fine grained control, lattice or ggplot2 should be considered.