How can i change the existing Bokeh plot ticks size, specifically package that was being used to plot already defined a plot layout of bokeh ? How can i overwrite those layout ? Below is the example code of the plot to reproduce the plot.
# !pip install arlpy
import arlpy.uwapm as pm
import arlpy.plot as plt
env = pm.create_env2d()
pm.plot_env(env, width=900)
Here is the generated figure for which i want to redefined layout.
This is a bit tricky and but it is possible to get it done. But I have to mention that I don't like this solution.
To get a figure you have to enable the hold argument because otherwise it will be plotted immediately and return None. Then you can get the current figure using arlpy.plot.gcf() and set all parameters. To show the figure now you have to use the bokeh call show because the figure is a bokeh object now and in arlpy it is not available to set the hold to False again and show the figure. In fact the figure is now waiting for some data to add.
Here is an example.
from bokeh.plotting import figure, show
import arlpy.plot
arlpy.plot.figure(title='Demo 1', width=500)
arlpy.plot.plot([0,10], [0,10], hold=True)
p = arlpy.plot.gcf()
p.axis.major_tick_line_width = 3
show(p)
Unfortunately I found no solution where I use import arlpy.uwapm as pm because there is no return parameter in the plot_envfunction. So you can`t get the figure and make some changes.
I hope this helps. But I guess it is not satisfying.
Related
I need some help to make my cph plot bigger, but unfortunately, it seems like figsize can't be applied on this plot! Can somebody help me please?
I'm using Jupyter Notebook on pandas!
cph.plot()
Here the problem is that the plot function actually plots my features, but they are too much so their names overlap and I can see nothing! I need the plot to be bigger!
Seems like cph.plot() calls matplotlib.pyplot.plot in the back-end. By default, Matplotlib uses the last created figure, so creating a figure with your specified width and height should do the trick:
import matplotlib.pyplot as plt
# 8, 12 => width and height in inches
plt.figure(figsize=(8, 12))
cph.plot(/*your params here*/)
See if this works.
you can try the following command:
import seaborn as sns
sns.set(rc={'figure.figsize':(18,10)})
cph.plot()
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
f_name = font_manager.FontProperties(fname='C:/Windows/Fonts/HANBatangExt.ttf').get_name()
rc('font', family=f_name)
뛰기운동
plt.plot(run_before, run_after, 'ro-')
걷기운동
plt.plot(walk_before, walk_after, 'bo-')
plt.figure(figsize=((10,8)))
plt.show()
It is not an error but the output you see is due to the fact that you have used
plt.figure(figsize=((10,8)))
after plt.plot. Therefore, you first get a figure on you screen and a figure object is created by plt.figure. To get rid of it, you should first set the figure size before plotting, something like this:
plt.figure(figsize=((10,8)))
plt.plot(run_before, run_after, 'ro-')
plt.plot(walk_before, walk_after, 'bo-')
plt.show()
There are other ways to set the figure size after plotting but since your code is fine enough, you are good to go with the above modification.
It's not an Error it shows your figure dimensions. If you want to get rid of it try using rcParams parameter
plt.rcParams["figure.figsize"] = (10,8)
It is not the error just a message that an image file is returned
If you are using the VS_code then
Click on the left side little code icon
Select Image/Png option this will make your graph visible
If you havent seleced the Image/Png option then you might not be able to see the output
I'm new to Bokeh and Python, and this is my first Stack Overflow question as well.
I'm using Bokeh to plot trajectory profiles of particles diffusing in the brain, but have it be animated. I have been able to successfully create a program that plots the points, but once all the points are plotted, it stops. I want to be able to loop the animation so that once all the points are plotted, it clears itself and starts over.
I am still very unfamiliar with coding terms, and I wasn't able to find something that could do this. I thought I was on the right track with importing using the reset function inside an if statement, but it doesn't seem to work. I have looked at the following as well for reference:
How to animate a circle using bokeh
Here is my code so far plotting a random trajectory:
import numpy as np
from bokeh.plotting import figure, show, gridplot, vplot, hplot, curdoc
from bokeh.io import output_notebook
from bokeh.client import push_session
from bokeh.core.state import State as new
# This is where the actual coding begins.
b = np.random.rand(300, 3)
xlist = b[:, 1]
ylist = b[:, 2]
# create a plot and style its properties. Change chart title here.
p = figure(title='PEG_PLGA15k_F68_R2_P81', title_text_font_size='13pt',
x_range=(min(xlist), max(xlist)), y_range=(min(ylist), max(ylist)),)
# add a text renderer to out plot (no data yet)
r = p.line(x=[], y=[], line_width=3, color='navy')
session = push_session(curdoc())
i = 0
ds = r.data_source
# create a callback that will add a number in a random location
def callback():
global i
ds.data['x'].append(xlist[i])
ds.data['y'].append(ylist[i])
ds.trigger('data', ds.data, ds.data)
if i < xlist.shape[0] - 1:
i = i + 1
else:
new.reset()
# Adds a new data point every 67 ms. Change at user's discretion.
curdoc().add_periodic_callback(callback, 67)
session.show()
session.loop_until_closed()
If all you want is to restart the animation once you reach some condition (like "all points have been plotted") you can just reset the DataSource. So, for instance, on your example you should have:
else:
i = 0
ds.data['x'] = []
ds.data['y'] = []
instead of:
else:
new.reset()
and that should do the trick. Just use your datasource... State is a more general component that should be used on different level and not to manage plot glyphs and datasources.
A couple of quick notes here:
On your question you've mentioned a link to the 0.10 version documentation but from your code I can tell you are not using a newer version (0.11.x). Always be sure to use the right docs for the version of Bokeh you are using since there might be a few changes between one version and another before the project reach 1.0.
You don't need to call ds.trigger('data', ds.data, ds.data) since bokeh property system will automatically detect your changes to the datasource fields inside your callback
You are designing/running your script as a bokeh script that uses a client session to the server (so you'll have a running instance of bokeh server somewhere and your script communicates with it). I'd suggest you to consider running your code as a Bokeh App instead, so your session and your code run inside the bokeh server instance. You can see more details about the difference at the bokeh server section on the official docs.
At the moment I am working with Spyder and doing my plotting with matplotlib. I have two monitors, one for development and another for (data) browsing and other stuff. Since I am doing some calculations and my code often changes, I often (re)execute the code and have a look at the plots to check if the results are valid.
Is there any way to place my matplotlib plots on a second monitor and refresh them from the main monitor?
I have already searched for a solution but could not find anything. It would be really helpful for me!
Here's some additional information:
OS: Ubuntu 14.04 (64 Bit)
Spyder-Version: 2.3.2
Matplotlib-Version: 1.3.1.-1.4.2.
I know it's an old question but I came across a similar problem and found this question. I managed to move my plots to a second display using the QT4Agg backend.
import matplotlib.pyplot as plt
plt.switch_backend('QT4Agg')
# a little hack to get screen size; from here [1]
mgr = plt.get_current_fig_manager()
mgr.full_screen_toggle()
py = mgr.canvas.height()
px = mgr.canvas.width()
mgr.window.close()
# hack end
x = [i for i in range(0,10)]
plt.figure()
plt.plot(x)
figManager = plt.get_current_fig_manager()
# if px=0, plot will display on 1st screen
figManager.window.move(px, 0)
figManager.window.showMaximized()
figManager.window.setFocus()
plt.show()
[1] answer from #divenex: How do you set the absolute position of figure windows with matplotlib?
This has to do with matplotlib, not Spyder. Placing the location of a figure explicitly appears to be one of those things for which there's really just workarounds ... see the answers to the question here. That's an old question, but I'm not sure there's been change since then (any matplotlib devs, feel free to correct me!).
The second monitor shouldn't make any difference, it sounds like the issue is just that the figure is being replaced with a new one.
Fortunately you can update figures you've moved to where you want them pretty easily, by using the object interface specifically, and updating the Axes object without creating a new figure. An example is below:
import matplotlib.pyplot as plt
import numpy as np
# Create the figure and axes, keeping the object references
fig = plt.figure()
ax = fig.add_subplot(111)
p, = ax.plot(np.linspace(0,1))
# First display
plt.show()
# Some time to let you look at the result and move/resize the figure
plt.pause(3)
# Replace the contents of the Axes without making a new window
ax.cla()
p, = ax.plot(2*np.linspace(0,1)**2)
# Since the figure is shown already, use draw() to update the display
plt.draw()
plt.pause(3)
# Or you can get really fancy and simply replace the data in the plot
p.set_data(np.linspace(-1,1), 10*np.linspace(-1,1)**3)
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
plt.draw()
I am creating a plot with matplotlib. Once I have the figure I am showing it inside a layout in my MainWindow, and the figure looks like this one:
Which looks good and everything is ok.
The problem is that, before showing it I am savin the figure with fig.savefig('EvolLine.png')
And the figure saved looks different. Then when I try to use this saved figure in a PDF file it does not look good.
Here it is the saved figure:
In addition, if I save the figure manually using the tool from the tool bar in the plot, then the saved figure looks good again.
I do not why if I save the figure "programatically" it looks bad, like compressed.
So how could I programatically save the figure and make it look like in the display??.
EDIT:
If that helps, this is the process that I am doing to save and plot:
fig = generateFigure(someData)
fig.savefig('EvolLine.png')
MyCanvas = FigureCanvas(fig)
navi_toolbar = NavigationToolbar(MyCanvas, self)
self.ui.verticalLayoutGraph4_3.addWidget(navi_toolbar)
self.ui.verticalLayoutGraph4_3.addWidget(MyCanvas)
#just to test
fig.savefig('EvolLine_AfterPlot.png')
Your problem is that when showing your figure in your program you are controlling the aspect ratio, meaning that the x-ticks do not overlap. However when saving the figure you are allowing matplotlib to automatically guess what it should be doing, and it's getting this wrong.
You can use fig.set_size_inches() to control the aspect ratio by setting an appropriate size, the code below demonstrates this as well as shows the different results.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,100,1000)
y = np.sin(x)
plt.plot(x,y)
plt.xticks(range(0,100,2))
fig = plt.gcf()
fig.set_size_inches(16,4)
plt.savefig('filename.png')
Original
Fixed