Set yaxis of all subplots to the same range - Matplotlib - python

I'm wondering how do I force my subplots to share the y-axis range.
This is my code:
f, axes = plt.subplots(7, 1, sharex='col', sharey='row', figsize=(15, 30))
distance = []
for i in range(simulations):
delta = numpy.zeros((simulations+samples, simulations+samples))
data_x = sample_x[i*samples:(i*samples)+samples] + ensamble_x
data_y = sample_y[i*samples:(i*samples)+samples] + ensamble_y
for j in range(simulations+samples):
for k in range(simulations+samples):
if j <= k:
dist = similarity_measure((data_x[j].flatten(), data_y[j].flatten()), (data_x[k].flatten(), data_y[k].flatten()))
delta[j, k] = delta[k, j] = dist
delta = 1-((delta+1)/2)
delta /= numpy.max(delta)
model = manifold.TSNE(n_components=2, random_state=0, metric='precomputed')
coords = model.fit_transform(delta)
mds = manifold.MDS(n_components=2, max_iter=3000, eps=1e-9, random_state=0,
dissimilarity="precomputed", n_jobs=1)
coords = mds.fit(delta).embedding_
close, far = find_distance(coords[:samples, :], coords[samples+i, :])
distance.append((close, far))
axes[i].scatter(coords[:samples, 0], coords[:samples, 1], marker='x', c=colors[i], s=50, edgecolor='None')
axes[i].scatter(coords[samples:, 0], coords[samples:, 1], marker='o', c=colors, s=50, edgecolor='None')
axes[i].scatter(coords[close, 0], coords[close, 1], marker='s', facecolor="none", c=colors[i], s=50, edgecolor='None')
axes[i].scatter(coords[far, 0] , coords[far, 1] , marker='s', facecolor="none", c=colors[i], s=50, edgecolor='None')
axes[i].set_title('Simulation '+str(i+1), fontsize=20)
markers = []
labels = [str(n+1) for n in range(simulations)]
for i in range(simulations):
markers.append(Line2D([0], [0], linestyle='None', marker="o", markersize=10, markeredgecolor="none", markerfacecolor=colors[i]))
lgd = plt.legend(markers, labels, numpoints=1, bbox_to_anchor=(1.0, -0.055), ncol=simulations)
plt.tight_layout()
plt.ylim(-1, 1)
plt.axis('equal')
plt.savefig('Simulations.pdf', bbox_extra_artists=(lgd,), format='pdf', bbox_inches='tight')
And it's result:
As can be seen, the y axis limits differs from one subplot to another.
I'd like to use the max/min range generated.
Thank you.
EDTI: MINIMAL EXAMPLE
%matplotlib inline
from sklearn.preprocessing import normalize
from sklearn import manifold
from matplotlib import pyplot as plt
from matplotlib.lines import Line2D
import numpy
import itertools
f, axes = plt.subplots(7, 1, sharex='col', sharey='row', figsize=(15, 30))
distance = []
for i in range(7):
delta = numpy.random.randint(0, 100, (100, 100))
axes[i].scatter(delta[:, 0], delta[:, 1], marker='x', c='r', s=50, edgecolor='None')
axes[i].set_title('Simulation '+str(i+1), fontsize=20)
axes[i].set_ylim(0, 100)
markers = []
plt.tight_layout()
plt.axis('equal')

Your 1st line
f, axes = plt.subplots(7, 1, sharex='col', sharey='row', figsize=(15, 30))
has an inappropriate value for the sharey parameter. Using sharey='row' you're asking that all the subplots in each row share the same y axis, but each of your subplots is in a row by itself, so you see no sharing.
If you try sharey=True or sharey='col' you'll get what you want.
Addendum
The following code
In [34]: a = np.random.random(21)
In [35]: b = a+5
In [36]: x = np.arange(21)
In [37]: f, (ax, bx) = plt.subplots(2,1,sharey='row') # like yours
In [38]: ax.plot(x,a)
Out[38]: [<matplotlib.lines.Line2D at 0x7f5b98004f98>]
In [39]: bx.plot(x,b)
Out[39]: [<matplotlib.lines.Line2D at 0x7f5b980238d0>]
In [40]: f, (ax, bx) = plt.subplots(2,1,sharey='col') # like mine
In [41]: ax.plot(x,a)
Out[41]: [<matplotlib.lines.Line2D at 0x7f5b94764dd8>]
In [42]: bx.plot(x,b)
Out[42]: [<matplotlib.lines.Line2D at 0x7f5b98038198>]
In [43]:
gives me the following two plots. Can you spot a single difference?

