Programmatically getting the labels in Octave - plot

In Octave, when I plot I can get the plot object. For example
pl = get(plot(...))
I can then specify the labels such as:
xlabel("something")
I'm working on an auto-grader and need to check the contents of the xlabel from the plot object pl. I'd think I'd be able to say something like
disp(all(pl.xlabel == "something"))
But, I'm getting an error saying xlabel doesn't belong to the plot object.

If there is only one axis object, you could get the current axis object with gca, then get the labels and such through the axis object.
ax = gca
disp(get(get(ax, "XLabel") "String"))
If you have multiple plots on different figures and no handle to the figure, you could do the following where you get the figure, rather than directly use gca:
p1 = plot((1:10).^2);
p2 = plot((1:10).^4);
xlabel('Matt');
fig = ancestor(p1, 'figure');
ax = get(fig, "CurrentAxes");
disp(get(get(ax, "XLabel") "String"))

Related

Link axes in Makie.jl if other plot elements present

I would like to create multiple subplots with their own individual legends and shared y-axis limits. I am currently creating the subplots in a loop by doing the following:
fig = Figure()
for i in 1:3
lines(fig[i, 1], rand(10), label="$i")
end
linkyaxes!(fig.content...)
fig
This works fine, but when attempting to add a legend to each subplot next:
fig = Figure()
for i in 1:3
lines(fig[i, 1], rand(10), label="$i")
axislegend()
end
linkyaxes!(fig.content...)
fig
this now throws an error:
MethodError: Cannot `convert` an object of type Makie.MakieLayout.Legend to an object of type Makie.MakieLayout.Axis
because fig.content now includes Makie.MakieLayout.Legend() objects, in addition to the original Axis objects from before.
Do I need to filter these out beforehand, or is there a better way to produce the desired plots?
I'm not sure this is the best approach, but you could ensure that you pass the axes to linkyaxes! this way:
axs = []
fig = Figure()
for i in 1:3
ax = lines(fig[i, 1], rand(10), label="$i").axis
push!(axs, ax)
axislegend()
end
linkyaxes!(axs...)

Custom legend labels - geopandas.plot()

A colleague and I have been trying to set custom legend labels, but so far have failed. Code and details below - any ideas much appreciated!
Notebook: toy example uploaded here
Goal: change default rate values used in the legend to corresponding percentage values
Problem: cannot figure out how to access the legend object or pass legend_kwds to geopandas.GeoDataFrame.plot()
Data: KCMO metro area counties
Excerpts from toy example
Step 1: read data
# imports
import geopandas as gpd
import matplotlib.pyplot as plt
%matplotlib inline
# read data
gdf = gpd.read_file('kcmo_counties.geojson')
Option 1 - get legend from ax as suggested here:
ax = gdf.plot('val', legend=True)
leg = ax.get_legend()
print('legend object type: ' + str(type(leg))) # <class NoneType>
plt.show()
Option 2: pass legend_kwds dictionary - I assume I'm doing something wrong here (and clearly don't fully understand the underlying details), but the _doc_ from Geopandas's plotting.py - for which GeoDataFrame.plot() is simply a wrapper - does not appear to come through...
# create number of tick marks in legend and set location to display them
import numpy as np
numpoints = 5
leg_ticks = np.linspace(-1,1,numpoints)
# create labels based on number of tickmarks
leg_min = gdf['val'].min()
leg_max = gdf['val'].max()
leg_tick_labels = [str(round(x*100,1))+'%' for x in np.linspace(leg_min,leg_max,numpoints)]
leg_kwds_dict = {'numpoints': numpoints, 'labels': leg_tick_labels}
# error "Unknown property legend_kwds" when attempting it:
f, ax = plt.subplots(1, figsize=(6,6))
gdf.plot('val', legend=True, ax=ax, legend_kwds=leg_kwds_dict)
UPDATE
Just came across this conversation on adding in legend_kwds - and this other bug? which clearly states legend_kwds was not in most recent release of GeoPandas (v0.3.0). Presumably, that means we'll need to compile from the GitHub master source rather than installing with pip/conda...
I've just come across this issue myself. After following your link to the Geopandas source code, it appears that the colourbar is added as a second axis to the figure. so you have to do something like this to access the colourbar labels (assuming you have plotted a chloropleth with legend=True):
# Get colourbar from second axis
colourbar = ax.get_figure().get_axes()[1]
Having done this, you can manipulate the labels like this:
# Get numerical values of yticks, assuming a linear range between vmin and vmax:
yticks = np.interp(colourbar.get_yticks(), [0,1], [vmin, vmax])
# Apply some function f to each tick, where f can be your percentage conversion
colourbar.set_yticklabels(['{0:.2f}%'.format(ytick*100) for ytick in yticks])
This can be done by passing key-value pairs to dictionary argument legend_kwds:
gdf.plot(column='col1', cmap='Blues', alpha=0.5, legend=True, legend_kwds={'label': 'FOO', 'shrink': 0.5}, ax=ax)

Change x and y labels on a gbm partial plot

