I am trying to create a plot and eventually save it as a file. But because I am making a lot of changes and want to test it out, I want to be able to view and save the plot at the same time. I have looked at this page to do what I want to do but in my system, it does not seem to be working as it is supposed to.
Here are my codes:
png('Save.png')
sample.df <- data.frame(group = c('A','B','A','C','B','A','A','C','B','C','C','C','B'),
X = c(2,11,3,4,1,6,3,7,5,9,10,2,8),
Y = c(3,8,5,2,7,9,3,6,6,1,3,4,10))
plot(Y ~ X, data = sample.df)
dev.copy(png, 'Save.png')
dev.off()
There are several issues (I am new to R so I might be missing something entirely):
(1) When I use png(), I cannot view the plot in RStudio so I used dev.copy() but it does not allow me to view my plot in R studio
(2) Even after I use dev.off(), I cannot view the saved file until I close the RStudio (says "Windows Photo Viewer can't open this picture because the picture is being edited in another program"). I need to restart every time so it is very inconvenient.
What am I doing wrong and how could I view and view saved file without restarting RStudio every time? Thank you in advance!
Addition
Based on Love Tätting's comments, when I run dev.list(), this is what I get.
> png('Save.png')
>
> sample.df <- data.frame(group = c('A','B','A','C','B','A','A','C','B','C','C','C','B'),
+ X = c(2,11,3,4,1,6,3,7,5,9,10,2,8),
+ Y = c(3,8,5,2,7,9,3,6,6,1,3,4,10))
>
> plot(Y ~ X, data = sample.df)
>
> dev.copy(png, 'Save.png')
png
3
> dev.off()
png
2
> dev.list()
png
2
> dev.off()
null device
1
> dev.list()
NULL
Why do I not get RStudioGD?
RStudio has its own device, "RStudioGD". You can see it with dev.list(), where it by default is the first and only one.
R's design for decoupling rendering and backend is by the abstraction of devices. Which ones you can use is platform and environment dependent. dev.list() shows the stack of current devices.
If I understand your problem correctly you want to display the graph first in RStudio, and then decide whether you want to save it or not. Depending on how often you save th image you could use the 'export' button in the plot pane in RStudio and save it manually.
Otherwise, your choice of trying to copy it would be the obvious one for me as well.
To my knowledge the device abstraction in R does not allow one to encapsulate the device as an object, so one for example could make it an argument to a function that does the actual plot. Since dev.set() takes an index as argument, passing the index as argument will be dependent on state of the stack of devices.
I have not come up with a clean solution to this myself and have sometimes retorted to bracketing the plot rendering code with a call to a certain device and saving it right after, and switching device depending on a global.
So, if you can, use RStudios export functionality, otherwise an abstraction would need to maintain the state of the global stack of devices and do extensive testing of its state as it is global and you cannot direct a plot call to a certain device, it simply plots to the current device (to my knowledge).
Edit after OP comment
It seems that it is somewhat different behaviour you are experiencing if you cannot watch the file after dev.off, but also need to quit RStudio. For some type of plot frameworks there is a need to call print on the graphical object to have it actually print to the file. Perhaps this is done by RStudio at shutdown as part of normal teardown procedures of open devices? In that ase the file should be empty if you forcibly look in its contents before quiting RStudio.
The other thing that sometimes work is to call dev.off twice. I don't know exactly why, but sometimes more devices get created than I have anticipated. After you have done dev.off, what does dev.list show?
Edit after OP's edit
I can see that you do, png(); dev.copy(); dev.off(). This will leave you with one more device opened than closed. You will still have the first graphics device that you started open as can be seen when you do the listing. You can simply remove dev.copy(). The image will be saved on dev.off() and should be able to open from the filesystem.
As to why you cannot see the RStudio graphics device, I am not entirely sure. It might be that other code is messing with your device stack. I would check in a clean session if it is there to make sure other code isn't tampering with the device stack. From RStudio forums and other SO questions there seem to have been plot pane related problems in RStudio that have resolved after updating RStudio to the latest. If that is a viable solution for you I would try that.
I've just added support for RStudio's RStudioGD device to the developer's version of R.devices package (I'm the author). This will allow you to do the following in RStudio:
library("R.devices")
sample.df <- data.frame(
group = c('A','B','A','C','B','A','A','C','B','C','C','C','B'),
X = c(2,11,3,4,1,6,3,7,5,9,10,2,8),
Y = c(3,8,5,2,7,9,3,6,6,1,3,4,10)
)
figs <- devEval(c("RStudioGD", "png"), name = "foo", {
plot(Y ~ X, data = sample.df)
})
You can specify any set of output target types, e.g. c("RStudioGD", "png", "pdf", "x11"). The devices that output to file will by default write the files in folder figures/ with filenames as <name>.<ext>, e.g. figures/foo.png in the above example.
The value of the call, figs, holds references to all figures produced, e.g. figs$png. You can open them directly from R using the operator !. For example:
> figs$png
[1] "figures/foo.png"
> !figs$png
[1] "figures/foo.png"
The latter call should show the PNG file using your system's PNG viewer.
Until I submit these updates to CRAN, you can install the developer's version (2.15.1.9000) as:
remotes::install_github("HenrikBengtsson/R.devices#develop")
In my package dndTree I use htmlwidgets to render drag-and-drop diagonal trees as implemented here. I changed the original code to be one big function makeTree(treeData,el) where treeData is JSON (created from jsonlite) and el is the element passed in from HTMLWidgets.
In the examples I saw online the way for setting the size of the d3 block was:
var width = el.getBoundingClientRect().width;
var height = el.getBoundingClientRect().height;
var tree = d3.layout.tree()
.size([height, width]);
This method worked fine for making the graph in the RStudio viewer and even popping it out to the browser. However, when using the included Shiny hooks, the el.getBoundingClientRect().height returned 0 (I checked with a console.log(height);). The width responded appropriately using the shiny hooks but I couldn't do anything to get the height to respond to inputs.
I took it a step further back and in the file dndTree.js in the initialize step I included a console log:
initialize: function(el, width, height) {
console.log(height);
return{}
}
which also returned a 0 for height.
Ultimately I added another argument to the function that makes the tree, fHeight which, if the bounding rectangle reports a height of 0 sets the height to fHeight. This isn't a good solution though because now there are two apparent height controllers but only one works and it only works when supplying the number of pixels as a number.
Why does the el element have a height of 0 when using the default shiny hooks?
This is my first attempt at using htmlwidgets and I'll be very honest that I've never written d3 from scratch. I've been taking working examples and trying to make it into a usable widget. My package code is on github (https://github.com/bmewing/df2hjson), but hopefully the relevant nuggets here are enough to identify my mistakes.
i have a gui with a area ggraphics and i would want create a subwindow with the graphic active in the area graphic, but dev.copy and svalue not work
options(guiToolkit = "RGtk2")
win<- gwindow ("window", width=1350,height=680,parent=c(1,1))
buttongraph<-gbutton("Click for enlarge graph",cont=win)
wingraphic<- ggraphics(cont=win)
hist(rnorm(100))
addHandlerChanged(buttongraph,handler=function(h,...){
subwin<- gwindow("subwin")
subwingraph<-ggraphics(cont=subwin)
svalue(wingraphic)
})
or
dev.copy(wingraphic)
The call svalue(wingraphic) <- "filename.png" tries to produce a graphic using some Gtk calls. It is fragile and if the comment in the file is still accurate, needs the device to be uncovered. Might work for you, but might not.
The ggraphics widget is just a frontend for cairoDevice which opens a new graphics device. If it was the current device, the call would be dev.copy(), not dev.copy(wingraphic) as dev.copy knows nothing about gWidgets objects. If you want to get the device for a given ggraphics object you can grab it with: getToolkitWidget(g)$getData(".devnum"), but you'll need to load RGtk2 first.
If you just want to make a given ggraphics instance the current device, you can do so with visible(subwingraph) <- TRUE.
I generate an excel file using the great PHPExcel library. At this moment I need to show all the columns into a single page. You know the feeling when you have to scroll left and right up and down to see all the data. Basically I have 33 columns and I need to fit them on any display
I don't know if is my setup or where is the problem, but I can't make it work. This is the code I'm using
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToPage(true);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1);
On MS Excel I select all thw colums then I choose View-> Zoom, then select Fit Selection. How can I do that programatically when excel file is generated with PHPExcel.
i hope i don't understand you wrong, here it goes:
phpExcel has an method called setZoomScalezoom(), however this does not auto fill the whole screen:
example:
$excel = new PHPExcel();
$sheet = $excel->getActiveSheet();
$sheet->getSheetView()->setZoomScale(300);
$writer = new PHPExcel_Writer_Excel5($excel);
$writer->save('test.xls');
got my information from:
source: http://typo3.org/extension-manuals/phpexcel_library/1.7.4/view/5/4/
Setting worksheet zoom level To set a worksheet’s zoom level, the
following code can be used:
$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75);
Note that zoom level should be in range 10 – 400.
I'm using Graphics.DrawImage() to resize images in my ASP.NET application.
This is working fine with all image formats, except gif.
Here is my original image:
When I resize to 300px it returns:
The code I'm using is:
Dim postedFile as new Bitmap("flower.gif")
Dim bmpOut As System.Drawing.Bitmap
Dim Format As ImageFormat = postedFile.RawFormat
bmpOut = New Bitmap(width, height)
Dim g As Graphics = Graphics.FromImage(bmpOut)
g.InterpolationMode = InterpolationMode.High
g.DrawImage(postedFile, 0, 0, width, height)
postedFile.Dispose()
Return bmpOut
bmpOut.Dispose()
I've also tried using all of the InterpolationMode's available, including InterpolationMode.HighQualityBicubic, but the image quality is still just as poor.
Why is this happening, and how can I prevent the image quality loss?
The problem is not in the resizing code you posted. I ran using the large image you posted and the result looks great. Your problem arises when you save your newly created 24 bits-per-pixel image to a new gif - with is 8bpp. You have basically two options:
Implement code to produce an optimized color palette for the new gif
(or maybe just use the palette from the original image)
Save to .png instead - which is a completely superior format
If you are saving the resized picture as .gif, I see no reason why this can't happen in the saved .gif. .gif's are limited to 256 colors (unless some hacks are done) and your resized imaged after all the manipulations may have well more than 256. Also, I wouldn't be surprised to find out that whatever routine you're using to convert images to .gif's isn't very concerned about quality.
This is not about interpolation, it is because ColorPalette is not set for target image. You have to quantize. See example at http://glennjones.net/2005/10/high-quality-dynamically-resized-images-with-dot-net/