Is there any way to create a plot like the one in figure below, having an axis scale of 1:1. By 1:1 I mean that if two ticks with values 100-200 have a distance on screen of 2cm on the x axis, it should be the same on the y axis. Instead as you can see in the figure, ticks on the x axis are much larger.
ax.set_aspect('equal') after the fact for each axis ax = fig.add_subplot(111, aspect='equal') when you generate the axes. example/doc
Related
Can you plot a histogram in matplotlib so that it appears upside down, i.e. the base of the histogram is along the top axis and it "hangs" down? Or, alternatively, if plotting with orientation='horizontal', so that the base of the histogram is on the right hand axis?
Yes, use invert_yaxis:
df = pd.DataFrame({'a':[1,2,3,1,2,2,2],
'b':[1,1,1,3,2,2,2]})
ax = df.plot.hist()
ax.invert_yaxis()
Output:
I want to plot the location of some disks generated randomly on a scatter plot, and see whether the disks are 'connected' to each other. For this, I need to set the radius of each disk fixed/linked to the axis scale.
The 's' parameter in the plt.scatter function uses points, so the size is not fixed relative to the axis. If I dynamically zoom into the plot, the scatter marker size remains constant on the plot and does not scale up with the axis.
How do I set the radius so they have a definite value (relative to the axis)?
Instead of using plt.scatter, I suggest using patches.Circle to draw the plot (similar to this answer). These patches remain fixed in size so that you can dynamically zoom in to check for 'connections':
import matplotlib.pyplot as plt
from matplotlib.patches import Circle # for simplified usage, import this patch
# set up some x,y coordinates and radii
x = [1.0, 2.0, 4.0]
y = [1.0, 2.0, 2.0]
r = [1/(2.0**0.5), 1/(2.0**0.5), 0.25]
fig = plt.figure()
# initialize axis, important: set the aspect ratio to equal
ax = fig.add_subplot(111, aspect='equal')
# define axis limits for all patches to show
ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.])
# loop through all triplets of x-,y-coordinates and radius and
# plot a circle for each:
for x, y, r in zip(x, y, r):
ax.add_artist(Circle(xy=(x, y),
radius=r))
plt.show()
The plot this generates looks like this:
Using the zoom-option from the plot window, one can obtain such a plot:
This zoomed in version has kept the original circle size so the 'connection' can be seen.
If you want to change the circles to be transparent, patches.Circle takes an alpha as argument. Just make sure you insert it with the call to Circle not add_artist:
ax.add_artist(Circle(xy=(x, y),
radius=r,
alpha=0.5))
My question is simple.Hot to make the two scatter plot in one figure?
There is error if I just write the two pl.scatter one by one.
a,b,c=np.loadtxt('mydata',usecols=(0,1,2),delimiter=",",unpack=True)
pl.scatter(a,b,color='g',s=0.5,'b')
pl.scatter(b,c,'r')
The other question is how to use the left y and right y axis together,say,the first scatter plot use the left y axis and,the second scatter plot use the right y axis.
You can use ax.twinx() to create a second y-axis that shares the same x-axis
ax1 = pl.axes()
ax2 = ax1.twinx()
ax1.scatter(a,b,color='g',s=0.5)
ax2.scatter(b,c,color='r')
The error you were seeing is probably because you have a non-keyword argument ('b') after a keyword argument (color='r').
I'm drawing the bloxplot shown below using python and matplotlib. Is there any way I can reduce the distance between the two boxplots on the X axis?
This is the code that I'm using to get the figure above:
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['ytick.direction'] = 'out'
rcParams['xtick.direction'] = 'out'
fig = plt.figure()
xlabels = ["CG", "EG"]
ax = fig.add_subplot(111)
ax.boxplot([values_cg, values_eg])
ax.set_xticks(np.arange(len(xlabels))+1)
ax.set_xticklabels(xlabels, rotation=45, ha='right')
fig.subplots_adjust(bottom=0.3)
ylabels = yticks = np.linspace(0, 20, 5)
ax.set_yticks(yticks)
ax.set_yticklabels(ylabels)
ax.tick_params(axis='x', pad=10)
ax.tick_params(axis='y', pad=10)
plt.savefig(os.path.join(output_dir, "output.pdf"))
And this is an example closer to what I'd like to get visually (although I wouldn't mind if the boxplots were even a bit closer to each other):
You can either change the aspect ratio of plot or use the widths kwarg (doc) as such:
ax.boxplot([values_cg, values_eg], widths=1)
to make the boxes wider.
Try changing the aspect ratio using
ax.set_aspect(1.5) # or some other float
The larger then number, the narrower (and taller) the plot should be:
a circle will be stretched such that the height is num times the width. aspect=1 is the same as aspect=’equal’.
http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_aspect
When your code writes:
ax.set_xticks(np.arange(len(xlabels))+1)
You're putting the first box plot on 0 and the second one on 1 (event though you change the tick labels afterwards), just like in the second, "wanted" example you gave they are set on 1,2,3.
So i think an alternative solution would be to play with the xticks position and the xlim of the plot.
for example using
ax.set_xlim(-1.5,2.5)
would place them closer.
positions : array-like, optional
Sets the positions of the boxes. The ticks and limits are automatically set to match the positions. Defaults to range(1, N+1) where N is the number of boxes to be drawn.
https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.boxplot.html
This should do the job!
As #Stevie mentioned, you can use the positions kwarg (doc) to manually set the x-coordinates of the boxes:
ax.boxplot([values_cg, values_eg], positions=[1, 1.3])
Can I have both twinx and twiny together (i.e. something like twinxy)?
I want to put a CDF on a bar plot where the X axis of the bar plot is in log-scale. I cannot make the Ys together, because the bar plot y range is very large comparing [0,1] for CDF.
Any ideas?
Thanks,
If I understand your question right, you want to plot two things on the same axes with no shared axis. There is probably a better way to do this, but you can stack twinx (doc) and twiny (doc) as such
ax # your first axes
ax_new = ax.twinx().twiny()
Which will give you tick marks on all sides of the plot. ax will plot against the bottom and left, ax_new will plot against the top and right.