Force ylim range in subgraph - python-2.7

When plotting a serie of subgraphs with matplotlib, I can't set the ylim range properly.
Here's part of the code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
(...) # loading npy data
titles = ["basestr1", "basestr2", "basestr3", "basestr4", "basestr5"]
labels = ["baselab1", "baselab2", "baselab3", "baselab4", "baselab5"]
linew = 2.24
ms = 10
mw = 2
fc = (1,1,1)
bc = (1,1,1)
mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=[(1,0.4,0.4), (0.1,0.6,0.1), (0.04,0.2,0.04)])
mpl.rcParams.update({'font.size': 12})
fig2 = plt.subplots(2, 2, figsize=(12,9), facecolor=fc)
plt.rc('font', family='serif')
ax0 = plt.subplot(221)
ax1 = plt.subplot(222)
ax2 = plt.subplot(223)
ax3 = plt.subplot(224)
axl = [ax0, ax1, ax2, ax3]
em = []
fp = []
fn = []
gm = []
for c,element in enumerate(elements):
em.append([i[0] for i in element])
fp.append([i[1][1] if 1 in i[1] else 0 for i in element]) # red
fn.append([i[1][2] if 2 in i[1] else 0 for i in element]) # light green
gm.append([i[1][3] if 3 in i[1] else 0 for i in element]) # dark green
axl[c].semilogy(em[c], fp[c], "-x", lw=linew, markersize=ms, mew=mw) # red
axl[c].semilogy(em[c], fn[c], "-x", lw=linew, markersize=ms, mew=mw) # light green
axl[c].semilogy(em[c], gm[c], "-o", lw=linew, markersize=ms, mew=mw, mfc='None') # dark green
axl[c].set_ylim([-10, 200]) # <-- Here's the issue; it seems not to work properly.
axl[c].grid(True,which="both")
axl[c].set_title(titles[c])
axl[c].set_xlabel(labels[c])
axl[c].set_ylabel(r'Count')
plt.legend(['False', 'True', 'Others'], loc=3, bbox_to_anchor=(.62, 0.4), borderaxespad=0.)
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
plt.savefig('/home/username/Desktop/figure.png',
facecolor=fig2.get_facecolor(),edgecolor='w',orientation='landscape',papertype=None,
format=None, transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=None)
plt.show() # block=False
Where elements is a list containing 4 arrays.
Each of these array looks like:
elements[0]
Out[16]:
array([[1, {0.0: 1252, 1.0: 11, 2.0: 170, 3.0: 11}],
[2, {0.0: 1251, 1.0: 12, 2.0: 163, 3.0: 18}],
[3, {0.0: 1229, 1.0: 34, 2.0: 148, 3.0: 33}],
...,
[6, {0.0: 1164, 1.0: 99, 2.0: 125, 3.0: 56}],
[7, {0.0: 1111, 1.0: 152, 2.0: 105, 3.0: 76}],
[8, {0.0: 1056, 1.0: 207, 2.0: 81, 3.0: 100}]], dtype=object)
Where am I wrong?
I can set any values I want in axl[c].set_ylim([-10, 200]) it doesn't change anything on the output graph.
Update:
Ok, it seems not possible to set other value as 1 as starting y-axis value here.

Related

Pyplot Barchart: Bars not grouping around xticks properly

