How to plot on a background image in Julia using Plots() - julia

I am trying to overlay a basic plot onto an image. It is not clear based on the Julia Docs: http://docs.juliaplots.org/latest/examples/pyplot/
How can I plot on an image? Here is my code in Julia:
using Plots
x_coordinate_holder = [30515.4, 30515.4, 30490.9, 30470.7, 30470.7, 30450.9, 30450.0,
30450.0, 30450.0, 30450.0, 30450.0, 30430.8, 30449.2, 30469.4,
30469.4, 30469.4, 30489.2, 30489.2, 30489.2, 30509.4, 30529.1,
30549.4, 30569.2, 30589.3, 30590.0, 30609.2, 30610.0, 30610.0,
30590.7, 30590.7, 30590.7, 30570.8, 30570.0, 30570.0, 30589.4,
30589.4, 30589.4, 30590.0, 30570.6, 30550.8, 30569.2, 30569.2,
30589.4, 30589.4, 30570.6, 30570.6, 30570.6, 30570.6, 30550.8,
30530.6, 30510.8, 30510.0, 30510.0, 30529.3, 30549.1, 30549.1,
30569.3, 30570.0, 30589.3, 30590.0, 30590.0, 30590.0, 30609.3,
30610.0, 30610.0, 30610.0, 30629.2, 30649.4, 30669.2, 30689.4,
30709.2, 30710.0, 30710.0]
y_coordinate_holder = [14186.3, 14186.3, 14209.2, 14229.3, 14229.3, 14249.1, 14269.3,
14269.3, 14269.3, 14269.3, 14269.3, 14289.1, 14290.0, 14290.0,
14290.0, 14290.0, 14309.2, 14309.2, 14309.2, 14329.4, 14330.0,
14349.4, 14369.2, 14389.3, 14370.5, 14350.8, 14330.6, 14330.6,
14330.0, 14330.0, 14330.0, 14349.2, 14330.8, 14330.8, 14310.6,
14310.6, 14310.6, 14290.8, 14270.6, 14270.0, 14270.0, 14270.0,
14270.0, 14270.0, 14270.0, 14270.0, 14270.0, 14270.0, 14270.0,
14250.6, 14250.0, 14230.7, 14249.1, 14230.7, 14210.9, 14210.9,
14190.7, 14209.1, 14190.7, 14209.5, 14209.5, 14209.5, 14210.0,
14229.3, 14210.9, 14190.7, 14209.2, 14210.0, 14190.8, 14190.0,
14190.0, 14209.3, 14209.3]
plotly()
plot(x_coordinate_holder, y_coordinate_holder, color = :blue, linewidth=2)
gui()
Note: I looked at How plot on Images with Plots.jl?
This example doesn't work anymore which is why I am asking the question again. Here is my updated code.
plotly()
img = Image("/path/to/image/file/exmaple/test.png)
plot(img)
plot!(x_coordinate_holder, y_coordinate_holder, color = :blue, linewidth=2)
gui() #Should open up a browser window/tab and show the plot in there.
When running this I get the following error:
* **ERROR: LoadError: UndefVarError: Image not defined** *
Can anyone provide a complete example?

Here is the code to plot an image with a plot on it, and have it auto scale:
using Plots
using Images
img = load("/Users/xxxx/xxxx/xxxx-xxxx.png")
xMin = minimum(x_coordinate_holder)-30
xMax = maximum(x_coordinate_holder)+30
yMin = minimum(y_coordinate_holder)-30
yMax = maximum(y_coordinate_holder)+30
#print("X-Coords: ", xMin, ", ", xMax, " Y-Coords: ", yMin, ", ", yMax, "\n")
plot1 = plot(img, xlim=(xMin,xMax), ylim=(yMin, yMax), yflip = false)
plot1 = plot!(x_coordinate_holder, y_coordinate_holder, color = :black, linewidth=0.4)
plot2 = plot(e_holder, color = :orange, linewidth=2)
plot(plot1, plot2)
gui()
Note that xlim and ylim allow the image I am plotting on to scale proportionally with the size of the plot(i.e. if the plot is larger, it auto scales the image to show the full plot).
Note that x_coordinate_holder, y_coordinate_holder, and e_holder are just arrays defined before I run this code.
This code makes plot1 and plot2 show up next to one another.
It is also worth mentioning that I tried to do this using plotly and was unsuccessful. I had it working without proper image scaling, but when I tried to scale the image it no longer worked so I went to the default backend.

Related

How to put background image to the plot in Rust plotters lib

I'm trying to draw car trips on a plane. I'm using Plotters library.
Here is some code example of trips' drawing procedure:
pub fn save_trips_as_a_pic<'a>(trips: &CarTrips, resolution: (u32, u32))
{
// Some initializing stuff
/// <...>
let root_area =
BitMapBackend::new("result.png", (resolution.0, resolution.1)).into_drawing_area();
root_area.fill(&WHITE).unwrap();
let root_area =
root_area.margin(10,10,10,10).titled("TITLE",
("sans-serif", 20).into_font()).unwrap();
let drawing_areas =
root_area.split_evenly((cells.1 as usize, cells.0 as usize));
for (index, trip) in trips.get_trips().iter().enumerate(){
let mut chart =
ChartBuilder::on(drawing_areas.get(index).unwrap())
.margin(5)
.set_all_label_area_size(50)
.build_ranged(50.0f32..54.0f32, 50.0f32..54.0f32).unwrap();
chart.configure_mesh().x_labels(20).y_labels(10)
.disable_mesh()
.x_label_formatter(&|v| format!("{:.1}", v))
.y_label_formatter(&|v| format!("{:.1}", v))
.draw().unwrap();
let coors = trip.get_points();
{
let draw_result =
chart.draw_series(series_from_coors(&coors, &BLACK)).unwrap();
draw_result.label(format!("TRIP {}",index + 1)).legend(
move |(x, y)|
PathElement::new(vec![(x, y), (x + 20, y)], &random_color));
}
{
// Here I put red dots to see exact nodes
chart.draw_series(points_series_from_trip(&coors, &RED));
}
chart.configure_series_labels().border_style(&BLACK).draw().unwrap();
}
}
What I got now on Rust Plotters:
So, after drawing it in the 'result.png' image file, I struggle to understand these "lines", because I don't see the map itself. I suppose, there is some way in this library to put a map "map.png" in the background of the plot. If I would use Python, this problem will be solved like this:
# here we got a map image;
img: Image.Image = Image.open("map-image.jpg")
img.putalpha(64)
imgplot = plt.imshow(img)
# let's pretend that we got our map size in pixels and coordinates
# just in right relation to each other.
scale = 1000
x_shift = 48.0
y_shift = 50.0
coor_a = Coordinate(49.1, 50.4)
coor_b = Coordinate(48.9, 51.0)
x_axis = [coor_a.x, coor_b.x]
x_axis = [(element-x_shift) * scale for element in x_axis]
y_axis = [coor_a.y, coor_b.y]
y_axis = [(element-y_shift) * scale for element in y_axis]
plt.plot(x_axis, y_axis, marker='o')
plt.show()
Desired result on Python
Well, that's easy on Python, but I got no idea, how to do similar thing on Rust.

Native PGFPlots in JULIA language changing font size

I am using the native PGFPlots.jl plotting software in Julia language.
I will be ever so grateful if you could let me know how to change the font size of:
Title (I suspect with legend style={font=\small})
legend
xlabel
ylabel
My code:
pushPGFPlotsOptions("scale=1.5")
Plot1 = GroupPlot(2, 2, groupStyle = "horizontal sep = 1.6cm, vertical sep = 2.cm")
push!(Plot1b, Axis([
Plots.Linear(Se, H_Kg, mark="none", style="red, very thick"),
Plots.Linear(Se, H_Vg, mark="none", style="dashed, blue, very thick"),
], title="Se(H)", xlabel=L"$Se[-]$", ylabel=L"$H[cm]$", style="smooth", xmin=Se_Min, xmax=Se_Max, ymin=H_Min, ymode="log"))
push!(Plot1, Axis([
Plots.Linear(Se, Kunsat_Kg, mark="none", style="red, very thick", legendentry=L"$KG$"),
Plots.Linear(Se, Kunsat_Vg, mark="none", style="dashed, blue, very thick", legendentry=L"$VG$"),
], title="K(Se)", xlabel=L"$Se[-]$", ylabel=L"$K(Se)[cm/h]$", style="smooth", xmin=Se_Min, xmax=Se_Max, ymin=K_Min, legendStyle = "{at={(-0.3,-0.4)}, anchor=south west, legend columns=-1}"))
save(Path, Plot1)
Many thanks for any help you may provide,

Barplot with errors in bokeh

I am trying to draw a figure like that http://seaborn.pydata.org/_images/seaborn-barplot-1.png
As I understand bokeh don't have special method for barplot with error, so I decided to use Seaborn and then convert it into bokeh chart by to_bokeh() function.
sns.set_style("whitegrid")
plot = sns.barplot(data=[[1,2], [3,4]])
plot.get_figure().savefig('1.jpg')
l = layout([[widgetbox(*controls), to_bokeh(plot.get_figure())]])
save(l)
It save normal plot, like at the picture, but bokeh shows only error line, and no bars.
What do I wrong, is it bug? Is there simpler way to draw chars like that in bokeh. I also should use strings as a ticks.Does bokeh support it?
I have found solution (at least I hope :) )
box_plot = figure(x_range=['Ctrl', '- FBC', 'Rescue'])
X = range(1, 4)
Y = some_data # e.g. mean(data)
Err = another_piece_of_data # e.g. std(data)
box_plot.vbar(x=X, width=0.5, top=Y)
#add errors
err_xs = []
err_ys = []
for x, y, err in zip(X, Y, Err):
err_xs.append((x, x))
err_ys.append((y - err, y + err))
box_plot.multi_line(err_xs, err_ys, color='red', line_width=2)
l = layout([[box_plot]])
save(l)

