I have a histogram shown here which I made using the following:
import pylab as pl
fd = FreqDist(list(industries))
X = np.arange(len(fd))
pl.bar(X, fd.values(), align='center', width=0.15)
pl.xticks(X, fd.keys(), rotation=90)
pl.tick_params(labelsize=8)
ymax = max(fd.values()) + 1
pl.ylim(0, ymax)
pl.subplots_adjust(bottom=0.3)
pl.savefig('internalDoorCount.jpg')
However I need the gap to reduce between the y-axis and the first histogram bar. Also how do you prevent overlapping of text?
You can try to avoid overlapping of the text by using this function:
pl.gcf().autofmt_xdate(bottom=0.3, rotation=-30, ha="left")
It's created for rotating date tick labels, but it should work good here. But you most probably have to either reduce the font size, and/or increase the width of your figure.
Assuming pl is matplotlib.pyplot, use pl.xlim. Because I'm not sure what values your x-axis takes, try
pl.xlim(min(X), max(X))
I cannot upvote and I'm amazed how old answers here are still helpful. So, as I still don't have points to comment, I'm answering here to correct a typo from #wflynny and say his answer is simple and works. The actual beginning of the code is "plt", instead of "pl":
plt.xlim(min(x),max(x))
The complete documentation is here.
Related
first must say, I love the mplfinance, it is a very nice way to display data on the chart.
my problem now is, I cant reduce the space to the borders. There is a parameter calle "tight_layout" but it cuts information off. Probably I do something wrong.
mpf.plot(df_history, show_nontrading=True, figratio=(10,7), figscale=1.5, datetime_format='%d.%m.%y',
xrotation=90, tight_layout=True,
alines=dict(alines=seq_of_points, colors=seq_of_colors, linestyle='-', linewidths=0.5),
type='candle', savefig=bildpfad, addplot=apdict,
update_width_config=dict(candle_linewidth=0.4))
When I use tight_layout=True, it lookes like this:
The space around the chart is perfekt, but the data in the chart is cut off.
and if I use tight_layout=False it uses too much space and the html file created looks crooked.
Does anybody know the right way?
There are a couple of different things you can do to fix this. First, understand the reason why this is happening. The tight_layout algorithm sets the x-axis limits to just outside the limits of your dataframe datetime index, whereas some of your alines points are obviously outside of this range. Given that, there are a few things you can do:
use kwarg xlim=(xmin,xmax) to manually set the x-axis limits that you want.
pad the end of you ohlc dataframe with nan values out to the latest date that you need on your plot.
request a bug fix or enhancement that tight_layout should take alines into account.
HTH.
P.S. Presently xlim only accepts numbers (int or float) that correspond to row numbers in your dataframe (or that correspond to matplotlib dates, see P.P.S. below). I hope to enhance xlim to accept dates sometime soon. In the meantime, try somthing like this:
xmin = 0
xmax = len(df_history)*1.4
mpf.plot(df_history,...,xlim=(xmin,xmax))
P.P.S. I just realized that the above (xmax = len(df_history)*1.4) will work only for show_nontrading=False. However with show_nontrading=True as you have it, you will need to set xmax and xmin differently, as:
import matplotlib.dates as mdates
...
# decide how many days past the end of the data
# that you want the maximum x-axis limit to be:
numdays = 10
# then:
xmin = mdates.date2num(df_history.index[0].to_py_datetime())
xmax = mdates.date2num(df_history.index[-1].to_py_datetime()) + numdays
mpf.plot(df_history,...,xlim=(xmin,xmax))
(notice above they are not both .index[0] but xmax derives from .index[-1])
My apologies that the above work-arounds for xlim are elaborate. This is motivating me even more to finish the xlim enhancement so that users can just pass in a date as a string or datetime. Users of mplfinance should not have to worry about these date conversion details.
I have a plot in matplotlib that looks like this:
I also have a different plot that looks like this:
What I want to do is create a plot that looks like this:
That is, I want to keep the data points exactly where they are in the first plot, but replace the x axis ticks and labels with the ones from the second plot. (In this case they are generated with plt.xscale('symlog').) I can't seem to find a straightforward way to do this. Is there one?
Note: it shouldn't really need saying, but the plot in this question isn't my actual plot, and I do have a reason to want to do this. I'm happy to clarify the question I'm asking, but I don't think it's helpful to ask for the details of why I need it. The question is about how to do the specific thing I've asked how to do, and on-topic responses are appreciated.
I looks to me that this question asks for a workaround in order to avoid transforming the data to the desired scale. This should be pretty straight forward by applying the inverse function to the data before plotting. Yet, there is not enough information given in the question as to what the problem would be for such solution.
Therefore one can only answer the question as it is; this basically translates into creating a completely unrelated axis.
import numpy as np
import matplotlib.pyplot as plt
x,y = np.random.rand(2,30)
fig, ax = plt.subplots()
ax.plot(x,y, ls="", marker="+")
ax2 = ax.twiny()
ax2.set_xscale("symlog")
ax2.tick_params(axis="x", which="both", bottom=True, labelbottom=True,
top=False, labeltop=False)
ax.tick_params(axis="x", bottom=False, labelbottom=False)
ax2.set_xlim(-50,50)
plt.show()
Here the x limits are chosen arbitrarily. The problem will be to relate the limits to the original data. Due to a 5% default margin on both sides, this will in general not be trivial and any function doing this task will become much more complicated than a function computing the inverse transform on the original data.
you can simply set the labels of the xticks like this.
plt.xticks(np.arange(3), [10, 10^2, 10^5])
In case anyone has the same problem in the future, here's a solution that works. I don't know if it's the best way.
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
# use ax1 to plot the data
ax1.axes("off")
ax2 = fig.add_axes(ax1.get_position())
ax2.patch.set_alpha(0)
# then do whatever you want to set up the axes of ax2. In my case:
ax1_xlim = ax1.get_xlim()
ax2.set_xlim([-np.power(10,-ax1_xlim[0]), np.power(10,ax1_xlim[1])])
I do not understand why all the comments and other answers were so focused on the 'why' of this simple task. I hope this will be helpful to others in spite of all the noise.
ImportanceOfBeingErnest said this is a rescaling problem, and I agree with him.
General principle
From what I understood, your are trying to do something like :
Plot your function with 'vanilla' unit => y = f(x)
Express the x axis in another unit => x [unit] = x' [deg]
Plot your function with new unit => y = f(x')
Choose nice xlim to have the point at the 'same location' as before (see ImportanceOfBeingErnest answer)
NB : you can write x' = g(x) another function and then have y = f ( g(x) )
All you need to know is this g function in order to rescale.
I repeat, I see this problem as a unit change problem. So the answer depends on the problem, its nature, its parameters. This is what hidden behind this g function.
Nearly the answer you need
In your case, according to the plot you shown, I can give you an approximate answer :
x' = 10 * ( x - 0.5)
np.semilogx(x',y)
0.5 because the new 0 seems to be where you had 0.5. I substract in order to center the new points in 0.5.
10 * because you transform 0.1 into 10^0.
I am plotting some columns of a csv using Pandas/Matplotlib. The index column is the time in seconds (which has very high number).
For example:
401287629.8
401287630.8
401287631.7
401287632.8
401287633.8
401287634.8
I need this to be printed as my xticklabel when i plot. But it is changing the number format as shown below:
plt.figure()
ax = dfPlot.plot()
legend = ax.legend(loc='center left', bbox_to_anchor=(1,0.5))
labels = ax.get_xticklabels()
for label in labels:
label.set_rotation(45)
label.set_fontsize(10)
I couldn't find a way for the xticklabel to print the exact value rather than shortened version of it.
This is essentially the same problem as How to remove relative shift in matplotlib axis
The solution is to tell the formatter to not use an offset
ax.get_xaxis().get_major_formatter().set_useOffset(False)
Also related:
useOffset=False in config file?
https://github.com/matplotlib/matplotlib/issues/2400
https://github.com/matplotlib/matplotlib/pull/2401
If it's not rude of me to point out, you're asking for a great deal of precision from a single chart. Your sample data shows a six-second difference over two times that are both over twelve and a half-years long.
You have to cut your cloth to your measure on this one. If you want to keep the years, you can't keep the seconds. If you want to keep the seconds, you can't have the years.
I have a simple plot code as
plt.plot(x,y)
plt.show()
I want to add some extra ticks on the x-axis in addition to the current ones, let's say at
extraticks=[2.1, 3, 7.6]
As you see I do not have a pattern for ticks so I do not want to increase the tick frequency for the whole axis; just keep the original ones and add those extras...
Is it possible, at all?
Regards
Yes, you can try something like:
plt.xticks(list(plt.xticks()[0]) + extraticks)
The function to use is xticks(). When called without arguments, it returns the current ticks. Calling it with arguments, you can set the tick positions and, optionally, labels.
For the sake of completeness, I would like to give the OO version of #Lev-Levitsky's great answer:
lines = plt.plot(x,y)
ax = lines[0].axes
ax.set_xticks(list(ax.get_xticks()) + extraticks)
Here we use the Axes object extracted from the Lines2D sequence returned by plot. Normally if you are using the OO interface you would already have a reference to the Axes up front and you would call plot on that instead of on pyplot.
Corner Caveat
If for some reason you have modified your axis limits (e.g, by programatically zooming in to a portion of the data), you will need to restore them after this operation:
lim = ax.get_xlim()
ax.set_xticks(list(ax.get_xticks()) + extraticks)
ax.set_xlim(lim)
Otherwise, the plot will make the x-axis show all the available ticks on the axis.
I would like to draw a standard 2D line graph with pylot, but force the axes' values to be between 0 and 600 on the x, and 10k and 20k on the y. Let me go with an example...
import pylab as p
p.title(save_file)
p.axis([0.0,600.0,1000000.0,2000000.0])
#define keys and items elsewhere..
p.plot(keys,items)
p.savefig(save_file, dpi=100)
However, the axes still adjust to the size of the data. I'm interpreting the effect of p.axis to be setting what the max and min could be, not enforcing them to be the max or min. The same happens when I try to use p.xlim() etc.
Any thoughts?
Thanks.
Calling p.plot after setting the limits is why it is rescaling. You are correct in that turning autoscaling off will get the right answer, but so will calling xlim() or ylim() after your plot command.
I use this quite a lot to invert the x axis, I work in astronomy and we use a magnitude system which is backwards (ie. brighter stars have a smaller magnitude) so I usually swap the limits with
lims = xlim()
xlim([lims[1], lims[0]])
To answer my own question, the trick is to turn auto scaling off...
p.axis([0.0,600.0, 10000.0,20000.0])
ax = p.gca()
ax.set_autoscale_on(False)
I tried all of those above answers, and I then summarized a pipeline of how to draw the fixed-axes image. It applied both to show function and savefig function.
before you plot:
fig = pylab.figure()
ax = fig.gca()
ax.set_autoscale_on(False)
This is to request an ax which is subplot(1,1,1).
During the plot:
ax.plot('You plot argument') # Put inside your argument, like ax.plot(x,y,label='test')
ax.axis('The list of range') # Put in side your range [xmin,xmax,ymin,ymax], like ax.axis([-5,5,-5,200])
After the plot:
To show the image :
fig.show()
To save the figure :
fig.savefig('the name of your figure')
I find out that put axis at the front of the code won't work even though I have set autoscale_on to False.
I used this code to create a series of animation. And below is the example of combing multiple fixed axes images into an animation.
Try putting the call to axis after all plotting commands.