Scenario: Five Graphs for Five Periods {3M, 6M, 1Y, 2Y & 3Y}, each with their own (1-2) scatter plots; sharing the same y-range (values).
Each period has different x-ranges and labeling policies.
For example, one could have either a fix or location policy; another none.
The X-Range appears to be immutable/plot-space. So I'm thinking of creating parallel plot spaces with their particular xRanges & labeling policies.
I studied the relationship of a plot space with the x.axis(s) & plot(s):
Graph <=== {NSMutableArray *plotSpaces}
x.axis/plot-space.
plot/plot-space
So I believe I can:
1) Create a plotspace.
2) Assign the plotspace to a particular plot, x-axis & xRange.
3) add or remove the plot to/from the graph.
4) Redraw the graph.
So when the user selects a period/plotspace, All I need to do is: replace any existing plots with the period plot(s) which will cause the graph to plot the plots & display the respective x-axis (Y-axis is common)?
[myGraph removePlot:(CPTPlot *)oldPlot];
[myGraph addPlot:(CPTPlot *)plot toPlotSpace:(CPTPlotSpace *)space];
...I'm a little lost here.
?
Axes are also assigned to a plot space. You would need to swap out the axes, too. You'll take a relatively large performance hit by adding and removing plots and axes all the time.
As you observed, the plot ranges are immutable. That just means that you can't change an existing range, not that you can't set a new one. Either create a new CPTPlotRange object or make a mutable copy of an existing one.
Whenever you want to change the plot scale, you need to do the following things. These can all change in place, without removing and replacing major pieces of the graph.
Change the plot ranges as described above.
Update the labeling policy and related properties of the axis.
Call -reloadData on the plot to load the new data.
Related
Is there a method to delete the last page created with the grid.newpage() or revert the graphic device to the state before the last plot was added?
Background:
I wrote a function that adds a layer (eg. geom_label) to an existing ggplot with location of data points based on the absolute plot dimensions (eg. inches/lines), rather than data range.
The procedure is: produce a plot, print it on the current device, measure the printed grobs and enhance the data frame to be plotted with relevant statistics (eg. origin of the coordinate system per panel, relative units per inch or per line), create the new plot with an additional layer with aesthetics computed with these new variables, print this final plot.
The main purpose was to have a tool that nicely aligns additional text/labels with summary statistics within the plotting area, even when facets or grouping variables are in use.
The issue is that an unnecessary page is produced with the plot I do not really use, except for making measurements, and I did not find any grid or grDevices method to delete the last printed page. Do you know of any such function?
There are some potential flawed workarounds: printing new ggplot object without calling grid.newpage() (but you no longer simply print(plot)), or plotting the first plot in a temporary device with same parameters as the target device (but it's not universal, and requires different approach per device; eg. solutions for .png and multipade .PDF will differ).
Grid units already let you place objects at fixed positions in the panel,
library(ggplot2)
library(grid)
ag <- grobTree(textGrob('+', x = unit(3,"cm"), y=unit(1,'npc') - unit(1,'in')))
qplot(1:10,1:10) +
annotation_custom(ag)
I just came into a problem while making several maps in R, the problem I came to is that I want to plot several maps and some geom_points in those maps, each map will have some points with different values and so the legend with the scales (size and color) will change between maps. All I want is to have exactly the same legend, representing the same values (for both color and size). I've tried with breaks etc but my data is continuous, so I didn't find any way to fix it.
EDIT:Simple example
Will try to explain with simple example by myself. Imagine I have these two arrays to be plotted into different coordinates for 2 different days:
c<-(1,2,3,2,1)
c<-(1,9,2,1,2)
What I want is to set the legend of the plot to be always representing the range 1-9 as values of the geom_points, no matter the specific values of the given day, in a way that no matter the values, the legend will be always the same and if I try to set some slides, the scale will not change
Any ideas?
I'm trying to create a dot chart in Stata, splitting it into two categories
Running a chunk of code:
sysuse nlsw88, clear
drop if race == 3
graph dot (mean) wage, over(occ) by(race)
Creates such output:
So far so good but I'd like to remove labels of Y axis from the right graph to give the data some more space.
The only way I've been able to do that was to manually edit graph and hide the axis label object:
Is there a way to do it programmatically? I do know I could use one more over() but in some graphs of mine that is already taken.
I believe the solution is buried in help bystyle and help by_option. However, I can't get it to work with your example (I'm on Stata 12). But the description is clear. For example:
A bystyle determines the overall look of the combined graphs,
including
whether the individual graphs have their own axes and labels or if instead the axes and labels are shared across graphs arrayed in the
same row and/or in the same column;
...
There are options that let you control each of the above attributes --
see [G-3] by_option --
And also
iyaxes and ixaxes (and noiyaxes and noixaxes) specify whether the y axes and x axes are
to be displayed with each graph. The default
with most styles and
schemes is to place y axes on the leftmost graph of each row and to place x axes on
the bottommost graph of each column. The y and
x axes include the
default ticks and labels but exclude the axes titles.
If for some reason that doesn't work out, something like
sysuse nlsw88, clear
drop if race == 3
graph dot (mean) wage, over(occ) by(race)
gr_edit .plotregion1.grpaxis[2].draw_view.setstyle, style(no)
does (but I don't really like the approach). You can mess with at least the axis number [#] to do a bit of customization. I guess recording changes in the graphical editor and then recycling the corresponding code, may be one way out of difficult situations.
I try to receive the data from a sensor from time to time and plot it in real time. That means the length of the dataset is not know before hand. And need to adjust the range of the graph dynamically.
I tried the following
plot(1,10, xlim=range(0,10), ylim=range(0,10), type='n')
points(1,data[1])
points(2,data[2])
But once the number of dots is beyond the range of x axis (10 in this case), the data points are out of the range. How to adjust the range accordingly?
Just issue a new plot command with an expanded range. On modern computers the time taken to recreate the plot is small and you generally will not see a delay. Any other approach will essentially do the same thing, clear the current plot and create a new plot.
The ggplot2 and lattice packages have ways of constructing a plot and updating the plot, but when the updated plot is shown it is redrawn from scratch.
There is a zoomplot function in the TeachingDemos package which will allow you to change the range of a plot, but it also will just redraw the plot from scratch (and due to changes in R 3.0.0 it is not currently working, so if you wanted to use it you would need to go back to R 2.15 or before, or wait for it to be fixed).
You can't adjust the range dynamically (sometimes Excel is better). However, you can keep track of what you've plotted, and redo the plot when you've reached the limit. You could also just make a new plot every time you get more data, which would be a way of faking a dynamic update.
Example plot:
http://i56.tinypic.com/eagjfn.jpg
Created with:
qplot(score, ..count.., data=df, fill=method, geom='density', position='stack')
Pretty much impossible to tell what goes with what. Any way to make this better? Ideally the legend draws lines "connecting" the areas to the item in the legend. Alternatively, I'd at least need some very different filling patterns for the areas.
The human eye does not do well distinguishing between more than 7-10 different categories whether they are indicated using color, shading or pattern. Adding lines or shadings here will, I think, only make this graph harder to read.
In situations like this, I often think that it's best to take a step back and rethink what message you intend for the graph to convey. Do you really need to compare all ~23 methods in a single graph, or can the methods be placed into subgroups and compared in multiple plots or facets? Are some of the methods' curves so similar that they could be combined into a single category?
For instance, I see ~3-4 natural groups just based on the similarity of the curves in your plot. You could plot a single, representative, method from each group to illustrate the large scale differences, and then create additional plots that focus in on the differences between methods within groups.