igraph axes xlim ylim plot incorrectly - r

if I make a graph g:
g <- read.table(text="
A B W
1 55 3
2 55 5
3 99 6 ",header=TRUE)
library(igraph)
g <- graph.data.frame(g)
and matrix of coordinates:
y<-1:5
x<-c(0.1,0.1,0.2,0.2,0.8)
l<-data.frame(x,y)
l<-as.matrix(l)
I can plot the graph with node positions according to custom coordinates and plot axes.
plot(g,layout=l,rescale=F,axes=TRUE,ylim=c(0,6),xlim=c(0,1))
But the xaxis limits do not function properly and I think are altered by yaxis limits. How can I control the xaxis they way i want for instance keeping it between 0 and 1.
i.e. plot(x,y,xlim=c(0,1),ylim=c(0,6))
Is this a bug? If it is and this cannot be solved is there another package that would have the same functionality?

The short answer is, you need to set the asp argument of the call to plot to 0 as the default is asp = 1 which produces the behavior you see (i.e., it's not a bug, it's a feature). The long answer with explanation follows.
As you noticed correctly, xaxis varies according to yaxis. Specifically, the x-axis has approxamitely the same distance between high and low numbers as yaxis:
If yaxis = c(0,6), the x-axis goes from -3 to 4. 6 - 0 = 6 and 4 - (-3) = 7
If yaxis = c(0,3), the x-axis goes from -1 to 2. 3 - 0 = 2 - (-1) = 3
Igraph seems to keep a constant ratio between the axes.
If you call ?plot.igraph (the plotting function called with an igraph object, can also be found via help(package = "igraph")), you find under See Also:
igraph.plotting for the detailed description of the plotting
parameters
And if you click on this link (or call ?igraph.plotting)and go through the parameters you will find:
asp A numeric constant, it gives the asp parameter for plot, the aspect ratio. Supply 0 here if you don't want to give an aspect ratio.
It is ignored by tkplot and rglplot.
Defaults to 1.
Hence the aspect parameter asp defaults to 1 in igraph. If you want another ratio, set it to 0:
plot(g,layout=l,rescale=F,axes=TRUE,ylim=c(0,6),xlim=c(0,1), asp = 0)
This answers your question. However, note that the points are now rather big. You will probably want to play around with the following parameters (found on ?igraph.plotting but note that many of the parameters need to be prefixed by vertex. as done by me):
vertex.size Default is 15, 5 seems better
vertex.label.cex Default is 1, 0.8 seems better.
The following produces a nicer plot:
plot(g,layout=l,rescale=F,axes=TRUE,ylim=c(0,6),xlim=c(0,1), asp = 0, vertex.size = 5, vertex.label.cex = 0.8)

Related

How can I get equal sized axes with R rgl 3D plots

I am plotting a 3D point plot with the rgl-package with
par(mar = c(0, 0, 0, 0), cex.lab=1)
plot3d(cart$x,cart$y,cart$z,"X","Y","Z")
This work so far. Only the 3 axis are differently sized due to the values.
I would need identical sizes axes.
Here is the current output.
All 3 axes should go to 10000, or whatever I set.
How can I achieve this?
(xlim etc does not work as I understand)
I think you want aspect3d(1,1,1) (although no reproducible example was given)
From ?aspect3d:
aspect3d(x, y = NULL, z = NULL)
If the ratios are all 1, the bounding box will be displayed as a
cube approximately filling the display. Values may be set larger
or smaller as desired.
I finally solved the challenge by adding three points at the end of the axes.
endpoints <- read.table(header = TRUE, text = "
x y z
-11000 0 0
0 -11000 0
0 0 11000
")
cart <- rbind(cart, endpoints)
plot3d(cart$x,cart$y,cart$z,"X","Y","Z")
Maybe not the most elegant solution, but it worked for me.

Is there a way to get around the inability to add measures as constant lines for Power BI scatter plots?

So I'd like to use a calculated or referenced value from another table as a y constant line in Power BI. I know there's no default way of doing it but I was wondering if there was a workaround. I have this:
And I want this:
The key is how to I get it to reference a value in another table or calculated column as that constant line since adding a measure isn't a feature right now. Thank you
You can add another chart (Line and Stacked Column Chart), include your metric in line values. Remove the background, changed to off the X and Y axis.
I suggest to use R or Python visual.
In that case, make sure to define the measure for horizontal line to ignore the filter context of X-axis dimension (use ALLSELECTED).
With this table (Tabell):
X Y Z
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
And this measure: Measure = CALCULATE(AVERAGE(Tabell[X]);ALLSELECTED(Tabell))+1
A scatter plot with a constant line that always is on average of X+1 can be created with this Python-script:
# dataset = pandas.DataFrame(X, Y, Z)
# dataset = dataset.drop_duplicates()
# Klistra in eller skriv in din skriptkod här:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# zorder is to make the dots above the grid
ax.scatter(dataset.Y, dataset.X, s=dataset.Z*100, c='grey',zorder=10)
# this shows a constant line between (0,Measure) and (10,Measure)
ax.plot([0,10],[max(dataset.Measure), max(dataset.Measure)], c='r', linestyle='--')
# this is to set the limit of the axes so the horisontal line doesnt decide the chart size
ax.set_xlim([0,6])
# to set the ticks yourself
ax.set_yticks(range(0,6,1))
# display a thin grid
plt.grid(True, lw=.3)
plt.show()
Result:

When plotting a curve in R, a piece of the curve gets cut off, not sure why

I am trying to plot this formula. As x approaches 0 from the right, y should be approaching infinity, and so my curve should be going upwards close to y-axis. Instead it gets cut off at y=23 or so.
my_formula = function(x){7.9*x^(-0.5)-1.3}
curve(my_formula,col="red",from=0 ,to=13, xlim=c(0,13),ylim=c(0,50),axes=T, xlab=NA, ylab=NA)
I tried to play with from= parameter, and actually got what I needed when I
put from=-4.8 but I have no idea why this works. in fact x doesn't get less than 0, and from/to should represent the range of x values, Do they? If someone could explain it to me, this would be amazing! Thank you!
By default, curve only chooses 101 x-values within the (from, to) range, set by the default value of the n argument. In your case this means there aren't many values that are close enough to 0 to show the full behaviour of the function. Increasing the number of values that are plotted with something like n=500 helps:
curve(my_formula,col="red",from=0 ,to=13,
xlim=c(0,13),ylim=c(0,50),axes=T, xlab=NA, ylab=NA,
n=500)
This is due mainly to the fact that my_formula(0) is Inf:
So plotting from=0, to=13 in curve means your first 2 values are by default (with 101 points as #Marius notes):
# x
seq(0, 13, length.out=101)[1:2]
#[1] 0.00 0.13
# y
my_formula(seq(0, 13, length.out=101)[1:2])
#[1] Inf 20.61066
And R will not plot infinite values to join the lines from the first point to the second one.
If you get as close to 0 on your x axis as is possible on your system, you can make this work a-okay. For instance:
curve(my_formula, col="red", xlim=c(0 + .Machine$double.eps, 13), ylim=c(0,50))

Using R to create a heat map to plot positive and negative values

I'm pretty new to R and I'm trying to create an heat map. This is an example of the data I created
Point Distance
9273206 11
9273206 21
9273206 -25
9279872 -9
9279872 10
9770644 9
10315636 25
13144752 5
13257732 -3
A value in the Point column can occur multiple times. I'm trying to create a heat map which represents the unique value from the Point column (on a horizontal line), the value from the Distance column are plotted around it. The negative value on the left en the positive on the right. This is an example of what I'm trying to create:
http://i.imgur.com/AhVAxOQ.png
The black line in the middle represents the unique values from the Point column and the red lines the data points from the Distance column.
I have look around to find ways to plot this, but could not find anything. Could someone explain how to do this or give me a few tips. Or should I use something totally different?
thanks in advance for your help
If someone can help me out with the text issue, I came up with this.
plot(Point ~ Distance, data = yourData, pch = '.', cex = 10,
col = 'red', ylab = "", yaxt = "n", las = 1)
abline(v = 0)
Which produces the following plot.
The unique axis values were a bit more challenging. I thought text might be the right way to get there, but my result is a bit hard to read. Hopefully someone knows how to fix it.
text(unique(dat$Point), labels = unique(dat$Point),
adj = c(1,2), pos = 2, offset = 0)

R Doplot() coordinates locator()

I drew a dotplot (using dotPlot() from seqinr package) of 2 fasta sequences and I need to extract some values (x,y) from the plot.
The Dotplot() output is an image
A generic dotplot maybe be this one
I need for example the values of start & end of the local alignment which are represented by the purple lines
so here an example
l=30
seq1 <- paste(sample(c("A","G","T","C"), l, repl=TRUE))
seq2 <- paste(sample(c("A","G","T","C"), l, repl=TRUE))
dotPlot(seq1,seq2, wsize = 2, wstep = 1, nmatch = 2, col = c("white", "green"), xlab = deparse(substitute(seq1)), ylab = deparse(substitute(seq2)))
locator(n=2, type="p")
$x
[1] 27.18720 31.23263
$y
[1] 20.45222 24.65726
So I want exactly the position of the 2 circled points,and as you can see the locator() gives decimal value .
I may use ceiling() or round() but i maybe get back an approximation error
I need the integer value of the point I clicked on, basically the nearest point to the place
Would be perfect to use identify(), which works with "normal" plots and gives back a vector with the closest plotted value to your "click", but it doesn't work on the dotPlot() output (the problem seems to be that it doesn't work on image output as locator() )
Any possible solution would be welcome, including using dotter in shell or python. Thanks
As you have mentioned Identify doesn't work since it need a plot not an image. Maybe a solution is to call image after plot(type="n",..) but this need to change the dotPlot function source code. Another elegant solution is to use lattice package and panel.identify the grid equivalent of identify.
Here an example, where I select some points ( 6 -> 15):
library(lattice)
dotplot(y~x,data.frame(x=letters,y=letters))
trellis.focus("panel", 1, 1)
> panel.identify()
[1] 6 7 8 9 10 11 12 13 14 15
Have a look at evolvedmicrobe/dotplot on github
https://github.com/evolvedmicrobe/dotplot/blob/master/R/plotters.R
It provides mkDotPlotDataFrame. With this you can better get coordinates between matches, like with identify.

Resources