Showing two data sets of `ax2.set_xticklabels` in a subplot - python

I have an upper subplot that shows two data sets: orange and green.
The following code shows the xtick labels of the green data set,
in the ax2 axis of the upper subplot (axis labelled as X2 in the figure):
ind_pos_Pd3 = [0, 4, 8, 12, 16]
axarr[0].set_xticks(X1_green[ind_pos_Pd3])
ax2.set_xticks(X1_green[ind_pos_Pd3])
ax2.set_xticklabels(["%.2f" % i for i in X2_green[ind_pos_Pd3]])
On the contrary, the following code shows the the xtick labels of the orange data set,
in the ax2 axis of the upper subplot (axis labelled as X2 in the figure):
ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32]
axarr[0].set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticklabels(["%.2f" % i for i in X2_orange[ind_pos_Bd3]])
Is there a way to "mix" both schemes and achieve a ax2 axis divided into two panels: the "lower panel" is filled with the labels from the green data set, and the "upper panel" is filled with the labels from the orange data set ?
Something like:
I was thinking on this pseudo-code:
ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32]
ind_pos_Pd3 = [0, 4, 8, 12, 16]
axarr[0].set_xticks(X1_orange[ind_pos_Bd3])
axarr[0].set_xticks(X1_green[ind_pos_Pd3])
ax2.set_xticks(X1_green[ind_pos_Pd3])
ax2.set_xticklabels(["%.2f \n %.2f" % i for i in zip(X2_orange[ind_pos_Bd3], X1_green[ind_pos_Pd3]])
However, the "%.2f \n %.2f" scheme is not working.
Minimal working example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
X1_orange = np.array([ 10., 30.1, 50.2, 70.3, 90.4, 110.51, 130.61, 150.71, 170.81,
190.91, 211.01, 231.11, 251.21, 271.31, 291.41, 311.52, 331.62, 351.72,
371.82, 391.92, 412.02, 432.12, 452.22, 472.32, 492.42, 512.53, 532.63,
552.73, 572.83, 592.93, 613.03, 633.13, 653.23])
X2_orange = np.array([ 2.56691976, 2.5781089 , 2.59624855, 2.62275805, 2.64568568, 2.66607658,
2.6959714 , 2.7231501 , 2.75529391, 2.78894345, 2.81573712, 2.84711104,
2.88437499, 2.9191375 , 2.95033337, 2.99340594, 3.02206115, 3.06383265,
3.08649135, 3.12707204, 3.18500195, 3.24240915, 3.25965166, 3.36137181,
3.35468811, 3.42661704, 3.46254097, 3.61136855, 3.65505401, 3.89043407,
3.80421353, 3.79380128, 4.01570509])
X1_green = np.array([ 10. , 30.1 , 50.2 , 70.3 , 90.4 , 110.51, 130.61, 150.71, 170.81,
190.91, 211.01, 231.11, 251.21, 271.31, 291.41, 311.52, 331.62])
X2_green = np.array([ 1.9894731 , 2.00259207, 2.01875725, 2.04333825, 2.07700656, 2.09629866,
2.14727031, 2.17488234, 2.2499103 , 2.2698862 , 2.31607409, 2.41452705,
2.50847008, 2.61117044, 2.70657103, 3.25283819, 3.31585812])
Y0_orange = np.array([-1.87483583, -1.82358431, -1.78627169, -1.75242213, -1.7299256 , -1.69363695,
-1.64623615, -1.59656948, -1.56967972, -1.55058869, -1.51874314, -1.45673839,
-1.40554361, -1.39904184, -1.35322104, -1.33906865, -1.30865871, -1.28099683,
-1.24897269, -1.19802619, -1.17268543, -1.13523614, -1.09290541, -1.05642197,
-1.00189406, -0.95390527, -0.90890049, -0.82522042, -0.76334378, -0.64504498,
-0.62782754, -0.47358849, -0.49772039])
Y0_green = np.array([-1.97113854, -1.92908192, -1.84404067, -1.75333855, -1.67575628, -1.58010168,
-1.48746063, -1.40770641, -1.31802444, -1.2302243 , -1.14927205, -1.04251178,
-0.91661452, -0.82924669, -0.65075739, -0.37715382, -0.21349827])
##### THREE SUBPLOTS::
###### Y0 plot:
f, axarr = plt.subplots(3, sharex=True, figsize=(11,5))
axarr[0].plot(X1_orange, Y0_orange, linestyle='--', marker="o", markersize=6, color='orange')
axarr[0].plot(X1_green, Y0_green, linestyle='--', marker="o", markersize=6, color='green')
axarr[0].set_ylabel('Y0', fontsize=15)
# Create a new axis:
axarr[0].grid()
ax2 = axarr[0].twiny()
# Make the ax1-ticks and ax1-tick-labels match the line color (blue):
axarr[0].tick_params('x', colors='blue')
# Make the ax2-ticks and ax2-tick-labels match the red color:
# this only controls the font and color of label
ax2.set_xlabel('x2', fontsize=14, color='red')
# this also adds the numbers on top of the tics,
# but sets the colors of the tics
ax2.tick_params('x', colors='orange')
# Set xlimits of ax2 the same as ax1
ax2.set_xlim(axarr[0].get_xlim())
# Set ticks at desired position
ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32]
axarr[0].set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticklabels(["%.2f" % i for i in X2_orange[ind_pos_Bd3]])
#ind_pos_Pd3 = [0, 4, 8, 12, 16]
#axarr[0].set_xticks(X1_green[ind_pos_Pd3])
#ax2.set_xticks(X1_green[ind_pos_Pd3])
#ax2.set_xticklabels(["%.2f" % i for i in X2_green[ind_pos_Pd3]])
# Just to align the Delta_V ylabel to the other 3 ylabel's
labelx = -0.075 # very close to the plot
axarr[0].yaxis.set_label_coords(labelx, 0.5, transform=None)
##### Y1 plot:
#f, axarr = plt.subplots(3, sharex=True)
axarr[1].set_ylabel('Y1', fontsize=15)
# Create a new axis:
axarr[1].grid()
ax2 = axarr[1].twiny()
# Make the ax1-ticks and ax1-tick-labels match the line color (blue):
axarr[1].tick_params('x', colors='blue')
# Make the ax2-ticks and ax2-tick-labels match the red color:
ax2.tick_params('x', colors='red')
ax2.set_xticklabels([]) # disable the tic labels
# Set xlimits of ax2 the same as ax1
ax2.set_xlim(axarr[1].get_xlim())
# Set ticks at desired position
ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32]
axarr[1].set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticks(X1_orange[ind_pos_Bd3])
# Label ticks of ax2 with values from X2
#ax2.set_xticklabels(["%.2f" % i for i in P])
axarr[1].yaxis.set_major_formatter(mtick.FormatStrFormatter('%1.e'))
#### Y2 plot:
axarr[2].set_ylabel('Y2', fontsize=15)
# Create a new axis:
axarr[2].grid()
ax2 = axarr[2].twiny()
# Make the ax1-ticks and ax1-tick-labels match the line color (blue):
axarr[2].tick_params('x', colors='blue')
# Make the ax2-ticks and ax2-tick-labels match the red color:
axarr[2].set_xlabel('X1', fontsize=14, color='blue')
# this also adds the numbers on top of the tics,
# but sets the colors of the tics
axarr[2].tick_params('x', colors='blue')
# Make the ax2-ticks and ax2-tick-labels match the red color:
ax2.tick_params('x', colors='red')
ax2.set_xticklabels([]) # disable the tic labels
# Set xlimits of ax2 the same as ax1
ax2.set_xlim(axarr[2].get_xlim())
# Set ticks at desired position
ind_pos_Bd3 = [0, 4, 8, 12, 16, 20, 24, 28, 32]
axarr[2].set_xticks(X1_orange[ind_pos_Bd3])
ax2.set_xticks(X1_orange[ind_pos_Bd3])
# Label ticks of ax2 with values from X2
axarr[2].yaxis.set_major_formatter(mtick.FormatStrFormatter('%1.e'))
plt.show()

