These two graphs have exactly the same x axis value of each point, is it possible to display the box whisker on top of the first graph?
I tried this:
fig1 = plt.figure()
ax = fig1.add_subplot(211)
ax.set_xscale('log')
ax.plot(x7,y7,'c+-')
ax.plot(x8,y8,'m+-')
ax.plot(x9,y9,'g+-')
ax.boxplot(dataset)
xtickNames = plt.setp(ax, xticklabels=boxx)
plt.setp(xtickNames)
The results only display the box whisker graph without the other three lines, so, I tried this instead:
fig1 = plt.figure()
ax = fig1.add_subplot(211)
ax2 = fig1.add_subplot(212)
ax.set_xscale('log')
ax.plot(x7,y7,'c+-')
ax.plot(x8,y8,'m+-')
ax.plot(x9,y9,'g+-')
ax2.set_xscale('log')
ax2.boxplot(dataset)
xtickNames = plt.setp(ax2, xticklabels=boxx)
plt.setp(xtickNames)
But I want them to be shown in the same graph, is that possible?
If you want two graphs with comparable X and Y ranges to appear one on top of the other, you can try "Hold". For example:
import pylab
pylab.plot([1,2,3,4],[4,3,2,1])
pylab.hold(True)
pylab.plot([1,2,3,4],[1,2,3,4])
Related
I'm working on analyzing some data using scanpy and I'm trying to plot 3 violin plots next to one another but I can't seem to get it to work. I tried using subplots a few different ways but they keep getting empty charts with the violin plots in between them. I tried a few different strategies but I can't seem to get them next to one another in a 1x3 grid. Below is my latest attempt along with part of the plot showing an empty plot stacked on top of a violin plot.
plt.figure()
plt.subplot(1,3,1)
sc.pl.violin(visium, keys = 'n_genes_by_counts')
plt.subplot(1,3,2)
sc.pl.violin(visium, keys = 'total_counts')
plt.subplot(1,3,3)
sc.pl.violin(visium, keys = 'pct_counts_mt')
Sample
Try to set multi_panel = True
like this:
sc.pl.violin(visium, ['n_genes_by_counts','total_counts','pct_counts_mt'],
jitter=0.3, multi_panel=True)
Either use the flag multi_panel = True in sc.pl.violin, or the ax flag:
plt.figure()
ax1 = plt.subplot(1,3,1)
sc.pl.violin(visium, keys = 'n_genes_by_counts', ax = ax1)
ax2 = plt.subplot(1,3,2)
sc.pl.violin(visium, keys = 'total_counts', ax = ax2)
ax3 = plt.subplot(1,3,3)
sc.pl.violin(visium, keys = 'pct_counts_mt', ax = ax3)
I have two subplots of horizontal bars done in matplotlib. For the first subplot, the number of y-axis ticks is appropriate, but I'm unable to figure out why specifying number of ticks for the second subplot is coming out to be wrong. This is the code:
import matplotlib.pyplot as plt
import numpy as np
# Plot separate subplots for genders
fig, (axes1, axes2) = plt.subplots(nrows=1, ncols=2,
sharex=False,
sharey=False,
figsize=(15,10))
labels = list(out.index)
x = ["20%", "40%", "60%", "80%", "100%"]
y = np.arange(len(out))
width = 0.5
axes1.barh(y, female_distr, width, color="olive",
align="center", alpha=0.8)
axes1.ticks_params(nbins=6)
axes1.set_yticks(y)
axes1.set_yticklabels(labels)
axes1.set_xticklabels(x)
axes1.yaxis.grid(False)
axes1.set_xlabel("Occurence (%)")
axes1.set_ylabel("Language")
axes1.set_title("Language Distribution (Women)")
axes2.barh(y, male_distr, width, color="chocolate",
align="center", alpha=0.8)
axes2.locator_params(nbins=6)
axes2.set_yticks(y)
axes2.set_yticklabels(labels)
axes2.set_xticklabels(x)
axes2.yaxis.grid(False)
axes2.set_xlabel("Occurence (%)")
axes2.set_ylabel("Language")
axes2.set_title("Language Distribution (Men)")
The rest of the objects like out are simple data frames that I don't think need to be described here. The above code returns the following plot:
I would like the second subplot to have equal number of ticks but experimenting with nbins always results in either more or fewer ticks than the first subplot.
First, if you want your two plots to have the same x-axis, why not use sharex=True?
x_ticks = [0,20,40,60,80,100]
fig, (ax1,ax2) = plt.subplots(1,2, sharex=True)
ax1.set_xticks(x_ticks)
ax1.set_xticklabels(['{:.0f}%'.format(x) for x in x_ticks])
ax1.set_xlim(0,100)
ax1.grid(True, axis='x')
ax2.grid(True, axis='x')
I am trying to create a subplot that consists of two figures. Each of the figures shows some data plotted vs a time axis. And for each figure I want to have two y axes corresponding to two different graphs shown within the same figure.
Let's start with the data corresponding to one of the y-axes. This data is the same for each of the two figures and is generated as follows (it is fairly ugly code and if you have any suggestions as on how to improve it, please let me know!):
pwm_len = len(Time)/6
pwm_max = 255
pwm_min = 150
pwm_mid = 200
pwm_zero = 0
pwm1 = np.repeat(pwm_max, pwm_len)
pwm2 = np.repeat(pwm_min, pwm_len)
pwm3 = np.repeat(pwm_max, pwm_len)
pwm4 = np.repeat(pwm_mid, pwm_len)
pwm5 = np.repeat(pwm_max, pwm_len)
pwm6 = np.repeat(pwm_zero, pwm_len)
pwm = pwm1 + pwm2 + pwm3 + pwm4 + pwm5 + pwm6
To create the figure, I am using the following code (please note that it is not working right now, due to some wrong usage of twinx() ):
fig, axs = plt.subplots(2, sharex=True, sharey=True)
plt.subplots_adjust(hspace=0.5)
axs_pwm = axs.twinx()
axs[0].plot(Time, velocity, 'b-')
axs_pwm[0].plot(Time, pwm, 'r-')
axs[0].set_ylabel('[mm/s]')
axs_pwm[0].set_ylabel('PWM')
axs[0].grid(True)
axs[1].plot(Time, velocity_filtered, 'b-')
axs_pwm[1].plot(Time, pwm, 'r-')
axs[1].set_ylabel('[mm/s]')
axs_pwm[1]-set_ylabel('PWM')
axs[1].grid(True)
plt.show()
apparently I am using the twinx() function in a wrong way. But what is a different way to draw the second y axis?
Extending upon ImportanceOfBeingErnest's's suggestion, you need the following:
Create the twin axis for each subplot using the index 0 and 1 while using twinx()
Use the respective twin axis' object to plot data and set y-axis labels
fig, axs = plt.subplots(2, sharex=True, sharey=True)
plt.subplots_adjust(hspace=0.5)
axs_pwm1 = axs[0].twinx() # Create twin axis for the first subplot
axs[0].plot(Time, velocity, 'b-')
axs_pwm1.plot(Time, pwm, 'r-')
axs[0].set_ylabel('[mm/s]')
axs_pwm1.set_ylabel('PWM')
axs[0].grid(True)
axs_pwm2 = axs[1].twinx() # Create twin axis for the second subplot
axs[1].plot(Time, velocity_filtered, 'b-')
axs_pwm2.plot(Time, pwm, 'r-')
axs[1].set_ylabel('[mm/s]')
axs_pwm2.set_ylabel('PWM')
axs[1].grid(True)
plt.show()
Or as suggested by #SpghttCd in the comments, you can predefine all the twin axis and then use index as
ax2 = [ax.twinx() for ax in axs]
ax2[0].plot(...)
ax2[1].plot(...)
I am using seaborn and twinx to plot two lines in one figure. However, as replicated below, the blue line is below the horizontal line because it is overlayed by the second plot:
import seaborn as sns
import matplotlib.pyplot as plt
l1 = sns.lineplot(x=[0,1,2],y=[1,2,3],color="#0188A8")
ax1 = plt.gca()
ax2 = ax1.twinx()
l2 = sns.lineplot(x=[0,1,2], y=[100,200,300],color="#D42227")
plt.xlabel('Number of Selves',fontsize=13)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0,1,2])
ax2.set_yticks([100,200,300])
After doing some googling, I found this which was close, but didn't help. Trying out their solution, the axis ticks will get distorted, as both lines are plotted on the second plot:
ax1 = plt.gca()
ax2 = ax1.twinx()
l1 = sns.lineplot(x=[0,1,2],y=[1,2,3],color="#0188A8")
l2 = sns.lineplot(x=[0,1,2], y=[100,200,300],color="#D42227")
plt.xlabel('Number of Selves',fontsize=13)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0,1,2])
ax2.set_yticks([100,200,300])
My question is, how can the blue line be on top of the horizontal grid lines while maintaining the ticks to be at the same position as they are in the first picture?
You cannot easily obtain the desired effect because all the artists of ax2 are drawn above the artists of ax1, regardless of their respective z-order.
The only "good" solution that I can suggest, is, as you had found out, draw both lines on ax2, but you have to use the data transform of ax1 for the first line so that it matches the numbers on the left axis.
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
l1 = sns.lineplot(x=[0,1,2],y=[1,2,3],color="#0188A8", ax=ax2, transform=ax1.transData)
l2 = sns.lineplot(x=[0,1,2], y=[100,200,300],color="#D42227", ax=ax2)
ax1.set_xlabel('Number of Selves',fontsize=13)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0,1,2])
ax2.set_yticks([100,200,300])
ax1.set_ylim(-0.5,3.5)
Note that, because there are actually no data on ax1, you have to manually specify the y-axis limits, it won't autoscale for you.
I have a matplotlib bar chart, which bars are colored according to some rules through a colormap. I need a colorbar on the right of the main axes, so I added a new axes with
fig, (ax, ax_cbar) = plt.subplots(1,2)
and managed to draw my color bar in the ax_bar axes, while I have my data displayed in the ax axes. Now I need to reduce the width of the ax_bar, because it looks like this:
How can I do?
Using subplots will always divide your figure equally. You can manually divide up your figure in a number of ways. My preferred method is using subplot2grid.
In this example, we are setting the figure to have 1 row and 10 columns. We then set ax to be the start at row,column = (0,0) and have a width of 9 columns. Then set ax_cbar to start at (0,9) and has by default a width of 1 column.
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))
num_columns = 10
ax = plt.subplot2grid((1,num_columns), (0,0), colspan=num_columns-1)
ax_cbar = plt.subplot2grid((1,num_columns), (0,num_columns-1))
The ususal way to add a colorbar is by simply putting it next to the axes:
fig.colorbar(sm)
where fig is the figure and sm is the scalar mappable to which the colormap refers. In the case of the bars, you need to create this ScalarMappable yourself. Apart from that there is no need for complex creation of multiple axes.
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
fig , ax = plt.subplots()
x = [0,1,2,3]
y = np.array([34,40,38,50])*1e3
norm = matplotlib.colors.Normalize(30e3, 60e3)
ax.bar(x,y, color=plt.cm.plasma_r(norm(y)) )
ax.axhline(4.2e4, color="gray")
ax.text(0.02, 4.2e4, "42000", va='center', ha="left", bbox=dict(facecolor="w",alpha=1),
transform=ax.get_yaxis_transform())
sm = plt.cm.ScalarMappable(cmap=plt.cm.plasma_r, norm=norm)
sm.set_array([])
fig.colorbar(sm)
plt.show()
If you do want to create a special axes for the colorbar yourself, the easiest method would be to set the width already inside the call to subplots:
fig , (ax, cax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios" : [10,1]})
and later put the colorbar to the cax axes,
fig.colorbar(sm, cax=cax)
Note that the following questions have been asked for this homework assignment already:
Point picker event_handler drawing line and displaying coordinates in matplotlib
Matplotlib's widget to select y-axis value and change barplot
Display y axis value horizontal line drawn In bar chart
How to change colors automatically once a parameter is changed
Interactively Re-color Bars in Matplotlib Bar Chart using Confidence Intervals