Im trying to group four bars around the xticks in a bar chart. Heres some sample data (mind you, Im running this in Python 2.7) and my code.
import matplotlib.pyplot as plt
import numpy as np
xps_s1 = range(2008, 2019)
xps_s2 = range(2012, 2019)
xps_s3 = range(2013, 2019)
xps_s4 = range(2014, 2019)
yps_s1 = [94.6, 93.9, 93, 94.7, 94.6, 95.4, 95, 93.6, 93, 93.6, 92.2]
yps_s2 = [81.5, 90.2, 91.5, 94, 95, 94.3, 95.3]
yps_s3 = [83.9, 92.7, 93.3, 94.4, 94.4, 94.6]
yps_s4 = [90.6, 95, 94.8, 94, 93.9]
y_means = [94.6, 93.9, 93, 94.7, np.mean([81.5, 94.6]),
np.mean([83.9, 90.2, 95.4]), np.mean([92.7, 91.5, 95, 90.6]),
np.mean([93.3, 94, 93.6, 95]), np.mean([94.4, 95, 93, 94.8]),
np.mean([94.4, 94.3, 93.6, 94]), np.mean([91.4, 94.6, 95.3, 92.2, 93.9])]
fig = plt.subplots()
ax = plt.axes(xlim=(2007,2019), ylim=(75, 100))
w = 0.2
plt.xticks(np.arange(2008, 2019, step = 1))
rects1 = ax.bar([x-w for x in xps_s1], yps_s1, width=w, align="center",
color='goldenrod', label='Sample1')
rects2 = ax.bar([x-w*2 for x in xps_s2], yps_s2, width=w, align="center",
color='grey', label='Sample2')
rects3 = ax.bar([x+w for x in xps_s3], yps_s3, width=w, align="center",
color='silver', label='Sample3')
rects4 = ax.bar([x+w*2 for x in xps_s4], yps_s4, width=w, align="center",
color='thistle', label='Sample4')
mean_line =ax.plot(xps_s1,y_means, label='Overall',
linestyle='-', color = "indianred")
legend = ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()
When I had three bars I set w = 0.3and the bars grouped nicely around the ticks (I had rects1 sit snuggly atop the tick, the other two right up against its flanks, the remaining .09 of width set the years apart)
Now with the above code they dont seem to be related to any tick really and they dont group properly.
What am I doing wrong?
Thanks a lot in advance!
I think you want to use align='edge' to simplify the calculations. Is this what you are trying to obtain?
import matplotlib.pyplot as plt
import numpy as np
xps_s1 = range(2008, 2019)
xps_s2 = range(2012, 2019)
xps_s3 = range(2013, 2019)
xps_s4 = range(2014, 2019)
yps_s1 = [94.6, 93.9, 93, 94.7, 94.6, 95.4, 95, 93.6, 93, 93.6, 92.2]
yps_s2 = [81.5, 90.2, 91.5, 94, 95, 94.3, 95.3]
yps_s3 = [83.9, 92.7, 93.3, 94.4, 94.4, 94.6]
yps_s4 = [90.6, 95, 94.8, 94, 93.9]
y_means = [94.6, 93.9, 93, 94.7, np.mean([81.5, 94.6]),
np.mean([83.9, 90.2, 95.4]), np.mean([92.7, 91.5, 95, 90.6]),
np.mean([93.3, 94, 93.6, 95]), np.mean([94.4, 95, 93, 94.8]),
np.mean([94.4, 94.3, 93.6, 94]), np.mean([91.4, 94.6, 95.3, 92.2, 93.9])]
fig = plt.subplots()
ax = plt.axes(xlim=(2007,2019), ylim=(75, 100))
w = 0.2
plt.xticks(np.arange(2008, 2019, step = 1))
rects1 = ax.bar([x-w for x in xps_s1], yps_s1, width=w, align="edge",
color='goldenrod', label='Sample1')
rects2 = ax.bar([x-w*2 for x in xps_s2], yps_s2, width=w, align="edge",
color='grey', label='Sample2')
rects3 = ax.bar([x for x in xps_s3], yps_s3, width=w, align="edge",
color='silver', label='Sample3')
rects4 = ax.bar([x+w for x in xps_s4], yps_s4, width=w, align="edge",
color='thistle', label='Sample4')
mean_line =ax.plot(xps_s1,y_means, label='Overall',
linestyle='-', color = "indianred")
legend = ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()

Arbitrary number of 3d points how to zip to get x,y,z for plotting

I'm trying to plot a figure in 3D given an arbitrary number of points
import numpy as np
p = [
np.array([ 0.0, 0.0, 0.0]),
np.array([10.0, 0.0,10.0]),
np.array([10.0,21.0,10.0]),
np.array([14.5,25.5,14.5]),
np.array([ 0.0,40.0, 0.0]),
np.array([36.0,40.0, 0.0])]
... up to p[14]
section1 = [4, 0,1,2,3,4]
section2 = [8,14,1,2,8]
I need to combine p[4],p[0],p[1],p[2],p[3],p[4] and zip them to get the X,Y,Z I need to plot the lines.
I've been reduced to:
X=[]
Y=[]
Z=[]
for i in range(len(section1)):
X.append(p[section1[i]][0])
Y.append(p[section1[i]][1])
Z.append(p[section1[i]][2])
Whenever I put the points in a list and zip it, I get a strange list of the original points.
What is the right way to do it?
Your p is a list of arrays:
In [566]: p = [
...: np.array([ 0.0, 0.0, 0.0]),
...: np.array([10.0, 0.0,10.0]),
...: np.array([10.0,21.0,10.0]),
...: np.array([14.5,25.5,14.5]),
...: np.array([ 0.0,40.0, 0.0]),
...: np.array([36.0,40.0, 0.0])]
In [567]: len(p)
Out[567]: 6
In [568]: section1 = [4, 0,1,2,3,4]
I can convert that into a 2d array with np.stack:
In [569]: arr = np.stack(p)
In [570]: arr.shape
Out[570]: (6, 3)
Then it's easy to select rows with the section1 list:
In [571]: arr[section1,:]
Out[571]:
array([[ 0. , 40. , 0. ],
[ 0. , 0. , 0. ],
[ 10. , 0. , 10. ],
[ 10. , 21. , 10. ],
[ 14.5, 25.5, 14.5],
[ 0. , 40. , 0. ]])
X = arr[section1,0] and so on. Though for plotting you might not need to separate out the columns.
Here is a way to do that:
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
p=np.random.rand(50,3)
section=[[21, 13, 2, 36, 20, 15,21],[7, 14, 19, 32,7]]
fig = plt.figure()
ax = fig.gca(projection='3d')
color=['red','blue']
for i in range(2):
x,y,z=p[section[i]].T
ax.plot(x,y,z,color[i])
plt.show()
For :

