Make custom legend with Julia Pyplot - plot

I would like to make a custom legend in Julia's pyplot, in which the legend labels are not necessarily related to individual series plotted on the graph. For example:
In Python (pyplot comes from matplotlib) this could be done with:
from matplotlib.lines import Line2D
custom_lines = [Line2D([0], [0], color=cmap(0.), lw=4),
Line2D([0], [0], color=cmap(.5), lw=4),
Line2D([0], [0], color=cmap(1.), lw=4)]
fig, ax = plt.subplots()
lines = ax.plot(data)
ax.legend(custom_lines, ['Cold', 'Medium', 'Hot'])
The issue is I cannot seem to access the Line2D object in pyplot (using pyplot as plt, plt.lines.Line2D does not work).
Any workaround?

I know it is not pyplot but MakieLayout will solve your problem:
Link to the example with code.
I got the answer from Julia Discourse.

I wasn't satisfied with the existing answer, but I managed to figure it out. Per the PyPlot.jl docs under Exported Functions,
(And the raw PyObject for the matplotlib modules is also accessible as PyPlot.matplotlib.)
So you can achieve your goal by just putting the full call in (I assign to a variable to avoid making the custom_lines ugly):
L2D = PyPlot.matplotlib.lines.Line2D
custom_lines = [L2D([0], [0], color=cmap(0.), lw=4),
L2D([0], [0], color=cmap(.5), lw=4),
L2D([0], [0], color=cmap(1.), lw=4)]
fig, ax = plt.subplots()
lines = ax.plot(data)
ax.legend(custom_lines, ['Cold', 'Medium', 'Hot'])

Related

Export plot from plotly into PDF

