Matplotlib.pyplot only displays final plot - python

I'm trying to create a simple 1 by 3 subplot of the maps I have. They only have 2 dimensions (longitude and latitude) after time averaging. The final map plots perfectly, but the first two subplots are just blank.
Thanks in advance for any advice!
import numpy as np
import xarray as xa
import cmocean.cm as cm
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
lgm = xa.open_dataset('lgm.nc', decode_times=False)
pre = xa.open_dataset('pre-i.nc', decode_times=False)
pd = xa.open_dataset('present.nc', decode_times=False)
def pco2_diff():
lgm_pco2 = lgm.O_pco2sur
pre_pco2 = pre.O_pco2sur
pd_pco2 = pd.O_pco2sur
#-------------------------Time averaged data-------------------------------
lgm_pco2_mean = lgm_pco2.mean("time")
pre_pco2_mean = pre_pco2.mean("time")
pd_pco2_mean = pd_pco2.mean("time")
#-----------------Get the ocean-atmosphere fluxes--------------------------
lgm_pco2_diff = lgm_pco2_mean - 189.65
pre_pco2_diff = pre_pco2_mean - 277.44
pd_pco2_diff = pd_pco2_mean - 368.89
#---------------------Basic plots, 1 at a time-----------------------------
lgm_pco2_diff.plot()
pre_pco2_diff.plot()
pd_pco2_diff.plot()
#-----------------------------Subplots-------------------------------------
f, (ax1, ax2, ax3) = plt.subplots(1, 3, sharey=True, sharex=False)
#1 row, 3 columns, sharing the y-axis, not sharing the x-axis
ax1 = lgm_pco2_diff.plot(vmin=-300, vmax=300, add_colorbar=False)
ax2 = pre_pco2_diff.plot(vmin=-300, vmax=300, add_colorbar=False)
ax3 = pd_pco2_diff.plot(vmin=-300, vmax=300,cmap=cm.thermal)

Maybe try the following:
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, sharey=True, sharex=False)
ax1.plot(lgm_pco2_diff, vmin=-300, vmax=300, add_colorbar=False)
ax2.plot(pre_pco2_diff, vmin=-300, vmax=300, add_colorbar=False)
ax3.plot(pd_pco2_diff, vmin=-300, vmax=300, cmap=cm.thermal)

Related

How to add a dollar sign to a seaborn heatmap

I have the following code that generates a Heatmap in Pandas:
def create_cohort(cohort_size,retention_matrix,titulo):
print(f"{titulo}\n")
with sns.axes_style("white"):
fig, ax = plt.subplots(1, 2, figsize=(12, 8), sharey=True, gridspec_kw={'width_ratios': [1, 11]})
# retention matrix
sns.heatmap(retention_matrix,
mask=retention_matrix.isnull(),
annot=True,
fmt='.0%',
cmap='Purples',
ax=ax[1])
ax[1].set_title(f'Cohort: {titulo}', fontsize=16)
ax[1].set(xlabel='Meses',
ylabel='')
# cohort size
cohort_size_df = pd.DataFrame(cohort_size).rename(columns={0: 'Tamanho da cohort'})
white_cmap = mcolors.ListedColormap(['white'])
sns.heatmap(cohort_size_df,
annot=True,
cbar=False,
fmt='.0f',
cmap=white_cmap,
ax=ax[0])
fig.tight_layout()
return
This is a example of graph:
I would like to change the format of the most left table to add '$' before the number. I know I have to change the fmt='.0f', but I do not know how. I also could not find documentation on the values I can pass in the fmt parameter. Can someone also explain to me how this works? What values can I use?
Instead of just setting annot=True, a list of strings, with the same shape as the dataframe can be provided:
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from matplotlib.ticker import PercentFormatter
import seaborn as sns
import pandas as pd
N = 12
cohort_size = pd.DataFrame({0: np.random.randint(20000, 50000, N)}, index=[f'2021:{i:02d}' for i in range(1, 13)])
retention_matrix = np.random.rand(N, N)
retention_matrix[:, 0] = 1
retention_matrix = np.where(np.tril(retention_matrix)[::-1], retention_matrix, np.NaN)
with sns.axes_style("white"):
fig, ax = plt.subplots(1, 2, figsize=(12, 8), sharey=True, gridspec_kw={'width_ratios': [1, 11]})
sns.heatmap(retention_matrix,
annot=True,
fmt='.0%',
cmap='Purples',
cbar_kws={'format': PercentFormatter(1)},
ax=ax[1])
ax[1].set(xlabel='Meses', ylabel='')
cohort_size_df = pd.DataFrame(cohort_size).rename(columns={0: 'Tamanho da cohort'})
labels = [[f'$ {s:,d}'] for s in cohort_size_df.iloc[:, 0]]
sns.heatmap(cohort_size_df,
annot=labels,
cbar=False,
fmt='',
cmap=ListedColormap(['white']),
ax=ax[0])
ax[0].tick_params(axis='y', labelrotation=0)
fig.tight_layout()
plt.show()

