Display x-axis for each subplot when faceting with facet_grid - ggplot2

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

Related

Legend title for ggplot with several options

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))

Some matplotlib colorbars disappear when colorbar axes are moved

I am using the following lines of python code to create a figure with multiple subplots in a Jupiter notebook and attempting to add colorbars to some of the plots. The following lines are 1 of 7 sections copied and pasted with adjustments to GridSpec, variables, labels and axes handles made for each:
fig = plt.figure(figsize=(20,20))
gs = gridspec.GridSpec(21, 13)
...
if i >= 1:
ax3 = plt.subplot(gs[6:9, 3*i+1:3*i+4],projection=ccrs.Robinson())
else:
ax3 = plt.subplot(gs[6:9, 3*i:3*i+3],projection=ccrs.Robinson())
if i == 0:
cs3 = ax3.contourf(Lon,lat,cldhgh.squeeze(),12,transform=ccrs.PlateCarree(),cmap='gist_gray',vmin=0,vmax=1)
ax3.coastlines()
Cticks=np.around(np.linspace(0,1,6),decimals=1)
Cbar_ax3 = fig.add_axes([0.3,0.58,0.01,0.10])
cb3 = fig.colorbar(cs3, spacing='proportional',orientation='vertical',cax=Cbar_ax3,ticks=Cticks)
#cb2.set_ticklabels(Cticks.astype(int).astype(str),fontsize=7)
cb3.set_ticklabels(Cticks.astype(str),fontsize=12)
cb3.set_label('High Cloud Fraction',fontsize=10)
else:
cs3 = ax3.contourf(Lon,lat,delta_cldhgh,61,transform=ccrs.PlateCarree(),cmap='BrBG',vmin=-0.2,vmax=0.2)
c3 = ax3.contour(Lon,lat,cldhgh.squeeze(),12,vmin=0,vmax=1,colors='black',linewidths=0.5)
ax3.coastlines()
if i == 1:
cticks=np.around(np.linspace(-0.2,0.2,5),decimals=1)
cbar_ax = fig.add_axes([1.02,0.58,0.01,0.10])
ax3.set_ylabel('Hybrid Sigma-Pressure level (mb)',fontsize=12)
#cb = fig.colorbar(cs, spacing='proportional',orientation='vertical',cax=cbar_ax,ticks=cticks)
cb3 = fig.colorbar(mappable=None, norm=Normalize(vmin=-0.2,vmax=0.2), cmap='BrBG',spacing='proportional',orientation='vertical',cax=cbar_ax,ticks=cticks)
cb3.set_ticklabels(cticks.astype(str),fontsize=12)
#cb2.set_ticklabels(cticks.astype(int).astype(str),fontsize=10)
cb3.set_label('Cloud Fraction Difference',fontsize=10)
...
plt.suptitle('Comparison of mappables of Background Climate States',fontsize=24,y=1.01)
#fig.text(-0.04, 0.5, 'Sigma Pressure Level (mb)', va='center', rotation='vertical')
fig.tight_layout(pad=0.2)
plt.show()
fig.savefig(figure_path+'Reference_Climate_Comparison_of_Mappables.pdf',bbox_inches='tight')
I am able to almost do this successfully, except the original guess I made for the x displacement of my colorbars on the left side of the figure was too large:
To fix this I simply adjusted the first index of each subplot's "Cbar_ax" variable to be slightly smaller (e.g. from 0.3 to 0.25):
Cbar_ax3 = fig.add_axes([0.25,0.58,0.01,0.10])
The adjustment works for some subplots, but for others the colorbars all but vanish:
I have no idea how to solve this problem. I can make the colorbars appear using plt.colorbar() instead of fig.colorbar() without an colorbar axes designation, but the subplots themselves are not a consistent size with the rest of the figure (since plt.colorbar steals axes space from it's parent axes by default). What am I not seeing here? Why do some of these colorbars disappear when I move them?

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.

Imshow subplots share colorbar using AxesGrid. How to plot a grid and set number of ticks

My Program plots three subplot using the same colorbar. Here is the code:
fig=pl.figure()
grid = AxesGrid(fig, 111,nrows_ncols=(3,1),
axes_pad = 0.2,
share_all=True,
label_mode = "L",
cbar_location = "right",
cbar_mode="single",
cbar_size='1%'
)
im = grid[0].imshow(np.random.random((10,50)))
grid.cbar_axes[0].colorbar(im)
im = grid[1].imshow(np.random.random((10,50)))
im = grid[2].imshow(np.random.random((10,50)))
pl.show()
This delivers the following picture:
No I want first to set the number of ticks. E.g. 3 ticks on the y-axis and 10 on the x-axis. Furthermore I want to plot a grid into the picture. But my normal coding works only if I don't use AxisGrid:
fig=pl.figure()
im = imshow(np.random.random((10,50)))
pl.locator_params(axis='x',nbins=20)
pl.locator_params(axis='y',nbins=3)
pl.grid()
pl.show()
What can I do to plot the grid into my subplots and change the number of ticks?
try this:
im = grid[0].imshow(np.random.random((10,50)))
ax = im.get_axes( )
ax.grid( 'on' )
ax.locator_params(axis='x',nbins=20)
ax.locator_params(axis='y',nbins=3)