You have to add a line axes[i].set_ylim(ymin,ymax) within the main loop where you make the plot. For example, below the following line
axes[i].set_title('Simulation '+str(i+1), fontsize=20)
add:
axes[i].set_ylim(-1,1)
That should solve it.
In your example, you are calling plt.ylim instead, but from the documentation "Get or set the y-limits of the current axes", which in your case correspond to the last axes.
Answer to the minimalist example:
As you see from your plot, all the axis but the last, have the same limits in the y-coordinate. Everytime you call plt.*, you affect the behaviour of the last axis. Your last call to plt.axis('equal') is what affects the last plot. Just remove this line.

Related

Adding a stacked plot as a subplot in python

Please I need help with a plot. I am making a 3x3 dimension figure containing 7 subplots. I want two(2) of the subplots (ax6 and ax7) to be stacked plots. Does anyone have an idea how I can make this work? I used the code below to make the grid.
fig = plt.figure()
fig.set_figheight(8)
fig.set_figwidth(10)
gs = gridspec.GridSpec(3, 3)
ax1 = plt.subplot(gs[0, 0])
ax2 = plt.subplot(gs[0, -2])
ax3 = plt.subplot(gs[0, -1])
ax4 = plt.subplot(gs[1, 0])
ax5 = plt.subplot(gs[-1, 0])
ax6 = plt.subplot(gs[1:, -2])
ax7 = plt.subplot(gs[1:, -1])
I tried making the stacked plot for ax6 using the code below
ax6[0].plot(s[['xa']], s[['ac1']], label = "Data")
ax6[0].plot(s[['xa']], s[['ac2']], label = "C-C")
ax6[0].plot(s[['xa']], s[['ac3']], label = "C-O")
ax6[0].plot(s[['xa']], s[['ac4']], label = "C=C")
ax6[0].plot(s[['xa']], s[['ea1']], label = "Envelope")
ax6[0].text(0.08, 0.70, 'C', ha='center', va='baseline', wrap=True, fontsize= 10, fontweight='bold', color='darkgreen', transform=ax6[0].transAxes)
ax6[1].plot(s[['xb']], s[['bc1']], label = "Data")
ax6[1].plot(s[['xb']], s[['bc2']], label = "C-C")
ax6[1].plot(s[['xb']], s[['bc3']], label = "C-O")
ax6[1].plot(s[['xb']], s[['bc4']], label = "C=C")
ax6[1].plot(s[['xb']], s[['be1']], label = "Envelope")
ax6[1].text(0.08, 0.70, 'm.C', ha='center', va='baseline', wrap=True, fontsize= 10, fontweight='bold', color='darkgreen', transform=ax6[1].transAxes)
Please look at the comments in the code:
import matplotlib.pyplot as plt
from matplotlib import gridspec
import numpy as np
fig = plt.figure(figsize=(10, 8))
g = gridspec.GridSpec(3, 3)
ax1 = plt.subplot(g[0, 0])
ax2 = plt.subplot(g[0, 1])
ax3 = plt.subplot(g[0, 2])
ax4 = plt.subplot(g[1, 0])
ax5 = plt.subplot(g[2, 0])
# Create another grid
g2 = gridspec.GridSpec(3, 3)
g2.update(hspace=0.00)
# Generate data for three subplots in g2
x = np.linspace(0, 2 * np.pi, 400)
ya = np.sin(x)
yb = np.cos(x)
y7 = np.sin(x) ** 2
# Get three different Axes objects
ax6a = plt.subplot(g2[1, 1])
ax6b = plt.subplot(g2[2, 1], sharex=ax6a)
ax7 = plt.subplot(g2[1:, -1])
# Hide the xticklabels of top subplot in the shared plots
plt.setp(ax6a.get_xticklabels(), visible=False)
# Set xticks for lower subplots in the shared plots
ax6b.set_xticks(np.pi * np.array([0, 1/2, 1, 3/2, 2]))
# Try plotting
ax6a.plot(x, ya)
ax6b.plot(x, yb, 'g')
ax7.plot(x, y7, 'r')
plt.tight_layout()
plt.show()
This gives:
This answer was motivated by this answer and examples from older documentation of matplotlib.
If you want ax7 (red color subplot here) represented in to two separate subplots, either create a new Gridspec or use g depending on attributes you want to assign them e.g. in the code above:
# ax7 = plt.subplot(g2[1:, -1])
# ax7.plot(x, y7, 'r')
ax7a = plt.subplot(g[1, 2])
ax7b = plt.subplot(g[2, 2])
ax7a.plot(x, y7, 'r')
ax7b.plot(x, y7, 'r')
This gives:

