Changing Axis direction Python ternary plot - ternary

How can I swap the axis direction of this ternary plot? such that the left axis (ZY) increases from bottom to top and bottom (ZX) increases from right to left and right axis (XY) increases from top to bottom.
This is my current code, I added tax.set_axis_limits but it didn't seem to have any effect
# Scatter Plot
scale = 100
figure, tax = ternary.figure(scale=scale)
figure.set_size_inches(10, 10)
x= new_df['X%']
y = new_df['Y%']
z = new_df['Z%']
points = [(x,y,z)]
tax.scatter(points)
tax.set_axis_limits(axis_limits={'b': [100,0], 'l':[0,1000],
'r': [100,00]})

Related

How to expand horizontal date scale while keeping legend within plot w/ asymmetrical vertical expansion

I am using ggplot2 to make several area plots of time series. To my eye, the plots look better if the time series covers the entire x axis, the height of the highest area is about 5% - 10% below the top of the plot area, and the legend is situated in the lower right corner of the plot.
Let base.plot be a base plot that labels the x axis and formats its tick marks, adds NBER recession bars, and locates the legend in the lower right corner of the plot itself with:
base.plot <- base.plot + theme(
legend.justification = c(1,0),
legend.position = c(1,0),
legend.title = element_blank()
)
This seems to work fine with my line plots, but on the area plots the legend box sticks out to the right and below the plot itself. Instead, its lower right corner should be at the lower right corner of the plot area. How can I fix this?
To change the plot's extent relative to its axes, I tried using the expand argument to expand the plot horizontally and vertically. Documentation for this argument leaves something to be desired, to say the least:
expand
A numeric vector of length two giving multiplicative and additive expansion constants. These constants ensure that the data is placed some distance away from the axes. The defaults are c(0.05, 0) for continuous variables, and c(0, 0.6) for discrete variables.
Is it too much to ask for the formula so we can know what the multiplicative and additive constants actually do? Otherwise, how else can we know how to set them? The above description appears in the documentation for scale_x_date; is it too much to ask for some mention of the defaults for date variables?
Flying blind, thanks to the useless documentation, I tried the solution for continuous variables:
scale_x_date(expand = c(0,0)),
But this just scrunched up the plot towards the right of the chart. So where can I learn about using scale_x_date with the expand argument?
As for the vertical axis, scale_y_date(expand = c(0,0)) did bring the bottom of the area plots down to the x-axis. But the top is too high. Somewhere I saw that a modification to the scale_y_date code now allows four arguments, two for the lower bound and two for the upper one. I tried this too, but there's no discernible difference from the plot using only the two parameters.
So, how can I get the lowest area plot to sit on the x axis and the highest point to be about 0.5 in from the top?

Y-Axis positions of barplot and base plot do not match

I was trying to plot a climate diagram and ran into the following problem:
After using barplot(...) for precipitation I superimposed another plot for the temperature. It is necessary for climate diagrams that the two y-axes (mm, °C) align at zero and that the precipitation/temperature ratio is 2:1 (e.g. 20mm precipitation corresponds to 10°C).
The problem: barplot(...) draws the axis to the plot's box while plot(...) leaves some space between the box and the axis margins.
Here is a simplified example. From the grid lines you see that the 0-values do not align:
barplot(0:10)
grid(col=1)
par(new=TRUE)
plot(0:10, xlim=c(-2,14), axes=FALSE)
axis(4,at=c(0:10), labels=c(0:10))
How can I get the right position and scaling of the two axes?
Don't use par(new = TRUE):
barplot(0:10)
grid(col=1)
lines(0:10, type = "p")
axis(4,at = c(0:10), labels = seq(0,20,2))
The function lines() is the right one here. The argument type = p is needed to plot points.
You need to adjust the y-values for the temperature, but now the second y-axis is in the right way, I think.

R: Matching x-axis scales on upper and lower plot using layout with base graphics