The trick is to add a new twin axis for each row of tick labels you want.
You can then position them properly setting the pad parameter in tick_params.
Allow me to make your example a little smaller so it's easier to follow
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
fig, ax = plt.subplots(figsize=(12,2))
np.random.seed(42)
x0 = np.arange(50)
y0 = np.random.rand(50)
x1 = np.arange(30)
y1 = np.random.rand(30) + 0.7
ax.plot(x0, y0, ls='--', marker='o', ms=6, color='orange')
ax.grid(True)
ax.tick_params('x', colors='blue')
ax.set_xlabel('x1', fontsize=14, color='blue')
ax.set_ylabel('y', fontsize=14)
tax1 = ax.twiny()
tax1.set_xlim(ax.get_xlim())
tax1.tick_params('x', colors='orange', pad=14)
tax1.set_xlabel('x2', fontsize=14, color='red', labelpad=6)
tax2 = ax.twiny()
tax2.set_xlim(ax.get_xlim())
tax2.plot(x1, y1, ls='--', marker='o', ms=6, color='green')
tax2.tick_params('x', colors='green')
tax2.set_xticks([0, 10, 20, 30])
fig.savefig('img.png', pad_inches=0, bbox_inches='tight')
As you pointed out in the comments an issue with this plot is that you get green and orange tick lines and you would like to have them in red just like the x2 label.
You can hide the green tick lines setting length=0 in tick_params, draw the orange plot ticks in red first and then set labels color to orange.
Here's the modified code
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
fig, ax = plt.subplots(figsize=(12,2))
np.random.seed(42)
x0 = np.arange(50)
y0 = np.random.rand(50)
x1 = np.arange(30)
y1 = np.random.rand(30) + 0.7
ax.plot(x0, y0, ls='--', marker='o', ms=6, color='orange')
ax.grid(True)
ax.tick_params('x', colors='blue')
ax.set_xlabel('x1', fontsize=14, color='blue')
ax.set_ylabel('y', fontsize=14)
tax1 = ax.twiny()
tax1.set_xlim(ax.get_xlim())
tax1.tick_params('x', colors='red', pad=14)
tax1.set_xlabel('x2', fontsize=14, color='red', labelpad=6)
[x.set_color("orange") for x in tax1.get_xticklabels()]
tax2 = ax.twiny()
tax2.set_xlim(ax.get_xlim())
tax2.plot(x1, y1, ls='--', marker='o', ms=6, color='green')
tax2.tick_params('x', colors='green', pad=6, length=0)
tax2.set_xticks([0, 10, 20, 30])
fig.savefig('img2.png', pad_inches=0, bbox_inches='tight')

