Legend title for ggplot with several options - ggplot2

I am plotting density plots by groups with different colors and linetypes.
ggplot(data = data,
aes(x=X, group=G, color=factor(G), linetype = factor(G))) +
geom_density()
How can I change the legend title while keeping it as one legend?

Your issue comes from the fact that when you add a legend title (e.g., using scale_color_discrete), you're only doing it for color and not linetype. The first plot is fine because the legends have identical arguments (i.e., neither is specified). You need to provide identical specifications for each legend in order to combine them. See this post for more information.
There may be other ways around this issue, but we can't say for certain since we can't access your dataset (data).
library(tidyverse)
data(mtcars)
# this is ok; one legend
ggplot(data = mtcars,
aes(x=mpg, group=cyl, color=factor(cyl), linetype = factor(cyl))) +
geom_density()
# this is not ok; now two legends
ggplot(data = mtcars,
aes(x=mpg, group=cyl, color=factor(cyl), linetype = factor(cyl))) +
geom_density() + scale_color_discrete("New Name?")
# this is ok again; back to one legend
ggplot(data = mtcars,
aes(x=mpg, group=cyl, color=factor(cyl), linetype = factor(cyl))) +
geom_density() +
scale_colour_manual(name = "New!",
labels = c("4", "6", "8"),
values = c("red", "blue", "pink")) +
scale_linetype_manual(name = "New!",
labels = c("4", "6", "8"),
values = c(2, 4, 6))

Related

Plotly does not properly show axis numbers with math_format

The code below indicates that, while using math_format command in ggplot 'labels', the plot displays well if ggplot is used, but it fails if it is displayed through plotly. I need to use plotly in my code. Does somebody have some suggestion?
library(tidyverse)
library(scales)
library(plotly)
p <- mtcars %>% ggplot(aes(x=mpg, y=disp))+
geom_point() +
scale_x_continuous(trans = log_trans(),
breaks = trans_breaks("log", function(x) exp(x), n.breaks = 5),
labels = trans_format("log", math_format(e^.x, format = function(x) number(x, accuracy = 0.01, decimal.mark = ','))))
p
ggplotly(p)

Display x-axis for each subplot when faceting with facet_grid

I've got a facet_grid plot with 8 subplots. I set the scale for the y axis as "free_y" while I need the x axis to be the same for each subplot. My issue is that, while every y-axis is shown, only three of the subplots show their x-axis.
here is my plot as of now
Is there a way to make it visible for all 8 of them?
Plus, I'd need to make the fill colour become more intense as we approach nighttime and vs, is there a way to do so?
May I also add a small sun/moon symbol on top of the bars corresponding to dawn/sunset?
Thank you!
This is my code:
(plotcircad <- ggplot(circad, aes(x=hourr,y=mean_d)) + geom_col() +
geom_uperrorbar(aes(ymax=mean_d+std_d), size=0.25, width = 0.25,
show.legend = FALSE,col="black") +
xlab("Time slot") + ylab("Mean (sd) distance from nest (m)") +
facet_wrap(~ring,scales = "free_y")) +
theme_classic() +
theme(axis.line.x = element_line(colour = 'black', size=0.5, linetype='solid'),
axis.line.y = element_line(colour = 'black', size=0.5, linetype='solid')) +
theme(panel.background = element_blank())
And here is a part of my dataset (it seems that I'm unable to share it as a code or an Excel file so it's just a picture of it)
part of my dataset

How to generate several legends for single plot matplotlib