I am trying to arrange 3 plots together. All 3 plots have the same y axis scale, but the third plot has a longer x axis than the other two. I would like to arrange the first two plots side by side in the first row and then place the third plot on the second row aligned to the right. Ideally I would like the third plot's x values to align with plot 2 for the full extent of plot 2 and then continue on below plot one. I have seen some other postings about using the layout function to reach this general configuration (Arrange plots in a layout which cannot be achieved by 'par(mfrow ='), but I haven't found anything on fine tuning the plots so that the scales match. Below is a crappy picture that should be able to get the general idea across.
I thought you could do this by using par("plt"), which returns the coordinates of the plot region as a fraction of the total figure region, to programmatically calculate how much horizontal space to allocate to the bottom plot. But even when using this method, manual adjustments are necessary. Here's what I've got for now.
First, set the plot margins to be a bit thinner than the default. Also, las=1 rotates the y-axis labels to be horizontal, and xaxs="i" (default is "r") sets automatic x-axis padding to zero. Instead, we'll set the amount of padding we want when we create the plots.
par(mar=c(3,3,0.5,0.5), las=1, xaxs="i")
Some fake data:
dat1=data.frame(x=seq(-5000,-2500,length=100), y=seq(-0.2,0.6,length=100))
dat2=data.frame(x=seq(-6000,-2500,length=100), y=seq(-0.2,0.6,length=100))
Create a layout matrix:
# Coordinates of plot region as a fraction of the total figure region
# Order c(x1, x2, y1, y2)
pdim = par("plt")
# Constant padding value for left and right ends of x-axis
pad = 0.04*diff(range(dat1$x))
# If total width of the two top plots is 2 units, then the width of the
# bottom right plot is:
p3w = diff(pdim[1:2]) * (diff(range(dat2$x)) + 2*pad)/(diff(range(dat1$x)) + 2*pad) +
2*(1-pdim[2]) + pdim[1]
# Create a layout matrix with 200 "slots"
n=200
# Adjustable parameter for fine tuning to get top and bottom plot lined up
nudge=2
# Number of slots needed for the bottom right plot
l = round(p3w/2 * n) - nudge
# Create layout matrix
layout(matrix(c(rep(1:2, each=0.5*n), rep(4:3,c(n - l, l))), nrow=2, byrow=TRUE))
Now create the graphs: The two calls to abline are just to show us whether the graphs' x-axes line up. If not, we'll change the nudge parameter and run the code again. Once we've got the layout we want, we can run all the code one final time without the calls to abline.
# Plot first two graphs
with(dat1, plot(x,y, xlim=range(dat1$x) + c(-pad,pad)))
with(dat1, plot(x,y, xlim=range(dat1$x) + c(-pad,pad)))
abline(v=-5000, xpd=TRUE, col="red")
# Lower right plot
plot(dat2, xaxt="n", xlim=range(dat2$x) + c(-pad,pad))
abline(v=-5000, xpd=TRUE, col="blue")
axis(1, at=seq(-6000,-2500,500))
Here's what we get with nudge=2. Note the plots are lined up, but this is also affected by the pixel size of the saved plot (for png files), and I adjusted the size to get the upper and lower plots exactly lined up.
I would have thought that casting all the quantities in ratios that are relative to the plot area (by using par("plt")) would have both ensured that the upper and lower plots lined up and that they would stay lined up regardless of the number of pixels in the final image. But I must be missing something about how base graphics work or perhaps I've messed up a calculation (or both). In any case, I hope this helps you get the plot layout you wanted.

Rotate labels for histogram bars - shown via: labels = TRUE

Here is shown how to label histogram bars with data values or percents using labels = TRUE. Is it also possible to rotate those labels? My goal is to rotate them to 90 degrees because now the labels over bars overrides each other and it is unreadable.
PS: please note that my goal is not to rotate y-axis labels as it is shown e.g. here
Using mtcars, here's one brute-force solution (though it isn't very brutish):
h <- hist(mtcars$mpg)
maxh <- max(h$counts)
strh <- strheight('W')
strw <- strwidth(max(h$counts))
hist(mtcars$mpg, ylim=c(0, maxh + strh + strw))
text(h$mids, strh + h$counts, labels=h$counts, adj=c(0, 0.5), srt=90)
The srt=90 is the key here, rotating 90 degrees counter-clockwise (anti-clockwise?).
maxh, strh, and strw are used (1) to determine how much to extend the y-axis so that the text is not clipped to the visible figure, and (2) to provide a small pad between the bar and the start of the rotated text. (The first reason could be mitigated by xpd=TRUE instead, but it might impinge on the main title, and will be a factor if you set the top margin to 0.)
Note: if using density instead of frequency, you should use h$density instead of h$counts.
Edit: changed adj, I always forget the x/y axes on it stay relative to the text regardless of rotation.
Edit #2: changing the first call to hist so the string height/width are calculate-able. Unfortunately, plotting twice is required in order to know the actual height/width.

R: How do I position multi-line tick labels at plots in base R?

In base R plots, I would like to attach multi-line labels to the ticks. Here is a test case, first with simple single-lined labels:
# plot some graph
x = (-10:10)/5
y = x^2
plot (y~x,type="l",axes=F)
ticks = c(-2,-1,0,1,2) # tick positions
labels = c("-2","-1","0","1","2") # tick labels
axis (1,at=ticks,labels=labels)
Now I would like to have some labels extend over several lines of text. When I use
labels = c("-2","-1","centre\n0","1","2") # some tick labels multi-line
the second line of the label is added above the existing labels, leaving insufficient space between the axis and the labels. The tick labels are aligned at the bottom.
How (1) do I have them aligned at the top or; (2) can I move all tick labels down in order to get more space between the axis and the labels?
Thanks in advance for your help!
I always find it easier to plot the second line as a new plot on top of the previous one. There is a problem with your data as I see it. I don't really know which is your intention but I will explain the method in detail below.
My problem is that your second labels are the same as the first apart from the word 'centre' which you add in at x=0. Therefore, in my case I have created a new label variable which will only have the second line elements i.e. only the word 'centre' with everything else being blank.
Data
This is your data
# plot some graph
x = (-10:10)/5
y = x^2
plot (y~x,type="l",axes=F)
ticks = c(-2,-1,0,1,2) # tick positions
labels = c("-2","-1","0","1","2") # tick labels
axis (1,at=ticks,labels=labels)
Solution1
Aligned at the bottom properly:
In this case I create a new plot that will have a longer bottom margin. Then I create only a bottom axis for that and set it to colour white so that only the labels are visible:
#bottom
#new plot
par(new=TRUE)
#new margins. default is c(5,4,4,2).First value is the bottom margin.
par(mar=c(4,4,4,2))
#new labels
labels = c("","","centre","","") # some tick labels multi-line
#make the axis
axis (1,at=ticks,labels=labels, col='white')
If you need centre and zero to be plotted the other way round just change the labels.
Solution2
Aligned at the top properly (if I get what you mean):
In your data axis needs to be: axis(3,at=ticks,labels=labels). The three there shows it should be aligned on top
The logic is the same as previously but you need to change the corresponding margin i.e. the third value:
#top
par(new=TRUE)
par(mar=c(5,4,3,2))
labels = c("","","centre","","") # some tick labels multi-line
axis (3,at=ticks,labels=labels, col='white')

Resources