Related
How can I make the lines for the x- and y-axes thicker in Julia Plots?
Is there a simple way to achieve this?
MWE:
using Plots
Nx, Ny = 101,101
x = LinRange(0, 100, Nx)
y = LinRange(0, 100, Ny)
foo(x,y; x0=50, y0=50, sigma =1) = exp(- ((x-x0)^2 + (y-y0)^2)/(2*sigma^2) )
NA = [CartesianIndex()] # for "newaxis"
Z = foo.(x[:,NA], y[NA,:], sigma=10);
hm = heatmap(x, y, Z, xlabel="x", ylabel="y", c=cgrad(:Blues_9), clim=(0,1))
plot(hm, tickfontsize=10, labelfontsize=14)
Leads to:
The posts I found so far suggested that this was not possible:
https://discourse.julialang.org/t/plots-jl-modify-frame-thickness/24258/4
https://github.com/JuliaPlots/Plots.jl/issues/1099
It this still so?
The actual code for my plot is much longer.
I would not like to rewrite all of it in a different plot library.
Currently, there does not seem to be an attribute for axes thickness in Plots.jl.
As a workaround, you may use the attribute thickness_scaling, which will scale the thickness of everything: lines, grid lines, axes lines, etc. Since you only want to change the thickness of axes, you need to scale down the others. Here is your example code doing that using pyplot backend.
using Plots
pyplot() # use pyplot backend
Nx, Ny = 101,101
x = LinRange(0, 100, Nx)
y = LinRange(0, 100, Ny)
foo(x,y; x0=50, y0=50, sigma =1) = exp(- ((x-x0)^2 + (y-y0)^2)/(2*sigma^2) )
NA = [CartesianIndex()] # for "newaxis"
Z = foo.(x[:,NA], y[NA,:], sigma=10);
hm = heatmap(x, y, Z, xlabel="x", ylabel="y", c=cgrad(:Blues_9), clim=(0,1))
plot(hm, tickfontsize=10, labelfontsize=14) # your previous plot
# here is the plot code that shows the same plot with thicker axes on a new window
# note that GR backend does not support `colorbar_tickfontsize` attribute
plot(hm, thickness_scaling=2, tickfontsize=10/2, labelfontsize=14/2, colorbar_tickfontsize=8/2, reuse=false)
See Julia Plots Documentation for more about plot attributes.
A simple workaround where you do not need to add attributes for all the fonts is to add verticle and horizontal lines at the limits for x and y of the plots. For example, if I have a figure fig with 4 subplots, each with the same bounds, I can use this to get a thicker box frame:
for i ∈ 1:4
vline!(fig[i], [xlim_lb, xlim_ub],
linewidth=3,
color=:black,
label=false)
hline!(fig[i], [ylim_lb, ylim_ub],
linewidth=3,
color=:black,
label=false)
end
or for the original example here, add this to the end:
frame_thickness = 5
vline!([x[1], x[end]], color=:black, linewidth=frame_thickness, label=false)
hline!([y[1], y[end]], color=:black, linewidth=frame_thickness, label=false)
So I used the plotrix library to plot a histogram using some weights , the histogram shows up as expected but when I tried a plot the mean as a vertical line it won't show up at all
Here's a snippet of my code:
library("plotrix")
library("zoom")
vals = seq.int(from = 52.5 , to = 97.5 , by = 5)
weights <- c(18.01,18.26,16.42,14.07,11.67,9.19,6.46,3.85,1.71,0.34)/100
mean <- sum(vals*weights)
wh <- weighted.hist(x = vals , w = weights , freq = FALSE)
abline(v = mean)
the abline() seems to work only with the normal hist() function
I am sorry if the question sounds stupid , I am R newbie however I did my research and could not find any helpful info.
Thanks in advance.
You should provide a sample of your data. Your calculation of the weighted mean is only correct if your weights sum to 1. If they do not, you should use weighted.mean(vals, weights) or sum(vals * weights/sum(weights)). The following example is slightly modified from the one on the weighted.hist manual page (help(weighted.hist)):
vals <- sample(1:10, 300, TRUE)
weights <- (101:400)/100
weighted.hist(vals, weights, breaks=1:10, main="Test weighted histogram")
(mean <- weighted.mean(vals, weights))
# [1] 5.246374
The histogram starts at 1, but this is 0 on the x-axis coordinates so we need to subtract 1 to get the line in the right place:
abline(v=mean-1, col="red")
Using your data we need to identify the first boundary to adjust the mean so it plots in the correct location"
wh$breaks[1]
# [1] 52.5
abline(v=mean - wh$breaks[1], col="red")
I have the next time series object, which I plot it using plot:
ts <- ts(c(1:4,2:5,3:6,4:7,5:8,6:9,7:10), frequency = 4)
plot(ts)
Plot of the ts
Now, I would like to draw a line between the first and the last observation using abline, but, although R doesn't show any error, it seems that it doesn't work when using it on a plot of time series. The code used to try to draw the line was:
abline(a = 1, b = (ts[length(ts)]- ts[1]) / (length(ts)-1))
Did anyone had the same problem and manage to solve it?
ts <- ts(c(1:4,2:5,3:6,4:7,5:8,6:9,7:10), frequency = 4)
plot(ts, xlim=c(1,8), type="o")
x1 <- 1; y1 <- ts[1]
x2<- 7.75; y2 <- ts[length(ts)]
abline(a = y1-x1*(y1-y2)/(x1-x2), b = (y1-y2)/(x1-x2) )
grid()
I am not sure that I fully understand what you want to achieve. But the following may be of help.
You may use the following simple code using lines:
# your code
ts <- ts(c(1:4,2:5,3:6,4:7,5:8,6:9,7:10), frequency = 4)
plot(ts)
# drawing a blue line from (1, 1) to (8, 10)
lines(x = c(1, 8), y = c(1,10), col="blue")
which yields the following simple plot
I tried to run the following script to change the x axis. I followed other answers given in Stack Overflow; however I don’t get what I’m looking for. The original x axis goes from 0 to 1 but I want to change it from 0 to 20.
x<-c(0,0.1,0.2,0.25,0.30,0.35,0.40,0.60,0.90,1)
y<-c(0,0.014,0.41165,0.258,0.57,0.57,0.1803,0.5844,0.10185,0.085)
da<-cbind(x,y)
dat=data.frame(da)
plot(y~x,data=dat,xaxt="n")
pas=c(0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19,20)
axis(1, at=1:20,labels=pas)
This script produces a figure with just a 0 at the last mark. I need a x axis from 0 to 20. Thanks
I am not sure why you are trying to do this but the following would work.
x <- c(0,0.1,0.2,0.25,0.30,0.35,0.40,0.60,0.90,1)
y <- c(0,0.014,0.41165,0.258,0.57,0.57,0.1803,0.5844,0.10185,0.085)
dat <- data.frame(x = x, y = y)
x.range <- c(0,20)
x.labels <- x.range[1]:x.range[2]
pas <- seq(0, 1, length.out = length(x.labels))
plot(y ~ x, data = dat, xaxt = "n", xlim = c(0,1))
axis(1, at = pas, labels = x.labels, cex.axis=0.65)
You may have missed the xlim/ylim.
Did you mean y axis? Then just use :
plot(y~x,data=dat,ylim=c(0,20))
plot(y~x,data=dat,xlim=c(0,20))# you need to remove the 'xaxt="n"' to see the x-axis
Although either way I am not sure this is the best idea given the range of the data.
Using ggplot2
library(ggplot2)
qplot(x,y,data=dat)+ scale_x_continuous(labels=c("0"="fake0","0.25"="fake5","0.5"="fake10",".75"="fake15","1"="fake20"))# replace 'fake#' with anything
Although I am not sure why are you trying to do this.
Refer to the above plot. I have drawn the equations in excel and then shaded by hand. You can see it is not very neat. You can see there are six zones, each bounded by two or more equations. What is the easiest way to draw inequalities and shade the regions using hatched patterns ?
To build up on #agstudy's answer, here's a quick-and-dirty way to represent inequalities in R:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
with(as.list(c(b,a)),{
id <- yB<=yA
# b<a area
polygon(x = c(xB[id], rev(xA[id])),
y = c(yB[id], rev(yA[id])),
density=10, angle=0, border=NULL)
# a>b area
polygon(x = c(xB[!id], rev(xA[!id])),
y = c(yB[!id], rev(yA[!id])),
density=10, angle=90, border=NULL)
})
If the area in question is surrounded by more than 2 equations, just add more conditions:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
d <- curve(0.5*x^2+0.2, add = TRUE) # Third curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
names(d) <- c('xD','yD')
with(as.list(c(a,b,d)),{
# Basically you have three conditions:
# curve a is below curve b, curve b is below curve d and curve d is above curve a
# assign to each curve coordinates the two conditions that concerns it.
idA <- yA<=yD & yA<=yB
idB <- yB>=yA & yB<=yD
idD <- yD<=yB & yD>=yA
polygon(x = c(xB[idB], xD[idD], rev(xA[idA])),
y = c(yB[idB], yD[idD], rev(yA[idA])),
density=10, angle=0, border=NULL)
})
In R, there is only limited support for fill patterns and they can only be
applied to rectangles and polygons.This is and only within the traditional graphics, no ggplot2 or lattice.
It is possible to fill a rectangle or polygon with a set of lines drawn
at a certain angle, with a specific separation between the lines. A density
argument controls the separation between the lines (in terms of lines per inch)
and an angle argument controls the angle of the lines.
here an example from the help:
plot(c(1, 9), 1:2, type = "n")
polygon(1:9, c(2,1,2,1,NA,2,1,2,1),
density = c(10, 20), angle = c(-45, 45))
EDIT
Another option is to use alpha blending to differentiate between regions. Here using #plannapus example and gridBase package to superpose polygons, you can do something like this :
library(gridBase)
vps <- baseViewports()
pushViewport(vps$figure,vps$plot)
with(as.list(c(a,b,d)),{
grid.polygon(x = xA, y = yA,gp =gpar(fill='red',lty=1,alpha=0.2))
grid.polygon(x = xB, y = yB,gp =gpar(fill='green',lty=2,alpha=0.2))
grid.polygon(x = xD, y = yD,gp =gpar(fill='blue',lty=3,alpha=0.2))
}
)
upViewport(2)
There are several submissions on the MATLAB Central File Exchange that will produce hatched plots in various ways for you.
I think a tool that will come handy for you here is gnuplot.
Take a look at the following demos:
feelbetween
statistics
some tricks