I use package plotly in order to make some plots. And the end my intention is to put this plot with high resolution in pdf. I don't know way but ggplot2 give me permission to do this, but with plotly I can't use option from R-Studio and convert directly into PDF. You can see that on pic below:
In order to fix this problem I try to do this with this lines of code:
pdf(file=paste("FINAL_plot.pdf",sep=""),width=10, height=5)
op <- par(mgp=c(1,0,0),mar=c(2, 2, 1, 1),# Room for the title and legend: 1_bottom,2_left,3_up,4_right
mfrow=c(1,2))
plot(FINAL_plot)
dev.off()
But unfortunately this lines of code didn't work and PDF is empty. So can anybody help me how to resolve this problem ?
Plotly plots can only be exported using the additional orca command line utility (https://github.com/plotly/orca)
You would first need to install the orca library on your OS (see https://github.com/plotly/orca#installation for details). After that you can export your plot using
library(plotly)
orca(FINAL_plot, "FINAL_plot.pdf")
Orca is now deprecated. You now must use Kaleido to install. In similarity to Orca, you must first have the Kaleido library installed on your OS.
To install:
install.packages('reticulate')
reticulate::install_miniconda()
reticulate::conda_install('r-reticulate', 'python-kaleido')
reticulate::conda_install('r-reticulate', 'plotly', channel = 'plotly')
reticulate::use_miniconda('r-reticulate')
To export:
library(plotly)
kaleido(FINAL_plot, "FINAL_plot.pdf")

In R, how do I save a data.tree plot to a file?

I'm unable to save a plot generated by the plot.Node function in data.tree. I've tried the following:
### Create tree object and plot it
data(acme);
plot(acme);
This works fine, showing the plot, as one would expect.
### Try saving it as png
png(filename='file.png', type='cairo-png');
plot(acme);
dev.off();
This creates an empty file. ggsave does the same. Apparantly, plot.Node uses DiagrammeR under the hood, so I looked into that package. It has a function to export graphs:
export_graph(acme, file_name="file.png");
This gives the error:
Error in file.exists(diagram) : invalid 'file' argument
When I transform to GraphViz first, I get a different error:
export_graph(ToGraphViz(acme), file_name="file.png");
Error in graph$dot_code : $ operator is invalid for atomic vectors
Clearly, exporting to GraphViz doesn't quite export to what DiagrammeR expects.
I'm in RStudio and so could in theory just save the plot using the GUI, but I need this for in a script.
Apparently, plot.Node doesn't actually plot anything - instead it seems to generate html/js. Does this mean that that result cannot be stored as a graphic? Or is there some export/conversion function somewhere that I'm completely missing? it certainly feels like I'm missing something obvious - I assume the need to store plotted data.trees as images is quite common. But I have no idea which potential solutions I can still explore.
I'd be very grateful for any pointers anybody has!
As sebastian-c suggested, things work now a bit differently than suggested by Matherion, as of R 3.3.3 with data.tree 0.7.0 and DiagrammeR 0.9.0
Pre-requisite: DiagrmmeRsvg and dependencies need to be installed. Depending on your OS, for this to work you might have to install V8. For example on ubuntu:
apt-get install libv8-3.14-delibv8-3.14-dev
And then in R:
install.packages("DiagrammeRsvg")
On Windows, I didn't have to install anything (maybe because Chrome is installed?).
Once DiagrammeRsvg is available, run:
library(data.tree)
data(acme)
library(DiagrammeR)
export_graph(ToDiagrammeRGraph(acme), "export.pdf")
I've found the answer, at least, partially. There exists a package dedicated to exporting GraphViz diagrams to SVG: DiagrammeRsvg.
So this works:
treeAsSVG <- export_svg(grViz(ToGraphViz(acme)));
writeLines(treeAsSVG, "filename.svg"));
The grViz is necessary to actually convert the ToGRaphViz output to something that can be interpreted by export_svg. I'm still not really sure (yet) what all goes on under the hood - for example, this does not work:
export_graph(grViz(ToGraphViz(acme)), file_name="filename.svg");
But, if anybody else has a similar problem and stumbles upon this question, perhaps this partial answer can help them to at least export something that can then be integrated in e.g. html pages.
By converting acme with as.phylo() it works, but it looks a little boring:
plot(as.phylo(acme),
show.node.label=TRUE,
node.pos=2,
no.margin=TRUE
)
# adding edge labels
edgelabels(as.vector(acme$Get("cost"))[-1],
adj = c(0,-0.5),
frame = "none")
solution with as.phylo()
I also tried as.igraph. However, the nodes overlap and it looks even less pretty:
plot(0, type="n", ann=FALSE, axes=FALSE,
xlim=extendrange(ig[,1]),
ylim=extendrange(ig[,2]))
plot(ig,
layout=layout_as_tree(ig,root=1),
vertex.shape="rectangle",
vertex.size=(strwidth(V(ig)$name) + strwidth("oo")) * 100,
#vertex.size2=strheight("I") * 2 * 100,
edge.label=acme$Get("p",traversal = "level")[-1]
)
solution with as.igraph()

How to turn off the "Hit <Return> to see next plot" prompt plot3D?

When using persp3D in package plot3D, there's only one plot produced but I still have to respond to the "Hit <Return> to see next plot" prompt. Is there a way to turn it off?
More generally, when there are multiple plots, do packages typically provide a way to specify a particular plot to show, similar to the which = c(1:3, 5) argument in plot.lm?
I ran into the same problem as you did and fixed it by the following code:
par(ask=F)
I hope it will help.
At some point, par(ask = F) was deprecated in favor of devAskNewPage.
In my copy of R 3.5.1, the following code plots without asking...
devAskNewPage(ask = FALSE)
# plot command here

why ggplot source code doesn't display the plot? [duplicate]

Let's assume I have 2 source files, the first one named example1.r and the second one example2.r (given below).
example1.r
plot(1:10,1:10)
example2.r
qplot(1:10,1:10)
When I source example1.r, the graph is drawn. It does not, however, when I source example2.r. What is the solution here?
(qplot in example2.r is ggplot2's function)
Update:
.R files: source's option print.eval=TRUE will lead to printing behaviour of the evaluation result like in the interactive command line.
source("Script.R", print.eval=TRUE)
.Rnw files: knitr by default emulates the behaviour of the interactive command line wrt. printing. Note that knitr can be specified as Sweaving engine also for R package vignettes.
This is my original answer. But note that this workaround is IMHO completely obsolete now (and it always was good for a small lazy niche only).
This is the famous FAQ 7.22: Why do lattice/trellis graphics not work?.
For grid graphics like ggplot2 or lattice, you need to print the graphics object in order to actually draw it.
Interactively on the command line this is done automatically. Everywhere else (inside files to be sourced, loops, functions, Sweave chunks) you need to print it explicitly.
print (qplot (1 : 10, 1 : 10))
Alternatively, you can redefine qplot to do the printing:
qplot <- function (x, y = NULL, z = NULL, ...) {
p <- ggplot2::qplot (x = x, y = y, z = z, ...)
print (p)
}
(this changes the axis labels to x and y).
I use this approach in vignettes where I want to write code exactly as a user in an interactive session would type it.

R programming Graph plot not appearing ggplot2 [duplicate]

Let's assume I have 2 source files, the first one named example1.r and the second one example2.r (given below).
example1.r
plot(1:10,1:10)
example2.r
qplot(1:10,1:10)
When I source example1.r, the graph is drawn. It does not, however, when I source example2.r. What is the solution here?
(qplot in example2.r is ggplot2's function)
Update:
.R files: source's option print.eval=TRUE will lead to printing behaviour of the evaluation result like in the interactive command line.
source("Script.R", print.eval=TRUE)
.Rnw files: knitr by default emulates the behaviour of the interactive command line wrt. printing. Note that knitr can be specified as Sweaving engine also for R package vignettes.
This is my original answer. But note that this workaround is IMHO completely obsolete now (and it always was good for a small lazy niche only).
This is the famous FAQ 7.22: Why do lattice/trellis graphics not work?.
For grid graphics like ggplot2 or lattice, you need to print the graphics object in order to actually draw it.
Interactively on the command line this is done automatically. Everywhere else (inside files to be sourced, loops, functions, Sweave chunks) you need to print it explicitly.
print (qplot (1 : 10, 1 : 10))
Alternatively, you can redefine qplot to do the printing:
qplot <- function (x, y = NULL, z = NULL, ...) {
p <- ggplot2::qplot (x = x, y = y, z = z, ...)
print (p)
}
(this changes the axis labels to x and y).
I use this approach in vignettes where I want to write code exactly as a user in an interactive session would type it.

Resources