I am having trouble changing the x and y labels on a partial plot for a gbm model. I need to rename them for the journal article.
I read this in and create the plot as follows:
library(gbm)
final<- readRDS(final_gbm_model)
summary(final, n.trees=final$n.trees)
Here is the summary output:
var rel.inf
ProbMn50ppb ProbMn50ppb 11.042750
ProbDOpt5ppm ProbDOpt5ppm 7.585275
Ngw_1975 Ngw_1975 6.314080
PrecipMinusETin_1971_2000_GWRP PrecipMinusETin_1971_2000_GWRP 4.988598
N_total N_total 4.776950
DTW60YrJurgens DTW60YrJurgens 4.415016
CVHM_TextZone CVHM_TextZone 4.225048
RiverDist_NEAR RiverDist_NEAR 4.165035
LateralPosition LateralPosition 4.036406
CAML1990_natural_water CAML1990_natural_water 3.720303
PctCoarseMFUpActLayer PctCoarseMFUpActLayer 3.668184
BioClim_BIO12 BioClim_BIO12 3.561071
MFDTWSpr2000Faunt MFDTWSpr2000Faunt 3.383900
PBot_krig PBot_krig 3.362289
WaterUse2 WaterUse2 3.291040
AVG_CLAY AVG_CLAY 3.280454
Age_yrs Age_yrs 3.144734
MFVelSept2000 MFVelSept2000 3.064030
AVG_SILT AVG_SILT 2.882709
ScreenLength ScreenLength 2.683542
HydGrp_C HydGrp_C 2.666106
AVG_POR AVG_POR 2.563147
MFVelFeb2000 MFVelFeb2000 2.505106
HiWatTabDepMin HiWatTabDepMin 2.421521
RechargeAnnualmmWolock RechargeAnnualmmWolock 2.252706
I can create a partial dependence plot as follows:
plot(final,"ProbMn50ppb",n.trees=final$n.trees)
But if I try to set the label arguments I get the following error:
plot(final,"ProbMn50ppb",n.trees=final$n.trees,ylab="LNNO3")
Error in plot.default(X$X1, X$y, type = "l", xlab = x$var.names[i.var], :
formal argument "ylab" matched by multiple actual arguments
How can I change the y and x axis labels?
The plot.gbm function passes its own name to the generic plot function so the two are colliding. So you will not be able to customize the plot the way you want in that mode. But the authors did provide an alternative when you set return.grid=TRUE. Instead of building a plot, it will output the data itself. You can then use that for any plot including ggplot2.
plotdata <- plot(gbm1, return.grid=TRUE)
plot(plotdata, type="l", ylab="ylab", xlab="xlab")
Example data from help(gbm)
You can also change the gbm object itself before plotting (or in a function):
your_gbm_obj$var.names[index] = "axis label"

R contour levels don't match filled.contour

Hopefully a straightforward question but I made a simple figure in R using filled.contour(). It looks fine, and what it should like given the data. However, I want to add a reference line along a contour for 0 (level = 0), and the plotted line doesn't match the colors on the filled.contour figure. The line is close, but not matching with the figure (and eventually crossing over another contour from the filled.contour plot). Any ideas why this is happening?
aa <- c(0.05843150, 0.11300040, 0.15280030, 0.183524400, 0.20772430, 0.228121000)
bb <- c(0.01561055, 0.06520635, 0.10196237, 0.130127650, 0.15314544, 0.172292410)
cc <- c(-0.02166599, 0.02306650, 0.05619421, 0.082193680, 0.10334837, 0.121156780)
dd <- c(-0.05356592, -0.01432910, 0.01546647, 0.039156660, 0.05858709, 0.074953650)
ee <- c(-0.08071987, -0.04654243, -0.02011676, 0.000977798, 0.01855881, 0.033651089)
ff <- c(-0.10343798, -0.07416114, -0.05111547, -0.032481132, -0.01683215, -0.003636035)
gg <- c(-0.12237798, -0.09753544, -0.07785126, -0.061607548, -0.04788856, -0.036169540)
hh <-rbind(aa,bb,cc,dd,ee,ff,gg)
z <- as.matrix(hh)
y <- seq(0.5,1.75,0.25)
x <- seq(1,2.5,0.25)
filled.contour(x,y,z,
key.title = title(main=expression("log"(lambda))),
color.palette = topo.colors) #This works
contour(x,y,z, level=0,add=T,lwd=3) #This line doesn't match plot
This is completely answered in the ?filled.contour help page. In the Notes section it states
The output produced by filled.contour is actually a combination of two plots; one is the filled contour and one is the legend. Two separate coordinate systems are set up for these two plots, but they are only used internally – once the function has returned these coordinate systems are lost. If you want to annotate the main contour plot, for example to add points, you can specify graphics commands in the plot.axes argument. See the examples.
And the examples given in that help page show how to annotate on top of the main plot. In this particular case, the correct way would be
filled.contour(x,y,z,
key.title = title(main=expression("log"(lambda))),
color.palette = topo.colors,
plot.axes = {
axis(1)
axis(2)
contour(x,y,z, level=0,add=T,lwd=3)
}
)
which produces

R How to set tick mark size using a trellis theme in Lattice?

I'm trying to use a trellis theme to set all my graphing parameters to keep my plotting statements short. I can't seem to find the correct trellis parameter access tick mark length (or any scale parameters for that matter).
library(lattice)
x = runif(100)
my.theme = trellis.par.get()
my.theme$axis.line = list(tck=c(4)) # this does not work
dp <- densityplot(~x)
# this works, but I want to do it using a theme
# dp <-densityplot(~x, scales=list(y=list(tck=c(4))))
png("dp.png", width=400, height=200)
trellis.par.set(my.theme)
plot(dp); dev.off()
Tick lengths for each of the plot's axes are controlled by (elements of) axis.components in lattice's graphical parameter list.
Run str(trellis.par.get("axis.components")) to see what you are aiming for, and then do something like the following:
mytheme <- list(axis.components = list(left = list(tck=4), right = list(tck=4)))
trellis.par.set(mytheme)
densityplot(~x)

Resources