Related

how to plot figure with arrows

How can I add arrows on x and y axes, show only the values that are used and add label for coordinates
My code on this moment:
x = [9, 8, 11, 11, 14, 13, 16, 14, 14]
y = [9, 16, 15, 11, 10, 11, 10, 8, 8]
fig = plt.figure(figsize=(7,7), dpi=300)
axes = fig.add_axes([0,1,1,1])
axes.set_xlim(0, 17)
axes.set_ylim(0, 17)
axes.invert_yaxis()
axes.scatter(x, y, color='green')
axes.vlines(x, 0, y, linestyle="dashed", color='green')
axes.hlines(y, 0, x, linestyle="dashed", color='green')
axes.spines.right.set_visible(False)
axes.spines.bottom.set_visible(False)
plt.show()
Visually:
enter image description here
And plot that I want to realize
enter image description here
You can draw arrows by overlaying triangle shaped points over the ends of your spines.
You'll need to leverage some transforms, but you can also create your labels by manually adding text to your Axes objects as well.
Labelling each coordinate can be done via axes.annotate, but you'll need to manually specify the location of each annotation to ensure they don't overlap with lines or other annotations.
import matplotlib.pyplot as plt
from matplotlib.ticker import FixedLocator
x = [9, 8, 11, 11, 14, 13, 16, 14, 14]
y = [9, 16, 15, 11, 10, 11, 10, 8, 8]
fig = plt.figure(figsize=(7,7), dpi=300)
axes = fig.add_axes([.05,.05,.9,.9])
# Plots the data
axes.scatter(x, y, color='green')
axes.vlines(x, 0, y, linestyle="dashed", color='green')
axes.hlines(y, 0, x, linestyle="dashed", color='green')
axes.set_xlim(0, 17)
axes.set_ylim(0, 17)
axes.set_xticks(x)
axes.set_yticks(y)
axes.invert_yaxis()
# Move ticks to top side of plot
axes.xaxis.set_tick_params(
length=0, bottom=False, labelbottom=False, top=True, labeltop=True
)
axes.xaxis.set_tick_params(length=0)
# Add arrows to the spines by drawing triangle shaped points over them
axes.plot(1, 1, '>k', transform=axes.transAxes, clip_on=False)
axes.plot(0, 0, 'vk', transform=axes.transAxes, clip_on=False)
axes.spines[['bottom', 'right']].set_visible(False)
# Add labels for 0, F_1 and F_2
from matplotlib.transforms import offset_copy
axes.text(
0, 1, s='0', fontstyle='italic', ha='right', va='bottom',
transform=offset_copy(axes.transAxes, x=-5, y=5, fig=fig, units='points'),
)
axes.text(
1, 1, s='$F_1$', fontstyle='italic', ha='right', va='bottom',
transform=offset_copy(axes.transAxes, x=0, y=5, fig=fig, units='points'),
)
axes.text(
0, 0, s='$F_2$', fontstyle='italic', ha='right',
transform=offset_copy(axes.transAxes, x=-5, y=0, fig=fig, units='points'),
)
# Add labels at each point. Leveraging the alignment of the text
# AND padded offset.
lc = ('top', 'center', 0, -5)
ll = ('top', 'right', -5, -5)
lr = ('top', 'left', 5, -5)
ur = ('bottom', 'left', 5, 5)
alignments = [lc, lc, lc, ll, lc, ll, lc, ur, lr]
for i, (xc, yc, (va, ha, padx, pady)) in enumerate(zip(x, y, alignments)):
axes.annotate(
xy=(xc, yc), xytext=(padx, pady),
text=f'$F(x_{i})$', ha=ha, va=va, textcoords='offset points')
plt.show()
Adding
axes.plot(1, 0, ">k", transform=axes.get_yaxis_transform(), clip_on=False)
axes.plot(0, 0, "vk", transform=axes.get_xaxis_transform(), clip_on=False)
Will do it for you. This is basically just a cheat plot of markers.
There are also
from mpl_toolkits.axisartist.axislines.AxesZero
which allow
for direction in ["xzero", "yzero"]:
# adds arrows at the ends of each axis
ax.axis[direction].set_axisline_style("-|>")
but they can't handle the reversed y axis in your case with default settings.

