How to modify the text arrangement in legend - python

I want to customize the number of rows in each column of the matplotlib legend text.
The code is:
import matplotlib.pyplot as plt
import numpy as np
for i in range(10):
plt.plot(np.linspace(0, 5, 5), np.random.randint(0, 10, 5), label=str(i))
plt.legend(ncol = 3, loc = 1)
plt.show()
What I get: the numbers of rows in each column are 4, 3, 3
What I want: the numbers of rows in each column are 4, 4, 2
I've tried adding plt.plot([], [], label='') before plt.show(), but it doesn't help

I solved this problem by adding an invisible line as 11th element like this:
import matplotlib.pyplot as plt
import numpy as np
lines = []
for i in range(10):
l, = plt.plot(np.linspace(0, 5, 5), np.random.randint(0, 10, 5), label=str(i))
lines.append(l)
l, = plt.plot(0, alpha=0, label=' ')
# alpha=0 will make the line and element in the legend invisible
lines.append(l)
plt.legend(handles=[l for l in lines], ncol = 3, loc = 1)
plt.show()
This will yield the following result:

Related

Plotting time series data with with 30sec break point and color

I am new in python programming. I can simply plot the input data shown in the figure with my code but how can I plot the time series data as mention in the figure. Any code and suggestions will be thankful.
My code is:
import matplotlib.pyplot as plt
import numpy as np
y_values = [5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
plt.figure()
plt.plot(x_values,y_values,"-x")
plt.show()
Although there is a way to draw a series of rectangular shapes, we used a general method and used horizontal bar charts. We added a list for the values in the bar chart and stacked the values. Class label names and class titles are now supported as annotations. You can try various other parameters.
import matplotlib.pyplot as plt
import numpy as np
y = [5]*11
y_values = [5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
fig, ax = plt.subplots(figsize=(12,1))
ax.barh(y=0, height=1.0, edgecolor='k', width=y[0], label='Time Interval')
for i in range(len(y)):
if y_values[i] == 5:
color = 'y'
else:
color = 'm'
ax.barh(y=0, left=sum(y[:i]), height=1.0, width=y[i], color=color, edgecolor='k', label='Time Interval')
for s in ['top','bottom','left','right']:
ax.spines[s].set_visible(False)
for i,(p,t) in enumerate(zip(y, y_values)):
ax.text(y=0.6, x=2.5+p*i, s=str(t))
ax.text(-0.08, 1, 'Class', transform=ax.transAxes)
ax.set_xticks([])
ax.set_yticks([])
ax.set_ylabel('Time Interval', rotation=0, labelpad=40, loc='center')
plt.show()
Try:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
y_values = ['class', 5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1]
x_values = np.arange(30, 331, 30)
x_values = np.concatenate((['Time'],x_values))
df = pd.DataFrame(data={'class': y_values, 'Time': x_values})
colors = {5: 'gold', 1: 'darkviolet'}
df['colors'] = df['class'].map(colors)
df['colors'].fillna('white', inplace=True)
df['Time'].iloc[1:] = ''
print(df)
fig, ax =plt.subplots(1,1)
ax.axis('tight')
ax.axis('off')
data = df.T.values
colors = [data[2].tolist()]
table = ax.table(cellText=[data[1].tolist()], colLabels=data[0].tolist(),loc="center", cellColours=colors)
table.set_fontsize(14)
for i in range(len(data[0])):
table[0, i].visible_edges = ''
table[1, 0].visible_edges = ''
table.scale(1.5, 1.5)
plt.show()

Update text in matplotlib's plot

I want to change text in matplotlib's plot with loop. I am able to print text with loop, but unable to delete the previous text and they got printed on top of each other.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1,2,3,4,5])
y = np.array([1,2,3,4,5])
fig, ax = plt.subplots()
ax.set_xlim([0,5])
ax.set_ylim([0,5])
for i in x:
pt = ax.plot(i, i, 'o')
tx = ax.text(1, 2, str(i), fontsize = 12)
plt.pause(1)
removePt = pt.pop()
removePt.remove()
I tried to delete text by
removeTx = tx.pop()
removeTx.remove()
but it has not worked.
Kindly suggest how can I remove the previous text from plot.
Just add tx.remove() after the pause:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])
fig, ax = plt.subplots()
ax.set_xlim([0, 5])
ax.set_ylim([0, 5])
for i in x:
pt = ax.plot(i, i, 'o')
tx = ax.text(1, 2, str(i), fontsize = 12)
plt.pause(1)
tx.remove()
plt.show()

how to make loop to create a graph of every column in dataset in python [duplicate]

