Skip weekends on stock charts with matplolib - python

This is not duplicate, because existing answers on similar questions don't describe exactly what I need.
Matplotlib has great formatters inside and I love to use them:
ax.xaxis.set_major_locator(matplotlib.dates.MonthLocator())
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%b%y'))
They let me plot such stock market charts:
This is what I need, but it has 1 issue: weekends. They are present on x axis and make my chart a little ugly.
Other questions about this issue give advice to create custom formatter. They show examples of such formatters. But no one of them do pretty formatting like matplotlib do:
May19, Jun19, Jul19...
I mean this line of code:
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%b%y'))
My question is: please help me to format x axis like matplotlib do: May19, Jun19, Jul19... and don't create weekends when stock market is closed.

What you could almost always do is something similar to what Nic Wanavit suggested.
Manually set your labels, depending on what you need on your axis.
Especially in this case the plot is looking a bit ugly because you have timespans in your data that are not provided with actual data (the weekends in this case) so pyplot will simply connect these points with the corresponding length from the x-axis.
What you can do then is just to plot your data equally distant - which is correct if the data is daily - otherwise consider to interpolate it using e.g. pandas bultin interpolation.
To avoid pyplot automatically detect the index I had to do this:
df['plotidx'] = [i for i in range(len(df['close'])):
Here all the closing values for the stock are stored in a column named 'close' obvsl.
You plot this correspondingly.
Then you can obtain all the ticks created via
labels = [item.get_text() for item in ax.get_xticklabels()]
Adjust them as desired with
labels[i] = string_for_the_label_no_i
Then get them back on the graph using
ax.xaxis.set_ticklabels(labels)
You need to somewhat "update" the plot then. Also keep in mind, that resizing a lot could end up with the labels being as also said in the documentation strange location.
It is some kind of a workaround but worked fine for me because it feels natural to plot data equally distant next to each other rather then making up some data for the weekends.
Greets

to set the x ticks
assuming that you have the dates variable in dataframe row df['dates']
ax.xaxis.set_ticks(df['dates'])

Related

Broken X axis for pandas time series with gaps

I have a time series with many gaps. Default plotting gives:
Obviously its impossible to discern any detail here, and I can't just make the plot meters wide. So I need to get rid of the gaps.
I can of course just plot it without gaps as done here, but just plotting everything on a continuous axis will make the plot very unintuitive:
The only proper solution would be a broken X axis to properly display datetime information without having gaps, like shown here
How do I get that? I could first have to identify the gaps and then place the broken axis thingy. But I can't believe that there is no easier way. Does anyone know of a simpler, cleaner way? I would have guessed that this is a standard pandas/matplotlib feature....

Identifying Plot Name or Visualization Implementation

I'm working on a dataset of SMS records [datetime_entry, sms_sent] and I was looking to copy a really effective trend visual from a well cited Electricity demand study. Does anyone know the name of this plot, or the implementation of something similar in Python (as I'm not sure this was done in Python).
I know how to subplot the 4 charts after splitting the data by quarter, I'm just stumped on the plot type and stylization.
This is what matplotlib calls an eventplot.
Essentially each vertical line represents an occurance of a Mwh demand during that specific hour. So each row in the plot should have as many vertical lines as there are days in that quarter.
While it works in this plot for these data, relying on the combination of alpha level + data density can be slightly unreliable as the data change as the number of overlapping points is not readily visible. So you can also create a similar visualization using hist2d, where you manually specify your bins.

Add Label Annotations on Axes

I currently annotate my charts with the last value of each series by adding a Label and supplying my the name of corresponding range it's plotted on:
Label(
...
x=data.index.max(),
y=data.loc[data.index.max(), 'my_col'],
y_range_name='my_range'
...
)
Which gives me:
How do I move the labels so they are positioned on their respective axis?
Example:
Please note that my labels' y-positioning is off, so I need some help with that aspect too. I've tried tweaking the y_offset but this has not yielded any consistently good results.
My data are always numerical time series.
As of Bokeh 1.2 there is no built-in annotation or glyph that will display outside the central plot area. There is an open issue on GitHub that this is similar to that you can follow or comment on. For the time being, something like this would require making a custom extension

3D plot in python

I have worked out a table somewhat like the one in the link. The ultimate goal for plotting is to find out if there is a seasonal change pattern for certain products in a state. I have tried to figure out a 3-D plot in python, with x-axis being product name, y-axis being month and z-axis being YR2012 and YR2013 respectively.
And another small question related to this is how could I make python know that the SALESMONTH column contains month type of data rather than plain integers.
Thanks!

Bokeh line graph looping

I’ve been working on bokeh plots and I’m trying to plot a line graph taking values from a database. But the plot kind of traces back to the initial point and I don’t want that. I want a plot which starts at one point and stops at a certain point (and circle back). I’ve tried plotting it on other tools like SQLite browser and Excel and the plot seems ok which means I must be doing something wrong with the bokeh stuff and that the data points itself are not in error.
I’ve attached the images for reference and the line of code doing the line plot. Is there something I’ve missed?
>>> image = fig.line(“x”, “y”, color=color, source=something)
(Assume x and y are integer values and I’ve specified x and y ranges as DataRange1d(bounds=(0,None)))
Bokeh does not "auto-close" lines. You can see this is the case by looking at any number of examples in the docs and repository, but here is one in particular:
http://docs.bokeh.org/en/latest/docs/gallery/stocks.html
Bokeh's .line method will only "close up" if that is what is in the data (i.e., if the last point in the data is a repeat of the first point). I suggest you actually inspect the data values in source.data and I believe you will find this to be the case. Then the question is why is that the case and how to prevent it from doing that, but that is not really a Bokeh question.

Categories