I have created 2 different figures(Fig1 and Fig2) in mathplotlib and saved them in pdf. Can anybody help me how to merger these 2 figures and create single figure. fig1 and fig2 has same x-Axis.
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
def lc_fslg(target,position,axes,titel,exc_true,l_pos):
for axi in axes:
pp = PdfPages('output\ ' + 'lc_over_fuselage_'+ axi + '.pdf')
plt.figure()
plt.axis('off')
plt.text(0.5, 0.5, titel+str(axi), ha='center', va='center')
pp.savefig()
plt.close()
for kind in ['ground','flight']:
plot_load_flow(target, position, kind, axi.lower(), titel, exc_true, l_pos)
plt.savefig(pp, format='pdf', papertype='a4', orientation='landscape', bbox_inches='tight')
plt.close('all')
pp.close()
def plot_load_flow(target,position,kind,axe,titel,exc_true,l_pos):
d_ax_label = {'tx': 'Tx [daN]', 'ty': 'Ty [daN]', 'tz': 'Tz [daN]'
, 'mx': 'Mx [daNm]', 'my': 'My [daNm]', 'mz': 'Mz [daNm]'}
max_v=[]
min_v=[]
max_vM=[]
min_vM=[]
pos_env=[]
if(kind == 'ground'):
for pos in l_pos:
load_at_pos = target.uload_at(pos)
max = load_at_pos[axe].loc[(load_at_pos['position'] == pos) & (load_at_pos['type'] == 'X')].max()
min = load_at_pos[axe].loc[(load_at_pos['position'] == pos) & (load_at_pos['type'] == 'X')].min()
if(not(np.isnan(max))& (not(np.isnan(min)))):
max_v.append(max)
min_v.append(min)
pos_env.append(pos)
x_env = [position[pos] for pos in pos_env]
plt.clf()
fig1 = plt.figure(figsize=(15, 15))
plt.plot(x_env, max_v, 'b-', markersize=15,linewidth=3.5, label='envelope '+str(kind))
plt.plot(x_env, min_v, 'b-', markersize=15,linewidth=3.5)
if(kind == 'flight'):
for pos in l_pos:
load_at_pos = target.uload_at(pos)
max = load_at_pos[axe].loc[(load_at_pos['position'] == pos)
& ((load_at_pos['type'] == 'G') | (load_at_pos['type'] == 'M'))].max()
min = load_at_pos[axe].loc[(load_at_pos['position'] == pos)
& ((load_at_pos['type'] == 'G') | (load_at_pos['type'] == 'M'))].min()
if (not (np.isnan(max)) & (not (np.isnan(min)))):
max_vM.append(max)
min_vM.append(min)
pos_env.append(pos)
x_env = [position[pos] for pos in pos_env]
plt.clf()
fig2 = plt.figure(figsize=(15, 15))
plt.plot(x_env, max_v, 'b-', markersize=15,linewidth=3.5, label='envelope '+str(kind))
plt.plot(x_env, min_v, 'b-', markersize=15,linewidth=3.5)
plt.plot(x_env, max_vM, 'g-', markersize=15,linewidth=3.5, label='envelope '+str(kind))
plt.plot(x_env, min_vM, 'g-', markersize=15,linewidth=3.5)
# define plot layout
plt.yticks(fontsize=20)
plt.ylabel(d_ax_label[axe], fontsize=30)
plt.xticks(fontsize=20)
plt.xticks(x_env,pos_env,fontsize=20,rotation='vertical')
plt.xlabel('frame position', fontsize=30)
plt.title(titel, fontsize=20)
legend = plt.legend(shadow=True, prop={'size': 20})
plt.grid(True)
plt.tight_layout()
Related
I'm trying to create the following plot in python:
Unfortunatelly, the positioning of the text seems to be very erratic, as when I try to move the text in the right panel to the right I get the following plot:
The code I am using the generate the plot is the following:
fig, ax = plt.subplots(figsize = (12,6), constrained_layout=True)
gs = fig.add_gridspec(1, 2, left=0.05, right=0.5, wspace=0.01)
plt.rcParams.update({'font.size': 12})
# plt.set_cmap('OrRd') # https://matplotlib.org/stable/tutorials/colors/colormaps.html
plt.set_cmap('binary')
ax.axis('off')
xmax = 20
color = 'red'
# Left plot
ax1 = fig.add_subplot(gs[0,0])
ax1.set_xlim([-0.5, xmax])
ax1.hist(data, bins = 11, density = True, color = color)
ax1.axes.get_yaxis().set_ticks([])
ax1.set_xlabel("S(m{}|m{})".format(D1,D2))
plt.gca().invert_xaxis()
# right plot
ax2 = fig.add_subplot(gs[0,1])
ax2.set_xlim([-0.5, xmax])
ax2.hist(data, bins = 14, density = True, color = color)
ax2.set_xlabel("S(m{}|m{})".format(D2,D1))
ax2.axes.get_yaxis().set_visible(False)
# legenda
textstr12 = '\n'.join((
"S(m{}|m{}) = {:.2f}".format(D1,D2, S12),
"D(m{}|m{}) = {:.2f}".format(D1,D2, D12),
"<D> = {:.2f}".format(exp_D12)))
textstr21 = '\n'.join((
"S(m{}|m{}) = {:.2f}".format(D2,D1, S21),
"D(m{}|m{}) = {:.2f}".format(D2,D1, D21),
"<D> = {:.2f}".format(exp_D21)))
# generate text
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
ax1.text(0.05, 0.95, textstr21, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props) #aqui irá mostrar a caixa na esquerda! por isso inverto para o caso S21.
################### line bellow is the buggy part
##### if I set ax2.text(0.57, 0.95, ...) I get the correct figure
ax2.text(0.97, 0.95, textstr12, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props)
plt.show()
I need to plot a graph with a lot of features, so I wrote a function for this purpose. I now want to plot 4 plots (2,2) when each of the subplot is a function that returns plot (g as an instance of seaborn).
I call the function this way:
g = comm_relplot(b53_communication,means_53,meanPstd_53,meanMstd_53)
and I tried:
fig, axs = plt.subplots(ncols=2, nrows = 2, figsize = (20,10))
axs[0,0] = comm_relplot(b53_communication,means_53,meanPstd_53,meanMstd_53)
but it's just plot it after the grid.
example for one function:
def control_relplot(control_data ,mean_c, meanPstd_c, meanMstd_c):
control = {'7':'Time spent with child',
'23':'Water preference'}
control_data['dates'] = control_data['submitted_at'].astype(str)
corr = control_data[['int_value_0','question_id','dates']]
corr1 = corr.copy()
for q in set(corr['question_id'].values):
for ind in corr.loc[corr['question_id'] == q].index:
if meanMstd_c[q] < corr.loc[ind,'int_value_0'] < meanPstd_c[q]:
corr1.loc[ind,'int_value_0'] = None
corr1 = corr1.dropna()
sns.set_style("white")
g = sns.relplot(x="dates", y="int_value_0", row="question_id", kind="line",
data=control_data, color = 'royalblue', linewidth= 3,
facet_kws={'sharey': False, 'sharex': True})
g.fig.set_size_inches(20,15)
g.fig.suptitle('B. Control 54', x=0.5, y=1.03, fontsize = 40)
for ax in g.axes.ravel():
ax.set_xticklabels(ax.get_xticklabels(), rotation=90, horizontalalignment='center',fontsize = 20)
x = []
for ticklabel in ax.get_xticklabels():
d = datetime.strptime(ticklabel.get_text(),'%Y-%m-%d')
d = d.strftime('%b-%d')
x.append(d)
ax.set_xticklabels(x)
#ax.set_yticklabels(ax.get_yticklabels(), fontsize = 12)
q = 7
for ax in g.axes:
data = corr1.loc[corr1['question_id'] == q]
ax[0].plot(data['dates'], data['int_value_0'], 'sr')
ax[0].axhline(mean_c[q], c = 'lightgray', linewidth = 1)
ax[0].axhline(meanPstd_c[q], ls = '--', c = 'gray')
ax[0].axhline(meanMstd_c[q], ls = '--', c = 'gray')
#ax[0].text(selff_data['dates'].max(), mean_c[q], 'mean', fontsize = 20)
if meanPstd_c[q] == meanMstd_c[q]:
ax[0].text(control_data['dates'].max(), meanPstd_c[q], 'mean', fontsize = 30)
else:
ax[0].text(control_data['dates'].max(), meanPstd_c[q], 'mean+std', fontsize = 30)
ax[0].text(control_data['dates'].max(), meanMstd_c[q], 'mean-std', fontsize = 30)
if meanPstd_c[q] < control_data.loc[control_data['question_id'] == q]['int_value_0'].max():
ax[0].set_ylim(top = control_data.loc[control_data['question_id'] == q]['int_value_0'].max()+0.5)
else:
ax[0].set_ylim(top = meanPstd_c[q]+0.5)
q = 23
for ax in g.axes.flat:
ax.set_xlabel(None)
ax.set_ylabel('score', fontsize=35)
ax.tick_params(axis='y', labelsize=30)
ax.tick_params(axis='x', labelsize=30)
if ax.get_title():
title_num = ax.get_title().split('= ')[1]
ax.set_title(ax.get_title().replace(ax.get_title(),control[title_num]),
fontsize=35, pad = 0.8, fontweight="bold")
plt.tight_layout(pad=1.08, h_pad=2)
return g '''
I need use Matplotlib to draw headmaps with chinese tick labels. But the result shows incomplete tick labels as below. I don't know why it happened. I tried to change other chinese font but doesn't work. How to fix it?
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['STZhongsong']
mpl.rcParams['axes.unicode_minus'] = True
def heatmap(data, row_labels, col_labels, ax=None,
cbar_kw={}, cbarlabel="", **kwargs):
if not ax:
ax = plt.gca()
im = ax.imshow(data, **kwargs)
cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)
cbar.ax.set_ylabel(cbarlabel, rotation=-90, va="bottom")
ax.set_xticks(np.arange(data.shape[1]))
ax.set_yticks(np.arange(data.shape[0]))
ax.set_xticklabels(col_labels)
ax.set_yticklabels(row_labels)
ax.tick_params(top=True, bottom=False,
labeltop=True, labelbottom=False)
plt.setp(ax.get_xticklabels(), rotation=-20, ha="right",
rotation_mode="anchor")
for edge, spine in ax.spines.items():
spine.set_visible(False)
ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)
ax.grid(which="minor", color="w", linestyle='-', linewidth=3)
ax.tick_params(which="minor", bottom=False, left=False)
return im, cbar
if __name__ == "__main__":
x,y = list("你这是干什么啦?"),list("你要吃什么?")
s = np.random.random([len(x), len(y)])
fig, ax = plt.subplots()
im, cbar = heatmap(s, x, y, ax=ax,
cmap="YlGn", cbarlabel="attention scores")
fig.tight_layout()
plt.savefig("test", dpi=300, bbox_inches = 'tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as mfm
import matplotlib.pyplot as plt
def heatmap(data, row_labels, col_labels, ax=None,
cbar_kw={}, cbarlabel="", **kwargs):
if not ax:
ax = plt.gca()
im = ax.imshow(data, **kwargs)
cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)
cbar.ax.set_ylabel(cbarlabel, rotation=-90, va="bottom")
ax.set_xticks(np.arange(data.shape[1]))
ax.set_yticks(np.arange(data.shape[0]))
font_path = "/Downloads/ZCOOLXiaoWei-Regular.ttf"
prop = mfm.FontProperties(fname=font_path)
ax.set_xticklabels(col_labels,fontproperties=prop,fontsize=50)
ax.set_yticklabels(row_labels,fontproperties=prop,fontsize=50)
ax.tick_params(top=True, bottom=False,
labeltop=True, labelbottom=False)
plt.setp(ax.get_xticklabels(), rotation=-20, ha="right",
rotation_mode="anchor")
for edge, spine in ax.spines.items():
spine.set_visible(False)
ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)
ax.grid(which="minor", color="w", linestyle='-', linewidth=3)
ax.tick_params(which="minor", bottom=False, left=False)
return im, cbar
if __name__ == "__main__":
x,y = list("你这是干什么啦"),list("你这是干什么啦")
s = np.random.random([len(x), len(y)])
fig, ax = plt.subplots(figsize=(10,10))
im, cbar = heatmap(s, x, y, ax=ax,
cmap="YlGn", cbarlabel="attention scores")
fig.tight_layout()
plt.savefig("test", dpi=300, bbox_inches = 'tight')
plt.show()
I have made few changes in the code and used the matplotlib.font_manager to render the Chinese font.
This is an example of my code to plot and save a figure:
I'm using Python 3.7.4 and matplotlib==3.0.3.
import matplotlib.pyplot as plt
import pandas as pd
from yahoo_fin import stock_info
import statsmodels.api as sm
brk_data = stock_info.get_data("BRK-A")
with plt.style.context('dark_background'):
fig, ax = plt.subplots(figsize=(16, 9))
sm.qqplot(brk_data['adjclose'].pct_change(1).fillna(0), fit=True, line='45', ax=ax)
plt.title('QQ Plot', fontsize = 16)
ax.axvline(0, c = 'w', linestyle = "--", alpha = 0.5)
ax.grid(True,linewidth=0.30)
ax.set_xlim(4,-4)
ax.set_ylim(5,-5)
plt.savefig('qqplot.png', bbox_inches = 'tight', pad_inches = 0.4, dpi = 300, edgecolor = 'k')
plt.show()
plt.close()
This code saves and displays the plot figure correctly, as follows:
But when the plot is built inside a function, the saved picture background will stay white, making the white ticks and labels from the 'dark-background' style invisible, e.g.:
for
def qqplot2(pct, save = False):
with plt.style.context('dark_background'):
fig, ax = plt.subplots(figsize=(16, 9))
sm.qqplot(pct, fit=True, line='45', ax=ax)
plt.title('QQ Plot', fontsize = 16)
ax.axvline(0, c = 'w', linestyle = "--", alpha = 0.5)
ax.grid(True,linewidth=0.30)
ax.set_xlim(4,-4)
ax.set_ylim(5,-5)
if save == True:
plt.savefig('qqplot2.png', bbox_inches = 'tight', pad_inches = 0.4, dpi = 300, edgecolor = 'k')
plt.show()
plt.close()
else:
plt.show()
calling the function with qqplot2(brk_data['adjclose'].pct_change(1).fillna(0), save = True) will display the correct plot:
but will save the figure incorrectly:
You just need to indent your if clause in the function like this:
def qqplot2(pct, save = False):
with plt.style.context('dark_background'):
fig, ax = plt.subplots(figsize=(16, 9))
sm.qqplot(pct, fit=True, line='45', ax=ax)
plt.title('QQ Plot', fontsize = 16)
ax.axvline(0, c = 'w', linestyle = "--", alpha = 0.5)
ax.grid(True,linewidth=0.30)
ax.set_xlim(4,-4)
ax.set_ylim(5,-5)
if save == True:
plt.savefig('qqplot2.png', bbox_inches = 'tight', pad_inches = 0.4, dpi = 300, edgecolor = 'k')
plt.show()
plt.close()
else:
plt.show()
I am trying to animate different objects in the same graph using pyplot's funcanimation.
It works almost as I expect it to, except for the order in which the different elements are displayed in. So the plot curve, text and legend are shown behind the image where they are barely seen.
Here is my (not so) minimal working example:
#! /usr/bin/python
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import random
def init():
line_simu.set_data([], [])
time_text.set_text('')
imobj.set_data(np.zeros((100, 100)))
imobj.set_zorder(0)
time_text.set_zorder(10)
return line_simu, time_text, imobj
def animate(i):
imobj.set_zorder(0)
time_text.set_zorder(10)
y_simu = np.linspace(0,100, 100)
x_simu = np.linspace(-10, 10, 100)
line_simu.set_data(x_simu, y_simu)
time_text.set_text('time = %.1f' % i )
global data
imobj.set_data( data + np.random.random((100,1)) * 0.5 )
return line_simu, time_text, imobj
def forceAspect(ax,aspect=1):
im = ax.get_images()
extent = im[0].get_extent()
ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect)
fig = plt.figure()
ax = plt.axes(xlim=(-15,15), ylim=(-110, 0) , aspect=1)
data = np.random.random((100,100)) - .5
imobj = ax.imshow( data , extent=[-15,15, -110, 0.0], origin='lower', cmap=plt.cm.gray, vmin=-2, vmax=2, alpha=.7, zorder=0, aspect=1)
line_simu, = ax.plot([], [],"r--", lw=2, markersize=4 , label = "Some curve" , zorder= 2 )
time_text = ax.text(-14.9, -108, '', zorder=10)
l = plt.legend(loc='lower right', prop={'size':8} )
l.set_zorder(200)
forceAspect(ax,aspect=1)
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=range( 50), interval=3000, blit=True)
plt.show()
Without animation, I can easily control the order of the different elements with set_zorder, but when the animation updates the image, this order is lost. I tried to set the zorder in the init function and again in the animate function, without success.
I am very thankful for any help on that matter.
To answer my own question: It seems that the order in witch the init() and animate() functions return objects controls the order in which they are displayed. Additionally those functions should return the legend object in order to include it in the animation.
Here is my corrected code:
#! /usr/bin/python
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import random
def init():
imobj.set_data(np.zeros((100, 100)))
line_simu.set_data([], [])
time_text.set_text('time = 0.0')
return imobj , line_simu, time_text, l
def animate(i):
global data
imobj.set_data( data + np.random.random((100,1)) * 0.5 )
imobj.set_zorder(0)
y_simu = np.linspace(-100,-10, 100)
x_simu = np.linspace(-10, 10, 100)
line_simu.set_data(x_simu, y_simu)
time_text.set_text('time = %.1f' % i )
return imobj , line_simu, time_text, l
def forceAspect(ax,aspect=1):
im = ax.get_images()
extent = im[0].get_extent()
ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect)
fig = plt.figure()
ax = plt.axes(xlim=(-15,15), ylim=(-110, 0) , aspect=1)
data = np.random.random((100,100)) - .5
imobj = ax.imshow( data , extent=[-15,15, -110, 0.0], origin='lower', cmap=plt.cm.gray, vmin=-2, vmax=2, alpha=1.0, zorder=1, aspect=1)
line_simu, = ax.plot([], [],"r--", lw=2, markersize=4 , label = "Some curve" , zorder= 1 )
time_text = ax.text(-14.0, -108, '', zorder=10)
forceAspect(ax,aspect=1)
l = plt.legend(loc='lower right', prop={'size':8} )
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=range( 50), interval=500, blit=True)
plt.show()