Is there a way a save plot generated by causalimpact in python?

Below is the sample code
import pandas as pd
from causalimpact import CausalImpact
data = pd.read_csv('https://raw.githubusercontent.com/WillianFuks/tfcausalimpact/master/tests/fixtures/arma_data.csv')[['y', 'X']]
data.iloc[70:, 0] += 5
pre_period = [0, 69]
post_period = [70, 99]
ci = CausalImpact(data, pre_period, post_period)
ci.plot()
I wanted to write above generated plot to html or atleast save as image . Is there any solution as type of ci.plot() is nonetype .
https://github.com/WillianFuks/tfcausalimpact
A very dirty (but working) solution would be to:
Get the code of ci.plot() using inspect
import inspect
print(inspect.getsource(ci.plot))
Create a new function based on ci.plot() which actually saves the plot
(or probably it's possible to rewrite the method of the class).
In my case it's function plot2 with a new parameter path.
Its only difference from the original function is the last line.
def plot2(self, path, panels=['original', 'pointwise', 'cumulative'], figsize=(15, 12)):
"""Plots inferences results related to causal impact analysis.
Args
----
panels: list.
Indicates which plot should be considered in the graphics.
figsize: tuple.
Changes the size of the graphics plotted.
Raises
------
RuntimeError: if inferences were not computed yet.
"""
plt = self._get_plotter()
fig = plt.figure(figsize=figsize)
if self.summary_data is None:
raise RuntimeError('Please first run inferences before plotting results')
valid_panels = ['original', 'pointwise', 'cumulative']
for panel in panels:
if panel not in valid_panels:
raise ValueError(
'"{}" is not a valid panel. Valid panels are: {}.'.format(
panel, ', '.join(['"{}"'.format(e) for e in valid_panels])
)
)
# First points can be noisy due approximation techniques used in the likelihood
# optimizaion process. We remove those points from the plots.
llb = self.trained_model.filter_results.loglikelihood_burn
inferences = self.inferences.iloc[llb:]
intervention_idx = inferences.index.get_loc(self.post_period[0])
n_panels = len(panels)
ax = plt.subplot(n_panels, 1, 1)
idx = 1
if 'original' in panels:
ax.plot(pd.concat([self.pre_data.iloc[llb:, 0], self.post_data.iloc[:, 0]]),
'k', label='y')
ax.plot(inferences['preds'], 'b--', label='Predicted')
ax.axvline(inferences.index[intervention_idx - 1], c='k', linestyle='--')
ax.fill_between(
self.pre_data.index[llb:].union(self.post_data.index),
inferences['preds_lower'],
inferences['preds_upper'],
facecolor='blue',
interpolate=True,
alpha=0.25
)
ax.grid(True, linestyle='--')
ax.legend()
if idx != n_panels:
plt.setp(ax.get_xticklabels(), visible=False)
idx += 1
if 'pointwise' in panels:
ax = plt.subplot(n_panels, 1, idx, sharex=ax)
ax.plot(inferences['point_effects'], 'b--', label='Point Effects')
ax.axvline(inferences.index[intervention_idx - 1], c='k', linestyle='--')
ax.fill_between(
inferences['point_effects'].index,
inferences['point_effects_lower'],
inferences['point_effects_upper'],
facecolor='blue',
interpolate=True,
alpha=0.25
)
ax.axhline(y=0, color='k', linestyle='--')
ax.grid(True, linestyle='--')
ax.legend()
if idx != n_panels:
plt.setp(ax.get_xticklabels(), visible=False)
idx += 1
if 'cumulative' in panels:
ax = plt.subplot(n_panels, 1, idx, sharex=ax)
ax.plot(inferences['post_cum_effects'], 'b--',
label='Cumulative Effect')
ax.axvline(inferences.index[intervention_idx - 1], c='k', linestyle='--')
ax.fill_between(
inferences['post_cum_effects'].index,
inferences['post_cum_effects_lower'],
inferences['post_cum_effects_upper'],
facecolor='blue',
interpolate=True,
alpha=0.25
)
ax.grid(True, linestyle='--')
ax.axhline(y=0, color='k', linestyle='--')
ax.legend()
# Alert if points were removed due to loglikelihood burning data
if llb > 0:
text = ('Note: The first {} observations were removed due to approximate '
'diffuse initialization.'.format(llb))
fig.text(0.1, 0.01, text, fontsize='large')
plt.savefig(path)
Call the new function instead:
plot2(ci, 'myplot.png')

How to fill the area of different classes in scatter plot matplotlib?

I am plotting my pandas data using matplotlib, My plot looks like this:
There are four classes in the dataset. I want to color the backgroud area for each class, something like this
My matplotlib code looks like this:
import pandas as pd
df = pd.read_csv('normalized.csv')
fig = plt.figure(figsize=(8,8))
plt.scatter(df['p1'], df['p2'], c= list(df['cs']), alpha=0.9)
plt.show()
I also tried sns for this:
import pandas as pd
df = pd.read_csv('normalized.csv')
sn.FacetGrid(df, hue="cs", size = 8).map(plt.scatter, "p1", "p2").add_legend()
plt.show()
How I can fill the backgroud area for four classes in any of module?
A filled contour could serve as background:
import numpy as np
import matplotlib.pyplot as plt
N = 100
M = 4
points = np.random.normal(np.tile(np.random.uniform(1, 10, 2 * M), N)).reshape(-1, 2)
group = np.tile(np.arange(M), N)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 5), sharey=True, sharex=True)
cmap = plt.cm.get_cmap('tab10', 4)
ax1.scatter(points[:, 0], points[:, 1], c=group, cmap=cmap)
ax2.scatter(points[:, 0], points[:, 1], c=group, cmap=cmap)
ax2.tricontourf(points[:, 0], points[:, 1], group, levels=np.arange(-0.5, 4), zorder=0, cmap=cmap, alpha=0.3)
plt.show()
Note that the contour plot also creates some narrow zones of inbetween values, because it only looks at numeric values and supposes that between a zone 0 and a zone 2 there must exist some small zone 1.
A bit more involved approach uses a nearest neighbor fit:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import neighbors
N = 100
M = 4
points = np.random.normal(np.tile(np.random.uniform(1, 10, 2 * M), N)).reshape(-1, 2)
groups = np.tile(np.arange(M), N)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(14, 5), sharey=True, sharex=True)
cmap = ListedColormap(['orange', 'cyan', 'cornflowerblue', 'crimson'])
ax1.scatter(points[:, 0], points[:, 1], c=groups, cmap=cmap)
ax2.scatter(points[:, 0], points[:, 1], c=groups, cmap=cmap)
clf = neighbors.KNeighborsClassifier(10)
clf.fit(points, groups)
x_min, x_max = points[:, 0].min() - 1, points[:, 0].max() + 1
y_min, y_max = points[:, 1].min() - 1, points[:, 1].max() + 1
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 50),
np.linspace(y_min, y_max, 50))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
ax2.imshow(Z, extent=[x_min, x_max, y_min, y_max], cmap=cmap, alpha=0.3, aspect='auto', origin='lower')
plt.show()
If you don't need to fill the space and do not bother about areas overlap (your data points show some overlap) then you can try to fill out the convex hull defined by each subset.
import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull
N = 100
points = [np.random.normal(np.tile(np.random.uniform(1, 5, 2), N)).reshape(-1, 2) for i in range(4)]
colors = ['r', 'g', 'b', 'k']
for k in range(4):
hull = ConvexHull(points[k])
plt.plot(points[k][:,0], points[k][:,1], '.', color = colors[k])
plt.fill(points[k][hull.vertices,0], points[k][hull.vertices,1], color = colors[k], alpha=0.3)
stack.imgur.com/2562R.png