Problems decimating a 2D python array

In order to plot a very high resolution array (1440*720) in matplotlib, I have resorted to using the decimate method of scipy.
However when trialing the function, it appeared to show some odd behaviour, where the top row of the plots looked brighter than the subsequent duller rows.
The following is a minimal reproducible example that should show the strange behaviour.
What might I be doing wrong?
import matplotlib.pyplot as plt
import numpy as np
import scipy.signal as sp
n=8
data = np.random.rand(64,64)
fig, ax1 = plt.subplots(num=444, nrows=1, ncols=1, figsize=(8, 6))
p1 = ax1.pcolor(np.flipud(data))
fig.colorbar(p1, ax=ax1, orientation='vertical', format='%.1f')
ax1.set_xlabel("X")
ax1.set_title(data.shape);
data2 = sp.decimate(data, n, n=None, ftype='iir', axis=0, zero_phase=True)
fig, ax1 = plt.subplots(num=445, nrows=1, ncols=1, figsize=(8, 6))
p1 = ax1.pcolor(np.flipud(data2))
fig.colorbar(p1, ax=ax1, orientation='vertical', format='%.1f')
ax1.set_xlabel("X")
ax1.set_title(data2.shape);
data3 = sp.decimate(data2, n, n=None, ftype='iir', axis=1, zero_phase=True)
fig, ax1 = plt.subplots(num=446, nrows=1, ncols=1, figsize=(8, 6))
p1 = ax1.pcolor(np.flipud(data3))
fig.colorbar(p1, ax=ax1, orientation='vertical', format='%.0f')
ax1.set_xlabel("X")
ax1.set_title(data3.shape);

Adding minor ticks to pandas plot

I have the following code:
from pandas_datareader import data as web
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1)
df = web.DataReader('F', 'yahoo')
df2 = web.DataReader('Fb', 'yahoo')
ax = df.plot(figsize=(35,15), ax=ax1)
df2.plot(y = 'Close', figsize=(35,15), ax=ax2)
plt.show()
This produces the chart which looks like this:
How can i change the minor ticks in pandas plot so it produces the x axis which looks like this:
Check this code:
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import matplotlib.dates as md
fig, (ax1, ax2) = plt.subplots(2, 1)
df = web.DataReader('F', 'yahoo')
df2 = web.DataReader('Fb', 'yahoo')
ax = df.plot(figsize=(35,15), ax=ax1)
df2.plot(y = 'Close', figsize=(35,15), ax=ax2)
for ax in (ax1, ax2):
ax.xaxis.set_major_locator(md.MonthLocator(bymonth = range(1, 13, 6)))
ax.xaxis.set_major_formatter(md.DateFormatter('%b\n%Y'))
ax.xaxis.set_minor_locator(md.MonthLocator())
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 0 )
plt.show()
You can manage the xticks with the ax.xaxis methods. The above code produce this plot:

Matplotlib: how to remove spacing between a group of subplots