I am trying to plot multiple histograms on the same window using a list of tuples. I have managed to get it to sketch only 1 tuple at a time and I just can't seem to get it to work with all of them.
import numpy as np
import matplotlib.pyplot as plt
a = [(1, 2, 0, 0, 0, 3, 3, 1, 2, 2), (0, 2, 3, 3, 0, 1, 1, 1, 2, 2), (1, 2, 0, 3, 0, 1, 2, 1, 2, 2),(2, 0, 0, 3, 3, 1, 2, 1, 2, 2),(3,1,2,3,0,0,1,2,3,1)] #my list of tuples
q1,q2,q3,q4,q5,q6,q7,q8,q9,q10 = zip(*a) #split into [(1,0,1,2,3) ,(2,2,2,0,1),..etc] where q1=(1,0,1,2,3)
labels, counts = np.unique(q1,return_counts=True) #labels = 0,1,2,3 and counts the occurence of 0,1,2,3
ticks = range(len(counts))
plt.bar(ticks,counts, align='center')
plt.xticks(ticks, labels)
plt.show()
As you can see from the above code, I can plot one tuple at a time say q1,q2 etc but how do I generalise it so that it plots all of them.
I've tried to mimic this python plot multiple histograms, which is exactly what I want however I had no luck.
Thank you for your time :)
You need to define a grid of axes with plt.subplots taking into account the amount of tuples in the list, and how many you want per row. Then iterate over the returned axes, and plot the histograms in the corresponding axis. You could use Axes.hist, but I've always preferred to use ax.bar, from the result of np.unique, which also can return the counts of unique values:
from matplotlib import pyplot as plt
import numpy as np
l = list(zip(*a))
n_cols = 2
fig, axes = plt.subplots(nrows=int(np.ceil(len(l)/n_cols)),
ncols=n_cols,
figsize=(15,15))
for i, (t, ax) in enumerate(zip(l, axes.flatten())):
labels, counts = np.unique(t, return_counts=True)
ax.bar(labels, counts, align='center', color='blue', alpha=.3)
ax.title.set_text(f'Tuple {i}')
plt.tight_layout()
plt.show()
You can customise the above to whatever amount of rows/cols you prefer, for 3 rows for instance:
l = list(zip(*a))
n_cols = 3
fig, axes = plt.subplots(nrows=int(np.ceil(len(l)/n_cols)),
ncols=n_cols,
figsize=(15,15))
for i, (t, ax) in enumerate(zip(l, axes.flatten())):
labels, counts = np.unique(t, return_counts=True)
ax.bar(labels, counts, align='center', color='blue', alpha=.3)
ax.title.set_text(f'Tuple {i}')
plt.tight_layout()
plt.show()

Setting labels for image automatically

I have a 2D array, and I plot in into three lines in one image, each line represents the numbers in each column.
I would like to set their labels as 'column = 1', 'column = 2', 'column = 3' automatically, based on which column the line represent.
How can I achieve this?
#%%
import numpy as np
import matplotlib.pyplot as plt
data = [
[1, 2, 4],
[2, 4, 6],
[5, 7, 9]
]
arr = np.array(data)
#Plotting
arr = arr[:,0:3]
fig, ax = plt.subplots(figsize=(8, 5))
x = np.linspace(0, 2, 3)
x = np.asarray(x)
plt.plot(x, arr, label="column")
plt.legend(bbox_to_anchor=(0.85, 1), loc='upper left', borderaxespad=0.)
plt.show()
You can set the lables in the legend method,
...
lines = plt.plot(x, arr)
column_names = tuple("column_" + str(i+1) for i,x in enumerate(data))
plt.legend(lines, column_names, bbox_to_anchor=(0.85, 1), loc='upper left', borderaxespad=0.)
plt.show()

LineCollection not displaying data for some axes on multiple axes plot

The following code will create a plot that appears to have invisible data on several if the subplots.
Why do I then need to include ax[i].autoscale_view(True,True,True)?
Why does print ax[i].lines show [] ?
Code
from matplotlib.collections import LineCollection
import matplotlib.pyplot as plt
import numpy as np
# example data with properties:
# len(lines) == 4 and len(lines[0]) == 10
# len(x) == 10
lines = [(1.2310957583605482, 1.283772297331087, 1.61856069891319, 2.1602226857314735, 1.0277068564151643, 1.1715166081037471, 1.463648931121718, 1.2329321041327499, 1.4080120164965291, 1.2225064185740224), (0.33323810593968223, 0.32582779060567746, 0.32836534361310366, 0.51831090602571572, 0.29791484909192673, 0.35713207695246518, 0.29463171650130665, 0.34633265872428215, 0.39298012050485071, 0.410877623134692), (10, 11, 13, 17, 8, 10, 12, 10, 11, 10), (0.9911659269366481, 0.989291500800633, 0.9880005820749531, 0.9820511801663299, 0.978444258093041, 0.9737543029212308, 0.9711834357704919, 0.9632772617693266, 0.95740331184712, 0.9523058427743931)]
x = [0.0, 0.00101010101010101, 0.00202020202020202, 0.0030303030303030303, 0.00404040404040404, 0.00505050505050505, 0.006060606060606061, 0.007070707070707071, 0.00808080808080808, 0.00909090909090909]
n=len(lines) # copy in lines and x data from below
fig, ax = plt.subplots(n, sharex=True, figsize = (8, 8))
for i, y in enumerate(lines):
xy = zip(x, y)
lc = LineCollection([xy], linewidth = 2)
ax[i].add_collection(lc)
plt.show()

Categories

Resources