How to create an ax.legend() method for contourf plots that doesn't require passing of legend handles from a user?

Desired feature
I would like to be able to call
ax.legend()
on an axis containing a contourf plot and automatically get the legend (see plot below for an example).
More Detail
I know how to create legend entries for contourf plots using proxies, see code below and which is already discussed in this Q&A. However, I would be interested in a solution where the final call to axes[0][-1].legend() does not require any handles being passed.
The plot generation (more complex plots than in this example) is happening in a package and the user will have access to fig and axes and depending on the plots might prefer some axis over the others to plot the legend in. It would be nice if the call to ax.legend() could be simple and would not require the use of proxies and explicit passing of handles. This works automatically for normal plots, scatter plots, hists, etc., but contourf does not accept label as a kwarg and does not come with its own handle so I need to create a proxy (Rectangle patch in this case).
But how could I attach/attribute/... the proxy alongside a label to the contourf plot or to the axes such that ax.legend() can automatically access them the way it does for other types of plots?
Example Image
Example Code
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.colors import LinearSegmentedColormap
########################
# not accessed by User #
########################
def basic_cmap(color):
return LinearSegmentedColormap.from_list(color, ['#ffffff', color])
cmap1 = basic_cmap('C0')
cmap2 = basic_cmap('C1')
x = np.linspace(0, 10, 50)
mvn1 = stats.multivariate_normal(mean=[4, 4])
mvn2 = stats.multivariate_normal(mean=[6, 7])
X, Y = np.meshgrid(x, x)
Z1 = [[mvn1.pdf([x1, x2]) for x1 in x] for x2 in x]
Z2 = [[mvn2.pdf([x1, x2]) for x1 in x] for x2 in x]
Z1 = Z1 / np.max(Z1)
Z2 = Z2 / np.max(Z2)
fig, axes = plt.subplots(2, 2, sharex='col', sharey='row')
for i, row in enumerate(axes):
for j, ax in enumerate(row):
cont1 = ax.contourf(X, Y, Z1, [0.05, 0.33, 1], cmap=cmap1, alpha=0.7)
cont2 = ax.contourf(X, Y, Z2, [0.05, 0.33, 1], cmap=cmap2, alpha=0.7)
###################################
# User has access to fig and axes #
###################################
proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33), alpha=0.7, linewidth=3)
proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33), alpha=0.7, linewidth=3)
# would like this without passing of handles and labels
axes[0][-1].legend(handles=[proxy1, proxy2], labels=['foo', 'bar'])
plt.savefig("contour_legend.png")
plt.show()
Well, I dappled a bit more and found a solution after all that's surprisingly simple, but I had to dig much deeper into matplotlib.legend to get the right idea. In _get_legend_handles it shows how it collects the handles:
for ax in axs:
handles_original += (ax.lines + ax.patches +
ax.collections + ax.containers)
So all I was lacking was to pass the labels to the proxies and the proxies to ax.patches
Example Code with Solution
changes
# pass labels to proxies and place proxies in loop
proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33),
alpha=0.7, linewidth=3, label='foo')
proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33),
alpha=0.7, linewidth=3, label='bar')
# pass proxies to ax.patches
ax.patches += [proxy1, proxy2]
###################################
# User has access to fig and axes #
###################################
# no passing of handles and labels anymore
axes[0][-1].legend()
full code
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.colors import LinearSegmentedColormap
########################
# not accessed by User #
########################
def basic_cmap(color):
return LinearSegmentedColormap.from_list(color, ['#ffffff', color])
cmap1 = basic_cmap('C0')
cmap2 = basic_cmap('C1')
x = np.linspace(0, 10, 50)
mvn1 = stats.multivariate_normal(mean=[4, 4])
mvn2 = stats.multivariate_normal(mean=[6, 7])
X, Y = np.meshgrid(x, x)
Z1 = [[mvn1.pdf([x1, x2]) for x1 in x] for x2 in x]
Z2 = [[mvn2.pdf([x1, x2]) for x1 in x] for x2 in x]
Z1 = Z1 / np.max(Z1)
Z2 = Z2 / np.max(Z2)
fig, axes = plt.subplots(2, 2, sharex='col', sharey='row')
for i, row in enumerate(axes):
for j, ax in enumerate(row):
cont1 = ax.contourf(X, Y, Z1, [0.05, 0.33, 1], cmap=cmap1, alpha=0.7)
cont2 = ax.contourf(X, Y, Z2, [0.05, 0.33, 1], cmap=cmap2, alpha=0.7)
# pass labels to proxies and place proxies in loop
proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33),
alpha=0.7, linewidth=3, label='foo')
proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33),
alpha=0.7, linewidth=3, label='bar')
# pass proxies to ax.patches
ax.patches += [proxy1, proxy2]
###################################
# User has access to fig and axes #
###################################
# no passing of handles and labels anymore
axes[0][-1].legend()
plt.savefig("contour_legend_solved.png")
plt.show()
This produces the same image as shown in the question.
Sorry, was able to come up with a solution on my own after all, but maybe this will be helpful for someone else in the future.

