Color bar limits matplotlib - python

I'm trying to create a plot with 4 hist2d subplots and one color bar.
The thing is that each subplot can have different ranges of z values, so the color bar is not uniform.
I want to set the color bar to a pre-defined range.
here is the code I'm using:
def multiple_med_plot_test(file):
extent = [-8, 37, 28, 46]
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(26, 11), constrained_layout=True,
subplot_kw={'projection': ccrs.PlateCarree()})
ax0 = axes[0][0]
ax1 = axes[0][1]
ax2 = axes[1][0]
ax3 = axes[1][1]
axes_dict = {'Dec': ax0, 'Aug': ax1, 'Sep': ax2, 'Sum': ax3}
for month in axes_dict.keys():
ax = axes_dict[month]
ax.add_feature(cfeature.LAND, edgecolor='k', zorder=50)
ax.set_extent(extent)
gl = ax.gridlines(draw_labels=True, zorder=100, color='grey', linestyle='--')
gl.top_labels = False
gl.right_labels = False
gl.xlabel_style = {'size': 16}
gl.ylabel_style = {'size': 16}
if ax in [ax1, ax3]:
gl.left_labels = False
ax.set_title(month, fontsize=18, color='darkred')
if month != 'Sum':
hist0 = ax.hist2d(file.Long, file.Lat, range=[(-8, 37), (28, 46)], bins=(500, 200))
elif month == 'Sum':
hist1 = ax.hist2d(file.Long, file.Lat, range=[(-8, 37), (28, 46)], bins=(500, 200))
fig.suptitle('Lightning Density per Month', fontsize=22)
cbar = fig.colorbar(hist1[3], ax=axes, shrink=0.95)
cbar.set_label('# of lightnings', fontsize=20, rotation=-90, labelpad=30)
cbar.ax.tick_params(labelsize=16)
# plt.savefig('D:/Lightning Data/Yearly_Summary', dpi=100)
plt.show()
In previous versions of the code I used plt.clim and that was awesome, but the way my code is right now doesn't let me do it.
I would like to get some help on this!

If you want a linear scale, set vmin and vmax parameters. For log-like scale or similar, use norm. See hist2d documentation.

Related

Remove lines around contourf with matplotlib and cartopy