Matplotlib: xticks labels not showing

I'm new to matplotlib and I'm having a small problem. I'm trying to make 3 plots stacked on top of each other, sharing the x axis and with 2 different y axis.
This is my current code
import numpy as np
import matplotlib.pyplot as plt
periods = range(1,13)
n0 = [4.2, 6.7, 10.6, 51.3, 339, 45.6, 56.3, 112.9, 182.7, 185.7, 126.2, 25.39]
alp = [2.12, 2.14, 2.19, 2.35, 2.54, 2.33, 2.34, 2.43, 2.45, 2.46, 2.466, 2.249]
B = [0.045, 0.041, 0.04, 0.04, 0.057, 0.048, 0.044, 0.057, 0.054, 0.065, 0.06, 0.045]
emin = [166, 201.9, 215, 270.7, 351.8, 263.7, 302.2, 323.6, 328.7, 346.1, 279.5, 259.8]
emax = [21806, 28407, 5706, 22087, 17978, 11699, 19440, 17988, 26938, 14812, 14195, 26121]
eq = [7.8, 11.8, 13.3, 15.2, 8.87, 10.5, 13.8, 7.6, 11.5, 7.4, 6.4, 13.5]
f, (ax1, ax2, ax3) = plt.subplots(3, sharex = True)
ax1.scatter(periods, emin, c="k")
ax1.set_ylabel(r"$E_{min}")
ax1.yaxis.set_ticks(range(160, 380, 40))
ax4 = ax1.twinx()
ax4.scatter(periods, n0, c="r")
ax4.set_ylabel(r"$N_0$", color = 'r')
ax4.tick_params(colors = 'r')
ax4.yaxis.set_ticks(np.arange(20, 340, 50))
ax2.scatter(periods, emax, c="k")
ax2.set_ylabel(r"$E_{max}$")
ax2.yaxis.set_ticks(np.arange(5000, 30000, 5000))
ax5 = ax2.twinx()
ax5.scatter(periods, alpha, c="r")
ax5.set_ylabel("alp", color = 'r')
ax5.tick_params(colors = 'r')
ax5.yaxis.set_ticks(np.arange(2.1, 2.6, 0.1))
ax3.scatter(periods, eq, c="k")
ax3.set_ylabel("Eq")
ax3.yaxis.set_ticks(np.arange(6, 15, 2))
ax3.set_xlabel("Periods")
ax6 = ax3.twinx()
ax6.scatter(periods, B, c="r")
ax6.set_ylabel("B", color = 'r')
ax6.tick_params(colors = 'r')
ax6.yaxis.set_ticks(np.arange(0.02, 0.09, 0.02))
ax6.xaxis.set_ticks(range(1,13))
f.subplots_adjust(hspace = 0)
plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)
plt.show()
But the x axis labels are not being shown. The label itself ("Periods") is fine, but the ticks aren't. I've tried to change the line
ax6.xaxis.set_ticks(range(1,13))
to every other number, but still doesn't work. Any help?
On a side note, how to rotate the y axis labels by 90 degrees so that they are horizontal? I've tried including rotation = 90 in the ylabel but it doesn't change (though other values work).
Thanks a lot
Edit: Forgot to add, if I erase the twinx axes it works fine
In order for your x ticks to appear you need to change the second to last line and set visible = True. In order to rotate the y labels by 90 degrees, use rotation = as you are doing, but set the rotation to 0. Doing this may make your labels and your ticks overlap. You can remove this by using the labelpad = in your ax.set_ylabel(). This is the spacing between the axis and the label.
f, (ax1, ax2, ax3) = plt.subplots(3, sharex = True)
ax1.scatter(periods, emin, c="k")
ax1.set_ylabel(r"$E_{min}$",rotation=0,labelpad=20)
ax1.yaxis.set_ticks(range(160, 380, 40))
ax4 = ax1.twinx()
ax4.scatter(periods, n0, c="r")
ax4.set_ylabel(r"$N_0$", color = 'r',rotation=0,labelpad=10)
ax4.tick_params(colors = 'r')
ax4.yaxis.set_ticks(np.arange(20, 340, 50))
ax2.scatter(periods, emax, c="k")
ax2.set_ylabel(r"$E_{max}$",rotation=0,labelpad=20)
ax2.yaxis.set_ticks(np.arange(5000, 30000, 5000))
ax5 = ax2.twinx()
ax5.scatter(periods, alp, c="r")
ax5.set_ylabel("alp", color = 'r',rotation=0,labelpad=15)
ax5.tick_params(colors = 'r')
ax5.yaxis.set_ticks(np.arange(2.1, 2.6, 0.1))
ax3.scatter(periods, eq, c="k")
ax3.set_ylabel("Eq",rotation=0,labelpad=20)
ax3.yaxis.set_ticks(np.arange(6, 15, 2))
ax3.set_xlabel("Periods")
ax6 = ax3.twinx()
ax6.scatter(periods, B, c="r")
ax6.set_ylabel("B", color = 'r',rotation=0,labelpad=10)
ax6.tick_params(colors = 'r')
ax6.yaxis.set_ticks(np.arange(0.02, 0.09, 0.02))
ax1.xaxis.set_ticks(np.arange(1, 13, 1))
f.subplots_adjust(hspace = 0,left=0.14,right=0.90)
plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=True)
plt.show()
This produces the following plot:
You may want to experiment with the labelpad to get the labels exactly where you want them as the length of your tick labels are not the same for each axis.

