I am using the native PGFPlots.jl plotting software in Julia language.
I will be ever so grateful if you could let me know how to change the font size of:
Title (I suspect with legend style={font=\small})
legend
xlabel
ylabel
My code:
pushPGFPlotsOptions("scale=1.5")
Plot1 = GroupPlot(2, 2, groupStyle = "horizontal sep = 1.6cm, vertical sep = 2.cm")
push!(Plot1b, Axis([
Plots.Linear(Se, H_Kg, mark="none", style="red, very thick"),
Plots.Linear(Se, H_Vg, mark="none", style="dashed, blue, very thick"),
], title="Se(H)", xlabel=L"$Se[-]$", ylabel=L"$H[cm]$", style="smooth", xmin=Se_Min, xmax=Se_Max, ymin=H_Min, ymode="log"))
push!(Plot1, Axis([
Plots.Linear(Se, Kunsat_Kg, mark="none", style="red, very thick", legendentry=L"$KG$"),
Plots.Linear(Se, Kunsat_Vg, mark="none", style="dashed, blue, very thick", legendentry=L"$VG$"),
], title="K(Se)", xlabel=L"$Se[-]$", ylabel=L"$K(Se)[cm/h]$", style="smooth", xmin=Se_Min, xmax=Se_Max, ymin=K_Min, legendStyle = "{at={(-0.3,-0.4)}, anchor=south west, legend columns=-1}"))
save(Path, Plot1)
Many thanks for any help you may provide,
Related
I have some 2D data in Julia representing a circular feature with some "holes" in it. I like to interpolate these holes by finding points fitting on a curve representing the shape of the feature.
Using Julia's PlotlyJS library I was able to find a nice spline interpolation curve for the points visually. However, I am not able to "access" that interpolation to calculate the actual points required. Any (alternative?) idea on how to get that?
Here is a working example in Julia:
using PlotlyJS
someData = [
3.47336 -0.471233;
3.53109 0.335963;
3.46748 1.10433;
3.13369 1.87227;
2.33268 2.51022;
1.21804 3.07551;
0.211065 3.3075;
-0.768256 3.18599;
-1.72856 2.87655;
-2.55477 2.58726;
-3.28657 1.99779;
-3.63637 1.31502;
-3.56652 -0.462201;
-2.96175 -0.956073;
-2.0519 -0.870708;
-1.07193 -0.837913;
-0.156219 -0.972855;
0.594719 -1.4576;
1.27607 -1.9387;
2.08427 -2.17288;
3.47336 -0.471233
]
plot([
scatter(
x=someData[:,1], y=someData[:,2], type="scatter", mode="markers", name="Some data",
marker=attr(size=8, color="orange", opacity=1)
),
scatter(
x=someData[:,1], y=someData[:,2], type="scatter", mode="lines", name="Plotly spline",
line=attr(color="green", width=2, shape="spline")
),
], Layout(scene=attr(aspectmode="data"), showlegend=true)
)
This was answered on the Julia Discourse here:
https://discourse.julialang.org/t/add-missing-points-in-a-2d-line/94211/3
Copy-pasting the solution (which isn't mine!):
using Dierckx, Plots
t = 1:size(data,1)
spl = ParametricSpline(t, data', bc="extrapolate", s=0.0)
tfine= range(1, size(data,1), 200)
Pfine = evaluate(spl, tfine)
t0, t1 = 12.5, 20.6
P0, P1 = evaluate.((spl,), [t0, t1])
plot(eachrow(Pfine)..., c=:blues)
scatter!(eachcol(data)...,legend=false )
scatter!([P0[1]], [P0[2]], ms=5, mc=:red)
scatter!([P1[1]], [P1[2]], ms=5, mc=:red)
I am learning how to create plots with slider bars. Here is my code based off the first example of this tutorial
using Plots
gr()
using GLMakie
function plotLaneEmden(log_delta_xi=-4, n=3)
fig = Figure()
ax = Axis(fig[1, 1])
sl_x = Slider(fig[2, 1], range = 0:0.01:4.99, startvalue = 3)
sl_y = Slider(fig[1, 2], range = -6:0.01:0.1, horizontal = false, startvalue = -2)
point = lift(sl_x.value, sl_y.value) do n, log_delta_xi
Point2f(n, log_delta_xi)
end
plot(n, 1 .- log_delta_xi.^2/6, linecolor = :green, label="n = $n")
xlabel!("ξ")
ylabel!("θ")
end
plotLaneEmden()
When I run this, it gives UndefVarError: plot not defined. What am I missing here?
It looks like you are trying to mix and match Plots.jl and Makie.jl. Specifically, the example from your link is entirely for Makie (specifically, with the GLMakie backend), while the the plot function you are trying to add uses syntax specific to the Plots.jl version of plot (specifically including linecolor and label keyword arguments).
Plots.jl and Makie.jl are two separate and unrelated plotting libraries, so you have to pick one and stick with it. Since both libraries export some of the same function names, using both at once will lead to ambiguity and UndefVarErrors if not disambiguated.
The other potential problem is that it looks like you are trying to make a line plot with only a single x and y value (n and log_delta_xi are both single numbers in your code as written). If that's what you want, you'll need a scatter plot instead of a line plot; and if that's not what you want you'll need to make those variables vectors instead somehow.
Depending on what exactly you want, you might try something more along the lines of (in a new session, using only Makie and not Plots):
using GLMakie
function plotLaneEmden(log_delta_xi=-4, n=3)
fig = Figure()
ax = Axis(fig[1, 1], xlabel="ξ", ylabel="θ")
sl_x = Slider(fig[2, 1], range = 0:0.01:4.99, startvalue = n)
sl_y = Slider(fig[1, 2], range = -6:0.01:0.1, horizontal = false, startvalue = log_delta_xi)
point = lift(sl_x.value, sl_y.value) do n, log_delta_xi
Point2f(n, 1 - log_delta_xi^2/6)
end
sca = scatter!(point, color = :green, markersize = 20)
axislegend(ax, [sca], ["n = $n"])
fig
end
plotLaneEmden()
Or, below, a simple example for interactively plotting a line rather than a point:
using GLMakie
function quadraticsliders(x=-5:0.01:5)
fig = Figure()
ax = Axis(fig[1, 1], xlabel="X", ylabel="Y")
sl_a = Slider(fig[2, 1], range = -3:0.01:3, startvalue = 0.)
sl_b = Slider(fig[1, 2], range = -3:0.01:3, horizontal = false, startvalue = 0.)
points = lift(sl_a.value, sl_b.value) do a, b
Point2f.(x, a.*x.^2 .+ b.*x)
end
l = lines!(points, color = :blue)
onany((a,b)->axislegend(ax, [l], ["$(a)x² + $(b)x"]), sl_a.value, sl_b.value)
limits!(ax, minimum(x), maximum(x), -10, 10)
fig
end
quadraticsliders()
ETA: A couple examples closer to what you might be looking for
I'm trying to do something that I'd normally consider trivial but seems to be very difficult in bokeh: Adding a vertical colorbar to a plot and then having the title of the colorbar (a.k.a. the variable behind the colormapping) appear to one side of the colorbar but rotated 90 degrees clockwise from horizontal.
From what I can tell of the bokeh ColorBar() interface (looking at both documentation and using the python interpreter's help() function for this element), this is not possible. In desperation I have added my own Label()-based annotation. This works but is klunky and displays odd behavior when deployed in a bokeh serve situation--that the width of the data window on the plot varies inversely with the length of the title colorbar's title string.
Below I've included a modified version of the bokeh server mpg example. Apologies for its complexity, but I felt this was the best way to illustrate the problem using infrastructure/data that ships with bokeh. For those unfamiliar with bokeh serve, this code snippet needs to saved to a file named main.py that resides in a directory--for the sake of argument let's say CrossFilter2--and in the parent directory of CrossFilter2 one needs to invoke the command
bokeh serve --show CrossFilter2
this will then display in a browser window (localhost:5006/CrossFilter2) and if you play with the color selection widget you will see what I mean, namely that short variable names such as 'hp' or 'mpg' result in a wider data display windows than longer variable names such as 'accel' or 'weight'. I suspect that there may be a bug in how label elements are sized--that their x and y dimensions are swapped--and that bokeh has not understood that the label element has been rotated.
My questions are:
Must I really have to go to this kind of trouble to get a simple colorbar label feature that I can get with little-to-no trouble in matplotlib/plotly?
If I must go through the hassle you can see in my sample code, is there some other way I can do this that avoids the data window width problem?
import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import Select
from bokeh.models import HoverTool, ColorBar, LinearColorMapper, Label
from bokeh.palettes import Spectral5
from bokeh.plotting import curdoc, figure, ColumnDataSource
from bokeh.sampledata.autompg import autompg_clean as df
df = df.copy()
SIZES = list(range(6, 22, 3))
COLORS = Spectral5
# data cleanup
df.cyl = df.cyl.astype(str)
df.yr = df.yr.astype(str)
columns = sorted(df.columns)
discrete = [x for x in columns if df[x].dtype == object]
continuous = [x for x in columns if x not in discrete]
quantileable = [x for x in continuous if len(df[x].unique()) > 20]
def create_figure():
xs = df[x.value].tolist()
ys = df[y.value].tolist()
x_title = x.value.title()
y_title = y.value.title()
name = df['name'].tolist()
kw = dict()
if x.value in discrete:
kw['x_range'] = sorted(set(xs))
if y.value in discrete:
kw['y_range'] = sorted(set(ys))
kw['title'] = "%s vs %s" % (y_title, x_title)
p = figure(plot_height=600, plot_width=800,
tools='pan,box_zoom,wheel_zoom,lasso_select,reset,save',
toolbar_location='above', **kw)
p.xaxis.axis_label = x_title
p.yaxis.axis_label = y_title
if x.value in discrete:
p.xaxis.major_label_orientation = pd.np.pi / 4
if size.value != 'None':
groups = pd.qcut(df[size.value].values, len(SIZES))
sz = [SIZES[xx] for xx in groups.codes]
else:
sz = [9] * len(xs)
if color.value != 'None':
coloring = df[color.value].tolist()
cv_95 = np.percentile(np.asarray(coloring), 95)
mapper = LinearColorMapper(palette=Spectral5,
low=cv_min, high=cv_95)
mapper.low_color = 'blue'
mapper.high_color = 'red'
add_color_bar = True
ninety_degrees = pd.np.pi / 2.
color_bar = ColorBar(color_mapper=mapper, title='',
#title=color.value.title(),
title_text_font_style='bold',
title_text_font_size='20px',
title_text_align='center',
orientation='vertical',
major_label_text_font_size='16px',
major_label_text_font_style='bold',
label_standoff=8,
major_tick_line_color='black',
major_tick_line_width=3,
major_tick_in=12,
location=(0,0))
else:
c = ['#31AADE'] * len(xs)
add_color_bar = False
if add_color_bar:
source = ColumnDataSource(data=dict(x=xs, y=ys,
c=coloring, size=sz, name=name))
else:
source = ColumnDataSource(data=dict(x=xs, y=ys, color=c,
size=sz, name=name))
if add_color_bar:
p.circle('x', 'y', fill_color={'field': 'c',
'transform': mapper},
line_color=None, size='size', source=source)
else:
p.circle('x', 'y', color='color', size='size', source=source)
p.add_tools(HoverTool(tooltips=[('x', '#x'), ('y', '#y'),
('desc', '#name')]))
if add_color_bar:
color_bar_label = Label(text=color.value.title(),
angle=ninety_degrees,
text_color='black',
text_font_style='bold',
text_font_size='20px',
x=25, y=300,
x_units='screen', y_units='screen')
p.add_layout(color_bar, 'right')
p.add_layout(color_bar_label, 'right')
return p
def update(attr, old, new):
layout.children[1] = create_figure()
x = Select(title='X-Axis', value='mpg', options=columns)
x.on_change('value', update)
y = Select(title='Y-Axis', value='hp', options=columns)
y.on_change('value', update)
size = Select(title='Size', value='None',
options=['None'] + quantileable)
size.on_change('value', update)
color = Select(title='Color', value='None',
options=['None'] + quantileable)
color.on_change('value', update)
controls = widgetbox([x, y, color, size], width=200)
layout = row(controls, create_figure())
curdoc().add_root(layout)
curdoc().title = "Crossfilter"
You can add a vertical label to the Colorbar by plotting it on a separate axis and adding a title to this axis. To illustrate this, here's a modified version of Bokeh's standard Colorbar example (found here):
import numpy as np
from bokeh.plotting import figure, output_file, show
from bokeh.models import LogColorMapper, LogTicker, ColorBar
from bokeh.layouts import row
plot_height = 500
plot_width = 500
color_bar_height = plot_height + 11
color_bar_width = 180
output_file('color_bar.html')
def normal2d(X, Y, sigx=1.0, sigy=1.0, mux=0.0, muy=0.0):
z = (X-mux)**2 / sigx**2 + (Y-muy)**2 / sigy**2
return np.exp(-z/2) / (2 * np.pi * sigx * sigy)
X, Y = np.mgrid[-3:3:100j, -2:2:100j]
Z = normal2d(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*normal2d(X, Y, 1.0, 1.0)
image = Z * 1e6
color_mapper = LogColorMapper(palette="Viridis256", low=1, high=1e7)
plot = figure(x_range=(0,1), y_range=(0,1), toolbar_location=None,
width=plot_width, height=plot_height)
plot.image(image=[image], color_mapper=color_mapper,
dh=[1.0], dw=[1.0], x=[0], y=[0])
Now, to make the Colorbar, create a separate dummy plot, add the Colorbar to the dummy plot and place it next to the main plot. Add the Colorbar label as the title of the dummy plot and center it appropriately.
color_bar = ColorBar(color_mapper=color_mapper, ticker=LogTicker(),
label_standoff=12, border_line_color=None, location=(0,0))
color_bar_plot = figure(title="My color bar title", title_location="right",
height=color_bar_height, width=color_bar_width,
toolbar_location=None, min_border=0,
outline_line_color=None)
color_bar_plot.add_layout(color_bar, 'right')
color_bar_plot.title.align="center"
color_bar_plot.title.text_font_size = '12pt'
layout = row(plot, color_bar_plot)
show(layout)
This gives the following output image:
One thing to look out for is that color_bar_width is set wide enough to incorporate both the Colorbar, its axes labels and the Colorbar label. If the width is set too small, you will get an error and the plot won't render.
As of Bokeh 0.12.10 there is no built in label available for colorbars. In addition to your approach or something like it, another possibility would be a custom extension, though that is similarly not trivial.
Offhand, a colobar label certainly seems like a reasonable thing to consider. Regarding the notion that it ought to be trivially available, if you polled all users about what they consider should be trivially available, there will be thousands of different suggestions for what to prioritize. As is very often the case in the OSS world, there are far more possible things to do, than there are people to do them (less than 3 in this case). So, would first suggest a GitHub Issue to request the feature, and second, if you have the ability, volunteering to help implement it. Your contribution would be valuable and appreciated by many.
I am trying to create a heatmap with color key on any side of the plot, but i am having no success trying to adjust the margins or key size. I am using following code -
Snippet of sample data used -
MainID ID_2G ID_4G ID_6G ID_1G ID_3G ID_5G
hsa-let-7a-3p 2.373537231 1.795512275 2.108466924 2.099991234 1.366411749 1.697434233
hsa-let-7b-5p 4.117668941 4.244217726 4.192366706 4.252280064 4.373915609 4.132854995
hsa-let-7c-5p 3.584669254 3.662052948 3.731995474 3.80026193 3.928874439 3.775407269
hsa-let-7d-5p 3.952963803 4.075568858 4.031767871 4.091068732 4.11592655 4.042351023
hsa-let-7d-3p 2.277758155 2.381779107 2.524793232 2.486192366 2.774166469 2.245618761
hsa-let-7e-5p 3.463884034 3.641849742 3.441178073 3.661688719 3.8048411 3.577103289
hsa-let-7f-2-3p 2.78571839 2.384983875 2.499306221 2.448944267 2.184072191 2.253735281
hsa-miR-18a-5p 2.546603115 2.330624781 2.314783332 2.276082493 2.101097208 2.089544815
hsa-miR-19a-3p 2.024735992 1.631655791 1.600963099 1.840353296 1.725433809 1.725462411
hsa-miR-19b-3p 2.819401121 2.319630645 2.548865836 2.497931242 2.284741961 2.407832623
hsa-miR-21-5p 4.602200029 4.529305849 4.447272794 4.401274715 4.210179352 4.346962906
hsa-miR-22-5p 0.728565601 0.54026564 0.798960548 0.822343985 1.424432416
hsa-miR-26a-1-3p 0.692296876 0.728565601 0.239234393 1.099991234 1.123374635 0.998463792
hsa-miR-27a-3p 3.047364444 2.938973296 2.975631676 3.03448808 2.806870902 2.927882898
hsa-miR-28-3p 3.296522595 3.500887977 3.421934457 3.376069375 3.488394173 3.487484824
hsa-miR-92a-1-5p 2.340656253 2.455565039 2.43235989 2.435782274 2.654852975 2.546648757
hsa-miR-92a-3p 4.579913865 4.668999646 4.550205109 4.617977976 4.703813937 4.663700925
hsa-miR-92a-2-5p 0.993326431 0.728565601 0.938205398 1.020808608 0.822343985 0.998463792
R code-
row.names(three_union) <- three_union$MainID
three_union <- three_union[,2:8]
three_matrix <- data.matrix(three_union)
heatmap.2(three_matrix,density.info="histogram", dendrogram = 'none', trace ='none', Rowv= F, Colv=F, col=heat.colors(256), cexCol=.6,cexRow = .5, key = TRUE, keysize = 2)
The plots is as follows, teh key is so large right now, and I have tried even lmat, lwid,lheo methods to make it fit! Can anyone please help!
Thanks a lot.
You do not need to change lmat unless you want the key in a different position. In addition to setting lhei and lwid you should change the some key.par's such as cex to reduce the text size of the legend.
heatmap.2(x, key=T, cexRow = 0.75, cexCol=0.75, trace="none",
lhei=c(2,4), lwid=c(2,3.5), keysize=0.75, key.par = list(cex=0.5))
Vs. without changing the text size:
heatmap.2(x, key=T, cexRow = 0.75, cexCol=0.75, trace="none",
lhei=c(2,4), lwid=c(2,3.5), keysize=0.75)
I've searched SO, Googled, read ?pdf, and come up dry as to the possibility of saving a plot as a pdf with layers that can be swtiched on and off in the pdf viewer margins. An example of what I'm talking about are the USGS quad topo-maps, which can be downloaded as pdfs with multiple layers, such as this (zipped pdf).
The following sentence in the pdf() help file sounds ominous, but I also wanted to check that I'm not misinterpreting it:
The R graphics model does not distinguish graphics objects at the level
of the driver interface.
I used to be able to save layered pdf's in Illustrator, but no longer have this program at my disposal. Perhaps someone can think of a workaround from within R? The data I'm using to map are large, but here's a toy example:
pdf("2objects.pdf")
plot(NULL, type = "n",xlim = c(0,1),ylim = c(0,1))
rect(0,.7,.7,0,border = "blue",lwd=2)
rect(.3,1,1,.3,border = "red",lty=2,lwd=2)
dev.off()
It looks like this (it's a png, but the above will give a pdf)
I'd like to be able to have the red and blue boxes as layers with visibility that can be switched on and off from within the pdf viewer.
Many thanks!
Edit: found thread in R-help (re: #mnel), and it looks to not be possible. I will still leave this question open, in case someone has come up with a nifty R-tastic workaround.
Edit (Sept 5th, 2012): I tried doing this via Sweave, and achieved partial success using the workaround posted here. This method produces a single pdf with 'layers' that can be switched on and off using hyperlinked text below the images. It uses 'animation' trickery to do so. While it is still not my ultimate desired outcome, it has the advantage of not depending on particular pdf viewers. I will still wait to see if someone posts a way to do layers, aka OCGs in a Sweave document, which I could then automate.
Edit (Sept 13, 2012): I posted my progress so far as an answer, using the code mentioned above. I was able to get it working in a more complex real world situation with no alterations to the code with overlays of different administrative and statistical boundaries within the US. In this case, I just named the different map overlays layer-0.pdf, layer-1.pdf, etc, and it worked without error. I still hope something better pops up here eventually.
Thanks all for you comments
I'm able to achieve this via ggplot.
library(ggplot2)
df <- data.frame(x = c(1,10), y = c(20,40), class = 1:2)
layered_plot <- ggplot(df, aes(xmin = x, xmax = x + 1, ymin = y, ymax = y + 2, fill = class)) +
geom_rect() +
opts(legend.position = "none")
# Now save this as pdf
ggsave(layered_plot, file="p1.pdf")
(This is just the png version for illustration but when I open the pdf in Illustrator, I can turn off the individual layers as needed).
Looks like the (tex) animation answer is the best I can come up with now. The following .Rnw file will create a pdf with a figure in the middle, and 2 text hyperlinks below it, which toggle visibility of the red and blue boxes independently. I found the Tex code that makes this work here. I've not looked at #Aaron's ocgtools suggestion yet, but will get there. Thanks all for your suggestions!
\documentclass{article}
%----------------------------------------------------------------%\
\usepackage[OT1]{fontenc}
\usepackage{Sweave}
\usepackage{animate}
\usepackage{hyperref}
\usepackage[margin=0.4in]{geometry}
%----------------------------------------------------------------%
\makeatletter
% command to create a toggle link
\newcommand{\ShowHideLayer}[3]{%
% #1: anim No. (zero-based),
% #2: layer No. (zero-based),
% #3: link text
\leavevmode%
\pdfstartlink user {
/Subtype /Link
/Border [\#pdfborder]%
/A <<
/S/JavaScript
/JS (
\if at anim#useocg%
if(a#1.fr[#2].state==true){
a#1.fr[#2].state=false;
}else{
a#1.fr[#2].state=true;
}
\else
if (a#1.fr[#2].display==display.visible){
a#1.fr[#2].display=display.hidden;
}else{
a#1.fr[#2].display=display.visible;
}
this.dirty=false;
\fi
)
>>
}#3%
\pdfendlink%
}
% command to create a link to show/hide all layers
\newcommand{\ShowHideAll}[2]{%
% #1: anim No. (zero-based),
% #2: link text
\leavevmode%
\pdfstartlink user {
/Subtype /Link
/Border [\#pdfborder]%
/A <<
/S/JavaScript
/JS (
var countvisible=0;
for(var i in a#1.fr){
\if at anim#useocg
if(a#1.fr[i].state==true){countvisible++;}
\else
if (a#1.fr[i].display==display.visible){countvisible++;}
\fi
}
if(countvisible){
for(var i in a#1.fr){
\if at anim#useocg
a#1.fr[i].state=false;
\else
a#1.fr[i].display=display.hidden;
this.dirty=false;
\fi
}
}
else{
for(var i in a#1.fr){
\if at anim#useocg
a#1.fr[i].state=true;
\else
a#1.fr[i].display=display.visible;
this.dirty=false;
\fi
}
}
)
>>
}#2%
\pdfendlink%
}
\makeatother
\begin{document}
% heres the R-making of the plots, saved to working directory,
% which should be the folder containing this .Rnw file
% 3 versions of the same plot, one for each layer
<<echo = FALSE, hide = TRUE>>=
pdf("layer-0.pdf")
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), xlab = "", ylab = "")
dev.off()
pdf("layer-1.pdf")
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), axes = FALSE, xlab = "", ylab = "")
rect(0, .7, .7, 0, border = "blue", lwd = 2)
dev.off()
pdf("layer-2.pdf")
plot(NULL, type = "n", xlim = c(0, 1), ylim = c(0, 1), axes = FALSE, xlab = "", ylab = "")
rect(.3, 1, 1, .3, border = "red", lty = 2, lwd = 2)
dev.off()
#
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{center}
%animated layer-set No. 0
% v-- frame rate ignored
\animategraphics[width=1\linewidth,step]{1}{layer-}{0}{2}
\ShowHideLayer{0}{1}{toggle red box}\\
\ShowHideLayer{0}{2}{toggle blue box}\\
\end{center}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}