Creating gallery-like plots in HTML from R Markdown - html

I am working on a data analysis project in R. In the end I need to hand in an HTML document.
I created a couple of PCA biplots using the autoplot funciton, about like this:
autoplot(pca, data = expression, x = 1, y = 2)
#pca is a prcomp element and expression is a data frame
By now, they are plotted one below the other in the HTML document. Is there a function that allows me to click through the different plots? So that only the first plot is shown and by clicking on an arrow or something, the second plot is shown in the same place? Kind of like a gallery.
The way multiple plots from the same chunk are show in an R Markdown would be even better, so you can select one specific plot by clicking on a miniature version of it
I've been looking through the internet a lot and hoped to find something from the html widgets page, but couldn't find anything after all.
I would really appreciate your help on this. Thanks :)
EDIT: I am not sure whether I am allowed to hand in a shiny applet, so being able to do it solely in the HTML would be awesome

Right, I found a way to do it that works fine for me. I used the {.tabset} argument I found at this link:
https://bookdown.org/yihui/rmarkdown-cookbook/html-tabs.html
## Results {.tabset}
### PC1-PC2 biplot
autoplot(pca, data = expression, x = 1, y = 2)
### PC1-PC3 biplot
autoplot(pca, data = expression, x = 1, y = 3)
## {-}
To use this, you have to create headers in your markdown using the # symbol. All headers that are one "level" below the one to which you added the {.tabset} argument (i.e. that have one more # symbol) will be the names of your tabs.
To close the tab section, you use the same number of # symbols you used in the header behind which you wrote the {.tabset} argument and write {-}.

Related

Is there a way to script several image maps on R?

So I have currently made several different monthly calendars. Here is one for example. They range from the years of 1858 to 1944 all with every individual month in a year. What I also have is several different HTML files with titles like 18580907-18580908-website.html where 1858-09-07 is the start year-month-day and 1858-09-08 is the end year-month-day. The contents of the HTML files are not relevant as those work and are not an issue. The issue I am facing and trying to accomplish is to make the PNG calendars I have created correctly associate with the HTML files.
So the question I am asking is whether there is a way to script the calendar PNGs to image map the files to their correct days. Basically, I am trying to image map the files so that if you were to click on a particular day of a calendar, it will open the file associated with that. And as mentioned, each file does have the appropriate start/end dates in the file name. With that being said, I honestly have no clue how to go about scripting it since every monthly calendar will be different, but if anyone has an idea on how to go about doing it, it would be greatly appreciated!
Obviously measuring the size of a day on the calendar would be the start as all the boxes in the calendar have the same size. So doing something like
fnames_html <- str_subset(files, "html")
# coords <- # Get the coordinates
cat('<map name="calendar">', "\n")
for(i in 1:length(fnames_html)) {
cat(paste0('<area shape="rect" coords=', coords[i], 'href="', fnames_html[i], '">'), "\n")
}
cat('</map>')
> fnames_html[1:10]
[1] "18580907-18580908-website.html" "18580908-18580909-website.html" "18580910-18580911-website.html"
[4] "18580913-18580914-website.html" "18580914-18580915-website.html" "18580915-18580916-website.html"
[7] "18580916-18580917-website.html" "18580917-18580918-website.html" "18580920-18580921-website.html"
[10] "18580921-18580922-website.html"
after getting the coordinates is the way to go about it, but I don't know how to script the coordinates in without manually hard coding each one (but that's not feasible as there are thousands of HTML files).

centering the y axis arrow