Matplotlib: plotting two legends outside of the axis makes it cutoff by the figure box

Task:
Plot a donut chart with two legends outside of the axis (first legend - on the right side with respect to the figure, second - on the bottom).
Problem:
When saving the figure, part of the 1st legend is cut off [especially when it contains a long text, see example below]
Desired result:
Make a tight layout of the figure by taking into consideration the dimensions of both legends.
Code:
import matplotlib.pyplot as plt
from pylab import *
ioff() # don't show figures
colors = [(102, 194, 165), (252, 141, 98), (141, 160, 203), (231, 138,195),
(166, 216, 84), (255, 217, 47), (171, 197, 233), (252, 205, 229)]
for icol in range(len(colors)):
red,green,blue = colors[icol]
colors[icol] = (red / 255., green / 255., blue / 255.)
fig = plt.figure(1, figsize=(8, 8))
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
sizes_component_1 = [12, 23, 100, 46]
sizes_component_2 = [15, 30, 45, 10, 44, 45, 50, 70]
component_1 = 'exampleofalongtextthatiscutoff', '2', '3', '4'
component_2 = 'Unix', 'Mac', 'Windows7', 'Windows10', 'WindowsXP', 'Linux', 'FreeBSD', 'Android'
patches1, texts1, autotexts1 = ax.pie(sizes_component_1, radius=1, pctdistance=0.9, colors=colors, autopct='%1.1f%%', shadow=False, startangle=90)
patches2, texts2, autotexts2 = ax.pie(sizes_component_2, radius=0.8, pctdistance=0.6, colors=colors, autopct='%1.1f%%', shadow=False, startangle=90)
# To draw circular donuts
ax.axis('equal')
# Draw white circle
centre_circle = plt.Circle((0,0),0.6,color='black', fc='white')
ax.add_artist(centre_circle)
# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
lgd1=ax.legend(patches1,component_1, frameon=False, loc='center left', bbox_to_anchor=(1.0, 0.8), borderaxespad=0.1)
lgd2=ax.legend(patches2,component_2, frameon=False, loc='center left', ncol=len(patches2)/2, bbox_to_anchor=(0.0, -0.005), borderaxespad=0)
ax_elem = ax.add_artist(lgd1)
fig.suptitle('Title', fontsize=16)
fig.savefig('donut.png',bbox_extra_artists=(lgd1,lgd2,), bbox_inches='tight')
plt.gcf().clear() # clears buffer
This issue is come with pie chart: https://github.com/matplotlib/matplotlib/issues/4251
And it is not fixed.

ValueError: Tensor A must be from the same graph as Tensor B

