How to draw vertical lines over two diagrams? - line

Since SF seems to have further problems it is kind of difficult to find answers to this question. I already know how to plot 2 diagrams with (set) multiplot. But how can I draw some vertical lines going over both diagrams. eg.
set parametric
set trange [a:b]
plot 16,t
I have no clue how to do this over two plots.
The plot should look like this: http://i.stack.imgur.com/90Uue.png

Usually, I use set arrow ... nohead to draw vertical lines. In order to plot them over two plots, I would use screen coordinates for the y-value:
set multiplot layout 2,1
set xrange [0:300]
set arrow 1 from first 16,screen 0.05 to first 16, screen 0.95 nohead lc rgb 'red' lw 2
set arrow 2 from first 256,screen 0.05 to first 256, screen 0.95 nohead lc rgb 'red' lw 2
plot x
unset arrow
plot 2*x
unset multiplot

Here is a code snippet that illustrates how to do it (though it needs some tuning in alignment).
set multiplot
# plot 1
set origin 0,0
set size 1,.5
set xrange [0:2*pi]
set yrange [-1.1:1.1]
plot sin(x)
# plot 2
set origin 0,.5
set size 1,.5
plot cos(x)
# line
set origin 0,0
set size 1,1
unset xtics
unset ytics
unset xlabel
unset ylabel
unset border
set parametric
plot 1,t
unset multiplot

Related

Matplotlib, Inkscape, Spyder, plots and SVG compatibility (true axis size)

