I want to plot 2 vectors again each other. The Julia documentation says I could just ex. write.
using Plots
x = 1:10; y = rand(10); # These are the plotting data
plot(x, y)
But I get the following error:
LoadError: MethodError: no method matching NamedTuple(::Base.Generator{Base.Iterators.Filter{Plots.var"#131#134"{Dict{Symbol,Any}},NTuple{6,Symbol}},Plots.var"#130#133"{Dict{Symbol,Any}}})
Closest candidates are:
NamedTuple() at boot.jl:545
NamedTuple(!Matched::Union{Tables.AbstractColumns, Tables.AbstractRow})
What is the problem? I have used the example from the documentation and have not changed anything.
Related
I have three variables: x,y, and z and I want to produce a surface plot.
z<-runif(50,0,1)
y<-runif(50,1,2)
x<-runif(50,3,6)
plot_ly(x = ~x, y = ~y, z= ~z) %>% add_surface()
I get the following error
Error: `z` must be a numeric matrix
What exactly does z represent if not the variable corresponding to the vertical axis? I have seen the Volcano example where they use the matrix to generate that plot, but I still am not sure what that z matrix represents in that example either.
What I would like is for someone to plot an easy to understand 3D function like z=f(x,y) = x^2 + y^2 using the surface functionality in plot_ly just so I can understand how to generate a plot based on three variables.
The problem with your above code is, that you haven't specified the trace type - and what you need to pass to the z argument depends on this specification.
Passing the arguments x, y, z suggests you want to display a scatter3d plot - you can test this by dropping add_surface():
z <- runif(50,0,1)
y <- runif(50,1,2)
x <- runif(50,3,6)
plot_ly(x = x, y = y, z = z)
Which gives the warning:
No trace type specified: Based on info supplied, a 'scatter3d' trace
seems appropriate. Read more about this trace type ->
https://plot.ly/r/reference/#scatter3d No scatter3d mode specifed:
Setting the mode to markers Read more about this attribute ->
https://plot.ly/r/reference/#scatter-mode
add_surface() on the other hand suggests you want to display a 3D Surface Plot.
You already mentioned the volcano example. This kind of plot only needs a single numeric matrix to create the plot (argument z).
Accordingly with your example code you mixed up both plot types which leads to the error message.
How to avoid this confusion?
If you have a look at ?plot_ly there is a description for arguments "..." passed to the according trace type (z is one of them):
Arguments (i.e., attributes) passed along to the trace type. See
schema() for a list of acceptable attributes for a given trace type
(by going to traces -> type -> attributes).
schema() is a very useful hint to orient oneself in the plotly library. Execute the following code to browse through the different plotly trace types and their available attributes in a very convenient way:
# install.packages("listviewer")
library(plotly)
library(listviewer)
schema(jsonedit = interactive())
I guess this is what you were after in the first place:
z <- runif(50,0,1)
y <- runif(50,1,2)
x <- runif(50,3,6)
plot_ly(x = x, y = y, z = z, type = 'mesh3d')
I want to draw a confidence ellipse. I search the R document and find the function: panel.ellipse. Here is the description website
Then I tried. I used the code below:
library(corrgram)
a<-c(1,2,3,4,5)
b<-c(2,4,6,5,3)
panel.ellipse(a, b)
But an error occur:
Error in plot.xy(xy.coords(x, y), type = type, ...) :
plot.new has not been called yet
I didn't call "plot.new", why did R say that?
You're linking to the latticeExtra::panel.ellipse function in the description link, but seem to be using corrgram which also has a panel.ellipse function. So I'm not sure which panel.ellipse function you are using/want to use.
From ?corrgram::panel.ellipse:
# CAUTION: The latticeExtra package also has a 'panel.ellipse' function
# that clashes with the same-named function in corrgram. In order to us
# the right one, the example below uses 'lower.panel=corrgram::panel.ellipse'.
# If you do not have latticeExtra loaded, you can just use
# 'lower.panel=panel.ellipse'.
Why not use ggplot2::stat_ellipse instead?
# Your sample data
a<-c(1,2,3,4,5)
b<-c(2,4,6,5,3)
df <- cbind.data.frame(a, b);
# Use stat_ellipse to draw confidence ellipse
require(ggplot2);
ggplot(df, aes(a, b)) + geom_point() + stat_ellipse();
I am using a package(LightGraphs.jl) in Julia, and it has a predefined histogram method that creates the degree distribution of a network g.
deg_hist = degree_histogram(g)
I want to make a plot of this but i am new to plotting in Julia. The object returned is a StatsBase.Histogram which has the following as its inner fields:
StatsBase.Histogram{Int64,1,Tuple{FloatRange{Float64}}}
edges: 0.0:500.0:6000.0
weights: [79143,57,32,17,13,4,4,3,3,2,1,1]
closed: right
Can you help me how I can make use of this object to plot the histogram?
I thought this was already implemented, but I just added the recipe to StatPlots. If you check out master, you'll be able to do:
julia> using StatPlots, LightGraphs
julia> g = Graph(100,200);
julia> plot(degree_histogram(g))
For reference, the associated recipe that I added to StatPlots:
#recipe function f(h::StatsBase.Histogram)
seriestype := :histogram
h.edges[1], h.weights
end
Use the histogram fields .edges and .weights to plot it e.g.
using PyPlot, StatsBase
a = rand(1000); # generate something to plot
test_hist = fit(Histogram, a)
# line plot
plot(test_hist.edges[1][2:end], test_hist.weights)
# bar plot
bar(0:length(test_hist.weights)-1, test_hist.weights)
xticks(0:length(test_hist.weights), test_hist.edges[1])
or you could create/extend a plotting function adding a method like so:
function myplot(x::StatsBase.Histogram)
... # your code here
end
Then you will be able to call your plotting functions directly on the histogram object.
plot( dnorm , col='white')
polygon( dnorm, col='grey' )
returns the above error message, not on plot, but on polygon.
body(polygon) %>% grep(pattern='numeric') finds only one occurrence on line 4, which doesn't seem to have anything to do with this error. So I'm at a loss as to where to look for the source of the problem.
plot has a function method, whereas polygon does not. From ?plot:
x: the coordinates of points in the plot. Alternatively, a single plotting structure, function or any R object with a plot method can be provided.
Additionally, from ?plot.function, the S3 method to plot functions:
## S3 method for class 'function'
plot(x, y = 0, to = 1, from = y, xlim = NULL, ylab = NULL, ...)
This explains why you get a plot with values from 0 to 1 with plot when you pass dnorm as an argument.
Note functions like dnorm are also known as closures. This explains why you get that error with polygon. Since polygon does not accept functions as an argument, it tries to convert dnorm, a closure, to a vector, but that isn't a valid conversion.
The error in polygon is actually happening in the as.double call within xy.coord:
> polygon(dnorm)
Error in as.double(y) :
cannot coerce type 'closure' to vector of type 'double'
> traceback()
2: xy.coords(x, y)
1: polygon(dnorm)
Note as.double doesn't register in the trace stack because it is a primitive. By looking at the source of xy.coords, you can see where the error is happening. To semi-confirm:
> as.double(dnorm)
Error in as.double(dnorm) :
cannot coerce type 'closure' to vector of type 'double'
dnorm(-3:3) actually produces a numeric vector, which is why that works with polygon.
The call to plot will resolve to a variety of default methods for different types of objects. See methods(plot) for a list in your environment. For dnorm it is plot.function, which takes the function as an argument and provides a set of inputs into the function. Incidentally this will also work with rnorm because plot.function provides a default argument of n=101.
A more common alias for plot.function is curve.
curve(dnorm, col="grey")
The polygon has no such analogous method for various types of objects.
You need to polygon( dnorm(-3:3) ) or whatever the xlim limits are. polygon lacks a method for treating functions (although plot has one).
How does the following code work? I got the example when I was reading the help line of R ?curve. But i have not understood this.
for(ll in c("", "x", "y", "xy"))
curve(log(1+x), 1, 100, log = ll,
sub = paste("log= '", ll, "'", sep = ""))
Particularly , I am accustomed to numeric values as arguments inside the for-loop as,
for(ll in 1:10)
But what is the following command saying:
for(ll in c("","x","y","xy"))
c("","x","y","xy") looks like a string vector? How does c("","x","y","xy") work inside curve
function as log(1+x)[what is x here? the string "x"? in c("","x","y","xy")] and log=ll ?
Apparently, there are no answers on stack overflow about how the curve function in R works and especially about the log argument so this might be a good chance to delve into it a bit more (I liked the question btw):
First of all the easy part:
c("","x","y","xy") is a string vector or more formally a character vector.
for(ll in c("","x","y","xy")) will start a loop of 4 iterations and each time ll will be '','x','y','xy' respectively. Unfortunately, the way this example is built you will only see the last one plotted which is for ll = 'xy'.
Let's dive into the source code of the curve function to answer the rest:
First of all the what does the x represent in log(1+x)?
log(1+x) is a function. x represents a vector of numbers that gets created inside the curve function in the following part (from source code):
x <- exp(seq.int(log(from), log(to), length.out = n)) #if the log argument is 'x' or
x <- seq.int(from, to, length.out = n) #if the log argument is not 'x'
#in our case from and to are 1 and 100 respectively
As long as the n argument is the default the x vector will contain 101 elements. Obviously the x in log(1+x) is totally different to the 'x' in the log argument.
as for y it is always created as (from source code):
y <- eval(expr, envir = ll, enclos = parent.frame()) #where expr is in this case log(1+x), the others are not important to analyse now.
#i.e. you get a y value for each x value on the x vector which was calculated just previously
Second, what is the purpose of the log argument?
The log argument decides which of the x or y axis will be logged. The x-axis if 'x' is the log argument, y-axis if 'y' is the log argument, both axis if 'xy' is the log argument and no log-scale if the log argument is ''.
It needs to be mentioned here that the log of either x or y axis is being calculated in the plot function in the curve function, that is the curve function is only a wrapper for the plot function.
Having said the above this is why if the log argument is 'x' (see above) the exponential of the log values of the vector x are calculated so that they will return to the logged ones inside the plot function.
P.S. the source code for the curve function can be seen with typing graphics::curve on the console.
I hope this makes a bit of sense now!