I'm doing text matching using tensorflow, before i call tf.nn.embedding_lookup(word_embedding_matrix, combine_result), I have to combine some words from 2 sentence(get m words from sentence S1 and also get m words from sentence S2, then combine them together as "combine_result"), but when the code gose to tf.nn.embedding_lookup(word_embedding_matrix, combine_result) it gives me the error:
ValueError: Tensor("Reshape_7:0", shape=(1, 6), dtype=int32) must be
from the same graph as Tensor("word_embedding_matrix:0", shape=(26320,
50), dtype=float32_ref).
the code is as bellow:
import tensorflow as tf
import numpy as np
import os
import time
import datetime
import data_helpers
NUM_CLASS = 2
SEQUENCE_LENGTH = 47
# Placeholders for input, output and dropout
input_x = tf.placeholder(tf.int32, [None, 2, SEQUENCE_LENGTH], name="input_x")
input_y = tf.placeholder(tf.float32, [None, NUM_CLASS], name="input_y")
dropout_keep_prob = tf.placeholder(tf.float32, name="dropout_keep_prob")
def n_grams(text, window_size):
text_left_window = []
# text_left_window = tf.convert_to_tensor(text_left_window, dtype=tf.int32)
for z in range(SEQUENCE_LENGTH-2):
text_left = tf.slice(text, [z], [window_size])
text_left_window = tf.concat(0, [text_left_window, text_left])
text_left_window = tf.reshape(text_left_window, [-1, window_size])
return text_left_window
def inference(vocab_size, embedding_size, batch_size, slide_window_size, conv_window_size):
# # Embedding layer
word_embedding_matrix = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
name="word_embedding_matrix")
# convo_unit = tf.Variable(tf.random_uniform([slide_window_size*2, ], -1.0, 1.0), name="convo_unit")
text_comp_result = []
for x in range(batch_size):
# input_x_slice_reshape = [[1 1 1...]
# [2 2 2...]]
input_x_slice = tf.slice(input_x, [x, 0, 0], [1, 2, SEQUENCE_LENGTH])
input_x_slice_reshape = tf.reshape(input_x_slice, [2, SEQUENCE_LENGTH])
# text_left_flat: [294, 6, 2, 6, 2, 57, 2, 57, 147, 57, 147, 5, 147, 5, 2,...], length = SEQUENCE_LENGTH
# text_right_flat: [17, 2, 2325, 2, 2325, 5366, 2325, 5366, 81, 5366, 81, 1238,...]
text_left = tf.slice(input_x_slice_reshape, [0, 0], [1, SEQUENCE_LENGTH])
text_left_flat = tf.reshape(text_left, [-1])
text_right = tf.slice(input_x_slice_reshape, [1, 0], [1, SEQUENCE_LENGTH])
text_right_flat = tf.reshape(text_right, [-1])
# extract both text.
# text_left_window: [[294, 6, 2], [6, 2, 57], [2, 57, 147], [57, 147, 5], [147, 5, 2],...]
# text_right_window: [[17, 2, 2325], [2, 2325, 5366], [2325, 5366, 81], [5366, 81, 1238],...]
text_left_window = n_grams(text_left_flat, slide_window_size)
text_right_window = n_grams(text_right_flat, slide_window_size)
text_left_window_sha = text_left_window.get_shape()
print 'text_left_window_sha:', text_left_window_sha
# composite the slice
text_comp_list = []
# text_comp_list = tf.convert_to_tensor(text_comp_list, dtype=tf.float32)
for l in range(SEQUENCE_LENGTH-slide_window_size+1):
text_left_slice = tf.slice(text_left_window, [l, 0], [1, slide_window_size])
text_left_slice_flat = tf.reshape(text_left_slice, [-1])
for r in range(SEQUENCE_LENGTH-slide_window_size+1):
text_right_slice = tf.slice(text_right_window, [r, 0], [1, slide_window_size])
text_right_slice_flat = tf.reshape(text_right_slice, [-1])
# convo_unit = [294, 6, 2, 17, 2, 2325]
convo_unit = tf.concat(0, [text_left_slice_flat, text_right_slice_flat])
convo_unit_reshape = tf.reshape(convo_unit, [-1, slide_window_size*2])
# convo_unit_shape_val = convo_unit_reshape.get_shape()
# print 'convo_unit_shape_val:', convo_unit_shape_val
embedded_chars = tf.nn.embedding_lookup(word_embedding_matrix, convo_unit_reshape)
embedded_chars_expanded = tf.expand_dims(embedded_chars, -1)
...
could please someone help me? Thank you very much!
Yaroslav answered in a comment above - moving to an answer:
This error happens when you create new default graph. Try to do tf.reset_default_graph() before the computation and not create any more graphs (i.e., calls to tf.Graph)