As stated in the title, I want to plot a bar which doesn't start from the axis(i.e., where x or y is 0). I tried to use the pgfplots package but I failed to achieve what I need. It doesn't matter if the bars are vertical or horizontal, I just need to find a way to plot the values (as indicated in the table) as bars to show how far from the optimal interval (20-30) they span as shown in the sketch.
sketch
intervals of C/N ratios
Related
full - clearest image, shows the labels extending out the right of my plot
"zoomed" - highlighting why this is a problem as the plot becomes unreadable when selecting and plotting subset of the x-axis range
I'm working on some data where I have plotted a spectrum and have added vertical lines to specific positions. I have labelled these lines but my problem is that if I want to "zoom in" by decreasing my x axis range, the full list of labels for the vertical lines are still plotted resulting in an unreadable plot.
I iterate through a list of x positions and labels for my vertical lines and plot as follows:
for x_pos, label in zip(list_x_pos, list_label):
plt.axvline(x=x_pos)
plt.text(x_pos, y, str(label), rotation=90)
plt.xlim(2, 5)
So, because my "x values" go > 5 the resulting plot is a tiny figure with a row of the labels extending out from it.
The only solution I can think of is to slice my list_x_pos but this will crate other problems for me so ideally looking to find a way to just show the labels within the range of the plot.
Hope I've made sense!
Thanks,
Olie
You can use plt.text(..., clip_on=True) to force texts outside of the box to not be displayed.
Resize the axes first and then plot the vertical line.
I have a gnuplot script that produces bar graphs like this:
The input data is in files that have a number of columns, each column ultimately contributes to a cluster in the chart (2 clusters shown in the example). Each file contributes to a bar in the chart (there are 9 in the example). Each file may have a large number of rows.
The script takes the input data files and, using the stats command, produces new files containing one row per column of the original files. Each row contains a mean, min and max value for its source column.
These new files are then used to plot the bar chart with error bars. Each file represents one bar and each row contributes to one cluster. The plot code is as follows:
plot for [f in FILES] f.'.stats' using 2:3:4 title columnhead(1), \
'' using (0):xticlabels(1) with lines
Now I have a second set of files and that produce another similar bar chart. I would like to combine these charts onto one so there will be two rows of 3-D bars, one in front of the other (rendered with a 3-D style - the new 'z' axis representing the two data sets (two sets of FILES).
Here is an example to illustrate the look I'm after (obviously not made with gnuplot!):
Can I do this with Gunplot?
I have read the user manual and the Gnuplot In Action book but haven't found anything that would indicate this is possible.
gnuplot version 5.3 (the development branch) adds a 3D barchart variant
3D boxes demo. However rendering the boxes in 3D unfortunately depends on features that were not present in earlier gnuplot release versions so I cannot offer a work-around for the current one (5.2.4). Also the new 3D variant does not show error bars, although I think one could construct a plot command that would add them.
I produced a 3D bar chart using the development 5.3 version (git checkout). Here is my splot command:
splot for [c = 1:ncats] for [f = 1:nfiles] \
word(cat_files[c],f).'.stats' \
using (f+column(0)*(nfiles+2)):(scale_y(c)):2 \
with boxes \
title (c==1 ? columnhead(1) : '')
The input data is in a set of 'stats' files as described in the question. To draw the plot, I separated the input FILES into categories - two (ncats) sets of files held in the array cat_files, each containing the same number of files (nfiles).
The categores equate to positions on the y-axis (rows) and the individual files equate to positions on the x-axis (bars). Rows in each file equate to clusters of bars and the values in each row is the bar height which is the Z axis. The Z axis was the Y axis in the 2D model. The nasty expressions are to position the bars on the x and y axes as I explain below.
I had a lot of difficulty getting this to work but I think that the result looks good:
The problems, which I cover below are:
matching colours between chart 'rows' of the y-axis
bar dimensions - making square bars is very hit-and-miss, hence my scale_y function.
x-axis label orientation
repeated items in the key, hence conditional expression for title.
no clustering support, hence nasty positioning expressions
What I have is brittle---it works on my Linux system but relies heavily on shell helpers. But it works. Hopefully this information helps others or can be taken as feedback to improve gnuplot to make it even more awesome!
Colours
To get the colours in each data set to line up, I set linetype cycle nfiles and hope gnuplot defines sufficient colours.
The reason for doing this is to reset the colour assignment between file sets (categories on the y-axis) so that the same bar in different file sets had the same colour. By explictly setting it to cycle after the known number of files (chart bars) I ensured the colours matched.
Bar dimensions
The bar dimensions (boxwidth and boxdepth) are relative to the axis ranges and it's therefore difficult to make them square.
If a bar rests on the extreme of the y axis (lower or upper) then it is cut in half vertically (it's visible box depth is half the defined boxdepth value).
I had to play with scaling the y axis so that my two category sets were displayed near each other. The default behaviour displayed a range from 1 to 2 in steps of 0.2 and placed the two plots at 1 and 2, making them appear far apart.
I tried set ytics to no effect. I ended up scaling the y value.
scale(y) = 0.1 * y - 0.05
set yrange [0:1]
set boxdepth (0.8 / clusters)
all the numbers are fudge factors. clusters is the number of clusters (rows in files). The numbers I have maintain a square appearance with my test data (I have data to display up to 5 clusters).
I had to start the x axis at 0.5 otherwise the first bar would appear too far in (if x starts at 0) or vertically half-cut off (if x starts at 1).
set xrange [0.5:*]
Axis labels
I replaced the automatic tick marks with custom labels. On the Y axis:
set ytics ()
set for [c = 1:ncats] ytics add (word(CATS,c) scale_y(c) )
Similarly for the x axis. First, where there is 1 cluster I label each category
set xtics ()
set for [f = 1:nfiles] xtics add (label(word(cat_files[1],f)) f)
Or where there are multiple clusters, I label the clusters:
set xtics ()
set set for [c = 2:(clusters+1)] xtics add (cell(f,c,1) (nfiles/2)+2+((c-2)*nfiles))
Here, cell is a shell helper that returns the value from file f at row c position 1. The horrible formula is a hack to position the label along the axis in the middle of the cluster. I also use shell helpers to get the number of clusters. I could not find a way in gnuplot to query rows and columns. Note that previously (when 2D plotting) I would have used xticlabels(1) to plot the clusered x-axis.
I wanted to turn the x labels to run perpendicular to the axis but this doesn't seem possible. I also wanted to tweak their positions with 'right' alignment but couldn't make that work either.
Key labels
An entry is added into the key for each bar plotted. Because these are repeated within each category they get duplicted in the key. I made it only add them once by using a conditional, changing from
title columnhead(1)
to
title (c==1 ? columnhead(1) : '')
I only show the key when there is more than one cluster.
Clustering
The 2D plot was clustered. I had difficulty making a clustered appearance in 3D. If I run the plot on clustered data then they overlay (they have the same Y values). To overcome this I used a formula to shift latter clusters along the x-axis and add a gap between them. So instead of a simple value for x:
... using (f):(scale_y(c)):2 ...
I have a formula:
... using (f+column(0)*(nfiles+2)):(scale_y(c)):2 ...
where f is the file number (eq. the bar number), column(0) is the cluster number, nfiles is the number of files (eq. the numer of bars, or cluster size), and 2 is the separator gap.
Incidentally, whilst doing this I discovered that ($0) doesn't work in gnuplot 5.3, you have to use column(0) instead ($0 works in 5.2.4).
I used the Arch Linux AUR package to build which gave me a package gnuplot-git-5.3r20180810.10527-1-x86_64.pkg.tar.xz.
An example plot with one cluster.
An example plot with three clusters and a key legend.
There are probably better ways to do the things I've done here. Being relatively new to gnuplot, I would be interested in any ways to improve upon this solution.
(I can't figure out how to format text in a comment, so I'll provide this as a separate answer)
Matching color: This is more reliably done by providing the color in a separate field of the using spec. From the help text:
splot with boxes requires at least 3 columns of input data. Additional
input columns may be used to provide information such as box width or
fill color.
3 columns: x y z
4 columns: x y z [x_width or color]
5 columns: x y z x_width color
The last column is used as a color only if the splot command specifies a
variable color mode. Examples
splot 'blue_boxes.dat' using 1:2:3 fc "blue"
splot 'rgb_boxes.dat' using 1:2:3:4 fc rgb variable
splot 'category_boxes.dat' using 1:2:3:4:5 lc variable
In the first example all boxes are blue and have the width previously set
by set boxwidth. In the second example the box width is still taken from
set boxwidth because the 4th column is interpreted as a 24-bit RGB color.
The third example command reads box width from column 4 and interprets the
value in column 5 as an integer linetype from which the color is derived.
Half-depth boxes at each end: This was an autoscaling bug (now fixed)
Please have a look at This Excel chart. Here is a screenshot:
Here is the data:
There is a scatter series of blue of dots (plus a trendline) and a green area series. The chart data are contained within the series.
The problem I have is that the x-axis values of the two series are not aligned. For example, the second and third blue dots at x = 3.1 and x = 3.8 are in the correct place along the x-axis, but in the green area series they appear to be above x = 2.0 and x = 3.3. How to fix this?
Change the Scatter to a Line Chart, then format Line Color so that there is "No Line". Add trendline.
There may be another way to do this while retaining the Scatterplot, I'm not sure, but this seems to be visually what you're looking for, but I think you will need to use a Line Chart for this unfortunately. The problem is summarized in this similar Q on SuperUser:
https://superuser.com/questions/964264/aligning-stacked-bar-chart-w-scatter-plot-data
The short answer is that your combining (unsuccessfully) a categorical series (the columns) with interval/ratio series (the line charts). So, Excel doesn't know how to plot your categories (columns) on an interval scale (the current X axis).
You can verify this by selecting Chart > Layout > Axes > Secondary Horizontal Axis > More Secondary Horizontal Axis Options. Without making any changes to the axes configuration, the second X-axis will now appear along the bottom of the chart, and you can see it is scaled differently from your Scatter data.
I.e., in the Scatter series, the data is X/Y pairs. But in your Area chart, it treats the X-values as categorical, and in this context "1.1" is no different than "Bob" -- it is a cardinal representation of the data rather than an ordinal representation.
The problem I have is that the x-axis values of the two series are not aligned.
So even though the two series appear to share the same set of X-Values, the Chart is simply incapable of treating those as the same type of data. The x-axes are not aligned because they are not the same data or even the same type of data!
All that said, if you change both series to XY Scatter, it is possible (with some extraordinary effort) to apply shading/coloring below a series or between two series, etc.
http://peltiertech.com/fill-under-between-series-in-excel-chart/
http://chandoo.org/wp/2013/02/13/shaded-line-charts-excel/
What you can do is plot the Area graph on a secondary axis. Then go to Chart -> Layout -> Axes -> Display Secondary Horizontal Axis to see the axis, right click for its properties and change the type of the Axis Type to "Date axis". This (kind of) changes the axis to a numerical type, as opposed to a category type.
However, the area graph will still be placed incorrectly too far to the right because Excel will continue to plot the series as a (kind of) category type, with its data points appearing in the centre of each category as opposed to at the correct x value like in an XY scatter plot.
To get the graphs overlaying the most correctly, you can create a Scaled-up x value series which is, say, 1,000 times the original x-values and use this for the x-values of the area plot. By scaling by 1,000 or 10,000, you eventually get the granularity to a point where it looks more like X-Y plot, but is actually an area plot, and the graphs look like they coincide perfectly.
I've made a chart with Excel 2010's "Combo" option for chart type so I can plot two data series for the same depth points. The image below shows the default, which is very close to what I want - except I would like to have the axes flipped so that the current X axis, which is depth, is displayed as the Y axis and both primary and secondary current Y axes plot as X axes. In other words, I'd like to rotate the chart area by 90 degrees clockwise. The "Switch Row/Column" doesn't do what I want (or expect) and I'm running out of both ideas and patience. Is there an easy fix? Or a hard fix?
Here's the plot as-is:
And here's a dummy plot of the end goal made by rotating the image around in Paint, in case the picture makes it clearer:
Finally, as was pointed out in the comments, the whole thing looks goofy and might be better plotted as a bar graph with two bars. I tried this as well and came away almost all set - but the gray bars plot from left to right and the blue bars plot from right to left. Seems like it should be as simple as changing the "Plot Series On" option to Primary Axis for both, but this destroys the graph.
I looked around and I think this link has instructions for what you're looking for: https://superuser.com/questions/188064/excel-chart-with-two-x-axes-horizontal-possible
I saw some Core-plot sample. Is there anything equivalent that will do my task easily? I also want to know feasibility with Core-plot in iPhone. (any issues with core-plot)
I want to have multi-colored vertical bar chart. Is it possible to customize Core-plot framework. Using only one barplot can we have multiple segment on it.
Thank you.
Naveen Thunga
To make a stacked bar plot, you need to make multiple plots, one for each segment. On all but the bottom plot, set barBasesVary to YES. The datasource will ask for a third field called CPTBarPlotFieldBarBase which is the base value for the bar. You will have to do the stacking calculations yourself.
The horizontal lines can be drawn using an additional bar plot. Give the bars a short height (tip - base). You can make the width wider than the others if you want--each plot is independent.
The space between the bars depends on several factors. By default, bar widths are specified in data coordinates. For example, if the bar locations are one unit apart, a bar width of 0.5 will make the bar width and the space between the bars equal; a bar width of 0.75 will make the space 1/3 of the bar width. The actual width in pixels depends on the size of the graph and how many bars are visible (determined by the plot range along that axis). If barWidthsAreInViewCoordinates is YES, then bar widths are given in pixels which keeps them the same apparent width as the plot range changes, but the space between them will change with the plot range.