I am trying to get my labels turned up correctly.
I want it to show 10 values on the list, but I have no idea how.
The usual way to show it doesn't work and when there are a lot of values, it is hard to read, see the picture.
Here you see that it is impossible to read the data.
Do you have an idea to make it work properly?
I have tried autoDateLocator, but that didn't work. The axis values were wrong.
I also tried to do that manually, but the same result happened.
Thanks in advance!
I have kinda 'solved this issue'. I asked around and didn't really find an answer that suited my needs, as every tick always gets shown.
However, when I keep the xtick_labels in the datetime-format, it gets sorted out by matplotlib itself, if there are too many values to show. This according to the dataset Armamatita provided
import matplotlib.pyplot as plt
import datetime
import numpy as np
x = np.array([datetime.datetime(i,1,1) for i in range(1700,2017)])
y = np.random.randint(0,100,len(x))
fig, ax = plt.subplots()
ax.plot(x,y)
plt.show()
I when the days I want to see is more than 14, I just let matplotlib pick te xtick_labels. When equal or less than 14, I add it myself using:
alldays = DayLocator()
weekFormatter = DateFormatter('%a %b %d %Y')
and this right before returning the fig:
ax.xaxis.set_major_locator(alldays)
ax.xaxis.set_major_formatter(weekFormatter)
It isn't the most neat pythonic code, but it does the trick.
Related
Matplotlib has some pretty sophisticated code figuring out how to show labels, but sometimes it cramps its labels more than looks good on presentations. Is there any way to tweek it?
For example, suppose we're plotting something against date:
figure = plt.figure(figsize=(8,1))
ax = plt.gca()
ax.set_xlim(xmin=np.datetime64('2010'), xmax=np.datetime64('2020-04-01'))
We get an x-axis like this:
But supposing we want it to show more spaced years, like this:
We can kludge it in any given case by editing the labels 'mechanically'. E.g.:
ax.set_xticks([tick for i, tick in enumerate(ax.get_xticks()) if i%2==0]) # Every other year.
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Y"))
But that's fragile, and it breaks whenever the x limits change.
Is there any way to force more spacing in the tick setup algorithm?
Oh! Found the matplotlib source code and it led me to AutoDateLocator:
ax.xaxis.set_major_locator(matplotlib.dates.AutoDateLocator(maxticks=8))
The corresponding locator for non-dates is MaxNLocator .
My for loop, presented here, is supposed to generate a plot for each year. It is supposed to print the year, then show a figure. But what happens is, all of the years get printed first, then all of the figures get printed.
On top of that. There is an empty figure that gets printed at the very end.
I am using Spyder for the record.
Pics attached to show the outputs.
Can you please help me understand what is happening here so that I can control my outputs in the future?
Thank you so much.
import pandas as pd
import matplotlib.pyplot as plt
plt.figure(0)
for i in range(5):
k=2014+i
crimesyear=crimes.loc[crimes['Year'].isin([k])]
crimesyear.groupby('Month')['INCIDENT_ID'].c**strong text**ount().plot(marker='o')
plt.figure(i+1)
plt.xticks(numpy.arange(12),months)
plt.ylabel('Number of Crimes')
plt.show
print(k)
First part of output
Last part of output
Matplotlib has a way of generating plots without using the stateful interface. This should help you generate plots in a loop.
fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(5, 10))
for i, a in enumerate(ax):
a.plot(np.arange(10))
a.set_title(f'test {i}')
Check out the Object-Oriented API of matplotlib here
Here is a simplified version of your graphs without all the data.
import pandas as pd
import numpy
import matplotlib.pyplot as plt
for i in range(5):
k=2014+i
plt.figure(i)
plt.title(str(k))
plt.ylabel('Number of Crimes')
plt.show()
Your extra blank graph came from the plt.figure(0) at the start. You only need to do plt.show() once at the end. You can set the titles using plt.title(<string goes here>). In general, displaying something is an asynchronous call to another program, so it is often difficult to predict the order that you'll see things - I'm not familiar with spyder for the specifics here.
I am very new to coding and just really stuck with a graph I am trying to produce for a Uni assignment
This is what it looks like
I am pretty happy with the styling my concern is with the y axis. I understand that because I have one value much higher than the rest it is difficult to see the true values of the values further down the scale.
Is there anyway to change this?
Or can anyone recommend a different grah type that may show this data mor clearly?
Thanks!
You can try using a combination of ScalarFormatter on the y-axis and MultipleLocator to specify the tick-frequency of the y-axis values. You can read more about customising tricks for data-visualisations here Customising tricks for visualising data in Python
import numpy as np
import seaborn.apionly as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
ax_data = sns.barplot(x= PoliceForce, y = TotalNRMReferrals) # change as per how you are plotting, just for an example
ax_data.yaxis.set_major_locator(ticker.MultipleLocator(40)) # it would have a tick frequency of 40, change 40 to the tick-frequency you want.
ax_data.yaxis.set_major_formatter(ticker.ScalarFormatter())
plt.show()
Based on your current graph, I would suggest lowering the tick-frequency (try with values lower than 100, say 50 for instance). This would present the graph in a more readable fashion. I hope this helps answer your question.
I am fairly new to Bokeh and try to achieve the following:
I have a dataset with rows containing dates in the format dd-mm-yyyy.
The dates are counted and then plotted.
When zoomed in I want Bokeh to show the indiviudal dates (that works already).
When zoomed out I want Bokeh only to show the months (or years when zoomed out even further). Right know the index gets pretty messy due to individual dates getting closer and closer the more you zoom out.
Is there a way to tell Bokeh to change what is shown in the index depending on how far you zoomed in or out?
Here is my code:
import pandas as pd
from bokeh.charts import TimeSeries
from bokeh.io import output_file, show, gridplot
transactionssent = dict(pd.melt(df,value_vars=['datesent']).groupby('value').size())
transactionssent2 = pd.DataFrame.from_dict(transactionssent, orient= 'index')
transactionssent2.columns = ['Amount']
transactionssent2.index.rename('Date sent', inplace= True)
ts = TimeSeries(transactionssent2, x='index', y='Amount')
ts.xaxis.axis_label = 'Date sent'
If someone knows please point me in the right direction.
Thanks and best regards,
Stefan
What you've described as what you want already sounds like the standard behavior of the built in datetime axis. So, my guess is that TimeSeries is treating your dates as string/categorical values, which would explain why you are not seeing standard datetime axis scaling.
I should add that bokeh.charts (including TimeSeries) has recently been removed to a separate project and also is known to have problems. I would actually discourage it's use at this point. Fortunately, it's also easy to plot timeseries with the bokeh.plotting API, which is stable, well-tested and documented, and in widespread use.
Here is an example to demonstrate:
import datetime
import numpy as np
from bokeh.io import show, output_file
from bokeh.plotting import figure
# some fake data just for this example, Pandas columns work fine too
start = datetime.datetime(2017, 1, 1)
x = np.array([start + datetime.timedelta(hours=i) for i in range(800)])
y = np.sin(np.linspace(0, 2, len(x))) + 0.05 * np.random.random(len(x))
p = figure(x_axis_type="datetime")
p.line(x, y)
output_file("stocks.html")
show(p)
Whose axis looks like this when first displayed:
But like this when zoomed in:
You can also further customize how the dates are formatter by setting various properties on the p.xaxis[0].formatter. For details about available properties, see the reference guide:
http://docs.bokeh.org/en/latest/docs/reference/models/formatters.html#bokeh.models.formatters.DatetimeTickFormatter
Hey probably a simple question, but cant find the answer to this. I am monitoring a series of bits with a timestamp. I can plot the state of them just fine, but in the plots there are a skewed line between 0->1 and 1->0, where there should just be a straight line at the time they switch. How to avoid this skewed line? It makes it look like i have values in between when i dont.
EDIT: As pointed out below, using step instead of plot solves the problem. Thanks:)
You can use the plt.step function instead of plot,
import numpy as np
import matplotlib.pyplot as plt
def heaviside(x):
return .5*(np.sign(x)+1.)
x = np.linspace(0,100,10)
y = heaviside(np.random.random(10)-.5)
plt.step(x,y)
plt.ylim(-1.5,1.5)
plt.show()
which gives,
You can use a stemplot:
plt.stem(x, y)
or a step plot
plt.step(x, y)