Make a frame with subplots in Matplotlib

I want to make a figure which consist of a frame with 4 figures, but in each figure there are three subplots. I am using the current version of Matplotlib
I show my code in order to do each individual figure, the point as I comment before, is how put 4 of this plots together in order to make a single figure
filename1 = "file1.txt"
filename2 = "file2.txt"
filename3 = "file3.txt"
datalist1 = np.loadtxt(filename1)
datalist2 = np.loadtxt(filename2)
datalist3 = np.loadtxt(filename3)
f, (ax1, ax2, ax3) = plt.subplots(3, sharex=True, sharey=True)
#First subplot
ax1.plot(datalist1[:,0], datalist1[:,1], 'k-')
ax1.plot(datalist2[:,0], datalist2[:,1], 'b-')
ax1.plot(datalist2[:,0], datalist2[:,2], 'g-')
ax1.plot(datalist2[:,0], datalist2[:,3], 'r-')
ax1.plot(datalist3[:,0], datalist3[:,1], 'k--')
ax1.set_ylim(-1.2, 1.2)
ax1.set_xlim(0, 10)
major_ticks_x = np.arange(0.0, 11, 2.0)
minor_ticks_x = np.arange(0.0, 11, 1.0)
major_ticks_y = np.arange(-1, 1.05, 1.0)
minor_ticks_y = np.arange(-1, 1.05, 0.25)
ax1.set_yticks(major_ticks_y)
ax1.set_yticks(minor_ticks_y, minor=True)
#Second subplot
ax2.plot(datalist1[:,0], datalist1[:,2], 'k-')
ax2.plot(datalist2[:,0], datalist2[:,4], 'b-')
ax2.plot(datalist2[:,0], datalist2[:,5], 'g-')
ax2.plot(datalist2[:,0], datalist2[:,6], 'r-')
ax2.plot(datalist3[:,0], datalist3[:,1], 'k--')
ax2.set_ylim(-1.2, 1.2)
ax2.set_xlim(0, 10)
ax2.set_yticks(major_ticks_y)
ax2.set_yticks(minor_ticks_y, minor=True)
#Third subplot
ax3.plot(datalist1[:,0], datalist1[:,3], 'k-')
ax3.plot(datalist2[:,0], datalist2[:,7], 'b-')
ax3.plot(datalist2[:,0], datalist2[:,8], 'g-')
ax3.plot(datalist2[:,0], datalist2[:,9], 'r-')
ax3.plot(datalist3[:,0], datalist3[:,1], 'k--')
ax3.set_ylim(-1.2, 1.2)
ax3.set_xlim(0, 10)
ax3.set_yticks(major_ticks_y)
ax3.set_yticks(minor_ticks_y, minor=True)
ax3.set_xticks(major_ticks_x)
ax3.set_xticks(minor_ticks_x, minor=True)
ax3.set_xlabel(r"$t$")
f.subplots_adjust(hspace=0.0)
plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)
The plot that I want to obtain is somtehing like this, in a single figure:
Somebody knows how can be do it?? Thanks for your attention.
OK, I'll bite. It is unclear what you want, but I assume you want 12 subplots (6 rows, 2 columns) grouped into 4 groups with shared x-axis.
As usual creating the subplots and plotting is easy. Sharing x-axis is straightforward as well, but requires some manual work. You can either set up the shared x-axis during the subplot creation or modify it after. I think modifying after is simpler.
Sorry for the manual part in the middle - it is possible to automate obviously.
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
fig, axx = plt.subplots(6, 2, figsize=(10,14))
## merge axis
axx[0, 0].get_shared_x_axes().join(axx[0, 0], axx[2, 0])
axx[0, 0].set_xticklabels([])
axx[1, 0].get_shared_x_axes().join(axx[1, 0], axx[2, 0])
axx[1, 0].set_xticklabels([])
axx[0, 1].get_shared_x_axes().join(axx[0, 1], axx[2, 1])
axx[0, 1].set_xticklabels([])
axx[1, 1].get_shared_x_axes().join(axx[1, 1], axx[2, 1])
axx[1, 1].set_xticklabels([])
axx[3, 0].get_shared_x_axes().join(axx[3, 0], axx[5, 0])
axx[3, 0].set_xticklabels([])
axx[4, 0].get_shared_x_axes().join(axx[4, 0], axx[5, 0])
axx[4, 0].set_xticklabels([])
axx[3, 1].get_shared_x_axes().join(axx[3, 1], axx[5, 1])
axx[3, 1].set_xticklabels([])
axx[4, 1].get_shared_x_axes().join(axx[4, 1], axx[5, 1])
axx[4, 1].set_xticklabels([])
# plot some data
for i, row in enumerate(axx):
for j, cell in enumerate(row):
if i <= 2:
cell.plot(np.random.rand(100))
else:
cell.plot(np.random.rand(200))
Here is the result.

Categories