I have a series of pyplot subplots that I've created using a gridspec. They all have an hspace between them, which is fine, except that I would like to keep three of them without any space. Is there a way to do this? Currently, they look like this:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure()
grid_spec = gridspec.GridSpec(nrows=10, ncols=10)
grid_spec.update(hspace=1.5)
ax1 = plt.subplot(grid_spec[0:4, :])
ax2 = plt.subplot(grid_spec[4:7, :], sharex=ax1)
# I would like to group the next 3 together
# so that they are stacked top to bottom and side by side
ax3 = plt.subplot(grid_spec[7:8, :5])
ax4 = plt.subplot(grid_spec[8:, :5], sharex=ax3)
ax5 = plt.subplot(grid_spec[8:, 5:6], sharey=ax4)
plt.show()
I would like them to be arranged like this so I can plot the following 2-D KDE diagram and have the relevant 1-D diagrams above and to the right (roughly displaying this sort of data crudely drawn in paint):
I appreciate any help with this one. Can't seem to find documentation on this sort of thing. Thanks!
You can use mpl_toolkits.axes_grid1.make_axes_locatable to subdivide the area of a subplot of a 3 x 2 grid.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig = plt.figure()
gs = fig.add_gridspec(nrows=3, ncols=2, hspace=.5,
height_ratios=[4, 3, 3], width_ratios=[7, 4])
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :], sharex=ax1)
ax3 = fig.add_subplot(gs[2, 0])
div = make_axes_locatable(ax3)
ax4 = div.append_axes("top", "40%", pad=0.2, sharex=ax3)
ax5 = div.append_axes("right", "25%", pad=0.2, sharey=ax3)
ax4.tick_params(labelbottom=False)
ax5.tick_params(labelleft=False)
plt.show()
Also, you can create a subgridspec, like
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(nrows=3, ncols=2, hspace=.5,
height_ratios=[4, 3, 3], width_ratios=[7, 4])
ax1 = fig.add_subplot(gs[0, :])
ax2 = fig.add_subplot(gs[1, :], sharex=ax1)
sub_gs = gridspec.GridSpecFromSubplotSpec(2,2, subplot_spec=gs[2,0], hspace=0.3, wspace=0.1,
height_ratios=[1,3], width_ratios=[3,1])
ax3 = fig.add_subplot(sub_gs[1,0])
ax4 = fig.add_subplot(sub_gs[0,0], sharex=ax3)
ax5 = fig.add_subplot(sub_gs[1,1], sharey=ax3)
ax4.tick_params(labelbottom=False)
ax5.tick_params(labelleft=False)
plt.show()
In both cases you will probably want to fine tune the parameters a bit. In general, the matplotlib gridspec tutorial gives a nice overview with many examples on this matter.

How to make additional subplot of equal width as existing fixed aspect subplot? [duplicate]

This question already has an answer here:
imshow and plot side by side
(1 answer)
Closed 4 years ago.
I have 2 subplots the first of which has a fixed ratio. The lower subplot I don't care about the ratio but the width should align with the upper subplot.
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(211, aspect='equal', autoscale_on=False, xlim=(0, 80), ylim=(0, 40))
ax.plot([0,10,20,40,60,70], [1,4,3,2,6,5], 'bo')
ax1 = fig.add_subplot(212, xlim=(0, 8000), ylim=(-200, 0))
ax1.plot([0,8000],[-200,0], '-')
plt.show()
How can I make both subplots have the same width?
Update:
I made it work!
import matplotlib.pyplot as plt
import numpy as np
gkw = {'height_ratios':[1, 2] }
fig, (ax1, ax2) = plt.subplots(2, 1, gridspec_kw = gkw )
ax1.set_aspect('equal')
ax1.set_autoscale_on(False)
ax1.set_xlim(left=0, right=80)
ax1.set_ylim(bottom=0, top=40)
ax1.plot([0,10,20,40,60,70], [1,4,3,2,6,5], 'bo')
ax2.set_xlim(left=0, right=8000)
ax2.set_ylim(bottom=-200, top=0)
ya = np.diff(np.array(ax2.get_ylim()))[0]
xa = np.diff(np.array(ax2.get_xlim()))[0]
wa = gkw['height_ratios'][0]/float(gkw['height_ratios'][1])
ia = 40/80
ax2.set_aspect(float(1/wa*ia/(ya/xa)))
ax2.plot([0,8000],[-200,0], '-')
plt.show()
Is this what you are looking for?
Both subplots have the same width
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.set_xlim((0,80))
ax1.set_ylim((0,40))
ax1.plot([0,10,20,40,60,70], [1,4,3,2,6,5], 'bo')
ax2.set_xlim((0,8000))
ax2.set_ylim((-200,0))
ax2.plot([0,8000],[-200,0], '-')
plt.show()

Categories

Resources