I use Plots in Julia 1.5.
How can I make the y-ticks as shown below?
We sometime see figure with the right type of axis in scientific paper.
I do not know if there is an easy and a quick way but here is my solution.
First we should arrange tick labels. Plots.jl provides us with formatter axis attribute. We can set this attribute to a function that takes the number value of the tick and returns a string as the tick label.
x=0:0.2:0.8
y=[1,2,3,4,5] * 10^-8
plot(x, y, ytick=y, yaxis=(formatter=y->string(round(Int, y / 10^-8))))
To annotate the axis with the correct scale, I use Plots.annotate! and Plots.text, and set the location and size of the annotation appropriately. The problem with this solution is that the annotation may overflow the plot area and may not be entirely visible if there is no title set. You may set a phantom title if such a problem occurs.
using LaTeXStrings
x = 0:0.2:0.8
y = [1,2,3,4,5] * 10^-8
plot(x, y, yticks = y, yaxis=(formatter=y->string(round(Int, y / 10^-8))), title=" ")
annotate!([(0, maximum(y) * 1.05, Plots.text(L"\times10^{-8}", 11, :black, :center))])
Note that I handled the conversion from numeric value to scientific notation manually. You may handle it automatically using tools from Printf module.
Here is the final result
Just add formatter = :plain to your plot function:
plot(x, y, formatter = :plain,)
formatter = identity is also an option (for displaying numbers with decimal point):
plot(x, y, formatter = identity,)
Related
For certain functions it is convenient and commonplace to plot one dataset with two x axes. My example at hand is a function of the form f(T)=A*exp(-H/(R*T)), which is to be plotted with 1/T on the x axis and log(f) on the y axis. In this form, it conveniently appears as a straight line, but for ease of reading the actual temperature T instead of 1/T, it is common to put the corresponding T values on a second x axis in the same plot (which is then of course reversed and also not linearly spaced). How do I achieve this with Julia and Plotly?
Here is an example of the type of plot I try to make. For what it's worth, in Gnuplot the additional second (upper) x-axis would be created with set link x2 via 1./x inverse 1./x.
For adding a second Y axis there is a twinx() method in the Plots.jl package. Unfortunately there is not twiny() method that could allow adding a secondary X axis.
However, you can take twinx() code and simply transpose it:
function twiny(sp::Plots.Subplot)
sp[:top_margin] = max(sp[:top_margin], 30Plots.px)
plot!(sp.plt, inset = (sp[:subplot_index], bbox(0,0,1,1)))
twinsp = sp.plt.subplots[end]
twinsp[:xaxis][:mirror] = true
twinsp[:background_color_inside] = RGBA{Float64}(0,0,0,0)
Plots.link_axes!(sp[:yaxis], twinsp[:yaxis])
twinsp
end
twiny(plt::Plots.Plot = current()) = twiny(plt[1])
And now use it like this:
using Plots
plot(1:10,rand(10), label = "randData", ylabel = "Y axis",color = :red, legend = :topleft, grid = :off, xlabel = "Numbers Rand")
p = twiny()
plot!(p,5:15,log.(5:15), label = "log(x)", legend = :topright, box = :on, grid = :off, xlabel = "Log values")
I'm trying to visualise missing data with the R package VIM.
I'm using R version 3.4.0 with RStudio
I've used the function aggr() but the colnames of my dataframe seem to be too long. Thus, some labels of the x axis don't appear.
I would like to increase the space at the bottom of the x axis.
library(VIM)
aggr(df)
Here is my dataframe df and the plot I obtain
I've tried with par() function but it doesn't change anything.
aggr(df,mar=c(10,5,5,3))
or
par(mar=c(10,5,5,3))
g=aggr(df,plot=FALSE)
plot(g)
I can reduce the font size with cex.axis but then labels are too small.
aggr(df,cex.axis=.7)
Here is the plot with small axis labels:
I've not find a lot of examples using aggr() that's why I ask for your help.
Thank you in advance.
I think you are looking for a graphical parameter oma which will allow you to resize the main plot. The help reference states:
For plot.aggr, further graphical parameters to be passed down. par("oma") will be set appropriately unless supplied (see par).
In your case you could do something like:
aggr(df, prop = T, numbers = F, combined = F,
labels = names(df), cex.axis = .9, oma = c(10,5,5,3))
Obviously, you need to play around with cex.axis and other parameters to find out what works best for your data.
How can I change the spacing of tick marks on the axis of a plot?
What parameters should I use with base plot or with rgl?
There are at least two ways for achieving this in base graph (my examples are for the x-axis, but work the same for the y-axis):
Use par(xaxp = c(x1, x2, n)) or plot(..., xaxp = c(x1, x2, n)) to define the position (x1 & x2) of the extreme tick marks and the number of intervals between the tick marks (n). Accordingly, n+1 is the number of tick marks drawn. (This works only if you use no logarithmic scale, for the behavior with logarithmic scales see ?par.)
You can suppress the drawing of the axis altogether and add the tick marks later with axis().
To suppress the drawing of the axis use plot(... , xaxt = "n").
Then call axis() with side, at, and labels: axis(side = 1, at = v1, labels = v2). With side referring to the side of the axis (1 = x-axis, 2 = y-axis), v1 being a vector containing the position of the ticks (e.g., c(1, 3, 5) if your axis ranges from 0 to 6 and you want three marks), and v2 a vector containing the labels for the specified tick marks (must be of same length as v1, e.g., c("group a", "group b", "group c")). See ?axis and my updated answer to a post on stats.stackexchange for an example of this method.
With base graphics, the easiest way is to stop the plotting functions from drawing axes and then draw them yourself.
plot(1:10, 1:10, axes = FALSE)
axis(side = 1, at = c(1,5,10))
axis(side = 2, at = c(1,3,7,10))
box()
I have a data set with Time as the x-axis, and Intensity as y-axis. I'd need to first delete all the default axes except the axes' labels with:
plot(Time,Intensity,axes=F)
Then I rebuild the plot's elements with:
box() # create a wrap around the points plotted
axis(labels=NA,side=1,tck=-0.015,at=c(seq(from=0,to=1000,by=100))) # labels = NA prevents the creation of the numbers and tick marks, tck is how long the tick mark is.
axis(labels=NA,side=2,tck=-0.015)
axis(lwd=0,side=1,line=-0.4,at=c(seq(from=0,to=1000,by=100))) # lwd option sets the tick mark to 0 length because tck already takes care of the mark
axis(lwd=0,line=-0.4,side=2,las=1) # las changes the direction of the number labels to horizontal instead of vertical.
So, at = c(...) specifies the collection of positions to put the tick marks. Here I'd like to put the marks at 0, 100, 200,..., 1000. seq(from =...,to =...,by =...) gives me the choice of limits and the increments.
And if you don't want R to add decimals or zeros, you can stop it from drawing the x axis or the y axis or both using ...axt. Then, you can add your own ticks and labels:
plot(x, y, xaxt="n")
plot(x, y, yaxt="n")
axis(1 or 2, at=c(1, 5, 10), labels=c("First", "Second", "Third"))
I just discovered the Hmisc package:
Contains many functions useful for data analysis, high-level graphics, utility operations, functions for computing sample size and power, importing and annotating datasets, imputing missing values, advanced table making, variable clustering, character string manipulation, conversion of R objects to LaTeX and html code, and recoding variables.
library(Hmisc)
plot(...)
minor.tick(nx=10, ny=10) # make minor tick marks (without labels) every 10th
I am creating a plot in R and I dont like the x axis values being plotted by R.
For example:
x <- seq(10,200,10)
y <- runif(x)
plot(x,y)
This plots a graph with the following values on the X axis:
50, 100, 150, 200
However, I want to plot the 20 values 10,20, 30 ... 200 stored in variable x, as the X axis values. I have scoured through countless blogs and the terse manual - after hours of searching, the closest I've come to finding anything useful is the following (summarized) instructions:
call plot() or par(), specifying argument xaxt='n'
call axis() e.g. axis(side = 1, at = seq(0, 10, by = 0.1), labels = FALSE, tcl = -0.2)
I tried it and the resulting plot had no x axis values at all. Is it possible that someone out there knows how to do this? I can't believe that no one has ever tried to do this before.
You'll find the answer to your question in the help page for ?axis.
Here is one of the help page examples, modified with your data:
Option 1: use xaxp to define the axis labels
plot(x,y, xaxt="n")
axis(1, xaxp=c(10, 200, 19), las=2)
Option 2: Use at and seq() to define the labels:
plot(x,y, xaxt="n")
axis(1, at = seq(10, 200, by = 10), las=2)
Both these options yield the same graphic:
PS. Since you have a large number of labels, you'll have to use additional arguments to get the text to fit in the plot. I use las to rotate the labels.
Take a closer look at the ?axis documentation. If you look at the description of the labels argument, you'll see that it is:
"a logical value specifying whether (numerical) annotations are
to be made at the tickmarks,"
So, just change it to true, and you'll get your tick labels.
x <- seq(10,200,10)
y <- runif(x)
plot(x,y,xaxt='n')
axis(side = 1, at = x,labels = T)
# Since TRUE is the default for labels, you can just use axis(side=1,at=x)
Be careful that if you don't stretch your window width, then R might not be able to write all your labels in. Play with the window width and you'll see what I mean.
It's too bad that you had such trouble finding documentation! What were your search terms? Try typing r axis into Google, and the first link you will get is that Quick R page that I mentioned earlier. Scroll down to "Axes", and you'll get a very nice little guide on how to do it. You should probably check there first for any plotting questions, it will be faster than waiting for a SO reply.
Hope this coding will helps you :)
plot(x,y,xaxt = 'n')
axis(side=1,at=c(1,20,30,50),labels=c("1975","1980","1985","1990"))
In case of plotting time series, the command ts.plot requires a different argument than xaxt="n"
require(graphics)
ts.plot(ldeaths, mdeaths, xlab="year", ylab="deaths", lty=c(1:2), gpars=list(xaxt="n"))
axis(1, at = seq(1974, 1980, by = 2))
I'm plotting a 3D histogram in R using the method from figure 6.15 here.
I've set scale = list(arrow=F), so that I have tick marks instead of arrows on each axis.
The plot looks fine, but I want to change the axis tick labels. My x-axis goes from 1-26, my y from 1-24, and my Z from 0-8E-6. Ideally I'd like a single label at each of the discrete x and y values, and then at some reasonable interval on the z axis.
I've tried using the scale option 'tick.number', but it seems to only take one number, or use the first in a list, so if I set it to 26 I get excess tick marks on the y axis, and the z axis looks like rubbish.
I see there is an 'at' and 'labels' options in scales, much like for 2D plots, but I can't seem to get it to work. The docs indicate it should be a list of vectors with locations and labels for each panel, so I tried:
at = list(c(1:26), c(1:24), c(2*10^-6, 4*10^-6, 8*10^-6))
but it complains:
(list) object cannot be coerces to type 'double'
I presume if I figure out how to use 'at' then 'label' should become clear.
EDIT:
Here is sample code:
library(latticeExtra)
Cg = 1:25
Cr = 1:25
freqs = rnorm(25, .5, .1)
cloud(freqs~Cg*Cr, xlim=c(27,-1), ylim=c(25,-1), panel.3d.cloud=panel.3dbars, par.settings=list(box.3d = list(col="transparent")), col.facet="grey", scales=list(arrows=F))
My data has different lengths X and Y axes, and not just the diagonal is filled, but it shows the axis problem.
From the docs of cloud (lattice):
‘at’ gives the vector of
cutpoints where the colors change
So it needs to be a vector, not a list of vectors. The error you are getting is caused by a failure to transform your list of vectors to numeric:
at = list(c(1:26), c(1:24), c(2*10^-6, 4*10^-6, 8*10^-6))
> as.numeric(at)
Error: (list) object cannot be coerced to type 'double'
The at parameter describes where the colors change, similar to levelplot. So it only needs to be one vector.
Those result needs further work, but it does satisfy your request and shows you what is meant by passing the arguments to 'scales' as a list:
cloud(freqs~Cg*Cr, xlim=c(27,-1), ylim=c(25,-1),zlim=c(0,1), # needed to add zlim
panel.3d.cloud=panel.3dbars, par.settings=list(box.3d = list(col="transparent")),
col.facet="grey",
scales=list(arrows=F, x=list(at = c(1:26), lab=c(1:26)) ,
y=list(at= c(1:24), lab=c(1:24)),
z= list(rot=20, # to prevent over-riding the tick marks
at= c(.2,.4,.8) , # data spans larger range
lab=c("2*10^-6 ", "4*10^-6 ", "8*10^-6 ") )
) )
The range of z is simply not what you offered with those small values, so you need to accept that reality. If you want to relabel the proportions, then I have shown you how to do it.