I have been plotting data for years during my PhD and always had to fight with something that unfortunately plagues the scientific community: negligent data manipulation.
My problem is that when I plot with matplotlib two graphics with different number lengths in the Y axis, the result is two graphics with two different X axis sizes.
When I copy the resulting SVG image directly from Spyder IPython console (Copy SVG) and paste in Inkscape for editing, matching the axis is a painful task which requires scaling them correctly with absolute precision. I am aware there plugins that are able to rescale plots in Inkscape and etc.
Bonus solved problem 1: for some reason, the size of an SVG created by matplotlib is scaled by 0.75 relative to Inkscape
Bonus solved problem 2: Matplotlib uses... inches, so the 25.4 that is in the following code lines is simply to convert from inch to millimeters.
Sometimes, having more control at the root is better than patching and patching and patching. So here is my solution to those who have been agonizing like me over being able to have two plots with the same absolute axis sizes:
from matplotlib import pyplot as plt
inch = False # Set to True if you want to use inch (blergh...).
width = 50 # The actual size in millimeters for the X axis to have.
height = 20 # The actual size in millimeters for the Y axis to have.
figsize = [(-0.212+width)/(1+24.4*(not inch)),(-0.212+height)/(1+24.4*(not inch))] # [W, H]
# Attention to the 0.212 mm which is thickness of the axis line; the cap at the end of the axis is half of thickness and is accounted for the size of the axis in Inkscape. So, when you use the size of a line from Inkscape as the desired size of the axis in a plot from matplotlib, ax.get_linewidth() by default should be 0.8 (whatever 0.8 is.. but it seems like 0.212/25.4 * 100).
height_scale = 3 # Scale to account for the axis title, labels and ticks.
width_scale = 2 # Scale to account for the axis title, labels and ticks.
figsize = [width_scale*figsize[0]/0.75, height_scale*figsize[1]/0.75]
fig = plt.figure(figsize = (figsize[0], figsize[1]))
wpos = (50/(1+24.4*(not inch)))/(figsize[0]/0.75) # Giving 50 mm mandatory position shift for the Y axis, to accommodate the title, labels and ticks.
hpos = (40/(1+24.4*(not inch)))/(figsize[1]/0.75) # Giving 40 mm mandatory position shift for the X axis to accommodate the title, labels and ticks.
# Now comes the problem. The AXIS size is defined relatively to the FIGURE size. The following values will simply use the rescaled FIGURE sizes:
wscale = 1/width_scale # = (width_scale*figsize[0]/0.75)/width_scale = figsize[0]/0.75 which is our target size for Inkscape.
hscale = 1/height_scale
ax = fig.add_axes([wpos, hpos, wscale, hscale])
Then you can plot at will, copy the SVG output (in Spyder's IPython console, at least) and paste it in Inkscape.
The only set back is that the whole FIGURE size will be abnormal and you'll have to remove the white background from it in Inkscape. But that is something probably all of us already do.
This is a minimal working code. You can paste it in your IPython console and copy the SVG output, paste it in Inkscape and check the axis line size. It will be with a width of 50 mm and a height of 20 mm.

gnuplot - making use of the yrange in pie charts?

This only works for me if I do not set a yrange.
Let's say I have a sample-time-overview.csv like
,avg,std,,,TProc,2267.5202096317,4573.0532262204
TParse,4.9922379603,138.6595434301,,,,,
THash,86.4020623229,548.8593468508,,,,,
TEnq,1.1181869688,2.0684998031,,,,,
TInQ,1482.2243626062,4257.8024051927,,,,,
TSend,2253.1871161473,4514.2823125251,,,,,
TWait,1.7578696884,43.1050730747,,,,,
TAnsw,14.3452407932,201.9216484892,,,,,
TProcAll,2269.2780793201,4573.3927526674,,,,,
TTotal,3853.3679320114,7095.0740689587,,,,,
where I am not interested in the first or last two lines.
Basically copy-pasted the code from the link above with minor adjusts:
#!/usr/bin/gnuplot
reset
filename = "sample-time-overview"
set terminal pngcairo size 500,500 enhanced font 'Verdana,10'
set output filename."_piechart.png"
#set title ""
unset border
unset tics
set xrange[-1:1.5]
#uncommend yrange and the plotdisappears
#set yrange[-1.25:1.25]
centerX=0
centerY=0
radius=1
set datafile separator ','
set key off
set style fill solid 1
stats filename.".csv" u 2 every ::1::7 noout prefix "A"
angle(x)=x*360/A_sum
percentage(x)=x*100/A_sum
pos=0.0
colour=0
yi=0
plot filename.".csv" u (centerX):(centerY):(radius):(pos):(pos=pos+angle($2)):(colour=colour+1) every::1::7 w circle lc var
system(sprintf("display %s_piechart.png", filename))
this ends up looking like
I uncomment the yrange and comment the unset border and it looks like this:
which is very annoying because when I then try to add labels ...
plot filename.".csv" u (centerX):(centerY):(radius):(pos):(pos=pos+angle($2)):(colour=colour+1) every::1::7 w circle lc var,\
"" u (1.5):(yi=yi+0.5/A_records):($1) every::1::7 w labels
this will happen:
Which I suspect is due to the missing yrange (because other than that, the code doesn't differ much from what was posted in the linked answer).
How do I get the bloody thing working?
It is better to configure graph properties just before the plot command. Other routines (e.g. stats and thus A_sum) will be affected by these properties (e.g. set yrange).
This is why the pie chart disappears.
Also, be sure to have equal unit lengths for the x and y axes (use set size ratio -1). If not, the circumference will be drawn with respect to the canvas size, and not with respect to the axes. The pie chart will appear cut otherwise (unless an appropriate yrange is given).
With some modifications, I obtain this chart:
This is the code:
filename = 'sample-time-overview'
rowi = 1
rowf = 7
# obtain sum(column(2)) from rows 1 to 7
set datafile separator ','
stats filename.'.csv' u 2 every ::rowi::rowf noout prefix "A"
angle(x)=x*360/A_sum
percentage(x)=x*100/A_sum
# circumference dimensions for pie-chart
centerX=0
centerY=0
radius=1
# label positions
yposmin = 0.0
yposmax = 0.95*radius
xpos = 1.5*radius
ypos(i) = yposmax - i*(yposmax-yposmin)/(1.0*rowf-rowi)
#-------------------------------------------------------------------
# now we can configure the canvas
set style fill solid 1 # filled pie-chart
unset key # no automatic labels
unset tics # remove tics
unset border # remove borders; if some label is missing, comment to see what is happening
set size ratio -1 # equal scale length
set xrange [-radius:2*radius] # [-1:2] leaves place for labels
set yrange [-radius:radius] # [-1:1]
#-------------------------------------------------------------------
pos = 0 # init angle
colour = 0 # init colour
# 1st line: plot pie-chart
# 2nd line: draw colored boxes at (xpos):(ypos)
# 3rd line: place labels at (xpos+offset):(ypos)
plot filename.'.csv' u (centerX):(centerY):(radius):(pos):(pos=pos+angle($2)):(colour=colour+1) every ::rowi::rowf w circle lc var,\
for [i=0:rowf-rowi] '+' u (xpos):(ypos(i)) w p pt 5 ps 4 lc i+1,\
for [i=0:rowf-rowi] filename.'.csv' u (xpos):(ypos(i)):(sprintf('%05.2f%% %s', percentage($2), stringcolumn(1))) every ::i+1::i+1 w labels left offset 3,0
Setting yrange also influences the execution of the stats command. Therefore you should try to set yrange[-1.25:1.25] after the stats command, not before.
PS:
Plotting the labels with
plot filename.'.csv' u (1.5):(yi=yi+0.5/A_records):($1) every::1::7 w labels
does not work for me. I have to remove the dollar sign:
plot filename.'.csv' u (1.5):(yi=yi+0.5/A_records):1 every::1::7 w labels
And I have to adjust the values 1.5 and 0.5 a little bit.

Error bar fine-tuning in gnuplot

I am trying to give different colors to the error bars in a bar plot using gnuplot, but I couldn't. Some of the default color combinations between the bar on which the error line sits are not good. I tried in python and got what I wanted, but would like to get a similar output using gnuplot.
The top picture is produced using the following MWE:
reset
set term postscript eps size 5.5,4.5 enhanced color font 'Arial-Bold' 25
set output 'check.eps'
set style fill solid 0.3 noborder
set bars front
set key horizontal Left reverse noenhanced autotitles nobox
set style histogram errorbars linewidth 9
set style data histograms
set xlabel " "
set xtics rotate by -45
set xlabel offset character 0, -1, 0
set yrange [0:100]
set ylabel "%"
plot \
newhistogram "label 1",'check.mat' \
using 2:3:4:xtic(1) t "M1", \
'' u 6:7:8 t "M2",\
newhistogram "label 2", '' u 10:11:12:xtic(1) t "M1",\
'' u 14:15:16:xtic(1) t "M2",\
newhistogram "label 3", '' u 14:15:16:xtic(1) t "M1",\
'' u 18:19:20:xtic(1) t "M2" lc rgb "black"
quit
I produced the bottom picture following the example given here: python matplotlib example. The colors for the error lines can be controlled using the variable ecolor in python. Do we have something similar in gnuplot?
I also don't understand why gnuplot is giving me dotted error lines for some of the cases. Is it possible to make them all solid?
I am beginner in gnuplot, so any help is greatly appreciated!

How to create an axis with relative position to other axis?

I have several fcontour plots, each with a colorbar. For the colorbar I'm creating extra axis. It is possible to set the position of the colorbar axis relative to their fcontour axis?
Im only able to set the position from axis relative to the figure. Thanks!
After reading the docs about mpl_toolkit.axes_grid as tcaswell suggested, I used divider = make_axes_locatable(ax) and cax = divider.append_axes("right", size="4.45%", pad=0.07,aspect = True). Usually divider.append_axes appends an axes with the same height to your plot, but as it seems you can change that setting aspect = True, and then modifying the aspect via cax.set_aspect and the size of your new axes.
The result is a colorbar which ALWAYS is beside its plot, and in my case it is a little shorter than the plot itself.
thanks tcaswell! :D

Gnuplot: plotting histograms on Y-axis

I'm trying to plot a histogram for the following data:
<text>,<percentage>
--------------------
"Statement A",50%
"Statement B",20%
"Statement C",30%
I used the set datafile separator "," to obtain the corresponding columns. The plot should have percentage on the X-axis and the statements on the Y-axis (full character string). So each histogram is horizontal.
How can I do this in gnuplot?
Or is there other tools for plotting good vector images?
The gnuplot histogram and boxes plotting styles are for vertical boxes. To get horizontal boxes, you can use boxxyerrorbars.
For the strings as y-labels, I use yticlabels and place the boxes at the y-values 0, 1 and 2 (according to the row in the data file, which is accessed with $0).
I let gnuplot treat the second column as numerical value, which strips the % off. It is added later in the formatting of the xtics:
set datafile separator ','
set format x '%g%%'
set style fill solid
plot 'data.txt' using ($2*0.5):0:($2*0.5):(0.4):yticlabels(1) with boxxyerrorbars t ''
The result with version 4.6.4 is:
#Christoph Thank you. Your answer helped me.
#Slayer Regarding your question to add labels using gnuplot v5.2 patchlevel 6 and using #Christoph's provided sample.
Sample Code:
# set the data file delimiter
set datafile separator ','
# set the x-axiz labels to show percentage
set format x '%g%%'
# set the x-axis min and max range
set xrange [ 0 : 100]
# set the style of the bars
set style fill solid
# set the textbox style with a blue line colour
set style textbox opaque border lc "blue"
# plot the data graph and place the labels on the bars
plot 'plotv.txt' using ($2*0.5):0:($2*0.5):(0.3):yticlabels(1) with boxxyerrorbars t '', \
'' using 2:0:2 with labels center boxed notitle column
Sample Data Provided:(plotv.txt)
<text>,<percentage>
--------------------
"Statement A",50%
"Statement B",20%
"Statement C",30%
Reference(s):
gnuplot 5.2 demo sample - textbox and the related sample data
gnuplot