How to mask data that appears in the ocean using cartopy and matplotlib

Not at all sure what I'm doing wrong besides perhaps the order that I am plotting the ocean in. I am trying to get the ocean feature in to mask the data in the ocean. I am trying to get data to not appear in the ocean and to get the ax.add_feature(cfeature.OCEAN) to be on top of the temperature data I am plotting so I see ocean and no data. Similar to what is happening in the great lakes region where you see lakes and no temperature data.
proj_map = ccrs.Mercator(central_longitude=cLon)
proj_data = ccrs.PlateCarree()
fig = plt.figure(figsize=(30,20))
ax = fig.add_subplot(1,1,1, projection=proj_map)
ax.set_extent([-84,-66,37,47.5])
CT = ax.contourf(Tlat, Tlon, tempF, transform=temp.metpy.cartopy_crs, levels=clevs,
cmap=cmap)
ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.5)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.LAKES)
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.add_feature(cfeature.STATES.with_scale('10m'), linewidth=0.5)
ax.add_feature(USCOUNTIES.with_scale('20m'), linewidth=0.25)
cbar = fig.colorbar(CT, orientation='horizontal', shrink=0.5, pad=0.05)
cbar.ax.tick_params(labelsize=14)
cbar.set_ticks([-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120])
cbar.ax.set_xlabel("Temp ($^\circ$F)",fontsize=20)
Here is what the image looks like
You need to use zorder option to specify proper orders of the plot on the map. Features with largers values of zorder will be plotted on top of those with lower values. In your case, you need zorder of the OCEAN larger than the filled-contour.
Here is a runnable demo code and its sample plot. Read comments in the code for explanation.
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(projection=ccrs.PlateCarree()))
extent = [-84, -66, 37, 47.5]
# generate (x, y), centered at the middle of the `extent`
mean = [(extent[0]+extent[1])/2, (extent[2]+extent[3])/2] #mean
cov = [[7, 3.5], [3.5, 6]] #co-variance matrix
x, y = np.random.multivariate_normal(mean, cov, 4000).T
# make a 2D histogram
# set the edges of the bins in x and y directions
bin_size = 40
lonrange = np.linspace(extent[0], extent[1], bin_size)
latrange = np.linspace(extent[2], extent[3], bin_size)
# the cell sizes of the bins:
dx = (lonrange[1]- lonrange[0])/2
dy = (latrange[3]- latrange[2])/2
# compute array of center points of the bins' grid
# the dimensions of mesh-grid < the edges by 1
lonrange2 = np.linspace(extent[0]+dx, extent[1]-dx, bin_size-1)
latrange2 = np.linspace(extent[2]+dy, extent[3]-dy, bin_size-1)
x2d, y2d = np.meshgrid(lonrange2, latrange2)
# create 2d-histogram
# zorder is set = 10
h = ax.hist2d(x, y, bins=[lonrange, latrange], zorder=10, alpha=0.75)
#h: (counts, xedges, yedges, image)
ax.add_feature(cfeature.OCEAN, zorder=12) #zorder > 10
ax.add_feature(cfeature.BORDERS, linewidth=0.5)
ax.gridlines(draw_labels=True, xlocs=list(range(-85, -60, 5)), ylocs=list(range(35, 50, 5)),
linewidth=1.8, color='gray', linestyle='--', alpha=0.8, zorder=20)
# plot colorbar, using image from hist2d's result
plt.colorbar(h[3], ax=ax, shrink=0.45)
# finally, show the plot.
plt.show()
The output plot:
If zorder option is not specified:
ax.add_feature(cfeature.OCEAN)
the plot will be:

How to limit lower error of bar plot to 0?

I calculated the rttMeans and rttStds arrays. However, the value of rttStds makes the lower error less than 0.
rttStds = [3.330311915835426, 3.3189677330174883, 3.3319538853150386, 3.325173772304221, 3.3374145232695813]
How to set lower error to 0 instead of -#?
The python bar plot code is bellow.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={'figure.figsize':(18,16)},style='ticks',font_scale = 1.5,font='serif')
N = 5
ind = ['RSU1', 'RSU2', 'RSU3', 'RSU4', 'RSU5'] # the x locations for the groups
width = 0.4 # the width of the bars: can also be len(x) sequence
fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111)
p1 = plt.bar(ind, rttMeans, width, yerr=rttStds, log=False, capsize = 16, color='green', hatch="/", error_kw=dict(elinewidth=3,ecolor='black'))
plt.margins(0.01, 0)
#Optional code - Make plot look nicer
plt.xticks(rotation=0)
i=0.18
for row in rttMeans:
plt.text(i, row, "{0:.1f}".format(row), color='black', ha="center")
i = i + 1
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
params = {'axes.titlesize':24,
'axes.labelsize':24,
'xtick.labelsize':28,
'ytick.labelsize':28,
'legend.fontsize': 24,
'axes.spines.right':False,
'axes.spines.top':False}
plt.rcParams.update(params)
plt.tick_params(axis="y", labelsize=28, labelrotation=20, labelcolor="black")
plt.tick_params(axis="x", labelsize=28, labelrotation=20, labelcolor="black")
plt.ylabel('RT Time (millisecond)', fontsize=24)
plt.title('# Participating RSUs', fontsize=24)
# plt.savefig('RSUs.pdf', bbox_inches='tight')
plt.show()
You can pass yerr as a pair [lower_errors, upper_errors] where you can control lower_errors :
lowers = np.minimum(rttStds,rttMeans)
p1 = plt.bar(ind, rttMeans, width, yerr=[lowers,rttStds], log=False, capsize = 16, color='green', hatch="/", error_kw=dict(elinewidth=3,ecolor='black'))
Output:

Pretty plot bar chart in python with matplotlib