I was making a plot of f(x,y,z) and wanted this to be displayed in a 2D-plane. To avoid cluttering my legend i decided to have different linestyles for y, different colors for z and place the two in two separate legends. I couldn't find out how to do this even after a lot of digging, so I'm posting the solution i came up with here :) If anyone has more elegant solutions I'm all ears :)
Basically the solution was to make three plots, set two of them to have size (0,0) and place those two where i wanted the legends. It feels like an ugly way to do it, but it gave a nice plot and i didn't find any other way :) The resulting plot looks like this:
def plot_alt(style = 'log'):
cmap = cm.get_cmap('inferno')
color_scale = 1.2 #Variable to get colors from a certain part of the colormap
#Making grids for delta T and average concentration
D_T_axis = -np.logspace(np.log10(400), np.log10(1), 7)
C_bar_list = np.linspace(5,10,4)
ST_list = np.logspace(-3,-1,100)
# f(x,y,z)
DC_func = lambda C_bar, ST, DT: 2*C_bar * (1 - np.exp(ST*DT))/(1 + np.exp(ST*DT))
#Some different linestyles
styles = ['-', '--', '-.', ':']
fig, ax = plt.subplots(1,3, figsize = (10,5))
plt.sca(ax[0])
for i, C_bar in enumerate(C_bar_list): #See plot_c_rel_av_DT() for 'enumerate'
for j, DT in enumerate(D_T_axis):
plt.plot(ST_list, DC_func(C_bar, ST_list, DT), color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))),
linestyle = styles[i])
# Generating separate legends by plotting lines in the two other subplots
# Basically: to get two separate legends i make two plots, place them where i want the legends
# and set their size to zero, then display their legends.
plt.sca(ax[1]) #Set current axes to ax[1]
for i, C_bar in enumerate(C_bar_list):
# Plotting the different linestyles
plt.plot(C_bar_list, linestyle = styles[i], color = 'black', label = str(round(C_bar, 2)))
plt.sca(ax[2])
for DT in D_T_axis:
#plotting the different colors
plt.plot(D_T_axis, color = cmap(np.log10(-DT)/(color_scale*np.log10(-D_T_axis[0]))), label = str(int(-DT)))
#Placing legend
#This is where i move and scale the three plots to make one plot and two legends
box0 = ax[0].get_position() #box0 is an object that contains the position and dimentions of the ax[0] subplot
box2 = ax[2].get_position()
ax[0].set_position([box0.x0, box0.y0, box2.x0 + 0.4*box2.width, box0.height])
box0 = ax[0].get_position()
ax[1].set_position([box0.x0 + box0.width, box0.y0 + box0.height + 0.015, 0,0])
ax[1].set_axis_off()
ax[2].set_position([box0.x0 + box0.width ,box0.y0 + box0.height - 0.25, 0,0])
ax[2].set_axis_off()
#Displaying plot
plt.sca(ax[0])
plt.xscale('log')
plt.xlim(0.001, 0.1)
plt.ylim(0, 5)
plt.xlabel(r'$S_T$')
plt.ylabel(r'$\Delta C$')
ax[1].legend(title = r'$\langle c \rangle$ [mol/L]',
bbox_to_anchor = (1,1), loc = 'upper left')
ax[2].legend(title = r'$-\Delta T$ [K]', bbox_to_anchor = (1,1), loc = 'upper left')
#Suptitle is the title of the figure. You can also have titles for the individual subplots
plt.suptitle('Steady state concentration gradient as a function of Soret-coefficient\n'
'for different temperature gradients and total concentrations')

Standard Plot size in Python-matplotlib

I am generating multiple plots using matplotlib.patches.rect depending on the requirements. Some cases 2 rectangles are plotted sometimes 4 rectangles. But the visualisation size differs depending on the numbers of such rectangles although the dimensions of rectangles remains the same. Here in my case every rectangle has fixed shape (1200X230).
Below is the entire working code:
sampledata = {'Layer':[1,2,3,4,5,6], 'Type':[1,1,2,2,2,2]}
ip0 = pd.DataFrame(sampledata, columns=['Layer','Type'])
for i in range(ip0['Type'].nunique()):
fig = plt.figure()
ax = fig.add_subplot(111)
ip = ip0[ip0['Type']== i+1]
b = i+1
ax.grid(linestyle='--',linewidth = '0.3', color = 'black')
for i in range(ip['Layer'].nunique()):
y_pos = (i*300)
r = matplotlib.patches.Rectangle(xy=(0, y_pos), width=1201,height=233,
facecolor = None, edgecolor = 'red', linewidth=1.2, fill = False)
ax.text(-230, y_pos+175, 'Layer-{}'.format(i),
color='g',rotation='vertical', fontsize= (36/ip['Layer'].nunique()))
ax.add_patch(r)
plt.xlim([0, 1500])
plt.ylim([0, (ip['Layer'].nunique()*300)])
plt.savefig(f'image_bin_{b}.jpeg',bbox_inches='tight', dpi =
1600,transparent=True)
I have attached pictures of 2 cases one where there 2 rectangles and one 4. Please help me making them look similar since the actual dimensions are equal.

How to adjust plot areas in ggplot?

I am trying to use grid.arrange to display multiple graphs on the same page generated by ggplot.Each subplot with difference x and y scale. Two subplot share the legend. My perpose is that to display the plot areas same size. Are there parameter to adjust plot area ( except legend area)? The facet is inadequate to arrange it.
df <- data.frame(class=paste0('a',1:20),
x1=runif(20),
x2=runif(20),
y1=runif(20),
y2=runif(20))
p1 <- ggplot(df,aes(x=x1,y=y1))+
geom_point(aes(color=class),size=2,show.legend=TRUE)+
stat_smooth(method='lm',color='black')+
theme_bw()
p2 <- ggplot(df,aes(x=x2,y=y2))+
geom_point(aes(color=class),size=2,show.legend=FALSE)+
stat_smooth(method='lm',color='black')+
theme_bw()
grid.arrange(p1,p2,nrow=2)
Using patchwork package
# install.packages("devtools", dependencies = TRUE)
# devtools::install_github("thomasp85/patchwork")
library(patchwork)
p1 / p2 + plot_annotation(title = "Plot title",
subtitle = "Plot subtitle",
tag_levels = 'A',
tag_suffix = ')')
Created on 2018-11-20 by the reprex package (v0.2.1.9000)