I am currently trying to draw an oscillation using Octave. This is what I want to achieve in the end:
In this diagram, the y axis arrow is drawn in the middle of the graph instead of at the top or bottom.
I think this way it makes a lot of sense because the arrow kind of mirrors the graph itself periodically.
Now, what I have so far:
x = [0:.1:10];
plot(x, sin(x);
box off
Which looks like this:
But I can't get the y axis arrow to be in the middle. So far I've read
The axis documentation
The page about two-dimensional plots
But I can't find anything about positioning the axis. Thanks for any help in advance.
Using your example:
x = [0:.1:10];
plot(x, sin(x));
box off
set( gca, 'xaxislocation', 'origin' )
Some more, possibly helpful tips:
In general, if you don't know what parameters are available in a graphical object handle, and you want to "check", you can use get with an empty string, e.g. get( gca, '' ) to check all the parameters that you can 'get' or 'set' on the current axes object.
Similarly, if you want to check what values a particular parameter can be set to, you can do, e.g. set( gca, 'xaxislocation' ), i.e. without providing the value to set it to. If that particular parameter only accepts values from a specific set of values (instead of e.g. a numerical array), then Octave will then show you what these options are (and also which is the default).
Obviously, if you know what you're looking for, you can also just go straight to the relevant page in the octave manual and search the page for it :)
Since the online manual is quite large, and has no 'search' facility of its own (it does within octave, but the online version doesn't), in order to jump straight to the relevant section I often find it useful to do a duckduckgo (or google) site-specific search, e.g. "xaxislocation site:https://octave.org/doc/v6.2.0/"

html div nesting? using google fetchurl

I'm trying to grab a table from the following webpage
http://www.bloomberg.com/markets/companies/country/hong-kong/
I have some sample code which was kindly provided by Phil Bozak here:
grabbing table from html using Google script
which grabs the table for this website:
http://www.airchina.com.cn/www/en/html/index/ir/traffic/
As you can see from Phil's code, there is alot of "getElement()" in the code. If i look at the html code for the Air China website. It looks like it's nested four times? that's why the string of .getElement?
Now I look at the source code for the Bloomberg page and its is load with "div"...
the question is can someone show me how to grab the table from this the Bloomberg page?
and just a brief explanation of the theory also would be useful. Thanks a bunch.
Let's flip your question upside down, and start with the theory. Methodology might be a better word for it.
You want to get at something specific in a structured page. To do that, you either need a way to zap right to the element (which can be done if it's labeled in a unique way that we can access), OR you need to navigate the structure more-or-less manually. You already know how to look at the source of a page, so you're familiar with this step. Here's a screenshot of Firefox Inspector, highlighting the element we're interested in.
We can see the hierarchy of elements that lead to the table: html, body, div, div, div.ticker, table.ticker_data. We can also see the source:
<table class="ticker_data">
Neat! It's labeled! Unfortunately, that class info gets dropped when we process the HTML in our script. Bummer. If it was id="ticker_data" instead, we could use the getElementByVal() utility from this answer to reach it, and give ourselves some immunity from future restructuring of the page. Put a pin in that - we'll come back to it.
It can help to visualize this in the debugger. Here's a utility script for that - run it in debug mode, and you'll have your HTML document laid out to explore:
/**
* Debug-run this in the editor to be able to explore the structure of web pages.
*
* Set target to the page you're interested in.
*/
function pageExplorer() {
var target = "http://www.bloomberg.com/markets/companies/country/hong-kong/";
var pageTxt = UrlFetchApp.fetch(target).getContentText();
var pageDoc = Xml.parse(pageTxt,true);
debugger; // Pause in debugger - explore pageDoc
}
This is what our page looks like in the debugger:
You might be wondering what the numbered elements are, since you don't see them in the source. When there are multiples of an element type at the same level in an XML document, the parser presents them as an array, numbered 0..n. Thus, when we see 0 under a div in the debugger, that's telling us that there are multiple <div> tags in the HTML source at that level, and we can access them as an array, for example .div[0].
Ok, theory behind us, let's go ahead and see how we can access the table by brute-force.
Knowing the hierarchy, including the div arrays shown in the debugger, we could do this, ala Phil's previous answer. I'll do some weird indenting to illustrate the document structure:
...
var target = "http://www.bloomberg.com/markets/companies/country/hong-kong/";
var pageTxt = UrlFetchApp.fetch(target).getContentText();
var pageDoc = Xml.parse(pageTxt,true);
var table = pageDoc.getElement()
.getElement("body")
.getElements("div")[0] // 0-th div under body, shown in debugger
.getElements("div")[5] // 5-th div under there
.getElement("div") // another div
.getElement("table"); // finally, our table
As a much more compact alternative to all those .getElement() calls, we can navigate using dot notation.
var table = pageDoc.getElement().body.div[0].div[5].div.table;
And that's that.
Let's go back to that pinned idea. In the debugger, we can see that there are various attributes attached to elements. In particular, there's an "id" on that div[5] that contains the div that contains the table. Remember, in the source we saw "class" attributes, but note that they don't make it this far.
Still, the fact that a kindly programmer put this "id" in place means we can do this, with getDivById() from that earlier question:
var contentDiv = getDivById( pageDoc.getElement().body, 'content' );
var table = contentDiv.div.table;
If they move things around, we might still be able to find that table, without changing our code.
You already know what to do once you have the table element, so we're done here!

Python graphics skipping every other pixel when drawing a .PPM file from a function

I'm writing a program for a college course. I import a .PPM file saved as a 2-d array from main into the function. Then I have to update the pixels of a graphics window (which is opened in main) using .setPixel and color_RGB() method and functions.
The pixels are updating, however there is a white pixel in between each colored pixel for some reason. It's not the PPM file (they were supplied by my professor and I've tried multiple ones), so it has to be my function.
Warning: I am not allowed to use anything in my program that we have not yet covered in our course (it's a first year, 4 month course so the scope is not massive). I don't need to know exactly HOW to fix it, as much as I need to know why it's doing it (AKA: I need to be able to explain how I fixed it, and why it was breaking in the first place).
Here is my function:
def Draw_Pic(pic,pic_array, sizeX, sizeY, gfx_window):
for y in range(sizeY):
for x in range(0, sizeX, 3):
pixel_color = color_rgb(pic_array[y][x],pic_array[y][x+1],pic_array[y][x+2])
pic.setPixel(x,y,pixel_color)
gfx_window.update()
You are using range(0, sizeX, 3) which creates a list with values 0 to sizeX with increment 3.
So your x goes 0..3..6..9 etc. Makes perfect sense for the part where you assemble pixel color from 3 components, but then you do pic.setPixel(x,y,colors) using the same interleaved x.
Hope that helped.
P.S. By the way, why "colors" and not "color"?
edit Also, that way you'll copy only 1/3 of the image in pic_array.

Stick Images together

I just tried to use Google Map Buddy to get satellite image from Google Map. This application first download small images from google map and then stick them together into new image. I had to wait about 2 hours to get images download my computer and it looks like it downloaded all images (22,194 images) but then the app told me that it cannot stick them together. When I started app again I though this app will reuse images on my comp but it start downloading them again. So I had to stop the process and ask you, guys, if you know how I can put that puzzle together.
The naming pattern of those images goes like this:
x=92651y=48130zoom=17.png
x=92652y=48130zoom=17.png
x=92653y=48130zoom=17.png
x=92654y=48130zoom=17.png
x=92655y=48130zoom=17.png
...
...
x=92664y=48131zoom=17.png
x=92665y=48131zoom=17.png
x=92666y=48131zoom=17.png
x=92667y=48131zoom=17.png
...
...
x=92689y=48132zoom=17.png
x=92690y=48132zoom=17.png
x=92691y=48132zoom=17.png
x=92692y=48132zoom=17.png
x=92693y=48132zoom=17.png
What can I do to stick them together programmatically using some simple scripting language? I have access to Mac and Windows systems and may be can install any simple scripting languages.
Thanks
You could use Python with Python Imaging Library (PIL).
First I'd make a list of filename and their coordinates. Extract the integer coordinates from the filenames with regular expressions and store them in a list of dictionaries:
>>> filename = 'x=92664y=48131zoom=17.png'
>>> imagePattern = re.compile(r'^x=(\d{5})y=(\d{5})zoom=17.png$')
>>> x,y = map(int, imagePattern.search(filename).groups())
>>> {'x':x, 'y':y, 'filename':filename}
{'y': 48131, 'x': 92664, 'filename': 'x=92664y=48131zoom=17.png'}
Having a list of dictionaries enables you to sort them according to either dimensions:
tileListSortedByX = sorted(tileList, key = lambda i: i["x"])
and also filter them:
fileListWhereX48131 = [tile for tile in tileList if tile["x"]==48131]
With these two operations you can easily imagine the for loops to iterate over tiles line by line.
The last thing you need to create a big empty image (with PIL) where you'll paste the small tile images into. Its size will be a multiple of the tile size.
>>> from PIL import Image
>>> bigImage = Image.new('RGB',(300,300),(255,255,255))
#creates a white 300x300 image
Pasting the small images into the big one looks like this:
>>> smallImage = Image.open(tile["filename"])
>>> bigImage.paste(smallImage,(0,0))
Hope you get the idea.
The process of "sticking images together" is usually called "stitching" or "mosaicing".
I found a list of many applications that do this on Wikipedia article - "Comparison of Photo Stitching Applications".
Edited: removed link to single app I found and replaced with wikipedia list of software.