I wrote a python code below to draw a bar chart for my data. I adjusted parameters but failed to make it beautiful(See attached pic).
The python code is shown below:
def plotElapsedDis(axis, jvm1, jvm2, ylabel, title, name):
import matplotlib.pyplot as plt
import numpy as np
#fig, ax = plt.subplots(111)
fig = plt.figure()
ax = fig.add_subplot(111)
## the data
N = len(jvm1)
#menMeans = [18, 35, 30, 35, 27]
#womenMeans = [25, 32, 34, 20, 25]
ind = np.arange(N)+1
width = 0.25 # the width of the bars
rects1 = ax.bar(ind-width, jvm1, width)
rects2 = ax.bar(ind, jvm2, width, color='r')
ax.set_ylabel(ylabel)
ax.set_title(title)
plt.xticks(ind , axis, rotation=-90)
ax.legend( (rects1[0], rects2[0]), ('Originl', 'Optimal') )
plt.savefig(name)
plt.close()
plotElapsedDis(keys, y_jvm1, y_jvm2, 'seconds', 'CPU Elapsed', '../tmp/cpu_elapsed.jpg')
The first three lists for plotElapsedDis are:
keys= [u'mergesort_hongli', u'so_object', u'gc_mb', u'socket_transfer_1mb', u'app_factorial', u'string_concat', u'printff', u'so_lists', u'so_lists_small', u'word_anagrams', u'fasta', u'count_multithreaded', u'app_mandelbrot', u'primes', u'nbody', u'app_fib', u'socket_transfer_1mb_noblock', u'nsieve_bits', u'gc_string', u'simple_server', u'gc_array', u'cal', u'spectral_norm', u'app_pentomino', u'so_sieve', u'eval', u'so_matrix', u'mbari_bogus1', u'fractal', u'simple_connect', u'partial_sums', u'pi', u'so_array', u'count_shared_thread', u'fiber_ring', u'list', u'binary_trees', u'app_tarai', u'monte_carlo_pi', u'observ', u'write_large']
y_jvm1= [20.703852000000001, 173.12867899999998, 74.149726000000001, 15.717608999999999, 26.226012000000001, 136.44825599999999, 46.775888000000002, 63.851292000000001, 13.929881, 71.078192999999999, 66.729854000000003, 92.045006000000001, 55.671535999999996, 24.082338, 46.349951999999995, 38.166196999999997, 15.777601000000001, 123.075288, 161.76140800000002, 12.053167, 60.597787000000004, 43.662361000000004, 45.789037999999998, 209.30117999999999, 32.190105000000003, 48.988551000000001, 55.191608000000002, 52.242056999999996, 89.343417000000002, 12.721064999999999, 109.08541600000001, 24.236315000000001, 19.817986000000001, 226.82451600000002, 100.985647, 60.686772999999995, 55.589548000000001, 69.965362999999996, 35.801557000000003, 25.728088, 16.169540999999999]
y_jvm2= [19.938967999999999, 178.796818, 67.512734999999992, 15.787599, 26.058038, 137.27913000000001, 12.535093, 59.649929999999998, 13.865891000000001, 60.618783000000001, 68.384602999999998, 283.39391599999999, 56.349432, 24.923209999999997, 44.113292999999999, 40.564831999999996, 12.393115, 120.76664, 152.30684499999998, 12.195145, 64.276227000000006, 18.565175999999997, 48.006701, 212.65967000000001, 32.544051000000003, 49.798428000000001, 58.516103000000001, 17.243377000000002, 92.973864999999989, 12.519096000000001, 111.39406500000001, 27.048887000000001, 20.014955999999998, 280.62933700000002, 86.977775999999992, 61.553642000000004, 50.455328000000002, 70.610264999999998, 28.390682999999999, 28.378685000000001, 17.351361000000001]
The problems with this generated pic above are that:
The label for x-aixs are too long, which are truncated(out of figure border).
Distict the bars by others instead of color. Since the pic will be print so that distinction by color would not be work. How to fill bars of one group with different style (e.g, the last bar infigure).
I will appreciate if anyone can help adjust the outlook of this pic. Thanks!
I would consider you clean up the names a little bit, that should help. Once you do that, you can change the rotation to 45 which will make it look better.
You can do that by changing plt.xticks(ind , axis, rotation=90) to plt.xticks("range", "custom label list", rotation=90)
def plotElapsedDis(axis, jvm1, jvm2, ylabel, title, name):
import matplotlib.pyplot as plt
import numpy as np
#fig, ax = plt.subplots(111)
fig = plt.figure()
ax = fig.add_subplot(111)
## the data
N = len(jvm1)
#menMeans = [18, 35, 30, 35, 27]
#womenMeans = [25, 32, 34, 20, 25]
ind = np.arange(N)+1
width = 0.25 # the width of the bars
# add "hatch"
rects1 = ax.bar(ind-width, jvm1, width, color='white', edgecolor='black', hatch="*")
rects2 = ax.bar(ind, jvm2, width, color='white', edgecolor='black', hatch='//')
ax.set_ylabel(ylabel)
ax.set_title(title)
plt.xticks(ind , axis, rotation=90)
ax.legend( (rects1[0], rects2[0]), ('Originl', 'Optimal') )
fig.tight_layout() # make sure it fits
plt.show()
plotElapsedDis(keys, y_jvm1, y_jvm2, 'seconds', 'CPU Elapsed', '../tmp/cpu_elapsed.jpg')

adjust the position of colorbar and equalize the size of subplots