kivy garden Grap xmin xmax update (real time)

is there a way to update xmin and xmax of Graph in kivy garden?
At the moment, my xmin is 0 and xmax is 10 and I am plotting a list containin (x,y) points. y starts from 0 and is incremented every second and x is just a counter that counts iterations. so once x is > 10 the graph is not updated in real time so the x axis does not move like e.g. 1-11 and next second 2-12 and next 3-13 etc etc so I always show 10 values but the grap is 'live'.
How to achieve it in kivy garden Graph?
graph = Graph(
xlabel='Iteration',
ylabel='Value',
x_ticks_minor=1,
x_ticks_major=5,
y_ticks_major=1,
y_grid_label=True,
x_grid_label=True,
padding=5,
xlog=False,
ylog=False,
x_grid=True,
y_grid=True,
xmin=0,
xmax=10,
ymin=0,
ymax=11,
**graph_theme)
Never used this flower, but try graph.xmin = <something>. If it doesn't work, the code probably has other name for that variable, because xmin in Graph(...) is only keyword argument. Try to look at its __init__() and after you see what has the value, try to access it via graph.<variable>. If it's not a local variable, then it should work.
However, this only says how to change it manually. If you have more of your code except graph = Graph(...), paste it, an issue may be there. Otherwise you could try to report a glitch at garden's repo for Graph.
According to the code found in "garden.graph" library you can call the instance of the graph to set properties of xmax, xmin, ymax and ymin.
As an example, I am seting the property of ymax to be maximum value of my data set:
Class Test(Widget):
data = #list of datapoints
graph_test = ObjectProperty(None)
def setgraph:
plot = MeshLinePlot(color=[1, 0, 0, 1])
self.graph_test.ymax=max(data[1])
plot.points = [(data[0][i], data[1][i]) for i in range(0,500)]
self.graph_test.add_plot(plot)
I also have a .kv file that contains the following
#:kivy 1.0.9
<Test>:
graph_test : graph_test
Graph:
id: graph_test
plot: MeshLinePlot
xlabel:'X'
ylabel:'Y'
x_ticks_minor:1000000000000
x_tics_major:5000000000000
y_ticks_major:1000
y_grid_label:True
x_grid_label:True
padding:5
x_grid:True
y_grid:True
xmin:123413241234
xmax:123412341234
ymin:2000
ymax:15000
pos: 0, 0
size: root.width , root.height
Old question, but I'm doing this with some Kivy Graphs and rather than resetting the XMin and XMax (which means those numbers would keep counting up for as long as the graph is running "live"), we shift the data points and leave the X range alone.
We built this simple LiveGraph class to wrap it, works nicely and is relatively performant.
class LiveGraph(Graph):
def __init__(self, num_data_points=50, **kwargs):
super(LiveGraph, self).__init__(**kwargs)
self._num_data_points = num_data_points
self.xmin = 0
self.xmax = num_data_points
build_chart()
def build_chart(self):
plot = MeshLinePlot()
# Initialize with empty Y values to start with
plot.points = [(x,0) for x in range(self._num_data_points)
# I tested a number of ways to do this - this ended up being
# the fastest.
def add_point(self, point_value):
new_points = self.plots[0].points
new_points = [(i, new_points[i+1][1]) for i in range(self._num_data_points - 1)]
new_points.append([len(new_points) - 1, new_value])
self.plots[0].points = new_points

R grid mismatch of units

The following function draws the rectangle r1 as required, but an attempt to offsets it by 0.5 in native units fails. I have tried x=unit(1,"native"), etc. but this does not solve the trivial problem. Thank you for your help.
#rm(list=ls(all=TRUE))
library(grid)
vp__g = viewport(xscale=c(-1.5,5.5), yscale=c(-5.5,2.0))
pushViewport(vp__g)
test = function() {
r1 = rectGrob(x=0, y=0, width=2, height=1, default.units="native")
grid.draw(r1)
r1a = editGrob(r1, vp=viewport(x=0.5,y=0.5), name="r1a")
grid.draw(r1a)
}
test()

Resources