I Have this map, made with cartopy like this:
`
fig, ax = plt.subplots(subplot_kw={'projection': ccrs.PlateCarree()})
fig.set_size_inches(15, 10, forward=True)
ax.set_extent([-75.5,-30,-31,6.5])
grid=ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,linewidth=0.05, color='gray', alpha=0.5)
grid.top_labels = False
grid.right_labels = False
grid.xlabel_style = {'color': 'grey', 'weight': 'bold', 'size': 'small'}
grid.ylabel_style = {'color': 'grey', 'weight': 'bold', 'size': 'small'}
ax.axis('off')
precip_colormap = colors.ListedColormap(nws_precip_colors)
norm = colors.BoundaryNorm(levels, val)
data_crs = ccrs.PlateCarree()
cs = ax.contourf(lonsi, latsi, values, transform=data_crs, levels=levels, cmap=precip_colormap, add_colorbar=False, extend='both', alpha=0.8, norm=norm, edgecolor=None)
plt.title(titulo_mapa, fontsize=20, pad=30, fontweight='bold', color='grey', fontproperties=prop)
cbar=plt.colorbar(cs)
cbar.set_ticks(levels)
cbytick_obj = plt.getp(cbar.ax.axes, 'yticklabels')
plt.setp(cbytick_obj, color='grey')
and it's fine, but I want to remove this border around the colors, like this where i circled.
I didn't find any solution anywhere :(

Adjust height for only one bar of my plot?

I have this dataframe
data = {'reference':[1, 2, 3, 4, 5, 6, 7, 8, 'Total'],
'label_1':[58.3,75.0,88.0,81.1,60.0,72.0,50.0,85.7,73.8],
'label_2':[41.7, 25.0, 9.3,17.0,40.0,27.3,40.9,14.3,24.5],
'label_3':[0.0,0.0,4.7,1.9,0.0,0.8,9.1,0.0,1.7]}
data = pd.DataFrame(data).set_index('reference')
data
I have made an horizontal barplot who look like this
fig, ax = plt.subplots()
data.plot(kind='barh', stacked=True, width=0.70, ax=ax, figsize= (15, 15))
ax.legend(["label_1",
"label_2",
"label_3"], loc='upper left', bbox_to_anchor=(1, 1));
ax.yaxis.grid(True)
ax.set_axisbelow(True)
plt.xticks(rotation=0)
fmt = '%.0f%%'
xticks = mtick.FormatStrFormatter(fmt)
ax.xaxis.set_major_formatter(xticks)
for c in ax.containers:
ax.bar_label(c, label_type='center', fmt='%.0f%%')
ax.set_yticklabels( ('name_1', 'name_2','name_3', 'name_4', 'name_5', 'name_6', 'name_7', 'name_8', 'TOTAL') )
plt.show()
I want to space up the 'Total' bar, I don't have any idea how to adjust the height for only one specific bar on my plot. Any help is appreciated, thx everyone!

In python, how to increase the current y-axis size?

In python, how to increase the current y-axis size?
Assuming, in the normal plot it is [0,50000]and [0,20000], but I want it to be [0,50000] and [0,50000]... [0,50000]. All histograms with y axis from 0 to 50000.
fig, axs = plt.subplots(ncols = 2, nrows = 3, figsize = (18, 18))
sns.distplot(df["EXT"], bins = 40, kde = False,
ax = axs[0, 0], color = sns.color_palette()[0]).set_title("Extroversion")
sns.distplot(df["EST"], bins = 40, kde = False,
ax = axs[0, 1], color = sns.color_palette()[1]).set_title("Neuroticism")
sns.distplot(df["AGR"], bins = 40, kde = False,
ax = axs[1, 0], color = sns.color_palette()[2]).set_title("Agreeableness")
sns.distplot(df["CSN"], bins = 40, kde = False,
ax = axs[1, 1], color = sns.color_palette()[3]).set_title("Conscientiousness")
sns.distplot(df["OPN"], bins = 40, kde = False,
ax = axs[2, 0], color = sns.color_palette()[4]).set_title("Openness")
fig.delaxes(axs[2, 1])
for ax in axs.flat:
ax.set(xlabel = None, ylabel = "Count")
plt.show()
plt.ylim(ymin, ymax)
or
ax.set_ylim(ymin, ymax)
in your case probably axs instead of ax
---------------edit--------------
I can't try your code starting from sns.distplot...
I tried the code below, however with minor change at how I created the figure itself. btw either 9,9 or 18,18 won't make any difference, it's just that my screen is not big enough to see all if I use 18,18.
fig = plt.figure(figsize=(9,9))
axs = []
for i in range(1,7):
axs.append(fig.add_subplot(3,2,i))
axs[i-1].set_ylim([0,1000])
With the code above, you will just see this:
I guess that should solve the main problem of your question, if I understand it correctly?
I managed to do
for ax in axs.flat:
ax.set(xlabel = None, ylabel = "Count"),
ax.set_ylim(0, 50000)

How to Prevent Overlapping of Subplots in Python?

I am plotting various parameters in three different subplots. My second and third subplots are overlapping and I'm not understanding what is causing it. I have specified ax1, ax2, and ax3 and I'm thinking the issue may be from fig.add_subplot() but I'm not sure how to fix it. See my code below for reference. I only included the portions for the set up of the figure and the final plot since all three plots are generated practically in the same manner. I also included an image of what the plot is looking like that I wish to fix.
# Convert dataframe to 2D maps
lon_grid, lat_grid = np.meshgrid(data.lon.unique(), data.lat.unique())
L_grid = data.L.values.reshape(len(data.lat.unique()), len(data.lon.unique()))
Lam_grid = data.lam.values.reshape(len(data.lat.unique()), len(data.lon.unique()))
R_grid = data.R2.values.reshape(len(data.lat.unique()), len(data.lon.unique()))
# Make figures
fig = plt.figure(figsize= (10, 30), facecolor='white')
ax1 = fig.add_subplot(1,1,1,projection=ccrs.PlateCarree())
ax2 = fig.add_subplot(2,1,2,projection=ccrs.PlateCarree())
ax3 = fig.add_subplot(3,1,3,projection=ccrs.PlateCarree())
# Draw coastlines, states and countries for plot 3
ax3.coastlines()
ax3.add_feature(cfeature.BORDERS)
ax3.add_feature(cfeature.STATES)
# Draw parallels and meridians for plot 3
parallels = np.arange(-90,91,30)
meridians = np.arange(-180,181,60)
gl = ax3.gridlines(crs=ccrs.PlateCarree(), draw_labels=False,
linewidth=2, color='gray', alpha=0.5, linestyle='--')
gl.xlocator = mticker.FixedLocator(meridians)
gl.ylocator = mticker.FixedLocator(parallels)
ax3.set_xticks(np.arange(-180,181,30), crs=ccrs.PlateCarree())
ax3.set_yticks(parallels, crs=ccrs.PlateCarree())
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()
ax3.xaxis.set_major_formatter(lon_formatter)
ax3.yaxis.set_major_formatter(lat_formatter)
# Add Longitude wrap-around points at 0/360 for plot 3
cyclic_R_grid, cyclic_lons = cutil.add_cyclic_point(R_grid, coord=data.lon.unique())
c3 = ax3.contourf(cyclic_lons, data.lat.unique(), cyclic_R_grid, alpha = 1.0,
transform=ccrs.PlateCarree(), levels = np.arange(0,100), \
vmin = 0.0, vmax = 100.0)
# Overplot rigidity
c3_ = ax3.imshow(np.flip(R_grid, axis=1), interpolation = 'gaussian', alpha = 0.6, extent = (-180,180,-90,90))
cbar = plt.colorbar(c3, ax=ax3, fraction=0.025)
cbar.set_label('R')
plt.show()
You are adding your subplots wrong. fig.add_subplot expects n_rows,n_cols, index in that order. So the correct definition would be
fig = plt.figure(figsize= (10, 30), facecolor='white')
ax1 = fig.add_subplot(3,1,1,projection=ccrs.PlateCarree())
ax2 = fig.add_subplot(3,1,2,projection=ccrs.PlateCarree())
ax3 = fig.add_subplot(3,1,3,projection=ccrs.PlateCarree())

Python: "Squeeze" a particular plot in subplot

Below, I plot the following Figure in Python:
As you can see the plot on the right is much more "smooth" than the one on the left. That's because the scaling of x-axis on both plot is different. More observations on the left than on the right (about three times more). Hence how can I "squeeze" horizontally the right plot such that I get somewhat an approximative look to the one of the left? Below is my code (I use Pandas):
fig, axes = plt.subplots(1, 2, sharey=True, figsize=(30, 15))
# plot the same data on both axes
#gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1])
ax1 = df1.plot(ax=axes[0], grid='off', legend=False,
xticks=[-250, -200, -150, -100, -50,
0, 25], lw=2, colormap='jet',
fontsize=20)
ax2 = df2.plot(ax=axes[1], grid='off', legend=False,
xticks=[-5, 0, 20, 40, 60, 80], lw=2,
colormap='jet', fontsize=20)
# zoom-in / limit the view to different portions of the data
# hide the spines between ax and ax2
ax1.set_ylabel('Treatment-Control Ratio', fontsize=20)
ax1.axhline(y=1, color='r', linewidth=1.5)
ax2.axhline(y=1, color='r', linewidth=1.5)
ax1.axvline(x=0, color='r', linewidth=1.5, linestyle='--')
ax2.axvline(x=0, color='r', linewidth=1.5, linestyle='--')
ax1.set_xlabel('Event Time - 1 Minute', fontsize=20)
ax2.set_xlabel('Event Time - 1 Minute', fontsize=20)
ax1.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax1.yaxis.tick_left()
ax2.yaxis.set_major_locator(plt.NullLocator())
ax1.tick_params(labeltop='off') # don't put tick labels at the top
plt.subplots_adjust(wspace=0.11)
plt.tight_layout()
With the help of #cphlewis and #gboffi I fixed the issue with the code below:
fig, axes = plt.subplots(figsize=(30, 15))
# plot the same data on both axes
gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1.2])
ax1 = plt.subplot(gs[0])
ax2 = plt.subplot(gs[1], sharey=ax1)
df_wpc.loc[-260:25].plot(ax=ax1, grid='off', legend=False,
xticks=[-250, -200, -150, -100, -50,
0, 25], lw=2, colormap='jet',
fontsize=20)
df_pc_et.loc[-5:91].plot(ax=ax2, grid='off', legend=False,
xticks=[-5, 0, 20, 40, 60, 80], lw=2,
colormap='jet', fontsize=20)
ax1.set_ylabel('Treatment-Control Ratio', fontsize=20)
ax1.axhline(y=1, color='r', linewidth=1.8)
ax2.axhline(y=1, color='r', linewidth=1.8)
ax1.axvline(x=0, color='r', linewidth=1.8, linestyle='--')
ax2.axvline(x=0, color='r', linewidth=1.8, linestyle='--')
ax1.set_xlabel('Event Time - 1 Minute', fontsize=20)
ax2.set_xlabel('Event Time - 1 Minute', fontsize=20)
ax1.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax1.yaxis.tick_left()
ax2.yaxis.set_major_locator(plt.NullLocator())
ax1.tick_params(labeltop='off') # don't put tick labels at the top
plt.subplots_adjust(wspace=0.7)
plt.tight_layout()

Categories

Resources