Following my previous question that didn't get any answer, I tried to solve my problem of adding colorbar instead of legend to my plots. There are couple of problems that I couldn't solve yet.
Update:
I want to move the colorbar to the proper position on the right of the plot.
I generate two plots with the same instruction but the second one looks completely different and I couldn't understand what caused this problem.
Here is my code:
import numpy as np
import pylab as plt
from matplotlib import rc,rcParams
rc('text',usetex=True)
rcParams.update({'font.size':10})
import matplotlib.cm as cm
from matplotlib.ticker import NullFormatter
import matplotlib as mpl
def plot(Z_s,CWL,filter_id,spectral_type,model_mag,mag,plot_name):
f= ['U38','B','V','R','I','MB420','MB464','MB485','MB518','MB571','MB604','MB646','MB696','MB753','MB815','MB856','MB914']
wavetable=CWL/(1+Z_s)
dd=model_mag-mag
nplist=['E', 'Sbc', 'Scd', 'Irr', 'SB3', 'SB2']
minimum,maximum=(0.,16.)
Z = [[0,0],[0,0]]
levels = list(np.linspace(0, 1, len(f)))
NUM_COLORS = len(f)
cm = plt.get_cmap('gist_rainbow')
mycolor=[]
for i in range(NUM_COLORS):
mycolor.append( cm(1.*i/NUM_COLORS)) # color will now be an RGBA tuple
mymap = mpl.colors.LinearSegmentedColormap.from_list('mycolors',mycolor)
CS3 = plt.contourf(Z, levels, cmap=mymap)
plt.clf()
FILTER=filter_id
SED=spectral_type
for (j,d) in enumerate(nplist):
bf=(SED==j)
if (j<3):
k=j
i_subplot = k + 1
fig = plt.figure(1, figsize=(5,5))
ax = fig.add_subplot(3,1,i_subplot)
for i in range(len(f)):
bb=np.where(FILTER[bf]==i)[0]
r=mycolor[i][0]
g=mycolor[i][1]
b=mycolor[i][2]
ax.scatter(wavetable[bb], dd[bb], s=1, color=(r,g,b))
if (k<2):
ax.xaxis.set_major_formatter( NullFormatter() )
ax.set_ylabel(r'$\Delta$ MAG',fontsize=10)
else:
ax.set_xlabel(r'WL($\AA$)',fontsize=10)
ax.set_ylabel(r'$\Delta$ MAG',fontsize=10)
fig.subplots_adjust(wspace=0,hspace=0)
ax.axhline(y=0,color='k')
ax.set_xlim(1000,9000)
ax.set_ylim(-3,3)
ax.set_xticks(np.linspace(1000, 9000, 16, endpoint=False))
ax.set_yticks(np.linspace(-3, 3, 4, endpoint=False))
ax.text(8500,2.1,nplist[j], {'color': 'k', 'fontsize': 10})
fontsize=8
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
for tick in ax.yaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
if (j==2):
cbar_ax = fig.add_axes([0.9, 0.15, 0.05, 0.7])
cbar=plt.colorbar(CS3, cax=cbar_ax, ticks=range(0,len(f)),orientation='vertical')
cbar.ax.get_yaxis().set_ticks([])
for s, lab in enumerate(f):
cbar.ax.text( 0.08,(0.95-0.01)/float(len(f)-1) * s, lab, fontsize=8,ha='left')
fname = plot_name+'.'+nplist[0]+'.'+nplist[1]+'.'+nplist[2]+'.pdf'
plt.savefig(fname)
plt.close()
else:
k=j-3
i_subplot = k + 1
fig = plt.figure(1, figsize=(5,5))
ax = fig.add_subplot(3,1,i_subplot)
for i in range(len(f)):
bb=np.where(FILTER[bf]==i)[0]
r=mycolor[i][0]
g=mycolor[i][1]
b=mycolor[i][2]
ax.scatter(wavetable[bb], dd[bb], s=1, color=(r,g,b))
if (k<2):
ax.xaxis.set_major_formatter( NullFormatter() )
ax.set_ylabel(r'$\Delta$ MAG',fontsize=10)
else:
ax.set_xlabel(r'WL($\AA$)',fontsize=10)
ax.set_ylabel(r'$\Delta$ MAG',fontsize=10)
fig.subplots_adjust(wspace=0,hspace=0)
ax.axhline(y=0,color='k')
ax.set_xlim(1000,9000)
ax.set_ylim(-3,3)
ax.set_xticks(np.linspace(1000, 9000, 16, endpoint=False))
ax.set_yticks(np.linspace(-3, 3, 4, endpoint=False))
ax.text(8500,2.1,nplist[j], {'color': 'k', 'fontsize': 10})
fontsize=8
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
for tick in ax.yaxis.get_major_ticks():
tick.label1.set_fontsize(fontsize)
if (j==5):
cbar_ax = fig.add_axes([0.9, 0.15, 0.05, 0.7])
cbar=plt.colorbar(CS3, cax=cbar_ax, ticks=range(0,len(f)),orientation='vertical')
cbar.ax.get_yaxis().set_ticks([])
for s, lab in enumerate(f):
cbar.ax.text( 0.08,(0.95-0.01)/float(len(f)-1) * s, lab , fontsize=8,ha='left')
fname = plot_name+'.'+nplist[3]+'.'+nplist[4]+'.'+nplist[5]+'.pdf'
plt.savefig(fname)
plt.close()
a=np.loadtxt('calibration.photometry.information.capak.cat')
Z_s=a[:,0]
CWL=a[:,1]
filter_id=a[:,2]
spectral_type=a[:,3]
model_mag=a[:,4]
mag=a[:,5]
plot_name='test'
plot(Z_s,CWL,filter_id,spectral_type,model_mag,mag,plot_name)
you can also download the data from here.
I will appreciate to get any help.
You can use plt.subplots() passing the gridspec_kw parameter to adjust the axes' aspect ratio in a very flexible way, and then select the top axes to include the colorbar.
I've worked on your code simplifying it quite a bit. Furthermore, I've changed many things in your code such as: PEP8, removed repeated calls to plt.savefig()and ax methods. The result is:
import numpy as np
import pylab as plt
from matplotlib import rc, rcParams, colors
rc('text', usetex=True)
rcParams['font.size'] = 10
rcParams['axes.labelsize'] = 8
def plot(Z_s, CWL, filter_id, spectral_type, model_mag, mag, plot_name):
f= ['U38', 'B', 'V', 'R', 'I', 'MB420', 'MB464', 'MB485', 'MB518',
'MB571', 'MB604', 'MB646', 'MB696', 'B753', 'MB815', 'MB856',
'MB914']
wavetable = CWL/(1+Z_s)
dd = model_mag-mag
nplist = ['E', 'Sbc', 'Scd', 'Irr', 'SB3', 'SB2']
minimum, maximum = (0., 16.)
Z = [[0, 0],[0, 0]]
levels = list(np.linspace(0, 1, len(f)+1))
NUM_COLORS = len(f)
cmap = plt.get_cmap('gist_rainbow')
mycolor = []
for i in range(NUM_COLORS):
mycolor.append(cmap(1.*i/NUM_COLORS))
mymap = colors.LinearSegmentedColormap.from_list('mycolors', mycolor)
CS3 = plt.contourf(Z, levels, cmap=mymap)
coords = CS3.get_array()
coords = coords[:-1] + np.diff(coords)/2.
FILTER = filter_id
SED = spectral_type
dummy = 2
xmin = 1000
xmax = 9000
ymin = -3
ymax = 3
fig, axes = plt.subplots(nrows=5, figsize=(5, 6),
gridspec_kw=dict(height_ratios=[0.35, 0.05, 1, 1, 1]))
fig2, axes2 = plt.subplots(nrows=5, figsize=(5, 6),
gridspec_kw=dict(height_ratios=[0.35, 0.05, 1, 1, 1]))
fig.subplots_adjust(wspace=0, hspace=0)
fig2.subplots_adjust(wspace=0, hspace=0)
axes_all = np.concatenate((axes[dummy:], axes2[dummy:]))
dummy_axes = np.concatenate((axes[:dummy], axes2[:dummy]))
for ax in axes_all:
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.axhline(y=0, color='k')
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.set_xticks([])
ax.set_yticks(np.linspace(ymin, ymax, 4, endpoint=False))
ax.set_ylabel(r'$\Delta$ MAG', fontsize=10)
axes[-1].set_xticks(np.linspace(xmin, xmax, 16, endpoint=False))
axes2[-1].set_xticks(np.linspace(xmin, xmax, 16, endpoint=False))
plt.setp(axes[-1].xaxis.get_majorticklabels(), rotation=30)
plt.setp(axes2[-1].xaxis.get_majorticklabels(), rotation=30)
axes[-1].set_xlabel(r'WL($\AA$)', fontsize=10)
axes2[-1].set_xlabel(r'WL($\AA$)', fontsize=10)
for ax in dummy_axes:
for s in ax.spines.values():
s.set_visible(False)
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('none')
ax.set_xticks([])
ax.set_yticks([])
for axes_i in [axes, axes2]:
cbar = plt.colorbar(CS3, ticks=[], orientation='horizontal',
cax=axes_i[0])
for s, lab in enumerate(f):
cbar.ax.text(coords[s], 0.5, lab, fontsize=8, va='center',
ha='center', rotation=90,
transform=cbar.ax.transAxes)
for (j, d) in enumerate(nplist):
bf = (SED==j)
if (j<3):
k = j
ax = axes[k+dummy]
ax.text(8500, 2.1, nplist[j], {'color': 'k', 'fontsize': 10})
for i in range(len(f)):
bb = np.where(FILTER[bf]==i)[0]
ax.scatter(wavetable[bb], dd[bb], s=1, color=mycolor[i])
else:
k = j-3
ax = axes2[k+dummy]
ax.text(8500, 2.1, nplist[j], {'color': 'k', 'fontsize': 10})
for i in range(len(f)):
bb = np.where(FILTER[bf]==i)[0]
ax.scatter(wavetable[bb], dd[bb], s=1, color=mycolor[i])
fname = '.'.join([plot_name, nplist[0], nplist[1], nplist[2], 'png'])
fig.savefig(fname)
fname = '.'.join([plot_name, nplist[3], nplist[4], nplist[5], 'png'])
fig2.savefig(fname)
if __name__=='__main__':
a = np.loadtxt('calibration.photometry.information.capak.cat')
Z_s = a[:, 0]
CWL = a[:, 1]
filter_id = a[:, 2]
spectral_type = a[:, 3]
model_mag = a[:, 4]
mag = a[:, 5]
plot_name = 'test'
plot(Z_s, CWL, filter_id, spectral_type, model_mag, mag, plot_name)
which gives:

Categories

Resources