My data set is like this: a python list with 6 numbers [23948.30, 23946.20, 23961.20, 23971.70, 23956.30, 23987.30]
I want them to be be a horizontal box plot above an x axis with[23855 and 24472] as the limit of the x axis (with no y axis).
The x axis will also contain points in the data.
(so the box plot and x axis have the same scale)
I also want the box plot show the mean number in picture.
Now I can only get the horizontal box plot.
(And I also want the x-axis show the whole number instead of xx+2.394e)
Here is my code now:
`
def box_plot(circ_list, wear_limit):
print circ_list
print wear_limit
fig1 = plt.figure()
plt.boxplot(circ_list, 0, 'rs', 0)
plt.show()
`
Seaborn code I am trying right now:
def box_plot(circ_list, wear_limit):
print circ_list
print wear_limit
#fig1 = plt.figure()
#plt.boxplot(circ_list, 0, 'rs', 0)
#plt.show()
fig2 = plt.figure()
sns.set(style="ticks")
x = circ_list
y = []
for i in range(0, len(circ_list)):
y.append(0)
f, (ax_box, ax_line) = plt.subplots(2, sharex=True,
gridspec_kw={"height_ratios": (.15, .85)})
sns.boxplot(x, ax=ax_box)
sns.pointplot(x, ax=ax_line, ay=y)
ax_box.set(yticks=[])
ax_line.set(yticks=[])
sns.despine(ax=ax_line)
sns.despine(ax=ax_box, left=True)
cur_axes = plt.gca()
cur_axes.axes.get_yaxis().set_visible(False)
sns.plt.show()
I answered this question in the other post as well, but I will paste it here just in case. I also added something that I feel might be closer to what you are looking to achieve.
l = [23948.30, 23946.20, 23961.20, 23971.70, 23956.30, 23987.30]
def box_plot(circ_list):
fig, ax = plt.subplots()
plt.boxplot(circ_list, 0, 'rs', 0, showmeans=True)
plt.ylim((0.28, 1.5))
ax.set_yticks([])
labels = ["{}".format(int(i)) for i in ax.get_xticks()]
ax.set_xticklabels(labels)
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['left'].set_color('none')
ax.spines['bottom'].set_position('center')
ax.spines['bottom'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
plt.show()
box_plot(l)
The result:
Do let me know if it correspond to what you were looking for.
Related
Plot the lists x=[1,2,…,100] and y=[1,2,…,100] with a black line and the lists x=[1,2,…,100] and
y=[100,99,98,…,1] with gray dots in the same Figure.I think this could help to ilustrate
I have already made the first linea, but I don´t know what function or library could be used. I leave the code here.
x = list(range(100))
y = list(range(100))
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(x,y, linestyle='-', color='black')
I want to show only exact values (x, y) on axes or coordinates of data point by matplotlib. My work below that
def plot_sample_individual(id = None):
if id is None:
id = random.randint(0, len(ca_the))
fig, ax = plt.subplots(1, 1, figsize=(5, 5))
ax.plot(week[:7], ca_the[id, :],'--ro')
ax.set_title('ID cá thể '+ str(ID[id, 0]))
ax.set_ylabel('Sản lượng trứng trung bình tuần')
ax.set_xlabel('Tuần')
and result of code is:
How to show only 3 values on axes y and 5 values in axes x ?
Use the x and y data to set the Axes ticks:
from matplotlib import pyplot as plt
x = [24,25,26,27,28]
y = [7,4,5,4,4]
fig,ax = plt.subplots()
ax.plot(x,y)
ax.set_xticks(x)
ax.set_yticks(y)
plt.show()
plt.close()
Ticks and tick labels
how to add labels to a horizontal bar chart in matplotlib?
Hi everyone, I'm a matplotlib and python newbie and I wanted to ask this question again to get a bit of help as to if there are easier ways to add labels for the count represented by each bar than the current solutions I've found.
Here is the code I have written:
from matplotlib.pyplot import figure
figure(num=None, figsize=(8, 24), dpi=80, facecolor='w', edgecolor='k')
df['Name'].value_counts()[:80].plot(kind='barh')
It works just fine, except for the showing labels next to the bars bit...
I looked on here how to add the label and so I change my code to this:
x = df['Name']
y = df['Name'].value_counts(ascending=True)
fig, ax = plt.subplots(figsize=(18,20))
width = 0.75 # the width of the bars
ind = np.arange(len(y)) # the x locations for the groups
ax.barh(ind, y, width, color="blue")
ax.set_yticks(ind+width/2)
ax.set_yticklabels(y, minor=False)
plt.title('Count of supplies')
plt.xlabel('Count')
plt.ylabel('ylabel')
for i, v in enumerate(y):
ax.text(v + 100, i + 0, str(v), color='black', fontweight='bold')
However, now my names aren't associated with the bars and are just like in order they appear within the dataframe. is there a way to just simply change the first code or to make it so the names associated with bars are correct in 2nd attempt (grouped with the bar they are labeling..)?
Image sorta explaining my issue:
Using the index of y as the index of the barh plot should put the y-labels on the correct spot, next to the corresponding bar. There's no need to manipulate the y-ticklabels. The bar labels can be left aligned and vertically centered. The right x-limit may be moved a bit to have room for the label of the longest bar.
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'Name': np.random.choice(list('AABBBBBCCCCCDEEF'), 20000)})
y = df['Name'].value_counts(ascending=False)
fig, ax = plt.subplots(figsize=(12,5))
ax.barh(y.index, y, height=0.75, color="slateblue")
plt.title('Count of supplies')
plt.xlabel('Count')
plt.ylabel('ylabel')
_, xmax = plt.xlim()
plt.xlim(0, xmax+300)
for i, v in enumerate(y):
ax.text(v + 100, i, str(v), color='black', fontweight='bold', fontsize=14, ha='left', va='center')
plt.show()
Currently, I have the first y axis (probability) of my subplots aligned. However, I am attempting to get the secondary y axis (sample size) of the subplots aligned. I've tried to simply set the y-axis limit, but this solution isn't very generalizable.
Here is my code:
attacks = 5
crit_rate = .5
idealdata = fullMatrix(attacks, crit_rate)
crit_rate = ("crit_%.0f" % (crit_rate*100))
actualdata = trueDataM(attacks, crit_rate)
[enter image description here][1]
fig, axs = plt.subplots(attacks+1, sharex=True, sharey=True)
axs2 = [ax.twinx() for ax in axs]
fig.text(0.5, 0.04, 'State', ha='center')
fig.text(0.04, 0.5, 'Probability', va='center', rotation='vertical')
fig.text(.95, .5, 'Sample Size', va='center', rotation='vertical')
fig.text(.45, .9, 'Ideal vs. Actual Critical Strike Rate', va='center')
cmap = plt.get_cmap('rainbow')
samplesize = datasample(attacks, 'crit_50')
fig.set_size_inches(18.5, 10.5)
for i in range(attacks+1):
axs[i].plot(idealdata[i], color=cmap(i/attacks), marker='o', lw=3)
axs[i].plot(actualdata[i], 'gray', marker='o', lw=3, ls='--')
axs2[i].bar(range(len(samplesize[i])), samplesize[i], width=.1, color=cmap(i/attacks), alpha = .6)
plt.show()
https://i.stack.imgur.com/HKJlE.png
Without data to confirm my assumptions it's hard to tell if this will be correct.
You are not making any attempt to scale the left y-axes so that data must all have the same range. To ensure the right y-axes all have the same scale/limits you need to determine the range (max and min) of the (all) data being plotted on those axes then apply that to all of them.
It isn't clear whether samplesize is a Numpy ndarray or a lists of lists, I'm also assuming that it is a 2-d structure with range(attacks+1) rows. Since you are making bar charts on the second y-axes you only need to find the largest height in all the data.
# for a list of lists
biggest = max(max(row) for row in samplesize)
# or
biggest = max(map(max,samplesize))
# for an ndarray
biggest = samplesize.max()
Then apply that scale to all the right y-axes before they are shown
for ax in axs2:
ax.set_ylim(top=biggest)
If you determine biggest prior to the plot loop you can just add a line to that loop:
for i in range(attacks+1):
...
axs2[i].set_ylim(top=biggest)
You'll find plenty of related SO Q&A'a searching with the terms: matplotlib subplots same y scale, matplotlib subplots y axis limits or something similar.
Here is a toy example:
from matplotlib import pyplot as plt
import numpy as np
lines = np.random.randint(0,200,(5,10))
bars = [np.random.randint(0,np.random.randint(0,10000),10) for _ in (0,0,0,0,0,)]
fig, axs = plt.subplots(lines.shape[0], sharex=True, sharey=True)
axs2 = [ax.twinx() for ax in axs]
#xs = np.arange(lines.shape[1])
xs = np.arange(1,11)
biggest = max(map(max,bars))
for ax,ax2,line,row in zip(axs,axs2,lines,bars):
bars = ax2.bar(xs,row)
ax.plot(line)
ax2.set_ylim(top=biggest)
plt.show()
plt.close()
I want to fix the position of the ticks on the logarithmic scale, such that they are the same in each subplot (see red annotation in image).
My code looks like this:
ax = fig.add_subplot(2,2, axis)
ax2 = ax.twinx()
ax2.set_yscale('log')
ax2.set_ylim(0,100)
Right now, set_yscale=('log') optimizes the tick spacing for each subplot. I prefer to adopt the tick spacing of the upper right subplot.
You can achieve this by getting the limits of the left twin axis and setting it as the limits of the right twin axis.
Consider the following working example. Follow this procedure for the subplots you want to align the axes of.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 3))
axl = fig.add_subplot(121)
axr = fig.add_subplot(122)
ax1 = axl.twinx()
ax1.plot(np.logspace(-2, 3, 5))
ax1.set_yscale('log')
ax2 = axr.twinx()
ax2.plot(np.logspace(0, 3, 5))
ax2.set_yscale('log')
ax2.set_ylim(ax1.get_ylim()) # <-- This is the key line
plt.tight_layout()
plt.show()
OP's solution:
Plot a dummy curve and set alpha=0. Make sure the curve spans y_min and y_max.
fig = plt.figure()
axes = [1,2,3,4]
for axis in axes:
ax = fig.add_subplot(2,2, axis)
ax2 = ax.twinx()
ax2.set_yscale('log')
ax2.plot(x_dummy, y_dummy, alpha=0) # <-- dummy plot
x_real, y_real = func_that_loads_data() # <-- your interesting plot
curve1 = ax2.plot(x_real, y_real)
plt.show()
The solution provided by Sheldore was impractical to implement because I plot my data using a for-loop (unavoidable unless I escalate the number of variables).
Since I overwrite the ax variable on every iteration, I would have to save the y-limit as a global variable. Read here why global variables should be avoided.
ax = fig.add_subplot(2,2, axis)
ax2 = ax.twinx()
ax2.set_yscale('log')
if axis == 1:
global yscale
yscale = ax2.get_ylim() # <-- where the magic happens
elif axis > 1:
ax2.set_ylim(yscale)